|
|
Zeile 53: |
Zeile 53: |
|
| |
|
| = TMP = | | = TMP = |
| == Funktion ==
| |
| ; 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 [https://wiki.debian.org/Initrd 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
| |
|
| |
| == Prüfung == | | == Prüfung == |
| ; So überprüfen Sie initramfs | | ; So überprüfen Sie initramfs |
initramfs - initial ram filesystem
Beschreibung
Ausgangsdateisystem im Arbeitsspeicher
- 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
- https://de.wikipedia.org/wiki/Initramfs
- Dokumentation des Linux-kernel zum initramfs
TMP
Prüfung
- 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)