init 脚本¶
1. mount_setup¶
分别挂载:
/proc、/sys、/dev、/run创建
/run/initramfs如果存在
/sys/firmware/efi则挂载mount -t efivarfs efivarfs /sys/firmware/efi/efivars如果存在
/proc/kcore则创建软连接ln -sfT /proc/kcore /dev/core分别创建软连接
/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/cmdline,parse_cmdline </proc/cmdline
解析命令行参数,并根据命令行参数设置对应值
3. rdlogger_start¶
打开日志
4. disablehooks¶
将配置为 disablehooks 中的值,去掉可执行属性
5. config¶
导入变量:EARLYHOOKS、HOOKS、LATEHOOKS、CLEANUPHOOKS、EMERGECYHOOKS
这个
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" "$@"