Zum Inhalt springen

initramfs

Aus Foxwiki

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


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

  1. 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
  1. 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
  1. 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

Anhang

Siehe auch

Links

Weblinks

  1. https://de.wikipedia.org/wiki/Initramfs
  2. 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)