/init(或/linuxrc)脚本是否在/dev 中创建临时设备节点?

/init(或/linuxrc)脚本是否在/dev 中创建临时设备节点?

考虑到 GRUB 执行以下几行:

kernel /vmlinuz root=/dev/sda1 ro
initrd /initrd

启动时,Linux 内核如何找到/dev/sda1设备节点?

我知道 initrd/initramfs 映像包含存储(等)设备的模块,这些模块被加载到内存中以允许访问存储。让我烦恼的是root=/dev/sda1内核如何准确地解析内核参数。

initrd/initramfs 中的/init(或) 脚本是否创建目录,然后在其中创建设备节点?或者“主要”和“次要”数字是硬编码在内核中的?/linuxrc/dev/dev/sda1/dev/sda1

答案1

如果您有 initramfs,内核只需解压并安装 initramfs,/init然后执行。其他一切都将由/init可执行文件处理。这也意味着内核不会安装root引导参数中指定的设备。

不同的发行版使用不同的 initramfs 框架,例如德拉库特对于 Fedora 或initramfs 工具对于 Debian。最常见的解决方案是使用udev,mdev或 之类的东西devtmpfs。有些也可能只是使用MAKEDEV生成静态布局或将设备文件集成到其图像中。

如果您在没有 initramfs 的情况下启动,则内核只能从具有已知主/次编号的设备启动,例如,/dev/sda1但不能从 lvm 设备启动。

答案2

根设备的主设备号和次设备号都存储在内核映像中(有关rdev详细信息,请参阅 的联机帮助页)。

然而,内核命令行参数不被内核解释。初始 ramdisk initrd 包含一个带有最小 Linux 的文件系统,通常执行解释部分。 initrd 的工作方式取决于您的发行版。它可能只包含节点 /dev/sda1 或一些在运行时创建它的脚本/程序。

如果您使用的是基于 Debian 的 Linux,您可以像这样解压缩您的 ramdisk:

mkdir /tmp/initrd
cd /tmp/initrd
zcat /boot/path/to/initrd | cpio -iv

debian initrds 是脚本,您可以看看它是如何工作的。内核解压 initrd 后,它会启动init您现在应该在 中找到的脚本/tmp/initrd。请注意它所在的块for x in $(cat /proc/cmdline); do

其中/proc/cmdline是使用 Grub 传递的参数(您现在可以使用 shell 检查/验证!)。如果您想更深入地了解 Debians initrd,您会注意到,您可以通过向root=/dev/nfsGrub 传递选项来使您的内核/initrd 使用 NFS 共享作为根文件系统。当您这样做时,不会/dev/nfs创建或安装任何节点。它只是告诉 initrd 做什么。

最后,每个这样的 initrd 都会运行某些选项提供的命令,例如init=默认值/sbin/init

回到标题中的最初问题:是的 /init (最有可能)在运行时创建该节点。它使用各种程序/启发式/巫毒来找出如何挂载根文件系统。

答案3

初始代码运行一个名为的程序,mdev它基本上是udev.这将扫描所有设备并创建/dev文件夹的初始内容。然后内核就能够有效地执行mount /dev/sda1 /并开始查找整个系统。

这里您想了解更多吗mdev

主设备号和次设备号实际上被硬编码到那些内核模块中,这些模块是设备驱动程序并且使用静态主设备号(例如,请参见文档/devices.txt在内核源代码中)。大多数(全部?)磁盘驱动程序内核模块都属于这一类。因此,正如 @Ulrich Dangel 所说,只要所需的模块静态链接到内核映像,某些内核就可以在没有 initramfs/initrd 的情况下启动。

相关内容