如何重新打包initrd.img?

在原始的/boot/initrd.img- kernel_ver binwalk显示了这个结构:

在此处输入图像描述

022528字节,CPIO存档仅包含特定文件夹层次结构中的GenuineIntel.bin固件。
22528字节开始,gzip archiwe包含适当的文件系统,此gzip也与CPIO一起存档

解压缩并修改后如何以相同的方式压缩initrd.img(具有相同的文件夹层次结构)? 喜欢这个原始结构:

在此处输入图像描述

建议评论后:

 find . | cpio --quiet --dereference -o -H newc | lzma -7 > ../cusotm.initrd.lz 

binwalk

在此处输入图像描述

这是完全不同的结构。

你重新包装

 cd your_working_directory_with_modifications find . | cpio --quiet --dereference -o -H newc | lzma -7 > ../cusotm.initrd.lz 

第二个命令重命名initrd,指定在grub中引导时使用的initrd。

我建议您在移动或重命名之前测试(引导)自定义initrd。

评论中讨论的其他信息:

首先,我认为您不了解cpio / tar的作用。 cpio和tar都会获取大量文件和/或目录,并将它们组合成一个文件或存档。

其次,我认为您不了解压缩的作用,压缩只会使生成的存档更小。 您可以使用任何希望进行压缩的工具。

看到

https://wiki.ubuntu.com/CustomizeLiveInitrd

https://wiki.gentoo.org/wiki/Initramfs/Guide

第三,linux内核使用cipo而不是tar。

看到

https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt

请参阅“为什么选择cpio而不是tar?” 部分

为什么选择cpio而不是tar?

这个决定是在2001年12月做出的。讨论从这里开始:

http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1538.html

并产生了第二个线程(特别是在tar vs cpio上),从这里开始:

http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1587.html

快速和脏的摘要版本(不能替代阅读上述线程)是:

1)cpio是标准。 它已有几十年的历史(从AT&T时代开始),并且已经在Linux上广泛使用(在RPM内部,Red Hat的设备驱动程序磁盘)。 这是1996年Linux Journal上关于它的文章:

  http://www.linuxjournal.com/article/1213 

它不像tar那样流行,因为传统的cpio命令行工具需要_truly_hideous_命令行参数。 但是,无论如何都没有说明存档格式,还有其他工具,例如:

  http://freecode.com/projects/afio 

2)内核选择的cpio归档格式比任何(几十种)各种tar归档格式更简单,更清晰(因此更容易创建和解析)。 完整的initramfs存档格式在buffer-format.txt中解释,在usr / gen_init_cpio.c中创建,并在init / initramfs.c中解压缩。 所有这三者总共不到26k的人类可读文本。

3)标准化tar的GNU项目与Windows上的zip标准化大致相同。 Linux不是其中之一,可以自由地做出自己的技术决策。

4)因为这是一个内核内部格式,所以很容易就可以了
一些全新的东西。 无论如何,内核提供了自己的工具来创建和提取这种格式。 使用现有标准是优选的,但不是必需的。

5)Al Viro做出了决定(引用:“tar很丑陋,不会在内核方面得到支持”):

  http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1540.html 

解释了他的推理:

  http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1550.html http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1638.html 

最重要的是,设计并实现了initramfs代码。

我想出了如何制作完全相同的initrd.img存档。

Bodhi.zazen的答案可能会有效,因为这是众所周知的解决方案:

 find . | cpio --quiet --dereference -o -H newc | lzma -7 > ../cusotm.initrd.lz 

但问题不同了。 如果在cpio存档中有一个gzip压缩文件系统,这个答案会很好,但在这种情况下,我还要保留特定文件夹结构中的英特尔固件。

要保持相同的文件夹层次结构,需要三个步骤:

  1. 使用简单的-o选项创建CPIO文件系统归档,而不使用newc格式,例如。 基础文件夹:

    find . | cpio -o | gzip -9 > ../base/file_system.gz

  2. 使用包含kernel / x86 / microcode / GenuineIntel.bin的 newc格式进行适当的归档:

    find kernel/ | cpio -o -H newc > new_initrd.img

  3. 将gzip压缩文件系统存档添加到正确的new_initrd.img:

    find base/ | cpio -o >> new_initrd.img

我最近遇到了同样的问题,我的网络搜索引导我进入这个主题,所以如果它帮助其他人追随这些脚步,这里是2018年对一个老问题的回答……

在“最近的”内核中,initrd.img文件似乎可以包含一个未压缩的cpio存档(即包含微代码更新),该存档位于包含正常initramfs目录树的(压缩的)cpio存档之前。

这在Debian Wiki页面中进行了简要讨论:
https://wiki.debian.org/initramfs#How_to_inspect_initramfs
但是,可以在initramfs-tools-core包中的unmkinitramfs命令中的splitinitramfs()函数中找到更精确的解析这种initrd.img文件的代码(例如https://git.launchpad.net/ubuntu) / + source / initramfs-tools / tree / unmkinitramfs )。

我自己没有尝试过重建这种类型的initrd.img文件,但基于该Wiki页面,似乎编辑initramfs启动脚本,根本不想打开GenuineIntel存档文件。 相反,您可以单独保存该cpio存档,然后解压缩第二个(压缩)存档,修改目录树,重建压缩的cpio存档,然后将保存的微码存档与新生成的存档连接起来。

(最初生成此“prepended”存档的代码位于/usr/share/initramfs-tools/hooks/intel_microcode 。)

在Ubuntu中, initrd.img是用gzip压缩的,我想在编辑时保留它。 这是如何:

提取:

 zcat /boot/initrd.img-3.19.0-80-generic | cpio --extract 

压缩:

 find . 2>/dev/null | cpio --quiet --dereference -o -H newc | gzip -9 > /boot/initrd.img-3.19.0-80-generic