在上次完成嵌入式应用的Linux裁减后,Linux的启动时间仍需要7s左右,虽然勉强可以接受,但仍然没有达到我个人所追求的目标——2s以内。况且,在实际的商用环境中,设备可靠性的要求可是“5个9”(99.999%,即OOS时间低于5分钟/年),这就意味着每减少一秒钟Linux启动(设备复位)时间,对可靠性都是一个明显的提升。

言归正传,如何着手对Linux的启动时间进行优化呢?

CELF(TheConsumerElectronicsLinuxForum)论坛为我们指引了一个方向。

(1)首先是对Linux启动过程的跟踪和分析,生成详细的启动时间报告。

较为简单可行的方式是通过PrintkTime功能为启动过程的所有内核信息增加时间戳,便于汇总分析。PrintkTime最早为CELF所提供的一个内核补丁,在后来的Kernel2.6.11版本中正式纳入标准内核。所以大家可能在新版本的内核中直接启用该功能。如果你的Linux内核因为某些原因不能更新为2.6.11之后的版本,那么可以参考CELF提供的方法修改或直接下载它们提供的补丁:linuxforum.org/CelfPubWiki">http://tree.celinuxforum.org/CelfPubWiki/PrintkTimes

开启PrintkTime功能的方法很简单,只需在内核启动参数中增加“time”即可。当然,你也可以选择在编译内核时直接指定“Kernelhacking”中的“Showtiminginformationonprintks”来强制每次启动均为内核信息增加时间戳。这一种方式还有另一个好处:你可以得到内核在解析启动参数前所有信息的时间。因此,我选择后一种方式。

当完成上述配置后,重新启动Linux,然后通过以下命令将内核启动信息输出到文件:

dmesg-s131072>ktime

然后利用一个脚本“show_delta”(位于Linux源码的s文件夹下)将上述输出的文件转换为时间增量显示格式:

/usr/src/linux-x.xx.xx/s/show_deltaktime>dtime

这样,你就得到了一份关于Linux启动时间消耗的详细报告。

(2)然后,我们就来通过这份报告,找出启动中相对耗时的过程。

必须明确一点:报告中的时间增量和内核信息之间没有必然的对应关系,真正的时间消耗必须从内核源码入手分析。

这一点对于稍微熟悉编程的朋友来说都不难理解,因为时间增量只是两次调用printk之间的时间差值。通常来说,内核启动过程中在完成一些耗时的任务,如创建hash索引、probe硬件设备等操作后会通过printk将结果打印出来,这种情况下,时间增量往往反映的是信息对应过程的耗时;但有些时候,内核是在调用printk输出信息后才开始相应的过程,那么报告中内核信息相应过程的时间消耗对应的是其下一行的时间增量;还有一些时候,时间消耗在了两次内核信息输出之间的某个不确定的时段,这样时间增量可能就完全无法通过内核信息反应出来了。

所以,为了准确判断真正的时间消耗,我们需要结合内核源码进行分析。必要的时候,例如上述第三种情形下,还得自己在源码中插入printk打印,以进一步确定实际的时间消耗过程。

以下是我上次裁减后Linux内核的启动分析:

内核启动总时间:6.188s

关键的耗时部分:

1)0.652s-Timer,IRQ,Cache,MemPages等核心部分的初始化

2)0.611s-内核与RTC时钟同步

3)0.328s-计算CalibratingDelay(4个CPU核心的总消耗)

4)0.144s-校准APIC时钟

5)0.312s-校准MigrationCost

6)3.520s-IntelE1000网卡初始化

下面,将针对上述各部分进行逐一分析和化解。

(3)接下来,进行具体的分项优化。

CELF已经提出了一整套针对消费类电子产品所使用的嵌入式Linux的启动优化方案,但是由于面向不同应用,所以我们只能部分借鉴他们的经验,针对自己面对的问题作出具体的分析和尝试。

内核关键部分(Timer、IRQ、Cache、MemPages……)的初始化目前暂时没有比较可靠和可行的优化方案,所以暂不考虑。

