[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