Openwrt linux 启动流程

OpenWRT 启动流程

Openwrt linux 启动流程_第1张图片

内核启动过程:【/init/mian.c】

Uboot --> start_kernel() --> rest_init() --> kernel_thread(kernel_init) --> kernel_init_freeable()

初始化过程:

Linux Kernel(kernel_init) --> /etc/preinit  --> /sbin/init --> /etc/preinit, /sbin/procd --> /sbin/procd。

/etc/preinit脚本是系统其它脚本的入口,在/etc/preinit脚本中,第一条命令为:

[ -z “$PREINIT” ] && exec /sbin/init

由于一开始PREINIT没有被设置,所以为空,执行/sbin/init

其中/sbin/init 由procd/init.c编译产生的(它先执行一些ulog_open、early、cmdline等函数。最后执行preinit()函数。)

init.c部分代码如下:

Openwrt linux 启动流程_第2张图片

当procd退出后会调用execvp函数执行/sbin/procd,替换当前的init进程,这就是系统启动完成后,进程号为1最终为/sbin/procd的由来,中间改变了几次。

Openwrt linux 启动流程_第3张图片

preinit函数配置了环境变量PREINIT,然后再去fork进程来执行/etc/preinit,执行完毕后,再调用回调函数spawn_procd,在回调函数spawn_procd中调用了execvp函数来启动/sbin/procd,/procd最后执行/etc/init.d/目录下的文件,从而启动系统各个服务。

Openwrt linux 启动流程_第4张图片

第二次开始执行 /etc/preinit的过程

Openwrt linux 启动流程_第5张图片

当PREINIT被设置好了,preinit就会执行上面的代码。

可以看到三个脚本被启动:

. /lib/functions.sh

. /lib/functions/preinit.sh

. /lib/functions/system.sh

这几个脚本主要定义了shell函数,在preinit.sh中,定义了一些函数挂到hook上,当运行时,这些hook会按函数加入的顺序来启动函数。如boot_hook_init()等函数,之后使用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

后面就是当前shell下依次在执行/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执行完毕并退出,进程消失了,但此时已经调用了回调函数spawn_procd(),而回调函数spawn_procd()里面execvp(“procd”),所以最终procd会重新被执行,从而启动系统其它各个配置!

lib/preinit/

Openwrt linux 启动流程_第6张图片

在/etc/preinit脚本中有如下代码:
. /lib/functions.sh
. /lib/functions/preinit.sh
. /lib/functions/system.sh
查看. /lib/functions/preinit.sh脚本

Openwrt linux 启动流程_第7张图片

Openwrt linux 启动流程_第8张图片

你可能感兴趣的:(linux,运维,服务器)