13

On original /boot/initrd.img-kernel_ver binwalk shows this structure:

enter image description here

From 0 to 22528 bytes there is CPIO archive contains only GenuineIntel.bin firmware in specific folder hierarchy.
From 22528 bytes there is gzip archiwe contains appropriate file system and this gzip is also archived with CPIO

After unpacking and modifying how can I compress initrd.img in the same way (with the same folder hierarchy) ? like this original structure:

enter image description here

After suggestion from comment :

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

binwalk :

enter image description here

This is completly different structure.

6
  • You extract the initrd.img into a working directory. You add your GenuineIntel.bin firmware in specific folder hierarchy to the working directory. You then remake the archive with find . | cpio --quiet --dereference -o -H newc | lzma -7 > ../cusotm.initrd.lz If that procedure is not working , clarify what commands you ran and what is not working.
    – Panther
    May 26, 2016 at 17:57
  • Your edit, with a picture, adds little to nothing of my understanding of your problem. You need to extract the image, add in your code, with the appropriate file structure and location of GenuineIntel.bin firmware and re-package into a new .img.
    – Panther
    May 26, 2016 at 18:02
  • @bodhi.zazen as I said this made different file...
    – EdiD
    May 26, 2016 at 18:19
  • @bodhi.zazen do you finally understand what I am asking ?
    – EdiD
    May 26, 2016 at 18:37
  • 1
    It looks like the initramfs file is a concatenation of CPIO archives. Each CPIO archive can be compressed (with gzip, xz etc.) or uncompressed. Your input file starts with an uncompressed one at offset 0, then it continues with a compressed one at offset 22528. Unfortunately I don't know of a standard tool which can extract a concatenation of maybe-compressed CPIO archives.
    – pts
    Jan 18, 2018 at 22:48

4 Answers 4

6

I figured it out how to make exactly the same initrd.img archive.

Bodhi.zazen answer will probably work because this is commonly known solution:

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

but the question was different. This answer would be good if in cpio archive there is one gzipped file system but in this situation there is also Intel firmware in specific folder structure which I want to keep.

To keep the same folder hierarchy three steps are needed:

  1. Make CPIO file system archive with simple -o option without newc format in created before eg. base folder:

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

  2. Make proper archive with newc format containing kernel/x86/microcode/GenuineIntel.bin:

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

  3. Add gzipped filesystem archive to the proper new_initrd.img:

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

4
  • 1
    Great! Thanks! +10! But how do you unpack original initrd?
    – rth
    Jul 17, 2018 at 15:30
  • Also, your solution creates a bit different structure. I've got the absolutely the same tructure in binwalk when I did the step (2) first and then find . | cpio -o | gzip -9 >> new_initrd.img
    – rth
    Jul 17, 2018 at 16:05
  • @EdiD how do you unpack original initrd? Feb 10, 2020 at 17:41
  • 1
    @ImranRazaKhan you need four steps: cpio -id < initrd.img-kernel_ver ; dd if=initrd.img-4.4.0-22-generic of=image.gz bs=22528 skip=1 -match your initrd.img file name and block size; gunzip image.gz; cpio -i < image
    – EdiD
    Feb 11, 2020 at 17:12
5

I recently ran into this same question and my web searching led me to this thread, so in case it helps others following in those footsteps, here's a 2018 answer to an old question...

It seems in "recent" kernels the initrd.img file can contain an uncompressed cpio archive (i.e. containing microcode updates) prepended to the (compressed) cpio archive containing the normal initramfs directory tree.

