Busybox initrd及初始化流程

Initrd文件系统加载流程:
    1. 引导加载程序,例如 GRUB,定义了要加载的内核,并将这个内核映像以及相关的 initrd 拷贝到内存中。我们可以在 Linux内核源代码目录中的 ./init 子目录中找到很多这种功能。
    2. 在内核和 initrd映像被解压并拷贝到内存中之后,内核就会被调用了。它会执行不同的初始化操作,最终会发现自己到了init/main.c:init()(subdir/file:function)函数中。
    3. 这个函数执行了大量的子系统初始化操作。此处会执行一个对init/do_mounts.c:prepare_namespace() 的调用,这个函数用来准备名称空间(挂载 dev文件系统、RAID或 md、设备以及最后的 initrd)。
    4. 加载 initrd 是通过调用init/do_mounts_initrd.c:initrd_load() 实现的。
    5. initrd_load()函数调用了init/do_mounts_rd.c:rd_load_image(),它通过调用init/do_mounts_rd.c:identify_ramdisk_image() 来确定要加载哪个RAM磁盘。
    6. 这个函数会检查映像文件的 magic 号来确定它是 minux、etc2、romfs、cramfs 或 gzip 格式。
    7. 在返回到initrd_load_image 之前,它还会调用 init/do_mounts_rd:crd_load()。这个函数负责为 RAM磁盘分配空间,并计算循环冗余校验码(CRC),然后对 RAM磁盘映像进行解压,并将其加载到内存中。
    8. 现在,我们在一个适合挂载的块设备中就有了这个 initrd 映像。
    9. 现在使用一个 init/do_mounts.c:mount_root()调用将这个块设备挂载到根文件系统上。它会创建根设备,并调用 init/do_mounts.c:mount_block_root()。
    10. 在这里调用init/do_mounts.c:do_mount_root(),后者又会调用 fs/namespace.c:sys_mount()来真正挂载根文件系统,然后 chdir 到这个文件系统中。
    11. 最后,返回到 init 函数中,并调用init/main.c:run_init_process。这会导致调用 execve 来启动 init 进程(在本例中是/linuxrc)。linuxrc 可以是一个可执行程序,也可以是一个脚本(条件是它有脚本解释器可用)。

Busybox init程序执行的顺序如下:

   1. 创建init的信号处理
 2. 初始化控制台
 3. 分析inittab文件,/etc/inittab
 4. 执行系统初始化脚本,/etc/init.d/rcS
 5. 执行所有inittab中类型为wait的程序
 6. 执行所有inittab中类型为once的程序
 7. 完成以上步骤后,init循环执行所有inittab中类型为respawn和askfirst的程序。

Busybox inittab文件示例:

::sysinit:/etc/init.d/rcS

# /sbin/getty respawn shell invocations for selected ttys.
tty1::respawn:/sbin/getty -nl /sbin/autologin 38400 tty1
tty2::askfirst:/sbin/getty 38400 tty2
tty3::askfirst:/sbin/getty 38400 tty3
#tty4::askfirst:/sbin/getty 38400 tty4
#tty5::askfirst:/sbin/getty 38400 tty5
#tty6::askfirst:/sbin/getty 38400 tty6

# Stuff to do when restarting the init
# process, or before rebooting.
::restart:/etc/init.d/rc.shutdown
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/etc/init.d/rc.shutdown

Busybox inittab文件解释:

/etc/inittab 文件中每个条目用来定义一个子进程,并确定它的启动方法,格式如下 :
<id>:<runlevels>:<action>:<process>
例如:
ttySAC0:askfirst:-/bin/sh
(1)<id>:表示这个进程要使用的控制台(即标准输入、标准输出、标准错误设备)。如果省略,则使用与init进程一样的控制台。
(2)<runlevels>:对于Busybox init程序,这个字段滑意义,可以省略。
(3)<action>:表示init程序如何控制这个子进程,
(4)<process>: 要执行的程序,它可以是可执行程序,也可以是脚本


如果<process>:字段有"-"字符,表示这个程序被称为“交互的”。在/etc/inittab/文件的控制下,init进程的行为总结如下:
(1)在系统启动前期,init进程首先启动<action>为sysinit wait once的3类子进程。
(2)在系统正常运行期间,init程序首先启动,<action>为respawn askfirst的两类子进程,并监视它们,发现某个子进程退出时重新启动它。
(3)在系统退出时,执行<action> 为shutdown restart ctrlaltdel的3类子进程之一或全部。

Action           执行条件                             说明
Sysinit          系统启动后最先执行            只执行一次,init进程等待它结束才继续执行其它动作
Wait             系统执行完sysinit进程后      只执行一次,init进程等待它结束才继续执行其它动作
Once            系统执行完wait进程后         只执行一次,init进程不等待它结束
Respawn      启动完once进程后               Init进程监测发现子进程退出时,重新启动它
Askfirst         启动完respawn进程后         与respawn类似,不过init进程先输出“ Please press Enter to actvie this console ”,等用户输入驾车键之后才启动子进程
Shutdown     当系统关机时                        即重启关闭系统命令时
Restart          Busybox中配置了CONFIG_FEATURE_USE_INITTAB,并且init进程接收到SIGHUP信号时    先重新读取,解析/etc/inittab文件,再执行 restart 程序
Ctrlatldel       按下 Ctr+Alt+del 组合键时

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值