La méthode de saut de bloc cpio donnée ne fonctionne pas de manière fiable. C'est parce que les images initrd que j'obtenais moi-même n'avaient pas les deux archives concaténées sur une limite de 512 octets.
À la place, faites ceci :
apt-get install binwalk
legolas [mc]# binwalk initrd.img
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 ASCII cpio archive (SVR4 with no CRC), file name: "kernel", file name length: "0x00000007", file size: "0x00000000"
120 0x78 ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86", file name length: "0x0000000B", file size: "0x00000000"
244 0xF4 ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode", file name length: "0x00000015", file size: "0x00000000"
376 0x178 ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/GenuineIntel.bin", file name length: "0x00000026", file size: "0x00005000"
21004 0x520C ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
21136 0x5290 gzip compressed data, from Unix, last modified: Sat Feb 28 09:46:24 2015
Utilisez le dernier numéro (21136) qui n'est pas sur une limite de 512 octets pour moi :
legolas [mc]# dd if=initrd.img bs=21136 skip=1 | gunzip | cpio -tdv | head
drwxr-xr-x 1 root root 0 Feb 28 09:46 .
drwxr-xr-x 1 root root 0 Feb 28 09:46 bin
-rwxr-xr-x 1 root root 554424 Dec 17 2011 bin/busybox
lrwxrwxrwx 1 root root 7 Feb 28 09:46 bin/sh -> busybox
-rwxr-xr-x 1 root root 111288 Sep 23 2011 bin/loadkeys
-rwxr-xr-x 1 root root 2800 Aug 19 2013 bin/cat
-rwxr-xr-x 1 root root 856 Aug 19 2013 bin/chroot
-rwxr-xr-x 1 root root 5224 Aug 19 2013 bin/cpio
-rwxr-xr-x 1 root root 3936 Aug 19 2013 bin/dd
-rwxr-xr-x 1 root root 984 Aug 19 2013 bin/dmesg
Si vous connaissez votre initrd.img
se compose d'une archive cpio non compressée suivie d'une archive cpio compressée avec gz, vous pouvez utiliser ce qui suit pour extraire tous les fichiers (des deux archives) dans votre répertoire de travail actuel (testé en bash) :
(cpio -id; zcat | cpio -id) < /path/to/initrd.img
La ligne de commande ci-dessus transmet le contenu de initrd.img
en entrée standard dans un sous-shell qui exécute les deux commandes cpio -id
et zcat | cpio -id
séquentiellement. La première commande (cpio -id
) se termine une fois qu'il a lu toutes les données appartenant à la première archive cpio. Le contenu restant est ensuite transmis à zcat | cpio -id
, qui décompresse et décompresse la seconde archive.
Il s'avère que l'initrd généré par le live-build de Debian (et à ma grande surprise, accepté par le noyau) est en fait la concaténation de deux images :
- une archive CPIO contenant les mises à jour du microcode à appliquer sur le processeur ;
- une archive cpio gzip-ed, qui contient en fait l'arborescence des fichiers initrd (avec les répertoires /etc /bin /sbin /dev ... qui étaient attendus).
Lors de l'extraction du fichier initrd.img d'origine, directement à partir de la sortie live-build, j'ai obtenu cette sortie :
$cpio -idv ../initrd.img
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/GenuineIntel.bin
896 blocks
Ce qui signifie que l'extraction cpio s'est terminée après l'analyse de 896 blocs de 512 octets chacun. Mais l'initrd.img d'origine était bien plus grand que 896*512 =458752B =448 KB :
$ls -liah initrd.img
3933924 -r--r--r-- 1 root root 21M Oct 21 10:05 initrd.img
Ainsi, l'image initrd réelle que je cherchais a été ajoutée juste après la première archive cpio (celle contenant les mises à jour du microcode) et était accessible à l'aide de dd :
$dd if=initrd.img of=myActualInitrdImage.img.gz bs=512 skip=896