initramfs 缓冲区格式

Al Viro, H. Peter Anvin

对于内核 2.5.x,旧的“初始 ramdisk”协议被“初始 ramfs”协议补充。 initramfs 内容使用与 initrd 相同的内存缓冲区协议传递,但内容不同。 initramfs 缓冲区包含一个存档,该存档被扩展到 ramfs 文件系统中;本文档详细介绍了 initramfs 缓冲区格式。

initramfs 缓冲区格式基于 “newc” 或 “crc” CPIO 格式,可以使用 cpio(1) 实用程序创建。 cpio 存档可以使用 gzip(1) 或通过 CONFIG_DECOMPRESS_* 提供的任何其他算法进行压缩。 因此,initramfs 缓冲区的一个有效版本是单个 .cpio.gz 文件。

initramfs 缓冲区的完整格式由以下语法定义,其中

*       is used to indicate "0 or more occurrences of"
(|)     indicates alternatives
+       indicates concatenation
GZIP()  indicates gzip compression of the operand
BZIP2() indicates bzip2 compression of the operand
LZMA()  indicates lzma compression of the operand
XZ()    indicates xz compression of the operand
LZO()   indicates lzo compression of the operand
LZ4()   indicates lz4 compression of the operand
ZSTD()  indicates zstd compression of the operand
ALGN(n) means padding with null bytes to an n-byte boundary

initramfs := ("\0" | cpio_archive | cpio_compressed_archive)*

cpio_compressed_archive := (GZIP(cpio_archive) | BZIP2(cpio_archive)
        | LZMA(cpio_archive) | XZ(cpio_archive) | LZO(cpio_archive)
        | LZ4(cpio_archive) | ZSTD(cpio_archive))

cpio_archive := cpio_file* + (<nothing> | cpio_trailer)

cpio_file := ALGN(4) + cpio_header + filename + "\0" + ALGN(4) + data

cpio_trailer := ALGN(4) + cpio_header + "TRAILER!!!\0" + ALGN(4)

用通俗的话说,initramfs 缓冲区包含压缩的和/或未压缩的 cpio 存档的集合(采用 “newc” 或 “crc” 格式);可以在成员之间添加任意数量的零字节(用于填充)。

cpio “TRAILER!!!” 条目(cpio 存档结束)是可选的,但不会被忽略;请参阅下面的“硬链接处理”。

cpio_header 的结构如下(所有字段都包含十六进制 ASCII 数字,并在左侧用 ‘0’ 完全填充到字段的完整宽度,例如,整数 4780 由 ASCII 字符串 “000012ac” 表示)

字段名称

字段大小

含义

c_magic

6 字节

字符串 “070701” 或 “070702”

c_ino

8 字节

文件 inode 编号

c_mode

8 字节

文件模式和权限

c_uid

8 字节

文件 uid

c_gid

8 字节

文件 gid

c_nlink

8 字节

链接数

c_mtime

8 字节

修改时间

c_filesize

8 字节

数据字段的大小

c_maj

8 字节

文件设备编号的主要部分

c_min

8 字节

文件设备编号的次要部分

c_rmaj

8 字节

设备节点引用的主要部分

c_rmin

8 字节

设备节点引用的次要部分

c_namesize

8 字节

文件名长度,包括最后的 0

c_chksum

8 字节

如果 c_magic 为 070702,则为数据字段的校验和;否则为零

c_mode 字段与 Linux 上 stat(2) 返回的 st_mode 的内容匹配,并编码文件类型和文件权限。

除非设置了 CONFIG_INITRAMFS_PRESERVE_MTIME=y,否则将忽略 c_mtime。

对于任何不是常规文件或符号链接的文件,c_filesize 应为零。

c_chksum 字段包含数据字段中所有字节的简单 32 位无符号和。 cpio(1) 将其称为 “crc”,这显然是不正确的(循环冗余校验是一种不同的且明显更强的完整性检查),但是,这是使用的算法。

如果文件名为 “TRAILER!!!”,则实际上是存档结束标记;存档结束标记的 c_filesize 必须为零。