将文件附加到 initramfs 映像 - 可靠吗?

将文件附加到 initramfs 映像 - 可靠吗?

我正在修改来自不同 Linux 发行版的一堆initramfs档案,其中通常只更改一个文件。

我想自动化该过程,而无需切换到 root 用户来提取initramfs映像内的所有文件并再次打包它们。

首先我尝试生成文件列表gen_init_cpio 没有提取存档上的所有内容initramfs,即通过脚本解析输出cpio -tvn initrd.img(如ls -l输出),该脚本将所有权限更改为八进制并将输出安排为gen_init_cpio所需的格式,例如:

dir /dev 755 0 0
nod /dev/console 644 0 0 c 5 1
slink /bin/sh busybox 777 0 0
file /bin/busybox initramfs/busybox 755 0 0

这涉及到一些替换,而且脚本对我来说可能很难写,所以我找到了一种更好的方法,我问的是它的安全性和便携性如何:

在某些发行版中,我们有一个initramfs包含串联部分的文件,显然内核会解析整个文件,提取包装在 1 字节边界中的所有部分,因此无需将每个部分填充为 512 字节的倍数。我认为这个“功能”对我来说很有用,可以避免在修改其中的文件时重新创建存档。事实上它有效,至少对于DebianCloneZilla

例如,如果我们修改了Debian 8.2.0/init上的文件initrd.gz,我们可以将其附加到initrd.gz映像中:

$ echo ./init | cpio -H newc -o | gzip >> initrd.gz

因此initrd.gz有两个串联的档案,原始档案和修改后的档案。让我们看看结果binwalk

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             gzip compressed data, maximum compression, has original file name: "initrd", from Unix, last modified: Tue Sep  1 09:33:08 2015
6299939       0x602123        gzip compressed data, from Unix, last modified: Tue Nov 17 16:06:13 2015

它工作完美。但它可靠吗?将数据附加到文件时有哪些限制initfamfs?在不将原始存档填充到 512 字节的倍数的情况下追加是否安全?哪个内核版本支持此功能?

答案1

它非常可靠,并且受到所有支持 initrd 的内核版本的支持,据我所知。这是构成 cpio档案的一个特征。只是继续提取其输入......我们可能知道该文件是一个接一个的两个 cpio 存档,但 cpio 只是将其视为单个输入流。initramfscpio

Debian 建议使用这种方法(将另一个 cpio 附加到 initramfs)将二进制 blob 固件添加到其安装程序 initramfs。例如:

Debian 安装程序 / Netboot 固件 | Debian 维基

Initramfs 本质上是 gzip 压缩的 cpio 存档的串联,这些存档被提取到 ramdisk 中并由 Linux 内核用作早期用户空间。 Debian 安装程序的 initrd.gz 实际上是一个 gzip 压缩的 cpio 存档,其中包含安装程序在启动时所需的所有文件。通过简单地附加另一个 gzipped cpio 存档 - 包含我们缺少的固件文件 - 我们就可以上路了!

答案2

否,现有的 initramfs需要填充以便可靠地继续解析附加到压缩档案的任意档案

尤其是xz“传统帧格式”lz4压缩很棘手,四分之三会失败 - 具体来说,每次前一个存档的字节数不能被 4 整除时。这通常会被忽视,因为将 raw format=newc cpio 放在前面时并不需要担心单个压缩存档 - 未压缩的形式始终对齐。

虽然从理论上讲,initramfs 格式除了是(可选压缩)存档的简单串联之外没有指定,但当解压缩例程(在某些情况下,根据设计)无法分辨一个存档在哪里结束以及下一个存档在哪里开始时,仍然需要填充。一些边缘情况是Linux 版本 5.14 中的改进,其他的似乎很难(如果不是不可能)在内核中明确检测到。如果压缩档案后面有附加数据,则诸如以下的消息表明它被忽略:

Initramfs unpacking failed: Decoding failed
Initramfs unpacking failed: invalid magic at start of compressed archive
Initramfs unpacking failed: broken padding

如果压缩仅应用于最后一个存档,则这些消息是无害的 - 没有进一步解析任何内容,但无论如何也没有任何内容需要解析。

相关内容