为什么我的initrd只有一个目录,即'kernel'?

use*_*730 41 linux debian initrd cpio

我正在使用 debian live-build 在可启动系统上工作。在该过程结束时,我获得了用于启动实时系统的典型文件:squashfs 文件、一些 GRUB 模块和配置文件,以及一个 initrd.img 文件。

我可以使用这些文件很好地启动,通过将 initrd 传递给内核

initrd=/path/to/my/initrd.img
Run Code Online (Sandbox Code Playgroud)

在引导加载程序命令行上。但是当我尝试检查 initrd 映像的内容时,如下所示:

$file initrd.img
initrd.img: ASCII cpio archive (SVR4 with no CRC)
$mkdir initTree && cd initTree
$cpio -idv < ../initrd.img
Run Code Online (Sandbox Code Playgroud)

我得到的文件树看起来像这样:

$tree --charset=ASCII
.
`-- kernel
    `-- x86
        `-- microcode
            `-- GenuineIntel.bin
Run Code Online (Sandbox Code Playgroud)

实际的文件系统树在哪里,典型的 /bin , /etc , /sbin ... 包含引导期间使用的实际文件?

小智 37

给出的 cpio 块跳过方法不能可靠地工作。那是因为我自己获得的 initrd 图像没有将两个档案连接在 512 字节的边界上。

相反,请执行以下操作:

apt-get install binwalk
legolas [mc]# binwalk initrd.img 
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             ASCII cpio archive (SVR4 with no CRC), file name: "kernel", file name length: "0x00000007", file size: "0x00000000"
120           0x78            ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86", file name length: "0x0000000B", file size: "0x00000000"
244           0xF4            ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode", file name length: "0x00000015", file size: "0x00000000"
376           0x178           ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/GenuineIntel.bin", file name length: "0x00000026", file size: "0x00005000"
21004         0x520C          ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
21136         0x5290          gzip compressed data, from Unix, last modified: Sat Feb 28 09:46:24 2015
Run Code Online (Sandbox Code Playgroud)

使用对我来说不在 512 字节边界上的最后一个数字 (21136):

legolas [mc]# dd if=initrd.img bs=21136 skip=1 | gunzip | cpio -tdv | head
drwxr-xr-x   1 root     root            0 Feb 28 09:46 .
drwxr-xr-x   1 root     root            0 Feb 28 09:46 bin
-rwxr-xr-x   1 root     root       554424 Dec 17  2011 bin/busybox
lrwxrwxrwx   1 root     root            7 Feb 28 09:46 bin/sh -> busybox
-rwxr-xr-x   1 root     root       111288 Sep 23  2011 bin/loadkeys
-rwxr-xr-x   1 root     root         2800 Aug 19  2013 bin/cat
-rwxr-xr-x   1 root     root          856 Aug 19  2013 bin/chroot
-rwxr-xr-x   1 root     root         5224 Aug 19  2013 bin/cpio
-rwxr-xr-x   1 root     root         3936 Aug 19  2013 bin/dd
-rwxr-xr-x   1 root     root          984 Aug 19  2013 bin/dmesg
Run Code Online (Sandbox Code Playgroud)

  • 只需`cd` 进入你解压cpio 存档的目录,运行`find | cpio -H newc -o &gt; /tmp/my_archive.cpio`,然后用`gzip /tmp/my_archive.cpio` gzip 它,最后,将它与微码图像连接起来,如果你有的话:`cat my_microcode_image.cpio /tmp/my_archive.cpio.gz &gt; mynewinitrd.img`。如果您没有微码映像,那么您可以在引导加载程序中按原样使用 gzip 文件 (2认同)
  • `binwalk` 在我的 Ubuntu 20.04 initrd 上列出了太多噪音。 (2认同)

小智 33

如果您知道您的文件initrd.img由一个未压缩的 cpio 存档和一个 gz 压缩的 cpio 存档组成,则可以使用以下命令将所有文件(从两个存档中)提取到当前工作目录中(在 bash 中测试):

(cpio -id; zcat | cpio -id) < /path/to/initrd.img
Run Code Online (Sandbox Code Playgroud)

上述命令行传递的内容initrd.img作为标准输入到其中执行所述两个命令子外壳cpio -idzcat | cpio -id顺序。第一个命令 ( cpio -id) 在读取了属于第一个 cpio 存档的所有数据后终止。然后将剩余的内容传递给zcat | cpio -id,它会解压缩并解压第二个存档。

  • 变体(对于当前的 ubuntu):`(cpio -i; cpio -i; unlz4 |cpio -i ) &lt; /initrd.img` (2认同)

use*_*730 21

事实证明,Debian 的实时构建生成的 initrd(令我惊讶的是,被内核接受)实际上是两个图像的连接:

  • 包含要应用于处理器的微码更新的 CPIO 存档;
  • 一个 gzip 格式的 cpio 存档,它实际上包含 initrd 文件树(带有 /etc /bin /sbin /dev ... 预期的目录)。

直接从实时构建输出中提取原始 initrd.img 后,我得到了以下输出:

$cpio -idv ../initrd.img
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/GenuineIntel.bin
896 blocks
Run Code Online (Sandbox Code Playgroud)

这意味着 cpio 提取在解析 896 个 512 字节的块后结束。但是原始的 initrd.img 比 896*512 = 458752B = 448 KB 大得多:

$ls -liah initrd.img
3933924 -r--r--r-- 1 root root 21M Oct 21 10:05 initrd.img
Run Code Online (Sandbox Code Playgroud)

因此,我正在寻找的实际 initrd 映像是在第一个 cpio 存档(包含微码更新的存档)之后附加的,并且可以使用 dd 访问:

$dd if=initrd.img of=myActualInitrdImage.img.gz bs=512 skip=896
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以使用unmkinitramfsinitramfs-tools >= 0.126,自 Debian 9 (stretch) 和 Ubuntu 18.04 (bionic) 起包含。

在 arch 上,您可以使用lsinitcpio