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