init 脚本

1. mount_setup

  1. 分别挂载:/proc/sys/dev/run

  2. 创建 /run/initramfs

  3. 如果存在/sys/firmware/efi则挂载mount -t efivarfs efivarfs /sys/firmware/efi/efivars

  4. 如果存在 /proc/kcore 则创建软连接ln -sfT /proc/kcore /dev/core

  5. 分别创建软连接 /proc/self/fs -> /dev/fd/proc/self/fd/0 -> /dev/stdin/proc/self/fd/1 -> /dev/stdin/proc/self/fd/2 -> /dev/stderr

2. parse_cmdline

cmdline 来自于 /proc/cmdlineparse_cmdline </proc/cmdline

解析命令行参数,并根据命令行参数设置对应值

3. rdlogger_start

打开日志

4. disablehooks

将配置为 disablehooks 中的值,去掉可执行属性

5. config

导入变量:EARLYHOOKSHOOKSLATEHOOKSCLEANUPHOOKSEMERGECYHOOKS

这个config 文件位于initramfs的根目录

6. 运行Hook中’run_earlyhook’

run\_hookfunctions 'run\_earlyhook' 'early hook' $EARLYHOOKS

# 相当于执行导入 hooks/ 文件夹下有可执行权限的Hook,如果hooks/xxx具体Hook中由 `run_earlyhook` 函数就会执行它

7. earlymodules

if [ -n "$earlymodules$MODULES" ]; then
    # busybox ash supports string replacements
    # shellcheck disable=SC3060,SC2086
    modprobe -qab ${earlymodules//,/ } $MODULES
fi

8. 运行Hook中’run_hook’

过程同 6

9. 是否premount…<正常启动不用>

10. 获取rootdev

根据 $root 环境变量

11. fsck_root

如果不是快速启动,则对 $root 设备执行fsck -Ta -C ... 命令

如果检查出错,则执行Hook中的 run_emergencyhook 函数

12. 执行 default_mount_handler /new_root

将根设备挂载到 /new_root 节点

如果挂载出错则执行每个Hook脚本中的 run_emergencyhook 函数

13. 执行Hook中的run_lasthook

14. 执行Hook中的run_cleanuphook

15. 检测是否挂载成功

通过stat -c %D 设备节点检测//new_root设备节点是否一样,如果一样则说明没有挂载成功

如果没有挂载成功则执行 Hook 中的 run_emergencyhook 函数,然后启动shell

如果挂载成功了,检测/new_root中是否有 init 程序,如果没有则同上

关闭log,执行 rdlogger_stop。。。

如果挂载成功,在/new_root中也有 init 程序,则执行:

exec env -i \
         "TERM=$TERM" \
         /usr/bin/switch_root /new_root "$init" "$@"