启动流程与进程信号
目标
以文档形式整理启动阶段以及 GRUB、target 的概念,直接读取 /proc 制作系统摘要,并向后台进程发送 signal 以确认状态变化。
为什么重要
启动失败时应查看哪里,取决于“控制权已经移交到哪里”。屏幕完全没有输出时,问题位于 firmware 与 bootloader 之间;能显示菜单却发生 kernel panic 时,问题位于 kernel 与 initramfs 之间;若在出现登录提示前停止,则问题发生在 init 之后。因此,不应只是背诵顺序,而应了解每个边界发生了什么变化。向 GRUB 添加 kernel parameter 时,根据只应用于普通条目还是连恢复条目也应用,使用的 directive 也不同。后半部分的 signal 实验用于亲手确认前面阅读材料中的状态表。停止不等于终止,signal 只会发送给指定 PID。
步骤
- 在
/root/lfcs-boot/boot-order.txt中按顺序每行写一个启动阶段,共四行:firmware、bootloader、kernel、init。 - 在
/root/lfcs-boot/grub.default中写四行:GRUB_TIMEOUT=5、GRUB_DEFAULT=0、GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"、GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"。 - 将
/proc/cmdline的内容原样写入/root/lfcs-boot/cmdline.txt。 - 在
/root/lfcs-boot/sysinfo.txt中写三行:kernel=<커널 릴리스>、memtotal_kb=<MemTotal 값>、swaptotal_kb=<SwapTotal 값>。值只填写数字。 - 在
/root/lfcs-boot/targets.txt中用四行写出 runlevel 与 target 的对应关系:0=poweroff.target、1=rescue.target、3=multi-user.target、5=graphical.target。 - 在后台启动
sleep 4000,将其 PID 写入/root/lfcs-boot/stopped_pid.txt,再向该进程发送停止 signal。然后在/root/lfcs-boot/stopped.txt中写一行state=<현재 상태 문자>。 - 启动第二个
sleep 4000,将其 PID 写入/root/lfcs-boot/term_pid.txt,只向该进程发送终止 signal 使其消失。然后在/root/lfcs-boot/term.txt中写两行:pid=<그 PID>和alive=no。第 6 步停止的进程必须仍然存活。
参考
- 刚刚在后台启动的进程 PID 保存在特殊变量
$!中。 - 状态字符既可以通过
ps -o stat=读取,也可以从/proc/<PID>/stat的第三个字段读取。 - 停止 signal 和强制终止 signal 都无法被应用捕获或忽略。
- 常见错误:第 7 步按名称发送 signal,会连同第 6 步的
sleep一起杀死,导致评分失败。请指定 PID。
整理启动阶段
在 /root/lfcs-boot/boot-order.txt 中按顺序每行写一个启动阶段,共四行:firmware、bootloader、kernel、init。
写出通电后控制权移交的四个阶段。每行一个小写单词。
GRUB 默认配置文件
在 /root/lfcs-boot/grub.default 中写四行:GRUB_TIMEOUT=5、GRUB_DEFAULT=0、GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"、GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"。
有两个 directive 用于保存 kernel parameter。一个只应用于普通条目,另一个连恢复条目也应用。值中有空格时,请用引号包裹。
当前 kernel 收到的 parameter
将 /proc/cmdline 的内容原样写入 /root/lfcs-boot/cmdline.txt。
启动时实际传给 kernel 的字符串原样保存在 proc 下的一个文件中。不要加工,直接保存。
从 /proc 制作系统摘要
在 /root/lfcs-boot/sysinfo.txt 中写三行:kernel=<커널 릴리스>、memtotal_kb=<MemTotal 값>、swaptotal_kb=<SwapTotal 값>。值只填写数字。
通过 uname 获取 kernel release,从 meminfo 对应行读取 memory total 和 swap total。单位为 kB,只填写数字。
runlevel 与 target 的对应关系
在 /root/lfcs-boot/targets.txt 中用四行写出 runlevel 与 target 的对应关系:0=poweroff.target、1=rescue.target、3=multi-user.target、5=graphical.target。
把 SysV runlevel 数字与 systemd target unit 名称配对。分别是关机、单用户、多用户和图形界面四种。
停止进程
在后台启动 sleep 4000,将其 PID 写入 /root/lfcs-boot/stopped_pid.txt,再向该进程发送停止 signal。然后在 /root/lfcs-boot/stopped.txt 中写一行 state=<현재 상태 문자>。
有一个特殊变量保存刚在后台启动的进程 PID。停止 signal 无法被应用捕获,状态字符也可以从 proc 的 stat 中读取。
只终止第二个进程
启动第二个 sleep 4000,将其 PID 写入 /root/lfcs-boot/term_pid.txt,只向该进程发送终止 signal 使其消失。然后在 /root/lfcs-boot/term.txt 中写两行:pid=<그 PID> 和 alive=no。第 6 步停止的进程必须仍然存活。
再启动一个新进程,只向它的 PID 发送终止 signal。前一步停止的进程必须仍然存活。