initramfs 缓冲区格式¶
Al Viro, H. Peter Anvin
最后修订:2002-01-13
从内核 2.5.x 开始,旧的“初始内存盘”协议正在被新的“初始内存文件系统”(initramfs)协议 {替换/补充}。initramfs 的内容使用与 initrd 协议相同的内存缓冲区协议传递,但内容不同。initramfs 缓冲区包含一个归档文件,该归档文件被解压到一个内存文件系统;本文档详细介绍了 initramfs 缓冲区的格式。
initramfs 缓冲区格式基于 “newc” 或 “crc” CPIO 格式,可以使用 cpio(1) 实用程序创建。可以使用 gzip(1) 压缩 cpio 归档文件。因此,initramfs 缓冲区的有效版本是单个 .cpio.gz 文件。
initramfs 缓冲区的完整格式由以下语法定义,其中
* is used to indicate "0 or more occurrences of"
(|) indicates alternatives
+ indicates concatenation
GZIP() indicates the gzip(1) of the operand
ALGN(n) means padding with null bytes to an n-byte boundary
initramfs := ("\0" | cpio_archive | cpio_gzip_archive)*
cpio_gzip_archive := GZIP(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 的内容匹配,并编码文件类型和文件权限。
对于任何非普通文件或符号链接的文件,c_filesize 应为零。
c_chksum 字段包含数据字段中所有字节的简单 32 位无符号和。cpio(1) 将其称为 “crc”,这显然是不正确的(循环冗余校验是一种不同的且更强的完整性检查),但是,这是使用的算法。
如果文件名为 “TRAILER!!!”,则实际上是归档文件结束标记;归档文件结束标记的 c_filesize 必须为零。
硬链接的处理¶
当看到 c_nlink > 1 的非目录时,将在元组缓冲区中查找(c_maj,c_min,c_ino)元组。如果未找到,则将其输入到元组缓冲区中,并像往常一样创建条目;如果找到,则创建一个硬链接,而不是该文件的第二个副本。没有必要(但允许)包含该文件的第二个副本;如果未包含文件内容,则应将 c_filesize 字段设置为零,以指示没有后续的数据部分。如果存在数据,则覆盖该文件的先前实例;这允许文件的承载数据实例出现在序列中的任何位置(据报告,GNU cpio 仅将数据附加到文件的最后一个实例。)
对于符号链接,c_filesize 不能为零。
当看到 “TRAILER!!!” 归档文件结束标记时,元组缓冲区将被重置。这允许将独立生成的归档文件连接在一起。
因此,要组合来自不同来源的文件数据(而无需重新生成 (c_maj,c_min,c_ino) 字段),可以使用以下两种技术之一
使用 “TRAILER!!!” 归档文件结束标记分隔不同的文件数据源,或者
确保所有非目录条目的 c_nlink == 1。