Een initial ramdisk uitpakken op CentOS 7

Een initial ramdisk is vanouds een gecomprimeerd cpio-archief waar kernel modules opstaan die de kernel nodig heeft om het Linux-systeem op te starten. Als je al zeer vroeg tijdens het opstarten iets specifieks wilt doen dan is de initial ramdisk de plek om
dat te doen. Je pakt het cpio-archief uit en doet je aanpassingen en pakt het weer in en comprimeert het vervolgens:

$ zcat /boot/initrd.img-3.16.0-33-generic | cpio -id
$ ls
bin  conf  etc  init  lib  lib64  run  sbin  scripts  var
...
<aanpassingen maken>
...
$ find . | cpio -oHnewc | gzip > /boot/initrd.img-3.16.0-33-generic

De uitvoer van het commando ls laat zien dat de initrd een aantal directories bevat en één file genaamd init.

De file init is een script dat wat controles uitvoert en zorgt dat alles goed staat, zodat het Linux-systeem kan worden opgestart. Echter onder CentOS versie 7 is de initrd iets anders opgezet. Ten eerste lijkt het erop dat de initrd niet is gecomprimeerd:

$ zcat /boot/initramfs-3.10.0-123.13.2.el7.x86_64.img |  cpio -id

gzip: /boot/initramfs-3.10.0-123.13.2.el7.x86_64.img: not in gzip format
cpio: premature end of archive

We doen het nogmaals zonder decompressie:

$ cat /boot/initramfs-3.10.0-123.13.2.el7.x86_64.img |  cpio -id
26 blocks
$ ls
early_cpio  kernel

Het enige dat je zult vinden is een bestand early_cpio en microcode voor de CPU. Waar het bestand early_cpio voor wordt gebruikt is mij onbekend. De microcode is in ieder geval bedoeld om zo vroeg mogelijk tijdens het opstarten op de CPU te laden om bekende bugs van de CPU te verhelpen. We missen echter de directories en bestanden die we normaliter in een initrd aantreffen.

Wanneer je de grootte van het bestand initramfs-3.10.0-123.13.2.el7.x86_64.img bekijkt zie je dat het veel groter is dan wat we net hebben uitgepakt:

$ ls -lh /boot/initramfs-3.10.0-123.13.2.el7.x86_64.img
-rw-r--r--. 1 root root 19M Apr  1 08:58 /boot/initramfs-3.10.0-123.13.2.el7.x86_64.img

Het lijkt erop dat we wat data missen. We zagen bij het uitpakken dat het cpio-archief 26 blokken bevat. Dit zijn blokken van 512 bytes en we kunnen dan de rest van het bestand door middel van dd als volgt verkrijgen:

$ dd if=/boot/initramfs-3.10.0-123.13.2.el7.x86_64.img bs=512 skip=26 | file -
/dev/stdin: gzip compressed data, from Unix, last modified: Wed Apr  1 08:58:04 2015, max compression

Het blijkt gecomprimeerde data te zijn en als we dat dan decomprimeren zien we dat het een cpio-archief is:

$ dd if=/boot/initramfs-3.10.0-123.13.2.el7.x86_64.img bs=512 skip=26 | gunzip | file -

Dit kunnen we uitpakken en dan zul je zien dat je de bekende initrd inhoud krijgt:

$ sudo dd if=/boot/initramfs-3.10.0-123.13.2.el7.x86_64.img bs=512 skip=26 | gunzip | cpio -id
37603+1 records in
37603+1 records out
19253073 bytes (19 MB) copied, 0.831203 s, 23.2 MB/s
91859 blocks

$ ls
bin  dev  etc  init  lib  lib64  proc  root  run  sbin  shutdown  sys  sysroot tmp  usr  var

Alhoewel, bekend zal het wellicht niet zijn aangezien de initrd aardig is uitgebreid en tegenwoordig systemd gebruikt om
op te starten.

Het maken van een aangepaste initrd is relatief simpel door een cpio-archief te maken van de microcode en een apart cpio-archief (gecomprimeerd) te maken van de initrd en deze vervolgens samen te voegen:

$ cat microcode.cpio initrd-aangepast.img > nieuweinitramfs.img

Meer informatie kun je vinden in de kernel documentatie in het bestand
Documentation/x86/early-microcode.txt.

Onderwerpen
Actieve filters: Wis alle filters
Loading...