当 Linux 启动时,initrd
会安装基本的支持文件和内核模块,这些是帮助进一步启动过程所必需的。随后在 Linux 操作系统中rootfs
安装和卸载。initrd
我的问题是,如果initrd
已卸载,用户如何仍能看到 挂载的文件initrd
?
例如: 中的一些文件/etc
等/lib
..
答案1
随后,rootfs 被挂载,initrd 从 Linux 操作系统中卸载
它并不完全是“卸载”的;大多数 Linux 发行版都没有使用可安装的 initrd年。相反,他们使用“initramfs”,这是一个存档,可以获取提取的进入最初安装在“/”的 RAM 文件系统 (tmpfs)。尽管仍然使用该initrd=
选项指定,但其行为与原始 initrd 机制完全不同。
我的问题是,当卸载 initrd 时,为什么目录 /etc、/lib、/bin、/usr、.. 及其内容仍然存在?
因为从 initramfs 的角度来看,它们实际上并不是“/etc”或“/lib”。 initramfs不直接挂载“/”– initramfs本身是“/”——相反,它将真正的根文件系统挂载在“/mnt”或“/newroot”之类的位置,因此这些目录从“/newroot/lib”等开始。
initramfs 完成的最后步骤之一是“pivot_root()”或“mount(MS_MOVE)”,该操作使“/newroot”成为新的“/”,本质上是交换两个挂载(旧的“/”,即 initramfs 被移动到子挂载)。
从 initramfs 解压出来的最小的“/bin”、“/etc”和“/lib”做在此过程中消失。
换句话说,这个过程大约是:
- 内核在 处挂载一个空的 tmpfs
/
。 - 内核将 initramfs.cpio 存档解压到内存中
/
,其中包含 /bin、/lib 等中的一些最小文件。 - 内核运行的
/init
是initramfs的“核心”。 - initramfs /init 脚本从内核命令行读取“root=”(或使用其他方法)并将真正的根文件系统安装在
/newroot
或类似的位置。此时,您的文件位于 /newroot/lib、/newroot/home 等。 - initramfs 可以选择在 /newroot 下安装其他必要的东西,例如“/newroot/run”处的 tmpfs,或作为“/newroot/usr”的基于 NFS 的 /usr。
- 我认为, initramfs /init 可以
/newroot
使用/
以下两种方法之一:- 它删除所有解压到 initramfs“/”中的文件,然后动作“/newroot”挂载到“/”上(覆盖现在空的 tmpfs,它永远留在那里)并使用 chroot() 使其永久化——这是 Arch Linux 的 initramfs 使用 switch_root 工具所做的;
- 或者它调用pivot_root()将initramfs /与/newroot“交换”,将后者转换为新的/并将initramfs移动到类似/run/initramfs的位置,然后可以卸载它 - 不确定是否仍然使用此方法。
- 最后,现在“/”是真正的根,/init(仍然从内存中运行)执行真正的根文件系统的
/sbin/init
.
通常,initramfs /init 是一个简单的 shell 脚本(尽管并非总是如此;它甚至可能是 systemd 的完整副本)。你可以看看架构 mkinitcpio /init。这内部使用了“overlay using mount(MS_MOVE)”方法;参见例如交换机根目录来自 util-linux。