「initrd」- initrd | InitRD | Initial RAM Disk

认识

initrd(Initial RAM Disk)是一个临时的、基于内存的虚拟磁盘(块设备),其“在 Linux Kernel 启动后”“真正的根文件系统被挂载之前”被加载到内存中使用。它的核心作用是作为一个桥梁,为 Kernel 提供挂载真实根文件系统所必需的驱动程序和工具。initrd 是 Linux 启动过程中一个历史悠久的、至关重要的组件。它通过提供一个临时的内存磁盘,解决了 Kernel 无法直接挂载复杂根文件系统的核心难题。理解 initrd 的工作原理对于深入理解 Linux 系统启动流程至关重要。

组成

它是个文件系统,initrd 的本质是一个经 gzip 压缩的文件系统镜像(通常是 `ext2` 格式)。很多发行版使用 ext2 格式。

其中包含部分关键的 Kernel Module 及某些特殊功能代码。

Bootloader 将其加载到内存,Kernel 将其解压到内存中,并将其作为文件系统挂载,以从中获取或执行必要文件。
Kernel 为了识别 initrd 该文件系统,需要相关的驱动(中间文件系统驱动)。

查看 initrd 内容:linux – Why is it that my initrd only has one directory, namely, ‘kernel’? – Unix & Linux Stack Exchange

技术原理与工作流程

整个启动过程如下:

  1. BIOS/UEFI:执行硬件自检,并加载引导程序(如 GRUB)。
  2. Bootloader (GRUB):根据配置文件,将 Linux Kernel 和 initrd 镜像文件加载到内存的指定位置,然后将控制权交给 Kernel。
  3. Linux Kernel:
    • Kernel 解压并执行。
    • Kernel 将内存中的 initrd 镜像解压缩,并将其内容加载到一个虚拟的块设备(如 `/dev/ram0`)中。
    • Kernel 将该内存块设备格式化为其内部的文件系统(如 `ext2`),并将其挂载为临时的根文件系统。
  4. 执行 /linuxrc:
    • Kernel 会在该临时根文件系统中寻找并执行一个名为 `/linuxrc` 的脚本(或可执行文件)。这是 initrd 环境的初始化进程。
  5. /linuxrc 的任务:
    • 该脚本负责完成挂载真实根文件系统的所有准备工作,通常包括:
      1. 加载 Kernel Module:通过 `insmod` 命令加载访问真实磁盘所需的驱动(如 SCSI 控制器、文件系统驱动)。
      2. 提供解密接口:如果根文件系统被加密,脚本会启动交互界面,提示用户输入密码,并使用工具(如 `cryptsetup`)进行解密。
      3. 激活逻辑卷:如果使用了 LVM,则使用 `vgscan` 和 `vgchange` 命令激活卷组。
      4. 创建设备节点:在 `/dev` 目录下创建正确的设备节点(如 `/dev/mapper/vg0-root`)。
  6. 挂载真正的根文件系统:
    • `/linuxrc` 脚本使用 `mount` 命令将准备好的真实根文件系统(如 `/dev/mapper/vg0-root`)挂载到一个临时目录(如 `/mnt/root`)。
  7. 切换根目录(Pivot Root):
    • 脚本执行 `pivot_root` 系统调用,将当前进程的根目录从 initrd 的根(`/`)切换到刚刚挂载好的真实根文件系统(如 `/mnt/root`)。
  8. 清理与移交控制权:
    • 卸载 initrd 文件系统。
    • 释放 initrd 占用的内存。
    • 最后,执行真实根文件系统中的 `/sbin/init`(通常是 Systemd 或 SysVinit),由它来接管后续的所有启动过程和服务管理。

性质

优点:

  • 解决了核心问题:成功解决了 Kernel 无法直接访问复杂存储设备的启动悖论。
  • 模块化:允许将非必需的驱动程序作为可加载模块,从而保持 Kernel 本身非常小巧和通用。

缺点:

  • 效率较低:因为它模拟了一个完整的块设备(`/dev/ram0`),这增加了一层不必要的抽象。Kernel 需要先处理该虚拟块设备,再处理其上的文件系统,造成了额外的开销。
  • 大小限制:initrd 镜像的大小在启动时就需要确定,无法动态调整。

构建

查看 initrd 内容

即使现在的 `initrd.img` 文件是 initramfs 格式,你仍然可以查看其内容:

# 1. 复制文件并解压(通常是 gzip 压缩的)
cp /boot/initrd.img-$(uname -r) /tmp/initrd.gz
cd /tmp
mkdir extracted
cd extracted
# 2. 解压并解包 cpio 归档
zcat ../initrd.gz | cpio -idmv

执行后,当前目录就会展开 initrd/initramfs 的完整文件结构,你可以查看里面的脚本、工具和模块。

改进

其已被更高效、更简单的 initramfs 技术所取代,今天,我们通常所说的“initrd”实际上指的就是它的继任者“initramfs”。initramfs 是 initrd 的现代继承者和替代品。如今,initramfs 已经完全取代了传统的 initrd。虽然很多 Linux 发行版和文档出于习惯仍将启动镜像称为 `initrd`(例如 `/boot/initrd.img-xxx`),但在技术上它们几乎都是 initramfs 格式。如今,initramfs 已经完全取代了 initrd。虽然很多系统和文档中仍沿用 `initrd` 这个名字,但技术上它们指的都是 initramfs。

参考

DeepSeek / 介绍 initrd
Documentation/initrd.txt
Initial ramdisk – Wikipedia