当前位置: 首页 > 科技观察

嵌入式Linux启动时间优化实践,2.41秒启动应用!

时间:2023-03-16 19:01:21 科技观察

目标系统硬件:BeagleBoneBlack(CortexA8)USB摄像头+LCD软件:Linux5.1+BuildrootrootfsFFmpeg,用于捕获视频并解码到LCD。当前启动时间:从开机到液晶显示第一张图片:9.45秒1.优化编译器ARMvsThumb2比较了基于ARM或Thumb2指令集编译的系统和应用程序。ARM:rootfs为3.79MB,ffmpeg为227KB。Thumb2:3.10MB(-18%),183KB(-19%)。性能方面:Thumb2的性能略有明显提升(约小于5%)。虽然性能有所提升,但我个人还是选择了ARM指令集。muslvsuClibcBuildroot有3种C库可供选择:glibc、musl、uClibc,这里我们只比较后2种较小的库。musl:680KB(统计/lib目录)。uClibc:570KB(-16%)。uClibc节省110KB,我们选择uClibc。2.优化应用我们可以通过./configure来选择FFmpeg的功能组件。此外,还可以通过strace和perf命令进行调试,优化FFmpeg内部的d-code。优化后的结果:文件系统:从16.11MB缩小到3.54MB(-78%)。程序加载和运行时间:快150毫秒。整体启动时间:快350毫秒。空间上的优化很大,但是启动时间上的优化很小,因为linux运行程序时只加载程序必要的部分。3、优化Init和root文件系统思路:使用bootchartd分析系统启动,削减不必要的服务。将/etc/init.d/下的启动脚本合并为一个。/proc和/sys未挂载。切掉BusyBox,文件系统越小,内核挂载的速度就越快。用我们的应用程序替换Init程序。静态编译应用程序。修剪掉不常用的文件,查找长时间未访问的文件:$find/-atime-1000-typef优化结果:文件系统:修剪Busybox后,从3.54MB缩小到2.33MB(-34%).开机时间:基本不变,可能是文件系统本身够小的缘故。使用initramfs作为rootfs:一般情况下,Linux系统会先挂载initramfs,initramfs很小,位于内存中,然后initramfs负责加载根文件系统。当我们把Buildroot的rootfs切得很小的时候,可以考虑直接当initramfs使用。那有什么好处?initramfs可以和Kernel拼接在一起,Bootloader负责将Kernel+initramfs加载到内存中,内核不再需要访问磁盘。内核不再需要块/存储和文件系统相关的功能,大小会变小,加载时间和初始化时间会更短。请注意,需要关闭initramfs压缩(CONFIG_INITRAMFS_COMPRESSION_NONE)。优化结果:即使禁用CONFIG_BLOCK和CONFIG_MMC后,总的启动时间还是长了20ms。这可能是因为Kernel+initramfs放在一起后,内核变大了很多,需要解压内核镜像,增加了解压时间。4、优化内核评估方法:在启动参数里添加initcall_debug,能得到更多内核log:[3.750000]callingov2640_i2c_driver_init+0x0/0x10@1[3.760000]initcallov2640_i2c_driver_init+0x0/0x10returned0after544usecs[3.760000]callingat91sam9x5_video_init+0x0/0x14@1[3.760000]at91sam9x5-videof0030340.lcdheo1:videodeviceregistered@0xe0d3e340,irq=24[3.770000]initcallat91sam9x5_video_init+0x0/0x14returned0after10388usecs[3.770000]callinggspca_init+0x0/0x18@1[3.770000]gspca_main:v2.14.0registered[3.770000]initcallgspca_init+0x0/0x18returned0after3966usecs...Also,youcanusescripts/bootgraph.pltoconvertdmesginformationintopictures:$scripts/bootgraph.plboot.log>boot.svgNext,findoutthelinkthatconsumesthemosttimeandoptimizeit.CutofftracingandturnoffTracersrelatedfunctionsinKernelhacking.Startuptime:550msfaster.Kernelsize:reducedby217KB.Cutoffsomeunusedhardwarefunctionsomap8250_platform_driver_init()//(660ms)cpsw_driver_init()//(112ms)am335x_child_init()//(82ms)...ThedefaultloopsperjiffywillbecalibratedeverytimeitstartsThevalueofthedelayloop,usedfortheudelay()function.Thismeasuresthevalueofloopsperjiffy(lpj).我们只需要启动一次内核,在日志中找到lpj的值:Calibratingdelayloop...996.14BogoMIPS(lpj=4980736)在启动参数中填写lpj=4980736:Calibratingdelayloop(skipped)presetvalue..996.14BogoMIPS(lpj=4980736)约82毫秒。禁用CONFIG_SMPSMP初始化很慢。它通常在默认配置中启用,即使对于单核CPU也是如此。如果我们的平台是单核的,可以禁用SMP。关机后内核缩小:-188KB(-4.6%),启动时间缩短126ms。禁用log启动参数并添加quiet,启动时间缩短577ms。在禁用CONFIG_PRINTK和CONFIG_BUG的情况下,内核缩小了118KB(-5.8%)。在禁用CONFIG_KALLSYMS的情况下,内核缩小了107KB(-5.7%)。总的来说,启动时间减少了767毫秒。打开CONFIG_EMBEDDED和CONFIG_EXPERT这将使系统调用更加精简,内核将变得不那么通用,但足以让您的应用程序保持运行状态。内核缩小了51KB。启动时间减少了34毫秒。选择SLAB内存分配器一般选择SLAB、SLOB、SLUB中的一种。SLAB:默认选择,最通用,最传统,最可靠。SLOB:更简洁,代码更少,更节省空间,适用于嵌入式系统,启用后内核减少5KB,但启动时间增加1.43S!SLUB:比较适合大型系统,启用后,启动时间会增加2ms。因此,我们仍然使用SLAB。内核压缩方式不同压缩方式的特点如下:实测结果:貌似gzip和lzo表现更好。测试效果应该和CPU/磁盘性能有关。内核编译参数启用CONFIG_CC_OPTIMIZE_FOR_SIZE,这个选项可以用gcc-Osgcc-O2代替。点击查看大图注意这只是在BeagleBoneBlack+Linux5.1上的测试结果,不同平台会有差异。禁用/proc等伪文件系统应考虑应用程序兼容性。ffmpeg依赖/proc,所以只能关闭一些proc相关的选项:CONFIG_PROC_SYSCTL、CONFIG_PROC_PAGE_MONITORCONFIG_CONFIGFS_FS,启动时间没有改变。禁用sysfs,将启动时间减少35毫秒。拼接DTB已启用CONFIG_ARM_APPENDED_DTB:$catarch/arm/boot/zImagearch/arm/boot/dts/am335x-boneblack-lcd4.dtb>zImage$setenvbootcmd'fatloadmmc0:181000000zImage;bootz81000000'启动时间减少了26毫秒。5.优化Bootloader这里我们采用最好的方案:使用UbootFalcon模式。Falcon模式只执行Uboot的第一阶段:SPL,然后跳过Stage2加载Kernel。启动时间减少了250毫秒。综上,启动优化基本完成,最终效果如下:[0.0000000.000000][0.0007850.000785]U-BootSPL2019.01(Oct272019-08:04:06+0100)[0.0578220.057822]尝试从MMC1[0.337821780.fdt_root:FDT_ERR_BADMAGIC[0.7753060.396428]Waitingfor/dev/video0tobeready...[1.9663671.191061]Startingffmpeg...[2.4122840.004277]Firstframedecoded从开机到LCD显示第一帧图像,总时间为2.41秒.最有效的步骤如下:Clicktoviewlargerimage仍然值得优化的空间:系统花了1.2秒等待USB摄像头枚举,这里有什么办法可以加快速度吗?是否可以关闭tty和终端登录?最后,在优化启动时间方面有一些准则需要遵循:请不要过早优化。从影响面最小的一些点开始优化。从上到下从rootfs、kernel、bootloader优化。聚焦短板。