对于上面分析结果中的2、3两项,CELF已有专项的优化方案:“RTCNoSync”和“PresetLPJ”。

前者通过屏蔽启动过程中所进行的RTC时钟同步或者将这一过程放到启动后进行(视具体应用对时钟精度的需求而定),实现起来比较容易,但需要为内核打补丁。似乎CELF目前的工作仅仅是去掉了该过程,而没有实现所提到的“延后”处理RTC时钟的同步。考虑到这个原因,我的方案中暂时没有引入这一优化(毕竟它所带来的时间漂移已经达到了“秒”级),继续关注中。

后者是通过在启动参数中强制指定LPJ值而跳过实际的计算过程,这是基于LPJ值在硬件条件不变的情况下不会变化的考虑。所以在正常启动后记录下内核信息中的“CalibratingDelay”数值后就可以在启动参数中以下面的形式强制指定LPJ值了:

lpj=9600700

上面分析结果中的4、5两项都是SMP初始化的一部分,因此不在CELF研究的范畴(或许将来会有采用多核的MP4出现?……),只能自力更生了。研究了一下SMP的初始化代码,发现“MigrationCost”其实也可以像“CalibratingDelay”采用预置的方式跳过校准时间。方法类似,最后在内核启动参数中增加:

migration_cost=4000,4000

而Intel的网卡驱动初始化优化起来就比较麻烦了,虽然也是开源,但读硬件驱动完全不比读一般的C代码,况且建立在如此肤浅理解基础上的“优化”修改也实在难保万全。基于可靠性的考虑,我最终在两次尝试均告失败后放弃了这一条路。那么,换一个思维角度,可以借鉴CELF在“ParallelRCs”方案中的“并行初始化”思想,将网卡驱动独立编译为模块,放在初始化脚本中与其它模块和应用同步加载,从而消除Probe阻塞对启动时间的影响。考虑到应用初始化也可能使用到网络,而在我们的实际硬件环境中,只有eth0是供应用使用的,因此需要将第一个网口初始化的0.3s时间计算在内。

除了在我的方案中所遇到的上述各优化点,CELF还提出了一些你可能会感兴趣的有特定针对性的专项优化,如:

ShortIDEDelays-缩短IDE探测时长(我的应用场景中不包含硬盘,所以用不上)

KernelXIP-直接在ROM或Flash中运行内核(考虑到兼容性因素,未采用)

IDENoProbe-跳过未连接设备的IDE口

OptimizeRCs-优化initrd中的linuxrc脚本(我采用了BusyBox更简洁的linuxrc)

以及其它一些尚处于设想阶段的优化方案,感兴趣的朋友可以访问CELFDeveloperWiki了解详情。

(4)优化结果

经过上述专项优化,以及对inittab、rcS脚本的冗余裁减,整个Linux内核的启动时间从优化前的6.188s下降到了最终的2.016s,如果不包含eth0的初始化,则仅需1.708s(eth0初始化可以和系统中间件及部分应用加载并行),基本达到了既定目标。与Kexec配合,可以大大降低软件故障导致的复位时间,有效的提升了产品的可靠性

(5)发现我加上三G模块初始化时间用了足足8秒,太慢了!其它模块基本上时间都不超500MS,ANDROID启动时间20秒,系统 很胖,码农慢慢除草去虫