This is discussed briefly in the Debian Wiki page:
https://wiki.debian.org/initramfs#How_to_inspect_initramfs
, but more precise code for parsing through this sort of initrd.img file can be found in the splitinitramfs() function within the unmkinitramfs command found in the initramfs-tools-core package (e.g. https://git.launchpad.net/ubuntu/+source/initramfs-tools/tree/unmkinitramfs ).

I have not tried to rebuild this sort of initrd.img file myself, but based on that Wiki page it seems that to edit the initramfs boot scripts, one would not want to unpack the GenuineIntel archive at all. Instead, you could just preserve that cpio archive as-is somewhere separately, then unpack the second (compressed) archive, modify the directory tree, and rebuild the compressed cpio archive, then concatenate the saved microcode archive with the newly-generated one.

(The code that originally generated this "prepended" archive is found in /usr/share/initramfs-tools/hooks/intel_microcode.)

4

You repackage with

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

The second command renames the initrd, you specifiy the initrd to use when booting in grub.

I suggest you test (boot)the custom initrd before moving or renaming it.

Additional information from the discussion in the comments:

First I do not think you are understanding the role of cpio / tar. both cpio and tar take a number of files and/or directories and make them into one file or archive.

Second I do not think you understand the role of compression, compression simply makes the resulting archive smaller. You can use any tool you wish for compression.

See

https://wiki.ubuntu.com/CustomizeLiveInitrd

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

Third, the linux kernel uses cipo rather then tar.

See

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

See the "Why cpio rather than tar?" section

Why cpio rather than tar?

This decision was made back in December, 2001. The discussion started here:

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

And spawned a second thread (specifically on tar vs cpio), starting here:

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

The quick and dirty summary version (which is no substitute for reading the above threads) is:

1) cpio is a standard. It's decades old (from the AT&T days), and already widely used on Linux (inside RPM, Red Hat's device driver disks). Here's a Linux Journal article about it from 1996:

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

It's not as popular as tar because the traditional cpio command line tools require _truly_hideous_ command line arguments. But that says nothing either way about the archive format, and there are alternative tools, such as:

 http://freecode.com/projects/afio

2) The cpio archive format chosen by the kernel is simpler and cleaner (and thus easier to create and parse) than any of the (literally dozens of) various tar archive formats. The complete initramfs archive format is explained in buffer-format.txt, created in usr/gen_init_cpio.c, and extracted in init/initramfs.c. All three together come to less than 26k total of human-readable text.

3) The GNU project standardizing on tar is approximately as relevant as Windows standardizing on zip. Linux is not part of either, and is free to make its own technical decisions.

4) Since this is a kernel internal format, it could easily have been
something brand new. The kernel provides its own tools to create and extract this format anyway. Using an existing standard was preferable, but not essential.

5) Al Viro made the decision (quote: "tar is ugly as hell and not going to be supported on the kernel side"):

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

explained his reasoning:

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

and, most importantly, designed and implemented the initramfs code.

15
  • This will not preserve folder structure. I want the same structure as original initrd.img. Meaning -> GenuineIntel.bin not compressed just archived with cpio on root in kernel/x86/microcode folder and why lzma while I'm talking about gzip ?
    – EdiD
    May 25, 2016 at 16:18
  • lzma gives a smaller archive. use gzip if you wish. I am not sure why you are concerned about compression or not, should work just fine with compression and result in a smaller image on the disk. Not really sure what you are trying to accomplish from what you posted.
    – Panther
    May 25, 2016 at 16:22
  • I want to know how was it originally done. Probably intel firmware is not compressed because of faster accessibility.
    – EdiD
    May 25, 2016 at 16:29
  • almost certainly was compressed, you can check the archive. Compression is used by default as it does not noticeably affect performance.
    – Panther
    May 25, 2016 at 16:36
  • There isn't anything in cpio manual about compression. Check accepted answer: superuser.com/questions/343915/…
    – EdiD
    May 25, 2016 at 16:45
1

in Ubuntu the initrd.img is compressed in gzip, I would like to preserve this when I edit it. this is how:

extract:

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

compress:

find . 2>/dev/null | cpio --quiet --dereference -o -H newc | gzip -9 > /boot/initrd.img-3.19.0-80-generic
3
  • Hmmm it looks like it works, but it actually will no longer boot my machine. I also noticed that the re-packed archive is significantly bigger than the original one, despite the repack using higher compression (-9). Need to get to the bottom.
    – nisc
    Jul 13, 2021 at 0:31
  • @nisc As far as I recall, that was the only combination worked and with boot. Maybe what's missing is a file permission set. Or theres differences between Ubuntu versions (I've used at the time 14,04) Jul 13, 2021 at 8:20
  • The different file size is probably due to --dereference but haven't confirmed/tested it
    – nisc
    Jul 14, 2021 at 5:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .