Openwrt启动流程及启动脚本分析

1 概述

        在linux的发展过程中,linux的启动程序也在发展,从sysv init到现在的upstartsystemd

通常该程序是进程号为1的进程,该程序在linux系统有着举足轻重的地方。在openwrt中,使

用了另外一种启动程序叫做procd,本文的重点并不在于介绍procd,本文主要介绍并解析

procdpreinit及各种脚本如何完成整个系统的初始化。

2 软件环境

        Linux发行版:ubuntu14.04 LTS

        Openwrt版本:barrier break 14.07 r42635 linux kernel 3.10.49

        硬件:MPR-A2模块(rt5350

        在查看linux内核代码及根文件系统下的脚本之前,需要对openwrt进行配置,运行

make menuconfigTarget System中选择Ralink RT288x/RT3xxxSubtarget中选择RT3x5x/RT5350 

based boardsTarget Profile选择HAME MPR-A2,然后make完成openwrt的编译。打完patch的内核

代码在build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_rt305x/目录下,根文件系统目

录在build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/root-ramips/

3 启动分析

3.1 内核启动点

        Linux的启动入口为start_kernel()init/main.c),该函数的最后会调用rest_init()init/main.c),

该函数创建两个内核线程initkthreadd之后,进入死循环,即所谓的0号进程。init线程执行

kenrel_init()init/main.c)函数,在kernel_init函数中,首先会检查内核的启动参数中是否有设置init

参数,如果有,则会使用该参数指定的程序作为init程序,否则会按照如下代码(打上patch后的)

中所示的顺序依次尝试启动,如果都无法启动就会导致kernel panic

                if (!run_init_process("/etc/preinit") ||

                        !run_init_process("/sbin/init") ||

                        !run_init_process("/etc/init") ||

                        !run_init_process("/bin/init") ||

                        !run_init_process("/bin/sh"))

                return 0;

        在目前的环境下,内核启动参数未设置init参数,所以会以/etc/preinit程序作为init程序,preinit实际为shell脚本。

3.2 相关文件

3.2.1 脚本文件

        /etc/preinit

        /lib/functions.sh

        /lib/functions/preinit.sh

        /lib/functions/system.sh

        /lib/preinit/下所有脚本

3.2.2 init程序

        在proc程序包中,编译完会生成两个可执行程序:initprocd,均在目 录/sbin下,这两个程序均会使用到。

3.3 过程分析

        这个初始化过程遵循如下主线:

 

        下面我们一步一步分析这个过程。

        在/etc/preinit脚本中,第一条命令如下:

                [ -z "$PREINIT" ] && exec /sbin/init

        在从内核执行这个脚本时,PREINIT这个变量时没有定义的,所以会直接执行/sbin/init/sbin/init程序主要做

了一些初始化工作,如环境变量设置、文件系统挂载、内核模块加载等,之后会创建两个进程,分别执行/etc/preinit

/sbin/procd,执行/etc/preinit之前会设置变量PREINIT/sbin/procd会带-h的参数,当procd退出后会调用exec执行

/sbin/proc替换当前init进程(具体过程可参见procd程序包中的initprocd程序)。这就是系统启动完成后,ps命令显示

的进程号为1的进程名最终为/sbin/procd的由来,中间是有几次变化的。

        继续看/etc/preinit脚本,出来变量设置外,接下来是执行了三个shell脚本:

                . /lib/functions.sh

                . /lib/functions/preinit.sh

                . /lib/functions/system.sh

        注意“.”和“/”之间是有空格的,这里的点相当与souce命令,但soucebash特有的,并不在POSIX标准中,“.

是通用的用法。使用“.”的意思是在当前shell环境下运行,并不会在子shell中运行。这几个shell脚本主要定义了shell函数,

特别是preinit.sh中,定义了hook相关操作的函数。

        之后会使用boot_hook_init定义五个hook结点如下:

                boot_hook_init preinit_essential

                boot_hook_init preinit_main

                boot_hook_init failsafe

                boot_hook_init initramfs

                boot_hook_init preinit_mount_root

        之后会向这些结点中添加hook函数。

        在之后就是一个循环,依次在当前shell下执行/lib/preinit/目录下的脚本,

                for pi_source_file in /lib/preinit/*; do

                . $pi_source_file

                done

        /lib/preinit/目录下的脚本具体类似的格式,定义要添加到hook结点的函数,然后通过boot_hook_add将该函数添加到

对应的hook结点。

        最后,/etc/preinit就会执行boot_run_hook函数执行对应hook结点上的函数。在当前环境下只执行了preinit_essential

preinit_main结点上的函数,如下:

                boot_run_hook preinit_essential

                boot_run_hook preinit_main

        到此,/etc/preinit执行完毕并退出。如果需要跟踪调试这些脚本,可以 在/etc/preinit的最开始添加一条命令set -x,这

样就会打印出执行命令的过程, 当并不会真正执行。

        至于系统服务程序的启动及初始化将全由procd完成,procd的功能不仅在于此,它还集成更多其他功能,具体可参见

procd的资料。

4 参考资料

        1.openwrt启动脚本分析,http://blog.chinaunix.net/uid-26598889-id-3060545.html

        2.Openwrt barrier break 14.07源码

 


  • 0
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenWrt是一个开源的嵌入式操作系统,主要用于路由器和其他网络设备。通过分析OpenWrt的源码,我们可以了解其编译过程和目录结构。 OpenWrt的源码包括多个子目录,其中最重要的是根目录下的Makefile文件。这个Makefile文件是执行make命令时的入口。在Makefile中,可以定义编译选项、目标和依赖关系。 在Makefile中,有一个名为"world"的目标,它是整个编译过程的入口。在这个目标中,根据是否定义了"OPENWRT_BUILD"变量,会执行不同的逻辑。如果"OPENWRT_BUILD"变量未定义,会执行第一个逻辑;如果定义了,会执行第二个逻辑。 整个编译过程涉及到多个子目录的目标生成。每个子目录都有自己的Makefile文件,用于定义该子目录下的编译选项、目标和依赖关系。通过递归调用子目录的Makefile,可以完成整个OpenWrt的编译过程。 在编译过程中,还包括了内核的编译过程、固件的生成过程和软件包的编译过程。这些过程都在相应的子目录中完成。 总结来说,通过分析OpenWrt的源码,我们可以了解其编译过程和目录结构。Makefile文件是整个编译过程的入口,通过递归调用子目录的Makefile,完成各个子目录的目标生成。同时,还包括了内核的编译过程、固件的生成过程和软件包的编译过程。 #### 引用[.reference_title] - *1* *2* *3* [openwrt源码框架解析](https://blog.csdn.net/daidi1989/article/details/53336845)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值