initramfs
initramfs - initial ram filesystem
Beschreibung
Ausgangsdateisystem im Arbeitsspeicher
- Nachfolger von initrd
- initramfs-Archiv
Ein initramfs-Archiv ist eine komprimierte Datei, die für den Systemstart benötigte Dateien enthält
- Es kann vom Linux-Kernel beim Booten als Stammverzeichnis eingehängt werden
- Anschließend wird ein auf dem initramfs vorhandenes Programm (init) gestartet
- Das gestartete Programm kann unterschiedliche Aufgaben erfüllen
- Eingebettetes System
Bei eingebetteten Systemen kann die ganze Funktionalität des Systems im initramfs enthalten sein
- Personal Computer nutzen das initramfs oft nur als einen Zwischenschritt, um Treiber zu laden und andere Vorbereitungen für den Start des eigentlichen Systems zu treffen
- Durch das initramfs bzw
- initrd wurde es möglich, den Bootprozess unter Linux flexibler zu gestalten und Funktionalität aus dem Kernel in den Userspace auszulagern
Bootvorgang
Der Linux-Kernel kann ab Version 2.5.46 von einem initramfs booten
- Das initramfs-Archiv kann im Kernel selbst enthalten sein oder vom Bootloader aus einer Datei in den Arbeitsspeicher geladen werden
- Der Kernel dekomprimiert das initramfs-Archiv und hängt das entpackte Archiv dann als Stammverzeichnis ein
- Als Nächstes wird versucht, das Programm /init aus dem initramfs zu starten
- Schlägt das Starten fehl, versucht der Kernel, das eigentliche root-Volume}} einzuhängen und von dort /sbin/init zu starten
Das initramfs selbst ist ein cpio-Archiv, das meist eine Unix-Shell (oft BusyBox) und andere grundlegende Programme enthält
- In diesem Fall ist /init ein einfaches Shellskript, das die im initramfs enthaltenen Programme auf die gewünschte Weise verknüpft
- Es ist aber auch möglich, dass /init ein C-Programm ist, das gegen eine kleine Variante der libc gelinkt wurde
- Die letzte Aufgabe von /init ist es meist, das eigentliche root-Volume (root device) über das Stammverzeichnis einzuhängen und /sbin/init von dort zu starten
Änderungen gegenüber initrd
- Im Kernel muss kein Dateisystem-Treiber fest einkompiliert sein
- Die Größe des initramfs unterliegt keiner festen Obergrenze
- Zugriffe auf das initramfs werden nicht gepuffert, wodurch Arbeitsspeicher gespart wird
- Verschiedene cpio-Archive können verkettet werden, was das Laden von mehr als einem initramfs-Archiv ermöglicht
Anhang
Siehe auch
Links
Weblinks
TMP
Wie initramfs funktioniert Das grundlegende initramfs ist das Root-Dateisystem-Image, das zum Booten des Kernels verwendet und als komprimiertes cpio-Archiv bereitgestellt wird. Diesem grundlegenden initramfs-Image kann ein unkomprimiertes cpio-Archiv vorangestellt werden, das die sehr früh im Boot-Prozess geladenen Microcode-Daten enthält. Beim Booten führt der Kernel Folgendes aus: Wenn ein unkomprimiertes cpio-Archiv am Anfang des initramfs vorhanden ist, wird der Mikrocode daraus extrahiert und in die CPU geladen. Wenn ein unkomprimiertes cpio-Archiv am Anfang des initramfs vorhanden ist, wird dieses übersprungen und der Rest der Datei als grundlegendes initramfs festgelegt. Andernfalls wird das gesamte initramfs als grundlegendes initramfs behandelt. Entpacken Sie das Basis-Initramfs, indem Sie es als komprimiertes (gzip standardmäßig auf Debian, LZ4 auf Ubuntu) cpio-Archiv in eine RAM-basierte Festplatte behandeln. Hängen Sie die RAM-basierte Festplatte ein und verwenden Sie sie als erstes Root-Dateisystem. Ein Großteil des Kernel-Initialisierungs- und Bootstrap-Codes kann dann auf diese Festplatte verschoben und im Benutzermodus ausgeführt werden. Aufgaben wie das Auffinden der echten Root-Festplatte, die Einrichtung des Netzwerks während des Bootvorgangs, die Handhabung von initrd-ähnlichen RAM-Disks, die ACPI-Einrichtung usw. werden auf diese Weise aus dem Kernel ausgelagert. Ein offensichtlicher Vorteil dieses Schemas ist, dass die Größe des Kernelcodes selbst schrumpfen kann. Dadurch wird zwar kein Speicher für ein laufendes System freigegeben, da der Linux-Kernel den Initialisierungscode bereits auslagert, wenn er nicht mehr benötigt wird. Aber eine kleinere Codebasis für den Kernel selbst macht die ganze Sache etwas einfacher zu warten, und das ist immer eine gute Sache. Die wirklichen Vorteile von initramfs sind jedoch: Die Anpassung des frühen Boot-Prozesses wird viel einfacher. Jeder, der Änderungen am Systemstart vornehmen muss, kann dies nun mit User-Space-Code tun; das Patchen des Kernels selbst ist nicht mehr erforderlich. Durch die Verlagerung des Initialisierungscodes in den User-Space wird das Schreiben dieses Codes einfacher – er verfügt über eine vollständige C-Bibliothek, Speicherschutz usw. Der User-Space-Code ist erforderlich, um über Systemaufrufe mit dem Kernel zu interagieren. Durch diese Anforderung wird eine Menge „Magie“ im Kernel, die derzeit vom Initialisierungscode verwendet wird, überflüssig. Das Ergebnis ist ein sauberer und sicherer Code. Er umfasst: Eine kleine C-Bibliothek („klibc“) wird zusammengeführt, um Initramfs-Anwendungen zu unterstützen. Mit klibc wird eine kleine kinit-Anwendung erstellt. Zu Beginn wird sie nur so viel Arbeit leisten, dass sie zeigt, dass der Mechanismus ordnungsgemäß funktioniert. Das Initrd-Subsystem (initial ramdisk) wird in kinit und aus dem Kernel selbst verschoben. Das Mounten des Root-Dateisystems wird in den Benutzerbereich verschoben. Viel Code für den Umgang mit Dingen wie NFS-gemounteten Root-Dateisystemen wird verschwinden. Der Kernel hat derzeit drei Möglichkeiten, das Root-Dateisystem zu mounten: Alle erforderlichen Geräte- und Dateisystemtreiber sind in den Kernel kompiliert, keine initrd. init/main.c:init() ruft prepare_namespace() auf, um das endgültige Root-Dateisystem zu mounten, basierend auf der Option root= und optional init=, um eine andere Init-Binärdatei als die am Ende von init/main.c:init() aufgeführte auszuführen. einige Geräte- und Dateisystemtreiber, die als Module erstellt und in einer Initrd gespeichert werden. Die Initrd muss eine Binärdatei „/linuxrc“ enthalten, die diese Treibermodule laden soll. Es ist auch möglich, das endgültige Root-Dateisystem über linuxrc zu mounten und den Pivot_root-Systemaufruf zu verwenden. Die Initrd wird über prepare_namespace() gemountet und ausgeführt. unter Verwendung von initramfs. Der Aufruf von prepare_namespace() muss übersprungen werden. Das bedeutet, dass ein Binärprogramm die gesamte Arbeit erledigen muss. Dieses Binärprogramm kann entweder durch Änderung von usr/gen_init_cpio.c oder über das neue initrd-Format, ein cpio-Archiv, in initramfs gespeichert werden. Es muss „/init“ heißen. Dieses Binärprogramm ist dafür verantwortlich, alle Aufgaben von prepare_namespace() zu übernehmen. Um die Abwärtskompatibilität zu gewährleisten, wird die /init-Binärdatei nur ausgeführt, wenn sie über ein initramfs-cpio-Archiv bereitgestellt wird. Ist dies nicht der Fall, führt init/main.c:init() prepare_namespace() aus, um das endgültige Root-Verzeichnis zu mounten und eine der vordefinierten init-Binärdateien auszuführen So überprüfen Sie initramfs Das initramfs-tools-core-Paket bietet lsinitramfs, um Dateien im initramfs aufzulisten, und unmkinitramfs, um Dateien aus dem initramfs zu extrahieren. Alternativ können Sie Folgendes tun (vorausgesetzt, es existiert bereits als leeres Arbeitsverzeichnis): Wenn die Ausgabe von lautet, betrachten Sie das initrd-Image als mit vorangestelltem Mikrocode. Extrahieren Sie den Mikrocode mit und lesen Sie die STDERR-Anzeige (in meinem Fall 48). extrahieren Sie die Basis-Initrd mit (passen Sie die Skip-Werte an die cpio-STDERR-Ausgabe an). Andernfalls extrahieren Sie die Initrd direkt mit Die Größe des Microcode-CPIO-Archivs kann unabhängig überprüft werden mit (Diese manuelle Methode hat bei mir irgendwann einmal funktioniert. Aber das ist nicht zuverlässig. Sie enthält den Kommentar „CPIO verrät uns nicht die wahre Größe“.) Bitte beachten Sie, dass Debian derzeit gzip als Komprimierungsmethode verwendet und die oben genannte Methode dies voraussetzt. Ubuntu scheint ab März 2018 LZ4 zu verwenden. initramfs-tools in Debian unterstützt LZ4 seit Debian Buster (893845).