怎样在 1 秒内启动 Linux - 开源中国社区
怎样在 1 秒内启动 Linux
oschina 2015年12月04日

怎样在 1 秒内启动 Linux

oschina oschina 发布于2015年12月04日 收藏 155 评论 29

尽可能快的启动系统,对于自动化设备是非常重要的。系统能够在用户无法感知的时间内启动,也就意味着在不需要工作时,可以完全切断电源,而不是挂起 进入休眠状态。本文基于Atmel AT91系列片上系统和NAND闪存,经过一系列的优化,将Linux系统启动时间,从最初的11秒,降低到最终的656毫秒。

背景知识

系统从上电到完全启动,需要经过许多过程。一个简化的启动流程大概包含:

  1. 硬件重置

  2. 启动引导程序(bootloader)

  3. 操作系统初始化

  4. 应用程序执行

其中硬件非常关键,但是硬件一般难以更改。后续的优化,主要针对引导程序、Linux内核和应用程序展开。

引导程序优化

引导程序主要完成对CPU的基础设置,处理ARM标记(ATAGS,ARM TAGS)或设备树(device trees),切换存储管理单元(MMU,Memory Management Unit)等工作。

对于U-Boot,常用的优化方式有:

  • 删除不不要的功能:如网络加载等,如果不需要,那么直接移除这些代码吧;

  • 关闭不需要的功能

    • 关闭内核镜像验证

    • 关闭引导程序输出

    • 关闭启动延迟

  • 将通用功能的引导程序修改成一个优化后的初始程序加载器(Initial Program Loader,IPL),对于U-Boot,可以通过SPL(Second Program Loader,第二阶段程序加载器)来实现。

内核优化

Linux内核被设计的非常灵活,可以针对需要的功能做各种配置优化。因此,优化内核对于系统启动速度是至关重要的。

首先,移除一切不要的驱动,尽可能的减少内核加载的内容,能够大大缩短系统启动时间。其次,还有很多内核选择可能需要进一步尝试,比如内核压缩方 式,对于嵌入式系统来说,LZO压缩方式,通常会是一个不错的选择。最后,还可以通过定制一些启动参数,达到加快启动的目的。例如可以通过“lpj=”参 数,预设每个循环需要的节拍数(loops per jiffy,lpj)的值,避免系统在启动时自动推算。这样在基于ARMv5的系统中,可以节省100ms以上的时间。

对于内核启动的优化,可以通过bootgraph.pl脚本(位于内核源码的script/bootgraph.pl)来绘制内核启动耗时图表,用以分析启动最耗时的地方。这个脚本使用非常简单,直接将dmesg的输出作为其输入,即可生成svg图表:

dmesg | perl scripts/bootgraph.pl > output.svg

生成的图表如下图,

图中每一个色段表示一个功能的初始化耗时。可以简单的关闭不需要的功能,或者针对功能进行特定的优化。

除了内核本身之外,内核所在的文件系统也对系统启动有着非常大的影响。对于使用闪存芯片作为存储的系统来说,UbiFS是一个很好的选择。它能够容忍意外断电,有着出色的挂载速度,以确保系统快速启动。

应用程序优化

内核完成系统启动之后,接来下就是执行应用程序。对于应用程序的优化,主要有两部分,一部分是由应用程序来接管启动的INIT进程,另一部分是优化应用程序的链接方式。

标准的SystemV INIT程序,需要执行一堆启动脚本。对于嵌入式系统来说,大部分是没有意义的。另一部分(比如挂载文件系统),可以由应用程序自己来实现。然后,可以在内核启动参数中通过“init=”参数,将INIT进程直接指定为应用程序。

应用依赖的动态链接库,会按照以下顺序查找:

  1. LD_PRELOAD环境变量指定的路径(一般对应文件/etc/ld.so.preload);

  2. ELF .dynamic节中DT_RPATH入口指定的路径,若DT_RUNPATH入口不存在的话;

  3. 环境变量LD_LIBRARY_PATH指定的路径,但如果可执行文件有setuid/setgid权限,则忽略这个路径;编译时指定--library-path会覆盖这个路径;

  4. ELF .dynamic节中DT_RUNPATH入口指定的路径;

  5. ldconfig缓存中的路径(一般对应/etc/ld.so.cache文件),若编译时使用了-z nodeflib的链接选项,则此步跳过;

  6. /lib,然后/usr/lib路径 ,若使用了-z nodeflib链接选项,则此步亦跳过;

因此,尽可能的将应用程序依赖的动态链接库放到优先查找的路径,可以加快链接速度。对于交叉编译环境特别需要注意,主机上的动态链接库位置和目标系统上的位置可能不一致,这会增加应用程序执行时动态链接库的加载时间。

总结

