Initramfs: Unterschied zwischen den Versionen
Keine Bearbeitungszusammenfassung  | 
				|||
| (17 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
'''initramfs''' -   | '''initramfs''' - initial ram filesystem  | ||
== Beschreibung ==  | == Beschreibung ==  | ||
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  | |||
* 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  | ||
* Anschließend wird ein auf dem initramfs vorhandenes Programm ([[init]]) gestartet  | * Anschließend wird ein auf dem initramfs vorhandenes Programm ([[init]]) gestartet  | ||
* Das gestartete Programm kann unterschiedliche Aufgaben erfüllen  | * Das gestartete Programm kann unterschiedliche Aufgaben erfüllen  | ||
; 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 19: | Zeile 25: | ||
Das initramfs selbst ist ein [[cpio]]-Archiv, das meist eine [[Unix-Shell]] (oft [[BusyBox]]) und andere grundlegende Programme enthält  | 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  | * 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 [[Standard C Library|libc]] gelinkt wurde  | * Es ist aber auch möglich, dass /init ein C-Programm ist, das gegen eine kleine Variante der [[Standard C Library|libc]] gelinkt wurde  | ||
* Die letzte Aufgabe von /init ist es meist, das eigentliche   | * 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 30: | Zeile 36: | ||
<noinclude>  | <noinclude>  | ||
== Funktion ==  | |||
; Root-Dateisystem-Image  | |||
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  | |||
; Vorteile  | |||
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 ====  | ||
# https://de.wikipedia.org/wiki/Initramfs  | |||
# [https://www.kernel.org/doc/html/latest/filesystems/ramfs-rootfs-initramfs.html Dokumentation des Linux-kernel zum initramfs]  | # [https://www.kernel.org/doc/html/latest/filesystems/ramfs-rootfs-initramfs.html Dokumentation des Linux-kernel zum initramfs]  | ||
Aktuelle Version vom 20. September 2025, 14:12 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
- Root-Dateisystem-Image
 
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
 
- Vorteile
 
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