Ubuntu 16.04.5 默认环境。
我想在初始化之前做一些自定义工作。grub.cfg 作为
linux /boot/vmlinuz ... ro init=/root/init.sh
初始化文件:
#!/bin/bash
# do some task
exec init 3
启动后,X启动。
如果是grub
linux /boot/vmlinuz ... ro init=/root/init.sh 3
,可以成功启动进入文本模式。
根据https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html,3不是内核的命令行参数,内核会将其作为参数传递给init,这里是/root/init.sh。
将 /root/init.sh 更改为:
#!/bin/bash
# do some task
echo $1
sleep 3s
exec init 3
我可以看到从内核传递的值。
在我看来,无论 grub -> kernel -> /root/init.sh 的值是什么,我都会丢弃该值并以运行级别 3 执行 init。为什么它不起作用。
答案1
根据 poettering 对我在 systemd 上的问题的回复:https://github.com/systemd/systemd/issues/10752
我们通常读取 /proc/cmdline,而不是 argv[],因为内核从后者中删除了一些我们需要知道的位。我们基本上完全忽略了 argv[]。
因此,您尝试做的事情不起作用,您必须使用带有新参数的某些文件来覆盖 /proc/cmdline。
关于“overmount”,根据https://unix.stackexchange.com/questions/364442/cant-mount-on-proc-cmdline/364448,
- 复制
/proc/cmdline
于/root/cmdline
3
在末尾添加/root/cmdline
- 运行命令
mount -n --bind -o ro /root/cmdline /proc/cmdline
- 运行命令
exec init
现在系统将以运行级别 3 启动。
综上所述,将/root/init.sh 修改为
#!/bin/bash
# do some task
cp /proc/cmdline /root/cmdline
sed -i.bck '$s/$/ 3/' /root/cmdline
mount -n --bind -o ro /root/cmdline /proc/cmdline
exec init
正如我所料,自定义作业完成后系统将启动到文本模式。