基于上面提到的三个优化点,可以将系统的启动时间,从最初的11s降低到656ms(数据参考Jan Altenberg在都柏林举行的嵌入式Linux会议上的演讲稿)。从硬件到引导程序再到内核最后到应用程序,每个启动步骤都有自己可优化的地方,经过一些简单的优化,就可以减少系统的启动时间。

转载自 InfoQ

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区。
转载请注明:文章转载自 开源中国社区 [http://www.oschina.net]
本文标题:怎样在 1 秒内启动 Linux
分享
评论(29)
最新评论
0
0

引用来自“eechen”的评论

用bootchart分析Linux开机过程,关掉影响开机速度的程序
http://static.oschina.net/uploads/space/2015/0111/161616_zaGh_561214.png
sudo apt-get install bootchart pybootchartgui pngquant 重启后图片生成在 /var/log/bootchart/ 下面, PNG图片太大的话可以用 pngquant pic.png 进行压缩优化.

安装bootchart时会执行以下操作:
update-initramfs: Generating /boot/initrd.img-3.14.18-031418-generic
由一个运行在initramfs里的工具执行审计操作,记录计算机启动时的状态.
/usr/share/initramfs-tools/scripts/init-top/bootchart
update-initramfs - generate an initramfs image
sudo nano /etc/init/bootchart.conf 注释掉 start on 这一行即可禁用 bootchart.
把这个帖你blog里,不然不太好收藏
0

引用来自“宋贺”的评论

厉害,然而并没有什么用,首先你去掉了一些校验,可能会导致数据异常等问题,另外你关闭了网络加载,难道你开机后不上网吗,如果上那么你需要手动开启,这个时间可比你开机就网络加载时间要长的长。。所以追求这个秒开没有什么意义

引用来自“AUV”的评论

不可以在系统启动之后再进行加载吗?
可以在启动后加载,写个脚本应该就可以了
0

引用来自“宋贺”的评论

厉害,然而并没有什么用,首先你去掉了一些校验,可能会导致数据异常等问题,另外你关闭了网络加载,难道你开机后不上网吗,如果上那么你需要手动开启,这个时间可比你开机就网络加载时间要长的长。。所以追求这个秒开没有什么意义
不可以在系统启动之后再进行加载吗?
0

引用来自“王新明”的评论

转载害死人,人家最初做这个报告,目的是汽车智能系统的快速启动。想想看,你点火的下一秒,智能系统也就启动了,就开始能够响应你的处理请求了。
对汽车的智能系统启动速度快还是很有必要的,原作者是有使用环境限定的
0
硬件flash要跟上
0
厉害,然而并没有什么用,首先你去掉了一些校验,可能会导致数据异常等问题,另外你关闭了网络加载,难道你开机后不上网吗,如果上那么你需要手动开启,这个时间可比你开机就网络加载时间要长的长。。所以追求这个秒开没有什么意义
0
dd
0
对物联网来说快速开关机非常重要
0

引用来自“taolu0615”的评论

一直开机,开关个显示器不适最快吗?
一个是断电情况
还有就是要省电,不操作最好关机吧,虽然我从不关机
0
转到手机也行吧?可以省很多电呀
0
启动快只占体验的绝小部分
0
这就是arm/mips的优势
0
转载害死人,人家最初做这个报告,目的是汽车智能系统的快速启动。想想看,你点火的下一秒,智能系统也就启动了,就开始能够响应你的处理请求了。
0
这样精简后的微型内核,在单片机里就很ok了
0
ARM 不要 BIOS 时间的吗?
0
这么计较开机时间干嘛呢? 每天早上上班打开电脑,然后去刷杯子打水时间都够了,实在不愿意等,就不要关机
0

引用来自“taolu0615”的评论

一直开机,开关个显示器不适最快吗?
是的
0

引用来自“taolu0615”的评论

一直开机,开关个显示器不适最快吗?
这里主要是说的是在一些工控嵌入式平台上面使用Linux,和你的工作电脑需求不同。
0
用bootchart分析Linux开机过程,关掉影响开机速度的程序
http://static.oschina.net/uploads/space/2015/0111/161616_zaGh_561214.png
sudo apt-get install bootchart pybootchartgui pngquant 重启后图片生成在 /var/log/bootchart/ 下面, PNG图片太大的话可以用 pngquant pic.png 进行压缩优化.

安装bootchart时会执行以下操作:
update-initramfs: Generating /boot/initrd.img-3.14.18-031418-generic
由一个运行在initramfs里的工具执行审计操作,记录计算机启动时的状态.
/usr/share/initramfs-tools/scripts/init-top/bootchart
update-initramfs - generate an initramfs image
sudo nano /etc/init/bootchart.conf 注释掉 start on 这一行即可禁用 bootchart.
顶部