内核如何挂载根分区?

Mr.*_*nce 34 linux boot kernel mount

我的问题是关于从单独的 /boot 分区启动 Linux 系统。如果大多数配置文件位于单独的 / 分区,内核如何在启动时正确挂载它?

对此的任何详细说明都会很棒。我觉得好像我错过了一些基本的东西。我最关心的是操作的过程和顺序。

谢谢!

编辑:我想我需要问的更多是在根内核参数中使用的开发文件的行。例如,假设我将我的根参数设为 root=/dev/sda2。内核如何拥有 /dev/sda2 文件的映射?

psu*_*usi 49

在古代,内核被硬编码以知道根 fs 的设备主要/次要编号,并在初始化内核中内置的所有设备驱动程序后挂载该设备。该rdev实用程序可用于修改内核映像中的根设备编号,而无需重新编译它。

最终引导加载程序出现并可以将命令行传递给内核。如果root=参数被传递,它会告诉内核根 fs 所在的位置,而不是内置值。需要访问的驱动程序仍然必须内置到内核中。虽然参数在/dev目录中看起来像一个普通的设备节点,但/dev在挂载根 fs 之前显然没有目录,因此内核无法在那里查找 dev 节点。相反,某些众所周知的设备名称被硬编码到内核中,因此可以将字符串转换为设备编号。因此,内核可以识别诸如 之类的东西/dev/sda1,但不能识别诸如/dev/mapper/vg0-root或 卷 UUID 之类的更奇特的东西。

后来,initrd出现在画面中。与内核一起,引导加载程序将加载initrd映像,这是某种压缩的文件系统映像(gzipped ext2 映像、gzipped romfs 映像、squashfs 最终成为主导)。内核会将此映像解压缩到 ramdisk 并将该 ramdisk 挂载为根 fs。此映像包含一些额外的驱动程序和启动脚本,而不是真正的init. 这些引导脚本执行各种任务来识别硬件、激活诸如raid 阵列和LVM 之类的东西、检测UUID,并解析内核命令行以找到真正的根,现在可以通过UUID、卷标和其他高级事物来指定。然后将真正的根 fs 挂载到 中/initrd,然后执行pivot_root系统调用以进行内核交换//initrd, 然后/sbin/init在真正的 root 上执行,然后卸载/initrd并释放 ramdisk。

最后,今天我们有了initramfs. 这类似于initrd,但它不是加载到 ramdisk 的压缩文件系统映像,而是压缩的 cpio 存档。一个 tmpfs 被挂载为根目录,并在那里提取存档。引导脚本没有使用pivot_root被视为肮脏黑客的 ,而是initramfs将真正的根安装在 中/root,删除 tmpfs 根中的所有文件,然后chroot进入/root和 exec /sbin/init

  • chroot后tmpfs会自动卸载吗?它就这样消失了吗? (2认同)

gee*_*aur 23

Linux 最初使用 ramdisk(称为initrd,代表“INITial RamDisk”)作为/. 该磁盘上的内容刚好足以找到真正的根分区(包括所需的任何驱动程序和文件系统模块)。它将根分区挂载到 上的临时挂载点initrd,然后调用pivot_root(8)以交换根挂载点和临时挂载点,使initrd处于umounted的位置,而实际的根文件系统位于 上/

  • @先生。霹雳舞。不仅仅是 LFS 没有 initrd。任何编译自己内核的人都可以选择不使用 initrd,这就是我在 Gentoo 上所做的。 (4认同)
  • 如果您没有像 LFS (linuxfromscratch.org) 这样的 initrd 怎么办? (2认同)