Ich habe mich ein wenig mit PXE-Boot und initramfs auseinander gesetzt, und ich muss sagen: das macht echt Spass!
Damit ich das nicht wieder vergesse, hier eine Step-by-Step-Anleitung wie man einen Rechner mit einem selbstgebauten Kernel und initramfs per PXE booten lässt:
Kernel-Konfiguration
Diese Konfiguration bezieht sich auf den Kernel der über das Netzwerk geladen und auf dem Client gestartet wird. Der Kernel muss alle Treiber beinhalten, die der Client zum booten und laden des initramfs braucht. Die Treiber müssen dabei einkompiliert werden; Module können zu diesem Zeitpunkt logischerweise noch nicht verwendet werden.
Die einzig wichtige Option in dem Kernel ist:
General Setup --> Initial RAM filesystem and RAM disk (initramfs/initrd) support (=y)
Initramfs erstellen
Für das initramfs legen wir uns ein paar Verzeichnisse an:
mkdir /usr/src/initramfs
cd /usr/src/initramfs
mkdir -p bin lib dev etc mnt/root proc root sbin sys
In dieses root-fs kopieren wir jetzt einfach alle Programme die wir in unserer initrd benötigen. Idealerweise baut man die Programme mit +static/+livecd so dass man nur das Executable kopieren muss. Falls das Ebuild das USE-Flag nicht bereitstellt, muss man entweder schauen ob das (hoffentlich vorhandene) configure-Script eine solche Option bereitstellt, oder mittels ldd <executable> herausfinden welche Dateien noch benötigt werden.
Anschliessend müssen wir nur noch das eigentliche Init-Script (PID=1) anlegen. Dieses Script wird nach dem mounten des initramfs gestartet und ist dafür verantwortlich, das neue Root zu mounten und den Init-Prozess an jemand anderen abzugeben.
#!/bin/busybox sh
# Mount the /proc and /sys filesystems.
mount -t proc none /proc
mount -t sysfs none /sys
# Mount the root filesystem.
mount -o ro /dev/sda1 /mnt/root
# Clean up.
umount /proc
umount /sys
# Boot the real thing.
exec switch_root /mnt/root /sbin/init
Das init-Script mountet momentan einfach /dev/sda1 und startet den
normalen Init-Prozess. Sicherlich nichts wildes, aber der Fantasie sind
da keine Grenzen gesetzt :) Anschliessend noch +x setzen und fertig.
Das initramfs-File ist ein gzip-komprimiertes cpio-Archiv. Ein find . -print0 | cpio -ov -0 --format=newc | gzip -9 > /tmp/initramfs.cpio.gz erstellt das passende Archiv.
TFTP-Server konfigurieren
Ich habe hier als TFTP-Server net-ftp/atftp verwendet.
In /etc/conf.d/atftp stellt man ein beliebiges Verzeichnis ein, das als
Root des TFTP dienen soll. In diese Verzeichnis kopiert man den
gebauten Kernel, das initramfs-Image und /usr/share/syslinux/pxelinux.0 (PXE Bootloader aus sys-boot/syslinux). Weiterhin legt man ein Verzeichnix pxelinux.cfg
an, das die Configs für die Clients behinhalten wird. Der Bootloader
sucht automatisch nach einer Datei mit seiner MAC-Adresse in dem
Verzeichnis. Falls er die nicht findet, nimmt der die Datei default.
Das ist ganz praktisch, da man so Client-spezifische Konfigurationen
anlegen kann.
Die default-Datei beinhaltet folgendes:
prompt 0 timeout 30 label linux menu label Freaky PXE kernel bzImage append initrd=initramfs.cpio.gz vga=0x307
DHCP-Server konfigurieren
Während eines PXE-Boots stellt der Client eine DHCP-Anfrage. Daher müssen wir noch dem DHCP-Server sagen, was er denn einem Client antworten soll. Für dnsmasq gibt man folgendes an:
dhcp-boot=pxelinux.0,,192.168.0.123
Dies weist den Client an von dem Server 192.168.0.123 den Bootloader in pxelinux.0 zu laden.
Durchkicken
Nun kann man den Client neustarten. Wenn man im BIOS das booten vom Netz aktiviert hat, sollte der Rechner nun vom Netz sich das initramfs holen, und danach lokal weiterbooten. Je nachdem was noch in init steht, kann man hier noch die abgefahrensten Sachen machen.
Zum weiterlesen:
- Initramfs @ gentoo-wiki.com
- Build Your Own LiveCD or LiveDVD @ gentoo-wiki.com
- Diskless Howto @ Gentoo Linux Documentation
