构建我自己的 initrd 时如何填充 /dev 目录?

Car*_*ito 9 udev initrd

我正在尝试学习有关 initrd 的东西。我按照本教程从头开始构建自己的 initrd,并在其上安装了 busybox。然后我用isolinux从它制作了一个.iso,所以我可以在virtualbox中测试它。它工作得很好!

我有来自 busybox 的基本命令,所以我想挂载一个文件系统。但是 /dev 目录几乎是空的(没有 sda),除了我在学习教程时创建的一些文件。我了解了 udev,我认为这就是我所需要的。但是我不知道该怎么做。

我应该从 udev 获取最新的源代码,编译它并将其添加到我的 initrd 中吗?然后在我的初始化脚本中调用 /bin/udev 或类似的东西?或者是否有其他/更好的方法来填充 /dev 目录?

编辑:关于我已经完成的工作的一些附加信息和更新。

  • 我在虚拟框中测试了所有内容。我刚刚在 virtual box 中安装了 ubuntu minimum,从我的 initrd 制作了一个 .iso,然后从 virtualbox 中的 iso 启动。
  • 我使用了 vmlinuz 并且/lib/modules存在于 debian-businesscard.iso 中,并将它们复制到我按照我之前链接的教程创建的 initrd 中。
  • 内核有 CONFIG_DEVTMPFS=y
  • 某些设备出现在 中/dev,例如 tty0-tty63 和其他一些设备,但没有 sda/hda。
  • lspci -k在我当前正在运行的操作系统和虚拟框来检查哪些模块使用。SATA Controller说它ahci用作模块。
  • 当我执行modprobe -v ahci它时,它会抱怨很多“未知符号:ata_some_stuff”,但之后它返回类似SCSI Subsystem initialized,ATA-6: VBOX HARDDISKDirect-Access ATA VBOX HARDDISK. 但是,在/dev.

我目前的/init/脚本如下:

#!/bin/ash
mount -t devtmpfs none /dev
mount -t proc /proc /proc
mount -t sysfs none /sys
modprobe -v ahci
echo "Hello world"
exec /bin/ash --login
Run Code Online (Sandbox Code Playgroud)

有没有人知道我做错了什么以及我应该做什么?

phe*_*mer 12

虽然吉尔斯的回答是正确的,但它是老派:-)。另一个值得注意的项目(对术语的挑剔而不是任何东西)是您链接到的指南是有关如何创建 initramfs 而不是 initrd 的说明。两者相似,用途相同,但在图像的存储和加载方式上有所不同。

无论如何,您问题的答案实际上非常简单。

  1. devtmpfs在内核中启用( CONFIG_DEVTMPFS=y)
  2. mount -t devtmpfs none /dev作为init脚本中的第一件事运行。

就是这样。devtmpfs 将/dev像 udev 一样填充。你甚至不需要预先填充/dev与像基础(在initramfs镜像)nullzeroconsole


Gil*_*il' 4

Udev/dev根据加载到内核中的驱动程序以及这些驱动程序检测到的设备自动填充。设备的名称及其权限基于管理员可以微调的一组规则。大多数Linux系统应该使用udev;例外情况是系统(通常是嵌入式),其硬件配置在系统设置时就已知,并且之后不会更改。

您通常会udev在启动序列的早期调用。在此之前您应该(必须?)做的几件事之一是 mount/proc/sys. 启动守护进程后,调用udevadm trigger --action=add; udevadm settle使 udev 处理来自内核的所有待处理事件 ( trigger),并等待事件处理完毕后再继续 ( settle)。然后您可以继续查找包含根文件系统的设备。

除了二进制文件之外,您还需要initrd 上的udevd其他部分。udev这包括 中的配置文件/etc/udev、基本配置以及/lib/udev辅助二进制文件,scsi_id例如/lib/udev. 您需要从包含在 initrd 中的 udev 规则调用的所有程序。

在 initrd 结束时,在将控制权转移到真正的根分区之前,您需要udevd像 initrd 中的所有其他程序一样停止。这不会从 中删除任何设备/dev。用于mount --move /dev /root/dev将安装移动/dev到真实根目录。

Gentoo 有一个initramfs 指南和一个initramfs wiki 页面,其中提到了 udev 等。Initramfs 是 initrd 的现代继承者,使用 cpio 存档而不是文件系统映像,并具有不同的进程接口(在 initrd 上,/linuxrc必须退出,而在 initramfs 上,/init必须exec从真正的根进行 init);如今大多数系统都已切换(即使该文件可能仍称为 initrd)。