Initramfs: Unterschied zwischen den Versionen
Keine Bearbeitungszusammenfassung |
K Textersetzung - „usw.“ durch „und weitere“ |
||
(12 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 3: | Zeile 3: | ||
== Beschreibung == | == Beschreibung == | ||
Ausgangs[[dateisystem]] im [[Arbeitsspeicher]]'' | Ausgangs[[dateisystem]] im [[Arbeitsspeicher]]'' | ||
* | * Nachfolger von [[initrd]] | ||
; initramfs-Archiv | |||
Ein initramfs-Archiv ist eine komprimierte Datei, die für den Systemstart benötigte Dateien enthält | Ein initramfs-Archiv ist eine komprimierte Datei, die für den Systemstart benötigte Dateien enthält | ||
* Es kann vom [[Linux (Kernel)|Linux-Kernel]] beim [[Booten]] als [[Stammverzeichnis]] eingehängt werden | * Es kann vom [[Linux (Kernel)|Linux-Kernel]] beim [[Booten]] als [[Stammverzeichnis]] eingehängt werden | ||
Zeile 10: | Zeile 11: | ||
* Das gestartete Programm kann unterschiedliche Aufgaben erfüllen | * Das gestartete Programm kann unterschiedliche Aufgaben erfüllen | ||
Bei [[Eingebettetes System|eingebetteten Systemen]] kann die ganze Funktionalität des Systems im initramfs enthalten sein | ; Eingebettetes System | ||
Bei [[Eingebettetes System|eingebetteten Systemen]] kann die ganze Funktionalität des Systems im initramfs enthalten sein | |||
* [[Personal Computer]] nutzen das initramfs oft nur als einen Zwischenschritt, um [[Gerätetreiber|Treiber]] zu laden und andere Vorbereitungen für den Start des eigentlichen Systems zu treffen | |||
* Durch das initramfs bzw | * Durch das initramfs bzw | ||
* initrd wurde es möglich, den Bootprozess unter Linux flexibler zu gestalten und Funktionalität aus dem [[Kernel (Betriebssystem)|Kernel]] in den [[Userspace]] auszulagern | * initrd wurde es möglich, den Bootprozess unter Linux flexibler zu gestalten und Funktionalität aus dem [[Kernel (Betriebssystem)|Kernel]] in den [[Userspace]] auszulagern | ||
Zeile 26: | Zeile 29: | ||
* 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 | * 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 | * Im Kernel muss kein Dateisystem-Treiber fest einkompiliert sein | ||
* Die Größe des initramfs unterliegt keiner festen Obergrenze | * Die Größe des initramfs unterliegt keiner festen Obergrenze | ||
Zeile 33: | Zeile 36: | ||
<noinclude> | <noinclude> | ||
== 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 und weitere 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 == | |||
; So überprüfen Sie initramfs | |||
Das [https://packages.debian.org/initramfs-tools-core initramfs-tools-core]-Paket bietet [https://manpages.debian.org/man/lsinitramfs lsinitramfs], um Dateien im initramfs aufzulisten, und [https://manpages.debian.org/man/unmkinitramfs 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 ([https://bugs.debian.org/893845 893845]) | |||
== Anhang == | == Anhang == | ||
=== Siehe auch === | === Siehe auch === | ||
{{Special:PrefixIndex/{{BASEPAGENAME}}/}} | {{Special:PrefixIndex/{{BASEPAGENAME}}/}} | ||
{{Special:PrefixIndex/Kategorie:Initramfs}} | |||
=== Links === | === Links === | ||
==== Weblinks ==== | ==== Weblinks ==== |
Aktuelle Version vom 28. April 2025, 10:29 Uhr
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
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 und weitere 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
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)
Anhang
Siehe auch
Links
Weblinks