我做了什么

我做了什么

我尝试提取 Ubuntu 18.10 的 initrd casper/initrd,结果出乎意料。我没有看到根文件系统和文件,只有一个名为的文件夹kernel

我做了什么

首先,我试图了解是否应该解压 initrd 或直接提取档案,因此我发出了这个命令:

$ file initrd
initrd: ASCII cpio archive (SVR4 with no CRC)

我得到了什么

根据输出,它应该是一个 cpio 档案,我用来cpio提取该档案。

$ cpio -id < initrd 
56 blocks
$ ls
initrd  kernel

如果我去看一下目录kernel,我得到了

kernel/
└── x86
    └── microcode
        └── AuthenticAMD.bin

2 directories, 1 file

我期望

应该有诸如init、、etc等文件和文件夹usr。例如:

bin  conf  cryptroot  etc  init  lib  lib64  run  sbin  scripts  usr  var

答案1

我发现 Ubuntu 18.10 的 initrd 的存档方式与以前的版本不同。在以前的版本中,initrd 通常是 lzma(或更早版本的 gzip)压缩的 cpio 存档。18.10 的 initrd 是由几个不同格式的二进制文件组成的存档。

要深入研究档案,您可能需要binwalk(或其他类似工具。您可以binwalk通过获得sudo apt install binwalk)。获得 后binwalk,发出命令binwalk initrd

$ binwalk initrd

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             ASCII cpio archive (SVR4 with no CRC), file name: ".", file name length: "0x00000002", file size: "0x00000000"
112           0x70            ASCII cpio archive (SVR4 with no CRC), file name: "kernel", file name length: "0x00000007", file size: "0x00000000"
232           0xE8            ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86", file name length: "0x0000000B", file size: "0x00000000"
356           0x164           ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode", file name length: "0x00000015", file size: "0x00000000"
488           0x1E8           ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/AuthenticAMD.bin", file name length: "0x00000026", file size: "0x00006B2A"
28072         0x6DA8          ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
28672         0x7000          ASCII cpio archive (SVR4 with no CRC), file name: "kernel", file name length: "0x00000007", file size: "0x00000000"
28792         0x7078          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86", file name length: "0x0000000B", file size: "0x00000000"
28916         0x70F4          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode", file name length: "0x00000015", file size: "0x00000000"
29048         0x7178          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/.enuineIntel.align.0123456789abc", file name length: "0x00000036", file size: "0x00000000"
29212         0x721C          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/GenuineIntel.bin", file name length: "0x00000026", file size: "0x00180C00"
1605296       0x187EB0        ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
1605632       0x188000        LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: -1 bytes

可以看到有两个微码二进制文件和一个 LZMA 压缩数据文件。后者就是我们想要的:lzma 压缩的 initrd。

让我们通过以下方式获取 lzma 压缩的 initrd

dd if=initrd bs=1605632 skip=1 | unlzma -c | cpio -id

您将获得问题中提到的预期文件。编辑要更改的文件。使用以下命令重新打包二进制文件:

查找 | cpio -H newc -o | lzma -c > initrd.partial.lz

最后将微码文件和新的 initrd (initrd.partial.lz) 连接起来

dd if=initrd of=initrd.microcode bs=512 count=3136
cat initrd.microcode initrd.partial.lz > initrd.new

现在将其重命名initrd.newinitrd并将其恢复为casper/initrd。您可以使用新的 initrd 启动实时系统。

我的回答受到这篇文章的启发https://unix.stackexchange.com/questions/163346/why-is-it-that-my-initrd-only-has-one-directory-namely-kernel

答案2

首先,使用unmkinitramfs提取 CPIO 档案。请注意,在现代 Linux 系统上,文件initrd.img-*是直接连接在一起的多个 CPIO 档案组成的复合档案,因此如果您使用cat initrd.img-* | cpio -id,它将仅提取第一个 CPIO 档案,通常是内核微码补丁。unmkinitramfs将提取包含的所有 CPIO 档案。

Usage: unmkinitramfs [-v] initramfs-file output-directory

output-directory接下来,根据需要修改 initrd 文件。

最后,要将所有东西打包成一个新的initrd,请使用mkinitrd.shhttps://github.com/xuancong84/netboot/blob/main/mkinitrd.sh

Usage: mkinitrd.sh output-directory new-initrd.img

相关内容