Die angegebene cpio-Block-Skip-Methode funktioniert nicht zuverlässig. Das liegt daran, dass die initrd-Images, die ich selbst erhielt, nicht beide Archive an einer 512-Byte-Grenze verkettet hatten.
Gehen Sie stattdessen wie folgt vor:
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
Verwenden Sie die letzte Zahl (21136), die für mich nicht auf einer 512-Byte-Grenze liegt:
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
Wenn Sie Ihren initrd.img
kennen aus einem unkomprimierten cpio-Archiv gefolgt von einem gz-komprimierten cpio-Archiv besteht, können Sie Folgendes verwenden, um alle Dateien (aus beiden Archiven) in Ihr aktuelles Arbeitsverzeichnis zu extrahieren (getestet in Bash):
(cpio -id; zcat | cpio -id) < /path/to/initrd.img
Die obige Befehlszeile übergibt den Inhalt von initrd.img
als Standardeingabe in eine Subshell, die die beiden Befehle cpio -id
ausführt und zcat | cpio -id
der Reihe nach. Der erste Befehl (cpio -id
) terminiert, sobald es alle Daten gelesen hat, die zum ersten cpio-Archiv gehören. Der restliche Inhalt wird dann an zcat | cpio -id
übergeben , das das zweite Archiv dekomprimiert und entpackt.
Es stellt sich heraus, dass die von Debians Live-Build generierte (und zu meiner Überraschung vom Kernel akzeptierte) initrd tatsächlich die Verkettung von zwei Bildern ist:
- ein CPIO-Archiv mit Microcode-Updates, die auf den Prozessor angewendet werden sollen;
- ein gzip-ed cpio-Archiv, das tatsächlich den initrd-Dateibaum enthält (mit den /etc /bin /sbin /dev ... -Verzeichnissen, die erwartet wurden).
Beim Extrahieren der ursprünglichen initrd.img direkt aus der Live-Build-Ausgabe erhielt ich diese Ausgabe:
$cpio -idv ../initrd.img
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/GenuineIntel.bin
896 blocks
Das bedeutet, dass die cpio-Extraktion nach dem Analysieren von 896 Blöcken mit jeweils 512 Bytes endete. Aber die ursprüngliche initrd.img war viel größer als 896*512 =458752B =448 KB :
$ls -liah initrd.img
3933924 -r--r--r-- 1 root root 21M Oct 21 10:05 initrd.img
Das eigentliche initrd-Image, nach dem ich gesucht habe, wurde also direkt nach dem ersten cpio-Archiv (das die Microcode-Updates enthält) angehängt und konnte mit dd:
aufgerufen werden$dd if=initrd.img of=myActualInitrdImage.img.gz bs=512 skip=896