什么是ramfs
Ramfs 是一个非常简单的文件系统,它将 Linux 的磁盘缓存机制(页面缓存和 dentry 缓存)导出为一个可动态调整大小的基于 RAM 的文件系统。 通常所有文件都被 Linux 缓存在内存中。从后备存储(通常是挂载文件系统的块设备)读取的数据页会被保留,以防再次需要它,但标记为干净(可释放)以防虚拟内存系统需要内存用于其他用途。类似地,写入文件的数据在写入后备存储后立即标记为干净,但保留用于缓存目的,直到 VM 重新分配内存。类似的机制(dentry 缓存)大大加快了对目录的访问速度。 使用 ramfs,没有后备存储。写入 ramfs 的文件像往常一样分配 dentry 和页面缓存,但无处可写。这意味着页面永远不会被标记为干净的,因此当 VM 寻求回收内存时,它们不能被释放。 实现 ramfs 所需的代码量很少,因为所有工作都由现有的 Linux 缓存基础设施完成。基本上,您将磁盘缓存安装为文件系统。因此,ramfs 不是可通过 menuconfig 移除的可选组件,因为节省的空间可以忽略不计。
tmpfs
ramfs 的一个缺点是您可以继续向其中写入数据,直到填满所有内存,并且 VM 无法释放它,因为 VM 认为文件应该写入后备存储(而不是交换空间),但 ramfs 没有没有任何后备商店。因此,应该只允许 root(或受信任的用户)对 ramfs 挂载进行写访问。 创建了一个名为 tmpfs 的 ramfs 衍生物,以增加大小限制以及将数据写入交换空间的能力。可以允许普通用户对 tmpfs 挂载进行写访问。
什么是initramfs
所有 2.6 Linux 内核都包含一个 gzip 压缩的“cpio”格式存档,当内核启动时,它会被提取到 rootfs 中。解压后,内核检查 rootfs 是否包含文件“init”,如果是,则以 PID 1 执行它。 如果找到,则此 init 进程负责使系统运行其余部分,包括定位和挂载真正的根设备(如果有的话)。如果在嵌入的 cpio 归档文件被提取到 rootfs 之后,它不包含一个 init 程序,内核将使用旧代码来定位和挂载一个根分区,然后执行 /sbin/init 的一些变体。 所有这些在几个方面与旧的 initrd 不同: - 旧的 initrd 始终是一个单独的文件,而initramfs存档链接到 linux 内核映像。(该目录linux-*/usr
专门用于在构建期间生成此存档。)
-
旧的 initrd 文件是一个 gzipped 文件系统映像(某些文件格式,例如 ext2,需要内核内置驱动程序),而新的 initramfs存档是 gzipped cpio 存档(就像 tar 只是更简单,请参阅 cpio(1)和initramfs 缓冲区格式)。内核的cpio提取代码不仅极小,而且还有__init文本和在引导过程中可以丢弃的数据。
-
由旧的 initrd(称为 /initrd,而不是 /init)运行的程序做了一些设置然后返回到内核,而来自initramfs的 init 程序 预计不会返回到内核。(如果 /init 需要移交控制权,它可以使用新的根设备过载 / 并执行另一个 init 程序。请参阅下面的 switch_root 实用程序。)
-
当切换另一个根设备时,initrd 将 pivot_root 然后卸载 ramdisk。但是initramfs是 rootfs:您既不能 pivot_root rootfs,也不能卸载它。而是删除 rootfs 中的所有内容以释放空间(find -xdev / -exec rm \'{}\' \';\'),使用新根目录(cd /newmount; mount –move . /; chroot .)重载 rootfs,附加stdin/stdout/stderr 到新的 /dev/console,然后执行新的 init。由于这是一个非常挑剔的过程(并且涉及在您可以运行之前删除命令),因此 klibc 包引入了一个帮助程序 (utils/run_init.c) 来为您完成所有这些工作。大多数其他软件包(例如busybox)将此命令命名为“switch_root”。