[Eisfair] Vorgehensweise um manuell die initrd.gz zu modifizieren
D. Oezbilen
oezbilen at gmx.net
Di Okt 15 20:06:09 CEST 2019
Hallo @all,
eine kleine Doku fuer alle, die irgendwann die initrd.gz modifizieren
muessen, weil ein Modul darin fehlt, ihr dieses Modul manuell nachziehen
muesst; weil HW-Wechsel, Controllerwechsel etc ansteht.
Ich selbst habe es erfahren, weil ich die unter kvm laufende x64-Einheit
auf das Blech bringen wollte. Unter kvm habe ich bewusst den sym53c8xx
genommen um nicht spaeter (bei einem Export der Einheit auf HW) mit
/dev/vdX -> /dev/sdX zu kaempfen (also kein virtio fuer die HD, nur
virtio fuer die NIC, marginaler Unterschied in der Geschwindigkeit,
unter kvm ist vdX auch nicht mehr angesagt). Auf der HW war fuer den
Fujitsu der ahci mit libahci notwendig.
Unter kvm hatte ich mir ein stuemperhaftes Skript dafuer angelegt, dass
die initrd.gz vorher sichert, wegkopiert, dort dann die initrd.gz mit
gzip und cpio entpackt, einen Editor aufruft, mit dem ich die
Erweiterungen ergaenzte, die initrd am Schluss wieder packt und lilo
ausfuehrt.
Dieses Skript kam mit der .74 initrd.gz auf der HW *nicht* klar.
Nach einem Kontakt mit Marcus, ob/was veraendert ist/wurde, war der
Hintergrund mir dann auch klar. Die Diff. HW-Inst. vs. virt. Umgebungen
ist, dass an der initrd.gz ein __vorderer__ Teil vorhanden ist, der den
microcode-Update-Block fuer die fehlerhaften Intel-CPUs enthaelt.
Eigenartigerweise kann lilo mit der unechten initrd.gz (s.u.) auch noch
umgehen.
BTW:
Schaut Euch bei Interesse dazu auch das u.a. Verzeichnis an. Thomas
sorgt vor, haelt notwendige Versionen hier vor.
cd /var/install/initrd
544545 -rw-r--r-- 1 root root 484K Mar 13 2019 initramfs_empty.tar.gz
544544 -rw-r--r-- 1 root root 3.3M Oct 15 09:26 initrd.gz.with.ucode
546169 -rw-r--r-- 1 root root 3.3M Oct 15 09:26 initrd.gz.without.ucode
544543 -rw-r--r-- 1 root root 15K Oct 15 09:26 ucode.img
Obwohl der Name (immer noch) initrd.gz ist, ergibt
file file initrd.gz
initrd.gz: ASCII cpio archive (SVR4 with no CRC)
laesst sich diese initrd.gz mit gzip *nicht* auspacken und cpio
praesentieren.
gzip -d initrd.gz
gzip: initrd.gz: not in gzip format
dg. ;-)
FYI:
Man kann initrd.gz mit
(cpio -id; zcat | cpio -id) < initrd.gz
auspacken, doch dann werden _beide_ Anteile (microcode/initrd) im selben
Pfad ausgepackt.
Etwas anders, umstaendlicher, ist es aber auch beherrschbar. Fuer die
Analyse der initrd.gz gibt es ein tolles Werkzeug, binwalk.
<https://github.com/ReFirmLabs/binwalk/archive/master.zip>
Entpackt und aus dem Verzeichnis
python setup.py install
ausgefuehrt ist es im System. Das ganze Procedere habe ich in zwei Teile
eingeteilt.
-- Beginn Teil1 --
Aufbau der initrd.gz:
(mcode-Block|initrd.gz(das ist die echte initrd.gz))
Der Pfad unter dem ich arbeite ist:
/temp/initrdgz
mit
/temp/initrdgz/mcode
/temp/initrdgz/initrd
Die initrd.gz liegt unter /temp/initrdgz
binwalk initrd.gz
=>
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/GenuineIntel.bin", file name length:
"0x00000026", file size: "0x00003800"
14972 0x3A7C ASCII cpio archive (SVR4 with no CRC),
file name: "TRAILER!!!", file name length: "0x0000000B", file size:
"0x00000000"
15360 0x3C00 gzip compressed data, maximum compression,
from Unix, last modified: 2019-10-15 07:26:46
Hierbei ist die Zahl 15360 wichtig. Dort faengt die echte initrd.gz an,
die uns interessiert.
Abgekuerzt:
binwalk initrd.gz | grep "gzip compressed data"
=>
15360 0x3C00 gzip compressed data, maximum compression,
from Unix, last modified: 2019-10-14
cd mcode
cpio -idv < ../initrd.gz
Ausgabe:
.
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/GenuineIntel.bin
30 blocks
+-- mcode
¦ +-- kernel
¦ +-- x86
¦ +-- microcode
¦ +-- GenuineIntel.bin
+-- initrd.gz
4 directories, 2 files
30 Blocks a 512 => 1530 s.o.
So kaeme man -sofern man selbst Microcode-Updates installieren will- an
den Microcode-Block.
D.h. 30 Blocks in der initrd.gz sind der Microcode-Update, danach kommt
die initrd.gz, also brauchen wir
=>
dd if=initrd.gz of=echte_initrd.gz bs=512 skip=30
30 * 512 = 15360
ls -liah
=>
total 6.5M
157975 drwxr-xr-x 3 root root 4.0K Oct 15 18:53 .
917505 drwxr-xr-x 3 root root 4.0K Oct 15 18:47 ..
160693 -rw-r--r-- 1 root root 3.3M Oct 15 18:53 echte_initrd.gz
158075 drwxr-xr-x 3 root root 4.0K Oct 15 18:49 initrd
158074 -rw-r--r-- 1 root root 3.3M Oct 15 09:26 initrd.gz
Es ist ein Unterschied zwischen den Datein da, gut so. ;-)
Weiter geht es mit:
gzip -d echte_initrd.gz
cd initrd
cpio -idv < ../echte_initrd
=>
.
tmp
bin
bin/[
bin/test
bin/echo
bin/ash
bin/sh
bin/[[
bin/sleep
var
var/tmp
var/run
newroot
dev
dev/console
dev/null
init
lib64
lib64/libc.so.6
lib64/libdl.so.2
lib64/libpthread.so.0
lib64/libz.so.1
lib64/ld-linux-x86-64.so.2
usr
usr/local
usr/local/bin
usr/local/bin/busybox
usr/lib64
usr/lib64/libcrypto.so.1.1
usr/lib64/liblzma.so.5
etc
etc/shadow
etc/fstab
etc/passwd
etc/host.conf
etc/mtab
etc/ld.so.cache
etc/nsswitch.conf
etc/group
proc
lib
lib/modules
lib/modules/3.16.74-eisfair-64-VIRT
lib/modules/3.16.74-eisfair-64-VIRT/libata.ko
lib/modules/3.16.74-eisfair-64-VIRT/hid.ko
lib/modules/3.16.74-eisfair-64-VIRT/usbhid.ko
lib/modules/3.16.74-eisfair-64-VIRT/ehci-pci.ko
lib/modules/3.16.74-eisfair-64-VIRT/psmouse.ko
lib/modules/3.16.74-eisfair-64-VIRT/xhci-hcd.ko
lib/modules/3.16.74-eisfair-64-VIRT/hid-cherry.ko
lib/modules/3.16.74-eisfair-64-VIRT/scsi_mod.ko
lib/modules/3.16.74-eisfair-64-VIRT/ohci-pci.ko
lib/modules/3.16.74-eisfair-64-VIRT/usbcore.ko
lib/modules/3.16.74-eisfair-64-VIRT/libahci.ko
lib/modules/3.16.74-eisfair-64-VIRT/ahci.ko
lib/modules/3.16.74-eisfair-64-VIRT/usb-common.ko
lib/modules/3.16.74-eisfair-64-VIRT/sd_mod.ko
lib/modules/3.16.74-eisfair-64-VIRT/ohci-hcd.ko
lib/modules/3.16.74-eisfair-64-VIRT/ehci-hcd.ko
lib/modules/3.16.74-eisfair-64-VIRT/hid-generic.ko
lib/modules/3.16.74-eisfair-64-VIRT/uhci-hcd.ko
sbin
sbin/insmod
15580 blocks
Bingo. ;-)
(Oder man kopiert vorher die _echte_initrd.gz ins Verz. initrd, fuehrt dort
gzip -dc echte_initrd | cpio -id
aus, muss dann auch aber die echte_initrd.gz loeschen, sonst wird diese
spaeter wieder mit eingepackt)
Jetzt kann man mit der ausgepackten initrd arbeiten. Das war Teil1, das
Auspacken.
-- Ende Teil1 --
-- Beginn Teil2 --
Teil2 ist die initrd wieder einzupacken und mit dem mcode-Anteil zu
verpacken.
In
/temp/initrdgz/initrd
stehend folgt
find ./ | cpio -H newc -o | gzip -9 > ../initrd.echte.gz
=>
15998 blocks
um die initrd.dz zu erzeugen.
ls -liah initrd.echte.gz
160693 -rw-r--r-- 1 root root 3.3M Oct 15 19:15 initrd.echte.gz
Jetzt noch den mcode Anteil zusammenfuehren. Wechsel nach
cd /temp/initrdgz/mcode, mit
find ./ | cpio -H newc -o > ../kernel.cpio
=>
30 blocks
(wieder die 30 Blocks, s.o.)
Achtung, hier wird nicht mit gzip komprimiert, nur eine
__UN__komprimierte Datei wird generiert.
Wieder rueck nach /temp/initrdgz
cd ..
ls -liah
=>
157975 drwxr-xr-x 4 root root 4.0K Oct 15 19:18 .
917505 drwxr-xr-x 3 root root 4.0K Oct 15 18:47 ..
160695 -rw-r--r-- 1 root root 7.7M Oct 15 18:53 echte_initrd
158075 drwxr-xr-x 13 root root 4.0K Oct 15 19:08 initrd
160693 -rw-r--r-- 1 root root 3.3M Oct 15 19:15 initrd.echte.gz
158074 -rw-r--r-- 1 root root 3.3M Oct 15 09:26 initrd.gz
160721 -rw-r--r-- 1 root root 15K Oct 15 19:18 kernel.cpio
160687 drwxr-xr-x 3 root root 4.0K Oct 15 18:55 mcode
die __eingerueckten__ Dateien sind die beiden, die man noch
zusammensetzen muss, also
cat kernel.cpio initrd.echte.gz > initrd.mod.new.gz
Diese Datei wird unter /boot geparkt und mit einem zusaetzlichen Eintrag
in /etc/lilo.conf
mage = /boot/kernel.n74
root = "UUID=20c0c9b5-b59d-46e0-9cef-9c235e0ccf8a"
label = 3.16.74-VIRTMOD
initrd = /boot/initrd.mod.new.gz
append = "ramdisk_size=262144 raid=noautodetect console=tty0
console=ttyS0,115200"
dem System (lilo ausfuehren) bekannt gemacht; finger crossing &&
reboot. Es funkt.
-- Ende Teil2 --
Das ganze in einen Skript gepresst und man ist fuer einen
HW/Konfigwechsel vorbereitet.
Viel Erfolg.
Oezbilen
Mehr Informationen über die Mailingliste Eisfair