How to modify initrd initial ramdisk of Ubuntu 18.10 Cosmic Cuttlefish
I tried to extract the initrd casper/initrd
of Ubuntu 18.10 and got an unexpected result. I did not see the root filesystem and files, but just a folder named kernel
.
What I have done
Firstly I tried to know if I should decompress the initrd or just extract the archive directly, so I issued this command:
$ file initrd
initrd: ASCII cpio archive (SVR4 with no CRC)
What I got
According to the output, it should be an cpio archive and I used cpio
to extract the archive.
$ cpio -id < initrd
56 blocks
$ ls
initrd kernel
If I went to have a look of the directory kernel
, I got
kernel/
└── x86
└── microcode
└── AuthenticAMD.bin
2 directories, 1 file
What I expect
There should be files and folders like init
, etc
, usr
, and so on. For example:
bin conf cryptroot etc init lib lib64 run sbin scripts usr var
I figure out the initrd of Ubuntu 18.10 is archived in a different way from the previous releases. In the previous releases the initrd is usually a lzma (or gzip for much earlier releases) compressed cpio archive. The initrd of 18.10 is an archive composed of several binary files in different formats.
To dive into the archive, you may need binwalk
(or other similar tools. You could get binwalk
by sudo apt install binwalk
). Once you get binwalk
, issue the command 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
You could see there are two microcode binary files and a LZMA compressed data file. The latter is what we want: the lzma compressed initrd.
Let's get the lzma compressed initrd by
dd if=initrd bs=1605632 skip=1 | unlzma -c | cpio -id
You will get the expected files mentioned in the questions. Edit the files you want to change. Use the following commands to repack the binary files:
find | cpio -H newc -o | lzma -c > initrd.partial.lz
And finally concatenate the microcode files and your new initrd (initrd.partial.lz) by
dd if=initrd of=initrd.microcode bs=512 count=3136
cat initrd.microcode initrd.partial.lz > initrd.new
Now rename initrd.new
to be initrd
and put it back to casper/initrd
. You could boot your live system with your new initrd.
My answer is inspired by this post https://unix.stackexchange.com/questions/163346/why-is-it-that-my-initrd-only-has-one-directory-namely-kernel