我想重新表述 Thelostcause 提出的一个非常有趣的问题(“PID = 1 时的飞溅”):
如何以及如何能够 “/sbin/init 启动”出现在ps 命令?
我还问:我们(运行“Linux系统”的我们)不是从
"init [2]" in old sysvinit, to
"/sbin/init vmlinuz" in new systemd init ?
其中 [2] 表示 sysv 运行级别,vmlinuz 表示 KCL(内核命令行)的第一个参数。
是否有人使用 ps 命令在其系统上看到 PID=1 又名 init 进程的任何其他或奇特名称?
小心:“ps”非常棘手:ps -p1
只给我“systemd”作为 CMD,并ps p1
在 COMMAND 输出字段中给我“/sbin/init arch5\vmlinuz-linux”。我用来ps axf
获得概览。
我承认我对我的问题有一些假设。 “splash”事件是 grub 和 systemd 之间的事情,这是一个早期(好吧,第一个)KCL 参数,它被内核和 initrd 忽略,直到 systemd 决定用第二个名称来美化它的 ps 输出(参见下面的第三个示例)。
添加(直接来自 Documentation/x86/boot.rst):
需要引导加载程序本身附加命令行选项的引导加载程序作者应该在 Documentation/admin-guide/kernel-parameters.rst 中注册它们,以确保它们不会与现在或将来的实际内核选项发生冲突。
initrd=<file>
An initrd should be loaded. The meaning of <file> is
obviously bootloader-dependent, and some boot loaders
(e.g. LILO) do not have such a command.
此外,一些引导加载程序将以下选项添加到用户指定的命令行中:
BOOT_IMAGE=<file>
The boot image which was loaded. Again, the meaning of <file>
is obviously bootloader-dependent.
auto
The kernel was booted without explicit user intervention.
如果这些选项是由引导加载程序添加的,强烈建议将它们放置在第一的,在用户指定或配置指定的命令行之前。否则,“init=/bin/sh”会被“auto”选项混淆。
...或 init=[链接到 systemd] 通过“splash”选项!
请注意 boot.rst 中附近如何提及 initrd= 和 init=。
kernel.org, boot-parameters.html
:这里,initrd=
引导选项被标记为[BOOT](“引导加载程序参数”)。这是唯一除了 [BOOT] 之外什么都没有的选项(locktorture.x 和 rcuperf.x 之一除外)。而且vga=
似乎也是一个特例:
这实际上是一个引导加载程序参数;该值使用特殊协议传递给内核。
普通的内核参数有[KNL](“内核启动参数”):root=、rw、init=、rdinit=、audit、debug等等——甚至“S”
难怪我和斯蒂芬感到困惑:bootloader、initrd=、init= 和这个“splash”确实密切相关。
S [KNL] Run init in single mode
这对我来说没有意义。或者内核是否会搜索“S”来主动将其传递给init?
你知道吗:我不打算(现在)测试 systemd 对“S”的作用。我遇到了严重的崩溃(没有消息),并且在重新启动后出现“身份验证错误”(这次pacman -S pam
至少很容易修复)。我所做的就是rdinit=xxxxx
(默认为/init)。难道内核不应该告诉我:“找不到所需的 RDINIT”或者类似的内容init=xxxx
吗? “NO INIT FOUND”也是一种恐慌,但带有消息的受控恐慌。
添加部分结束
我真正的问题之一是:
你如何解释这一点?我的 init 启动了下一个 init!
(这个问题与我自己的问题有点偏离主题,但我想展示所有这些例子)
1 ? Ss 0:01 init [S]
214 tty1 Ss 0:00 init [S]
215 tty1 S 0:00 \_ bash
238 tty1 R+ 0:00 \_ ps axf
239 tty1 R+ 0:00 \_ tail
这就是我从 Uefi shell 启动 NUC 的方法。 “S”表示此特殊紧急 sysvinit 运行级别(没有 inittab 条目,如果没有 /etc/inittab 则应输入)。你好,只是想看看它去了哪里:
fedora\vmlinuz root=/dev/sda3 init=/usr/bin/sysvinit S HELLO
此 KCL 在 dmesg 和 /proc/cmdline 中显示未受影响。这里 dmesg:
[ 0.000000] Command line: fedora\vmlinuz root=/dev/sda3 init=/usr/bin/sysvinit S HELLO
[ 0.000000] Kernel command line: fedora\vmlinuz root=/dev/sda3 init=/usr/bin/sysvinit S HELLO
我现在在我的内核中看不到这个双重“[内核]命令行”。这只是“命令行”。如果他们故意改变这一点,我会说他们是对的。 (fedora 内核不是古董......它类似于 4.18)
这是具有四个 tty 的正常运行级别:
1 ? Ss 0:00 init [2]
286 tty1 Ss 0:00 /bin/bash -l
303 tty1 R+ 0:00 \_ ps axf
304 tty1 D+ 0:00 \_ /bin/bash -l
287 tty2 Ss+ 0:00 /sbin/agetty -J tty2
288 tty3 Ss+ 0:00 /bin/bash
289 tty4 Ss+ 0:00 /bin/bash
旧的 sysvinit 显示为“init [2]”。 “2”当然是(默认)运行级别,也是 /sbin/init 的参数,但括号必须由 sysvinit 添加才能看起来不错。在此 ps 输出中,您可以看到“/bin/bash”和“/bin/bash -l”之间的区别。
在 systemd 下并带有 initrd (archlinux):
1 ? Ss 0:01 /sbin/init arch5\vmlinuz-linux
... .. .... snip systemd-journald etc.
469 ? Ss 0:00 login -- root
484 tty1 Ss 0:00 \_ -bash
922 tty1 S+ 0:00 \_ xinit fvwm
... ...
有人从哪里得到的“溅”,这是无稽之谈,我明白了“arch5\vmlinuz-linux”。 arch5 是我在 EFI 引导分区上创建的目录,vmlinuz-linux 是我安装后在 /boot 中找到内核的方式。我只需将它与 initrd 文件一起复制到 arch5。
如果您从真正的引导加载程序(如 grub)引导 systemd init:在“/sbin/init”之后您会得到什么?还有像我一样的内核文件名吗?或飞溅或安静或只是任何剩余的东西?
@Stephen:我想知道当你说内核“消耗”参数时你的意思是什么?在我的 initrd= 示例中,内核根本不消耗任何内容:它由引导加载程序或 Uefi Shell 与 initrd 文件一起加载。
(在这里,我与 Stephen 争论,他在启动时在命令行中处理 initrd=、root= 和 init=)
好的,所以 initrd= 在这种情况下是由内核自己加载的(EFI 存根,使用 Uefi 支持),但是参数是否“已使用”?不,它还在那里。一切都还在那里,并“结束”在 /proc/cmdline 中。模块不是被告知要在那里查找命令行选项吗?
我现在的结论是:sbin/init splash?谁在乎!引导参数有规则,如果 init 获得未使用的“splash”作为参数,ps 将显示它。
我认为这个答案是完全错误的......但如果有一个很好的解释命令行又名引导选项,以及从 bootloader/Uefi shell 到 /sbin/init 的引导过程,我想我会找到它。
顺便说一句,我来这里的原因是:
我第一次从磁盘启动时遇到了很多问题(我的 NUC 是一个套件,所以当我开始时它实际上是空的)。我从 GPT 分区开始,即使你得到了这个“保护性 MBR”,这样你就可以使用“Legacy BIOS”来启动,我当然想留下 Legacy/MBR 并使用纯 Uefi/GPT。但是 GPT 的 grub 安装太让我困惑了!我的“视觉”BIOS 没有显示任何可启动的内容。现在我知道:Uefi 不会引导设备,它会引导 EFI 应用程序,例如 BOOTX64.EFI,您首先必须使用 efibootmgr(来自 Linux)或 bcfg(来自 Uefi Shell)注册。
我正准备将 SSD 重新分区为 MBR。
然后我发现一个很短的帖子(这里或 stackoverflow)说:
“如果您有 Uefi BIOS,则不需要引导加载程序”
我简直不敢相信事情竟然这么简单。我激活了“Uefi Shell”作为启动选项,启动到它,输入“fs0:”真正“进入”启动分区,然后只是“vmlinuz”——瞧,因为缺少 root= 而导致快速内核恐慌,但有没有人曾经比我更高兴看到内核恐慌吗?
也许只有我几天后才发现“没有找到初始化”。 (我首先给了他 /bin/bash 只是为了保持传统)。
答案1
您所看到的(新)行为在以下问题的答案中进行了解释所有内核参数真的都被内核使用了吗?
当使用引导加载程序(例如 Grub)引导时,内核命令行通常类似于以下内容
BOOT_IMAGE=/boot/vmlinuz-4.9.0-9-amd64 root=/dev/mapper/vg--fast-root ro single
您可以在 中看到这一点/proc/cmdline
,它始终显示完整的内核命令行,无论之后如何处理它。模块参数从那里解析modprobe
(参见内核文档了解详情)。
该root
值和ro
选项由内核“消耗”。该BOOT_IMAGE
值是在init
的环境中设置的(请参阅/proc/1/environ
)。single
作为参数传递给init
, 作为内核文档中有描述:
内核从内核命令行解析参数到“--”;如果它无法识别参数并且不包含“.”,则该参数将传递给 init:带有“=”的参数进入 init 的环境,其他参数作为命令行参数传递给 init。 “--”之后的所有内容都作为参数传递给 init。
由于root
和ro
对内核有意义,因此内核将它们保留下来并且不会将它们传递给init
.
就您而言,您将从 UEFI shell 启动。 Arch 场景与上面的描述完全匹配:您的arch5\vmlinuz-linux initrd=arch5\initramfs-linux.img root=/dev/sda3
命令行结果被initrd
内核root
使用,并作为参数按原样arch5\vmlinuz-linux
传递。 init
initrd 由内核内部的 EFI 存根加载,使用 EFI 服务来查找该文件。 “显然不是来自内核”的错误消息是由内核的 EFI 支持产生的,请参阅这里对于“无法打开文件”和这里对于“尝试将文件加载到更高的地址”。efi_printk
使用 EFI 输出文本。
在 Fedora 的情况下,您使用的是sysvinit
,这会更改其命令行(如 所示ps
)以指示当前的运行级别。
在 Thelostcause 的例子中,splash
它是 Grub 构建的内核命令行的一部分,并最终init
遵循相同的规则。
在您的双重init
场景中,看起来第二个init
是会话管理器,而不是系统范围的init
.