kernel启动优化

来源:互联网 发布:手机淘宝买家实名认证 编辑:程序博客网 时间:2024/06/06 03:21


由于老衲最近在做车载linux kernel优化,特别是对启动时间的优化,从一开始的漫无目的,到现在的算是了解的过程,下了很大功夫。

特别是优化到最后2s以内,每10ms的优化太让人吐血了。杂话不多说,开整。

工欲善其事,必先利其器。

要调整启动时间,肯定得需要一个比较精确的时间戳,常用的有直接在kernel的menuconfig中选中printk_time,这样每条log前面都会打出相应的时间。这个就可以直接在menuconfig中配置,比较方便。但是精度不太高,因为选中printk_time也会影响启动时间。

这里推荐使用ckermit,直接嵌套minicom,配置完了之后可以将log重定向到一个文件中,在文件中对每条log就有详细的时间戳。

ubuntu系统直接sudo apt-get  install ckemit

vim ~/.kermrc

set line /dev/ttyUSB0        #配置dbug串口                                                                                                                           
set speed 115200            #配置dbug uart速率
set carrier-watch off         #
set handshake none 
set flow-control none      # 配置硬件流控  
robust
set file type bin 
set file name lit 
set rec pack 1000
set send pack 10000
set windows 5
set protocol xmodem 
set protocol zmodem
set session-log TIMESTAMPED-TEXT # 配置log重定向格式 
log session                    #将log写入文件session中,此文件位于~/session
connect                          #自动链接串口,如果不写这条命令,需在进入ckermit 命令行后输入 c 或 connect

:wq! #保存退出

执行 sudo kermit

进入ckermit并自动链接串口,ps:如果想从串口退出 按下 "Ctrl + \" 并输入 “q”

工具配置好后,放下,开始分析从哪优化

三军未动,粮草先行

kernel启动分为三部分

uboot引导 -> kernel载入启动 -> 挂载文件系统(跑初始化脚本)

1.uboot启动

对uboot不是很了解,希望有懂的大拿能协助我完成这部分内容。对这部分只是有点想法

首先,去除万恶的bootdelay,这部分最低也是1s。其次,去除不必要的在uboot部分启动的驱动,加入MMU(别问我为什么,关于加MMU这部分是另一位大神告诉我的,据说很有用,此处也希望各位大拿协助),跳过kernel的头部信息0-4k,直接从kernel的主启动部分down入内存。

首先要了解uboot是如何将kernel down入到内存中,根据硬件不同,uboot的配置也不同,但是优化点大同小异,本人使用的硬件平台如下

norflash:16m 放置uboot与kernel

emmc:4g 放置文件系统

Arm Cortex-A9架构的freescale imx6系列

所以在我的板子上,uboot需要将uImage从norflash中down入ram中。

那么,优化点来了。。。

拷贝数据肯定要用到memcpy,memset,特别是uImage还是比较大的(我裁剪完有2.9M),能将memcpy与memset的运行速度优化了,会直接减少启动时间,这里是用汇编写了一个memcpy 与 memset,众所周知,汇编的执行效率要大于C。此处大概优化几毫秒(这个地方是从2s 优化到 1.3s的过程中考虑到的。。)

2.kernel启动

首先uImage会有一个解压缩的过程,在编译的时候,会对uImage配置一个压缩算法,常用的有bz2,gzip,lzop,(貌似现在已经不支持bz2了)那么通过对比这几种压缩算法,找出一款最适合自己的。。。

Alogrithm          % remaining     MB/s Encoding  MB/s Decoding

gzip                         13.4                       21               %2

lzop                         20.5                      135                     410

bz2                          XX                         XX                       XX

由于历史悠久,老衲已经忘却了bz2的压缩信息,不过确是与gzip差不多


那么由此看出,最适合老衲的就是lzop,因为空间大小完全不用考虑,很足够,但是解压速率是gzip的四倍不到,已经很快了。


其次就是lpj 熟悉的人一看见他就有种跳过的冲动,这货就是kernel启动时,check一下子,没什么用,只要前期都ok了,这部分就是skip用的

关于lpj的值,可以通过打log去判断,每一个硬件环境,lpj的值基本不同。


以上都是小点,little point, 其实占用时间最长的  就是 启动kernel时 加载各个模块,跑各个probe所占用的时间

这部分分为三部:

1)内核裁剪,将用不着的模块干掉。

2)优化所需build-in的启动时间

这里需要详细说一下,有个技巧,就是在kernel目录下的 init/main.c中 do_initcalls函数中

            static void __init do_initcalls(void)                                                                                                                   
{
    initcall_t *fn;
    for (fn = __early_initcall_end; fn < __initcall_end; fn++){
    //  printk("==========================now will call : %p\n",fn);
        do_one_initcall(*fn);
    }   
}
将printk那行打开即可。

这里会调到所有注册在module_init段中的函数

换句话说就是你需要编译的module都会在这调用。那么就会很方便的 查看出哪个模块占用多少时间。从而去针对性的优化。


其他的 都是一些简单的,比如说优化log等级,优化开机logo,将无用模块搬入文件系统启动。(类似于延时启动)

3.文件系统优化

水太深,老衲用的还是比较旧的

由于各个文件系统不同,启动sequence也不一样。业内公认启动最快的是systemd,因为这货竟然是并发启动。


由于板子不同,需求不同,所以每个不同的系统的优化肯定有很多不同之处


希望大家多多讨论,将我没有 涉及到的,或者优化的不对的地方翻出来,一起研究研究。  


0 0
原创粉丝点击