Feeds:
Posts
Comments

Archive for January, 2015

Intro

As described in the Kernel doc, https://www.kernel.org/doc/Documentation/x86/early-microcode.txt, it is possible to combine 2 CPIO archives together into a single initramfs, simply by cat’ing them (see link above for details on the how/why).
But I ran into an issue while extracting it : only 1 of the archive would be extracted by the cpio command. How to extract the other one ?

Let’s do it manually.

How To

First, the issue :

Trying to extract Fedora 21’s initramfs (isolinux/initrd0.img), there was clearly something wrong :

[cedric@laptop f21]$ file initrd0.img
initrd0.img: ASCII cpio archive (SVR4 with no CRC)
[cedric@laptop f21]$ mkdir initrd0
[cedric@laptop f21]$ cd initrd0/
[cedric@laptop initrd0]$ cpio -idv < ../initrd0.img
.
early_cpio
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/AuthenticAMD.bin
kernel/x86/microcode/GenuineIntel.bin
1251 blocks
[cedric@laptop initrd0]$ du -sh .
648K    .
[cedric@laptop initrd0]$ du -sh ../initrd0.img
37M     ../initrd0.img

There’s clearly data missing here :
1) that initramfs would not be sufficient to boot (there’s no init!)
2) we have about 36.5M of data missing!

How to get around

After a quick search, I didn’t find help to retrieve the remaining data, so I decided to go manually.

From the output, we know that the first archive is 648K extracted, and the archive is 1251 blocks (no compression was used for this archive). Thus we can guess that the block size is 512 bytes (1251 x 512 is close to 648K).
Let’s see what’s after that.

Note : 1251 x 512 = 640,512 = 0x9C600

[cedric@laptop f21]$ hexdump -C initrd0.img | less
[...]
0009c430  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
0009c600  1f 8b 08 00 09 77 7f 54  02 03 ec 59 09 54 13 57  |.....w.T...Y.T.W|
0009c610  f7 7f 6f 08 18 10 34 20  2a 82 d8 80 04 41 10 92  |..o...4 *....A..|

2 good news there :
1) offset 0x9c600 looks like the begining of something
2) “1f 8b” at offset 0 is the magic type for “gzip compressed data” (37\213 in octal) :

[cedric@laptop initrd0]$ grep "gzip compressed data" /usr/share/misc/magic
0       string          37\213        gzip compressed data

So now we just need to extract that gzip data out, and that will probably contain our actual initramfs :

[cedric@laptop f21]$ mkdir initrd1
[cedric@laptop f21]$ cd initrd1
[cedric@laptop initrd1]$ dd if=../initrd0.img of=initrd1.img bs=1b skip=1251
72966+1 records in
72966+1 records out
37359079 bytes (37 MB) copied, 0.151864 s, 246 MB/s
[cedric@laptop initrd1]$ file initrd1.img
initrd1.img: gzip compressed data, last modified: Wed Dec  3 21:48:09 2014, max compression, from Unix
[cedric@laptop initrd1]$ zcat initrd1.img | cpio -idv
[...]
etc/plymouth
etc/plymouth/plymouthd.conf
proc
init
138243 blocks
[cedric@laptop initrd1]$ du -sh .
109M    .

… Now that sounds more right : we have a real initramfs, and the sizes are better.

Read Full Post »