Por*_*jim 12 linux boot kernel init-script initramfs
将根文件系统挂载ro在 initramfs(和 initrd)中的原因是什么。
例如,Gentoo initramfs 指南使用以下命令挂载根文件系统:
mount -o ro /dev/sda1 /mnt/root
Run Code Online (Sandbox Code Playgroud)
为什么不是下面的?
mount -o rw /dev/sda1 /mnt/root
Run Code Online (Sandbox Code Playgroud)
我可以看到可能有一个很好的理由(并且可能涉及switchroot),但是似乎没有任何地方记录。
War*_*ung 19
的初始ramdisk(initrd的)通常仅这是需要安装实际的根文件系统和越区切换启动到它包含根文件系统的精简版本。
initrd 的存在是因为在现代系统中,引导加载程序的智能程度不足以可靠地找到根文件系统。像引导加载程序这样的小程序有太多的可能性无法覆盖。考虑 NFS 根、非标准 RAID 卡等。引导加载程序必须仅使用 BIOS 以及可以塞入引导扇区的任何代码来完成其工作。
initrd 存储在引导加载程序可以找到的某个地方,并且它足够小,它占用的额外空间通常不会打扰任何人。(在小型嵌入式系统中,通常没有“真正的”根,只有 initrd。)
initrd 很宝贵:它的内容在任何情况下都必须保留,因为如果 initrd 中断,系统将无法启动。其设计者为确保这一点所做的一种设计选择是使引导加载程序加载 initrd 只读。还有其他原则也适用于这一点,例如在没有“真正”根的小型系统的情况下,您仍然单独安装/tmp,/var/cache例如用于存储东西。更改 initrd 的情况很少,因此应该非常小心。
再回到那里正常情况下是一个真正的根文件系统,它最初是只读方式挂载因为initrd的了。出于同样的原因,它会尽可能长时间地保持只读状态。任何需要完成的对真正根的写入都被推迟到系统启动时,根据偏好,或者至少在启动过程的后期无法满足该偏好时。
在这个只读阶段发生的最重要的事情是检查根文件系统以查看它是否被干净地卸载。这是引导加载程序当然可以做的事情,而不是将它留给 initrd,但是如果根文件系统没有完全卸载,会发生什么?然后它必须打电话fsck检查并可能修复它。所以,在这里会initrd得到fsck,如果是负责这一步,而不是等到切换到“真正”的根源在哪里?您可以说在构建它时需要复制fsck到 中initrd,但现在它更大了。最重要的是,哪个 fsck将复制?Linux 系统经常使用十几种不同的文件系统。您是否只复制了当时真正根所需的那个initrd被建造?您是否initrd通过将所有可用复制扩大大小fsck.foo 程序,以防根文件系统后来迁移到其他文件系统类型,而有人忘记重建 initrd?
Linux 引导系统架构师明智地选择不让 initrd 承担这些问题。他们将真正的根文件系统的检查委托给真正的根文件系统,因为它比 initrd 更适合这样做。
一旦引导过程进行到足够安全,initrd 就会从真正的根目录下用 换出pivot_root(8),并且文件系统以读写模式重新挂载。