linux启动时间极限优化,Linux启动时间的极限优化相关推荐

  1. Linux启动时间的极限优化(Z)

    作者: Maco    该文章转载自网络大本营:http://xrss.cn/Info/13420.Html 在上次完成嵌入式应用的Linux裁减后,Linux的启动时间仍需要 7s 左右,虽然勉强可 ...

  2. 克制linux启动盘,制作Linux启动盘的四种方法

    出处: Linux的启动软盘有boot盘和boot/root盘之分,所谓的boot盘只能用来启动已经安装在硬盘上的 Linux系统,而boot/root盘本身就是一个迷你Linux系统.Linux启动 ...

  3. linux 启动 x,(1)linux启动过程

    head.S是linux启动后的第一个文件,主要完成以下功能: 1.检查处理器信息,并保存: 2.检查平台号,并保存: 3.创建页表,并开启MMU功能: 4.对内核data section.bbs s ...

  4. linux启动脚本springboot,Linux 启动停止SpringBoot jar 程序部署Shell 脚本的方法

    废话不多说了,先给大家上代码,具体代码如下所示: #!/bin/bash cd `dirname $0` cur_shell_dir=`pwd` cur_shell_name=`basename ${ ...

  5. 各个架构下的linux启动流程-从linux被加载到start_kernel

    引言 本文关注点 在 架构相关的启动过程 代码在 arch/xxx 中arch/xxx 的作用是 1.boot(从kernel的第一行代码到start_kernel)2.start_kernel之后调 ...

  6. 嵌入式linux启动过程分析,嵌入式Linux裸机开发(二)——S5PV210启动过程分析

    嵌入式Linux裸机开发(二)--S5PV210启动过程分析 一.iROM启动方式简介 友善之臂Smart210开发板的SoC为三星S5PV210,S5PV210采用iROM启动方式进行启动,通过查阅 ...

  7. linux启动weblogic指令,linux下如何启动和关闭weblogic

    在你定义的域中能够找到以下命令: /[youHome]/domains/[yourDomain]/startWebLogic.sh /[youHome]/domains/[yourDomain]/st ...

  8. linux 启动脚本 tty,Linux启动过程简介

    许多人对Linux的启动过程感到很神秘,因为所有的启动信息都在屏幕上一闪而过.其实, Linux的启动过程并不象启动信息所显示的那样复杂,它主要分成两个阶段: 1.启动内核.在这个阶段,内核装入内存并 ...

  9. linux启动xorg进程,Linux 黑话解释:Xorg,X11,Wayland,什么是显示服务器

    原标题:Linux 黑话解释:Xorg,X11,Wayland,什么是显示服务器 您是否想知道X Server,Xorg,X11,Wayland以及诸如此类的东西到底是什么?Wayland vs Xo ...

最新文章

  1. 与Henrik Feldt谈论Suave 1.0
  2. python分布式日志收集系统_Go实现海量日志收集系统(一)
  3. 单例带来的线程安全问题
  4. 点击panel滚动条滚动到底部
  5. PHP超级配置模块--PHP4,PHP5,module,cgi任你玩转--应用于Apache
  6. Multiple Dispatch
  7. linux gst-launch 播放视频旋转,【视频开发】Gstreamer中一些gst-launch常用命令
  8. PHP常见缓存技术分析,让重复的调用缓存以加快速度
  9. 每个人都有属于自己的机会
  10. curl -s http://192.168.232.191/openapi/v2 | jq 不显示JSON格式的文档说明
  11. 图解 Java 中的数据结构及原理,傻瓜也能看懂!
  12. c语言0x00如何不截断_数组越界及其避免方法,C语言数组越界详解
  13. 快速给视频批量添加水印,操作简单
  14. AI再造一个“李佳琦”,难嘛?
  15. word里双横线怎么打_word双下划线怎么打出来
  16. Ubuntu快速下载电驴ed2k文件
  17. 360 Pika 主从配置
  18. 计算机桌面有个方框,电脑桌面总出现蓝色框怎么办
  19. 腾讯云快速增长背后 三大短板仍需补足
  20. python编程入门与案例详解-quot;Python小屋”免费资源汇总(截至2018年11月28日)...

热门文章

  1. 生物技术行业十年回顾:微生物组发展未达预期?
  2. 一图读懂丨2019新型冠状病毒,你需要知道什么?
  3. R语言笔记7:认识循环函数、lapply和sapply
  4. sklearn随机森林模型:ValueError: Unknown label type: ‘unknown‘
  5. R语言对dataframe进行行数据筛选(row selection)多种方案:使用R原生方法、data.table、dplyr等方案
  6. R回归模型glm与lm的区别
  7. java jibx_Jibx 处理XML
  8. java message bus_【Microsoft Azure学习之旅】消息服务Service Bus的学习笔记及Demo示例...
  9. IBM Bluemix云计算大会见闻
  10. K近邻算法KNN的简述