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 必須為零。
硬連結處理¶
當看到 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。