Chinaunix首页 | 论坛 | 博客

oha

  • 博客访问: 179567
  • 博文数量: 187
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 1645
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

xxx

文章分类

全部博文(187)

文章存档

2018年(17)

2017年(63)

2016年(83)

2015年(23)

我的朋友

分类: LINUX

2018-04-10 17:38:34

参考原文:http://www.tinylab.org/elinux-org-boot-time-optimization/

  •  
  • 避免使用 udev,因为它花费相当一部分时间来构建 /dev 目录。在嵌入式系统中,通常会事先知道需要哪些设备,在哪些情况下用哪些驱动,所以我们知道在 /dev 下,哪些设备入口需要创建,这些应该静态而不是动态创建。所以,在这里,mknod 是友,udev 是敌,(注意系统自动分配/dev/设备文件的主从设备号的问题,如果是手动分配,复制文件到/dev/目录下是可以的,如果是自动分配,每次启动可能分配的不一样的主从设备号,再复制可能导致驱动里的主从设备号和设备文件的主从设备号不一样)。
  • 如果你还是喜欢 udev 而且也喜欢快速启动,也可以尝试这种方法:在系统启动时开启 udev 并备份它创建的设备节点。接着,修改系统的初始化脚本成这样:不再运行 udev,而是把刚备份的设备节点拷贝到 /dev 目录中,之后再像往常一样安装热插拔守护进程(即 udev)。这个戏法避免了启动时的设备节点创建但是还是可以让系统在之后(按需动态)创建设备节点。 



  • 文档网址https://tinylab.gitbooks.io/elinux/content/zh/dev_portals/Boot_Time/Boot_Time.html ;


    启动时内核命令行参数
    内核源码树下的 Documentation/kernel-parameters.txt 文件列出了所有可用的引导参数,并指明了处理每个参数的具体文件
  •  
  •   quiet           [KNL] Disable most log messages 





  • https://blog.csdn.net/hubu01/article/details/1618590
    首先是对Linux启动过程的跟踪和分析,生成详细的启动时间报告。

      较为简单可行的方式是通过PrintkTime功能为启动过程的所有内核信息增加时间戳,便于汇总分析。PrintkTime最早为CELF所提供的一个内核补丁,在后来的Kernel 2.6.11版本中正式纳入标准内核。

      开启PrintkTime功能的方法很简单,只需在内核启动参数中增加“time”即可。当然,你也可以选择在编译内核时直接指定“Kernel hacking”中的“Show timing information on printks”来强制每次启动均为内核信息增加时间戳
        Kernel hacking  --->      
               printk and dmesg options  --->      
                 [*] Show timing information on printks                                       │ │ 
                  │ │      (4) Default message log level (1-7)   

    ///////////////////////////////////////////////////////

         CPU Power Management  --->        
                    CPU Frequency scaling  --->    
                         Default CPUFreq governor (performance)  --->     
                                 (X) performance
                                    ( ) powersave
                                    ( ) userspace
                                    ( ) ondemand
                                    ( ) conservative
                                    ( ) interactive

    ////////////////////////////////////////////////////
    http://www.wowotech.net/bbs/180.html


    占用时间最长的  就是 启动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,将无用模块搬入文件系统启动。(类似于延时启动)


    linux4.15内核如下
    linux内核 init/main.c

    static void __init do_initcall_level(int level)
    {
        initcall_t *fn;

        strcpy(initcall_command_line, saved_command_line);
        parse_args(initcall_level_names[level],
               initcall_command_line, __start___param,
               __stop___param - __start___param,
               level, level,
               &repair_env_string);

        for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
        {
            /*printk("======M:fn%p=====\n",fn);*/
            do_one_initcall(*fn);

        }
    }

    static void __init do_initcalls(void)
    {
        int level;

        for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
        {
            /*printk("=====Level:%d=====\n",level);*/
            do_initcall_level(level);
        }
    }

    串口输出结果里
    [    0.347538] ======M:fn80745924=====
    [    0.348311] 2020000.serial: ttymxc0 at MMIO 0x2020000 (irq = 19, base_baud = 5000000) is a IMX
    [    1.727805] console [ttymxc0] enabled
    [    1.733490] 21e8000.serial: ttymxc1 at MMIO 0x21e8000 (irq = 234, base_baud = 5000000) is a IMX
    [    1.743330] ======M:fn80745928=====

    linux4.1.15_imx6]$ vim System.map
    80745924 t __initcall_imx_serial_init6

    这个
    fn80745924占用时间挺长。

    可以找到是如下这个模块
    drivers/tty/serial/imx.c:static int __init imx_serial_init(void)
    drivers/tty/serial/imx.c:module_init(imx_serial_init);



    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    阅读(418) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~
    评论热议
    请登录后评论。

    登录 注册