Warum brauche ich initramfs?

16

Ich fand heraus, dass wenn ich jffs oder sd als Dateisystem wähle (und nicht initramfs), die Kernelgröße sehr klein ist (1,4 MB im Vergleich zu initramfs-3,4 MB). Es zeigt, dass initramfs sehr viel Platz in Anspruch nimmt. Damit ich es vollständig entfernen kann, werde ich einen sehr kleinen Kernel haben, was ich will.

Die grundlegende Frage, die mir in den Sinn kommt, lautet: Warum brauche ich initramfs? Kann ein Linux-Kernel nicht einfach ohne ein anfängliches Dateisystem booten?

Meine Endanwendung führt nur Berechnung und Kommunikation durch - überhaupt keine Sotrage. Ein Betriebssystem ohne Dateisystem macht also Sinn - zumindest für meine Anwendung.

gpuguy
quelle
2
Auf initramfs kann man nicht verzichten. Es ist möglich, auf die zusätzliche initramfs-Datei zu verzichten, aber unabhängig davon, was Sie tun, enthält der Kernel eine eigene leere Datei oder nicht. Also verstehe ich Ihre Frage nicht - von welcher Distribution sprechen Sie? Wie bauen Sie Ihren Kernel? Können Sie die .config-Datei des Kernels bereitstellen? Das ist sehr wichtig. Ich vermute, Ihre Distribution kompiliert ihre initramfs direkt in den Kernel - und füllt daher die ansonsten leeren initramfs, die sie enthält - aber ich kann es aufgrund der von Ihnen bereitgestellten Informationen nicht wissen.
mikeserv
2
@mikeserv, offensichtlich ein eingebautes, aber leeres / unbenutztes initramfs zählt nicht.
Psusi
@Psusi, die Kernel-Dokumente stimmen nicht überein. Und ich bin nur so unnachgiebig, weil es kein Geheimnis geben muss - es ist nur so /root- das ist es. Das Einzige, was es anders macht, ist switch_root, dass es jederzeit möglich ist , selbst wenn bei bestimmten geladenen Kernelmodulen die richtigen Vorsichtsmaßnahmen getroffen werden. Initramfs ist nichts anderes als ein Festplatten-Image - randvoll oder nein, es ist da. Und du bist nie ohne - es ist schließlich deine Wurzel. Es sollte einfach kein Rätsel sein, denke ich, und ich mag all die unnötigen Verwirrungen, die damit verbunden sind, nicht.
mikeserv
2
@mikeserv, nein, / root ist das Ausgangsverzeichnis für den Root-Benutzer. Das rootfs ist /, über dem dann das echte root gemountet ist. Sie argumentieren nur Semantik. Für die Zwecke dieser Diskussion bedeutet das Fehlen eines initramfs, dass sich keine Datei auf der Festplatte befindet, die der Bootloader laden und an den Kernel übergeben muss.
Psusi
Das stimmt, ich habe / root nur aus Gründen der Klarheit verwendet, aber ich gebe dir das. Aber nein, sie sind keine Semantik, sondern die grundlegende Mechanik Ihres Linux-Kernels. Das sind grundlegende Dinge. Versuchen wir einfach, sie richtig zu machen.
mikeserv

Antworten:

10

Die Vergrößerung eines initramfs ist nicht auf den ramfs-Treiber zurückzuführen (er ist nur ein paar kB groß und wird auch für andere Dinge benötigt), sondern auf das initramfs selbst. Das initramfs enthält Programme, die zum Assemblieren und Mounten des realen Root-Dateisystems erforderlich sind.

Initramfs macht es viel einfacher und in einigen Fällen möglich (zB verschlüsselt /), das System zu booten. Es wird dringend empfohlen, es auf einer PC-ähnlichen Hardware mit vielen hot-plug-fähigen Peripheriegeräten aufzubewahren. Andererseits ist es sehr sinnvoll, ein eingebettetes Gerät ohne initramfs zu booten, mit einem Kernel, der nur die spezielle Hardwarekonfiguration unterstützt, für die es entwickelt wurde.

Der Kernel muss natürlich von einem Dateisystem booten: Es muss eine Möglichkeit geben, die gewünschte Anwendung zu laden. Wenn Sie nichts ausführen möchten, können Sie die Maschine auch ausgeschaltet lassen.

Wenn Sie kein initramfs verwenden möchten, weisen Sie Ihren Bootloader einfach an, kein initramfs zu übergeben. Nehmen Sie natürlich auch keinen in die Ausgabe des Kernel-Builds auf - wie dies geschieht, wenn dies überhaupt architektur- und bootloaderabhängig ist, vmlinuxund schließen bzImageSie beispielsweise nicht die initramfs ein (sie sind der rohe bzw. der komprimierte Kernel) ), aber uImage(für U-Boot) packt sowohl den Kernel als auch das initramfs, falls vorhanden.

(Technisch gesehen gibt es, wie mikeserv bemerkt, immer ein initramfs - aber standardmäßig ein leeres 134-Byte-Archiv. Was Sie sehen und loswerden wollen, ist ein "wahres", nicht leeres initramfs, das von erstellt wurde Ihren Build-Prozess und die darin enthaltenen Tools, die dann zum Mounten des Root-Dateisystems verwendet werden.)

Ein initramfs kann ein vernünftiger Weg sein, um ein System mit nur einer Anwendung ohne persistente Daten zu erstellen: Legen Sie Ihre gesamte Anwendung in das initramfs, booten Sie das und behalten Sie es. Auf diese Weise können Sie Ihren persistenten Speicher oder Ihr Boot-Image einfacher organisieren (Sie benötigen lediglich den Kernel und initramfs, die gebündelt werden können). Dieser Ansatz hat jedoch einige Nachteile: Alle Daten im initramfs werden dauerhaft im RAM gespeichert, und Sie können die Dateien im Boot-Image nicht einfach ändern. Sie müssen das Archiv neu erstellen.

Gilles 'SO - hör auf böse zu sein'
quelle
Wenn Sie einen 2.6er oder neueren Linux-Kernel verwenden, haben Sie initramfs. Ob Sie wie üblich ein sekundäres initramfs-Image verwenden oder nicht, ist eine andere Sache, aber initramfs ist nicht optional.
mikeserv
2
@mikeserv Du hast einen, ja. Aber ein leerer Initramfs ist Erdnüsse. Es muss nicht verwendet werden (was erfordert, dass es genügend Programme enthält, um die reale Wurzel zu mounten, was die Größe in einem typischen eingebetteten System auf nicht vernachlässigbare Weise erhöht).
Gilles 'SO - hör auf böse zu sein'
Pflichterdnüsse sowieso. Und ich weiß nicht, wann ich etwas anderes gesagt habe! Der Fragesteller forderte Informationen an, wie er es als Dateisystem entfernen kann - was nicht möglich ist.
mikeserv
Und ja, es muss verwendet werden - ohne initramfs gibt es keine Wurzel. Je.
mikeserv
8

Aus LFS :

Der einzige Zweck eines initramfs ist das Mounten des Root-Dateisystems. Das initramfs ist ein vollständiger Satz von Verzeichnissen, die Sie in einem normalen Root-Dateisystem finden würden. Es wird in einem einzigen cpio-Archiv gebündelt und mit einem von mehreren Komprimierungsalgorithmen komprimiert.

...

Es gibt nur vier Hauptgründe für ein Initramfs in der LFS-Umgebung: Laden der Rootfs aus einem Netzwerk, Laden von einem logischen LVM-Volume, Verwenden von verschlüsselten Rootfs, für die ein Kennwort erforderlich ist, oder Festlegen der Rootfs als LABEL oder UUID. Alles andere bedeutet normalerweise, dass der Kernel nicht richtig konfiguriert wurde.

...

Bei den meisten Distributionen sind Kernelmodule der Hauptgrund für ein initramfs. In einer allgemeinen Distribution gibt es viele Unbekannte wie Dateisystemtypen und Plattenlayouts. In gewisser Weise ist dies das Gegenteil von LFS, bei dem die Systemfähigkeiten und das Layout bekannt sind und normalerweise ein benutzerdefinierter Kernel erstellt wird. In dieser Situation wird ein initramfs selten benötigt.

Eine andere Quelle www.kernel.org

Daneben gibt es viele Linux-Systeme, die Router mögen, die kein initramfs verwenden.


quelle
1

Sie benötigen ein initramfs für komplexere Setups, wie z. B. den Netzwerkstart oder lvm oder raid, da für die Konfiguration des Zugriffs auf das Root-Dateisystem einige Dienstprogramme im Benutzermodus erforderlich sind. Für eine einfache, konventionelle Partition auf einer Festplatte können Sie dann auf ein initramfs verzichten, solange Sie die Festplattentreiber in den Kernel integriert haben und das Root-Argument nicht über die UUID, sondern über den Gerätepfad angeben. Natürlich kann sich der Gerätepfad ändern, je nachdem, welche Plug-and-Play-Geräte (dh USB-Geräte) Sie angeschlossen haben, oder auch nur zufällige Timing-Abweichungen. Aus diesem Grund werden für die Zuverlässigkeit so gut wie alle Benutzer UUIDs und Initrams verwendet.

Psusi
quelle
Das ist auch falsch.
mikeserv
6
@mikeserv, dein Kommentar ist nutzlos. Wenn Sie das behaupten wollen, müssen Sie erklären, warum.
Psusi
Ich habe die Kernel-Dokumentation erstellt, die ungefähr 99% meiner Antwort enthält.
mikeserv
@mikeserv, es ist richtig. Ich verwende Gentoo Linux seit Jahren ohne initramfs.
Tim
1

Dies ist eine alte Frage, scheint aber noch keine akzeptierte Antwort zu haben, daher werde ich sie hier rauswerfen.

Von https://www.kernel.org/doc/Documentation/early-userspace/README (ganz unten steht, dass es seit 2004 nicht aktualisiert wurde.)

Der Kernel hat derzeit 3 ​​Möglichkeiten, das Root-Dateisystem zu mounten:

a) Alle erforderlichen Geräte- und Dateisystemtreiber im 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 ().

b) Einige Geräte- und Dateisystemtreiber, die als Module erstellt und in einer initrd gespeichert wurden. 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 einzuhängen und den Systemaufruf pivot_root zu verwenden. Die initrd wird über prepare_namespace () eingehängt und ausgeführt.

c) mit initramfs. Der Aufruf von prepare_namespace () muss übersprungen werden. Dies bedeutet, dass eine Binärdatei die ganze Arbeit erledigen muss. Diese Binärdatei kann entweder durch Ändern von usr / gen_init_cpio.c oder über das neue initrd-Format, ein cpio-Archiv, in initramfs gespeichert werden. Es muss "/ init" heißen. Diese Binärdatei ist dafür verantwortlich, alles zu tun, was prepare_namespace () tun würde.

Um die Abwärtskompatibilität zu gewährleisten, wird die Binärdatei / init nur ausgeführt, wenn sie über ein initramfs-cpio-Archiv stammt. Ist dies nicht der Fall, führt init / main.c: init () prepare_namespace () aus, um das endgültige Root-Verzeichnis einzuhängen und eine der vordefinierten init-Binärdateien auszuführen.

Ich glaube, dass Geräte / Distributionen wie Raspberry Pi usw. keine initramfs verwenden. in einigen Fällen kann der Kernel auf dem Root - Partition (durch den Bootloader montiert , die erforderlichen fs Module hat.) In anderen Fällen , in denen der Kern auf einer ist beispielsweise /bootPartition können die Initramfs auf derselben Partition direkt zugegriffen werden , bevor sie die rootfs wie andere Befestigungs angegeben haben.

In einigen Fällen sind die initramfs können in die gleiche Datei wie der Kernel eingebaut werden , aber dies ist nicht immer der Fall. (a) scheint ziemlich klar zu sagen, dass in einigen Fällen initramfs nicht notwendig ist.

thom_nic
quelle
0

Ich finde die folgende Erklärung klarer,

initramfsist ein Root-Dateisystem, das in den Kernel eingebettet und zu einem frühen Zeitpunkt des Startvorgangs geladen wird. Es ist der Nachfolger von initrd. Es bietet einen frühen Benutzerbereich, in dem Dinge ausgeführt werden können, die der Kernel während des Startvorgangs nicht ohne weiteres selbst ausführen kann.

Die Verwendung von initramfs ist optional. Standardmäßig initialisiert der Kernel die Hardware mithilfe integrierter Treiber, stellt die angegebene Root-Partition bereit und lädt das Init-System der installierten Linux-Distribution. Das init-System lädt dann zusätzliche Module und startet Dienste, bis Sie sich schließlich anmelden können. Dies ist ein gutes Standardverhalten und für viele Benutzer ausreichend. initramfs ist für Benutzer mit erweiterten Anforderungen gedacht. für Benutzer, die so früh wie möglich arbeiten müssen, noch bevor die Root-Partition gemountet wird.

Hier einige Beispiele, was Sie mit initramfs tun können:

  • Hängen Sie die Root-Partition ein (für verschlüsselte, logische und ansonsten spezielle Partitionen).
  • Stellen Sie eine minimalistische Rettungshülle bereit (falls etwas schief geht);
  • Passen Sie den Startvorgang an (z. B. Begrüßungsnachricht, Startspritzen usw.).
  • Module laden (zB Treiber von Drittanbietern);
  • Alles, was der Kernel nicht kann (solange Sie es im User-Space tun können, z. B. durch Ausführen von Befehlen). Wenn Sie keine erweiterten Anforderungen haben, benötigen Sie kein initramfs.
Sufiyan Ghori
quelle
-1

Egal was du tust, du hast initramfs. Es gibt kein Tun ohne es - es ist das einzige Dateisystem, das Ihnen auferlegt wird. Von kernel.org :

Was ist rootfs?

Rootfsist eine spezielle Instanz von ramfs(oder tmpfs, falls aktiviert), die in 2.6-Systemen immer vorhanden ist. Sie können die Bereitstellung nichtrootfs annähernd aus demselben Grund aufheben, aus dem Sie den Init-Prozess nicht beenden können. Anstatt einen speziellen Code zum Überprüfen und Behandeln einer leeren Liste zu haben, ist es für den Kernel kleiner und einfacher, nur sicherzustellen, dass bestimmte Listen nicht leer werden können.

Die meisten Systeme hängen einfach ein anderes Dateisystem über rootfsund ignorieren es. Der Platz, den eine leere Instanz von RAMFS einnimmt, ist winzig.

Wenn * CONFIG_TMPFS * aktiviert ist, rootfswird tmpfsstatt ramfsstandardmäßig verwendet. Um Kraft ramfs, fügen Sie "rootfstype=ramfs"an die Kernel - Befehlszeile.

Was ist initramfs?

Alle 2.6 Linux-Kernel enthalten ein"cpio"Archiv imgzipped-Format, das beim Booten des Kernels extrahiert rootfswird. Nach dem Extrahieren prüft der Kernel, obrootfseine Datei enthalten ist"init" , und führt sie in diesemFallals PID 1 aus. Wenn dieserinitProzessgefunden wird,ist er dafür verantwortlich, dass das System den Rest des Weges nach oben fährt, einschließlich des Auffindens und Einbindens des realen Root-Geräts ( wenn überhaupt). Wennder Kernelnach dem Extrahieren des eingebettetenArchivsrootfskeininitProgrammenthält, greift ercpioauf den älteren Code zurück, um eine Root-Partition zu finden und zu mounten, und führt dann eine Variante davon/sbin/initaus.

All dies unterscheidet sich in mehrfacher Hinsicht von der alten initrd:

  • Die alte initrd war immer eine separate Datei, während das initramfs-Archiv mit dem Linux-Kernel-Image verknüpft ist. (Das Verzeichnis linux - * / usr dient dazu, dieses Archiv während des Builds zu erstellen.)

  • Die alte initrd-Datei war ein komprimiertes Dateisystem-Image (in einigen Dateiformaten wie ext2, für das ein Treiber in den Kernel integriert werden musste), während das neue initramfs-Archiv ein komprimiertes cpio-Archiv ist (wie tar nur einfacher, siehe cpio (1)). und Dokumentation / early-userspace / buffer-format.txt). Der cpio-Extraktionscode des Kernels ist nicht nur extrem klein, sondern enthält auch Text und Daten, die während des Startvorgangs verworfen werden können.

  • Das Programm, das von der alten initrd (die / initrd, nicht / init genannt wurde) ausgeführt wurde, führte einige Setups durch und kehrte dann zum Kernel zurück, während von dem init-Programm von initramfs nicht erwartet wird, dass es zum Kernel zurückkehrt. (Wenn / init die Steuerung übergeben muss, kann es / mit einem neuen Root-Gerät überladen und ein anderes Init-Programm ausführen. Siehe das Dienstprogramm switch_root weiter unten.)

  • Beim Wechseln eines anderen Root-Geräts hat initrd pivot_root ausgeführt und anschließend die Ramdisk umgemountet. Aber initramfs ist rootfs: Sie können rootfs weder pivot_root noch die Bereitstellung aufheben. Löschen Sie stattdessen alles aus rootfs, um Speicherplatz freizugeben (find -xdev / -exec rm '{}' ';'), und hängen Sie rootfs mit dem neuen root-Wert (cd / newmount; mount --move. /; Chroot.) Über. Hängen Sie stdin / stdout / stderr an das neue / dev / console an und führen Sie das neue init aus.

Da dies ein bemerkenswert ausdauernder Prozess ist (und das Löschen von Befehlen erfordert, bevor Sie sie ausführen können), hat das klibc-Paket ein Hilfsprogramm (utils / run_init.c) eingeführt, das dies alles für Sie erledigt. Die meisten anderen Pakete (z. B. busybox) haben diesen Befehl "switch_root" genannt.

Initramfs auffüllen:

Der 2.6-Kernel-Erstellungsprozess erstellt immer ein gzipptes cpio-Format initramfs-Archiv und verknüpft es mit der resultierenden Kernel-Binärdatei. Standardmäßig ist dieses Archiv leer (verbraucht 134 Byte auf x86).

Mit der Konfigurationsoption CONFIG_INITRAMFS_SOURCE (in General Setup in menuconfig und in usr / Kconfig) kann eine Quelle für das initramfs-Archiv angegeben werden, die automatisch in die resultierende Binärdatei aufgenommen wird. Diese Option kann auf ein vorhandenes gzipptes cpio-Archiv, ein Verzeichnis mit zu archivierenden Dateien oder eine Textdateispezifikation wie das folgende Beispiel verweisen:

  dir /dev 755 0 0
  nod /dev/console 644 0 0 c 5 1
  nod /dev/loop0 644 0 0 b 7 0
  dir /bin 755 1000 1000
  slink /bin/sh busybox 777 0 0
  file /bin/busybox initramfs/busybox 755 0 0
  dir /proc 755 0 0
  dir /sys 755 0 0
  dir /mnt 755 0 0
  file /init initramfs/init.sh 755 0 0

Führen Sie "usr / gen_init_cpio" (nach der Kernel-Erstellung) aus, um eine Verwendungsmeldung zu erhalten, die das oben genannte Dateiformat dokumentiert.

Ein Vorteil der Konfigurationsdatei besteht darin, dass kein Root-Zugriff erforderlich ist, um Berechtigungen festzulegen oder Geräteknoten im neuen Archiv zu erstellen. (Beachten Sie, dass diese beiden Beispieleinträge "file" Dateien mit den Namen "init.sh" und "busybox" in einem Verzeichnis mit dem Namen "initramfs" unter dem Verzeichnis linux-2.6. * Erwarten. Weitere Informationen finden Sie unter Documentation / early-userspace / README mehr Details.)

Der Kernel ist nicht von externen cpio-Tools abhängig. Wenn Sie anstelle einer Konfigurationsdatei ein Verzeichnis angeben, erstellt die Build-Infrastruktur des Kernels eine Konfigurationsdatei aus diesem Verzeichnis (usr / Makefile ruft scripts / gen_initramfs_list.sh auf) und fährt mit dem Packen dieses Verzeichnisses mithilfe der Konfigurationsdatei fort (indem es an eingespeist wird) usr / gen_init_cpio, erstellt aus usr / gen_init_cpio.c). Der cpio-Erstellungscode für die Erstellungszeit des Kernels ist vollständig in sich abgeschlossen, und der Boot-Time-Extractor des Kernels ist (offensichtlich) ebenfalls in sich abgeschlossen.

mikeserv
quelle
1
Sie können ohne initramfs booten. Ihre Antwort wird anhand der Vorteile von initramfs erläutert. Dies gilt jedoch nicht für typische eingebettete Systeme, und selbst auf Desktops oder Servern, auf denen ein initramfs empfohlen wird, ist dies nicht obligatorisch.
Gilles 'SO - hör auf, böse zu sein'
@ Gilles - nein, du kannst nicht. Unabhängig davon, was Sie tun, haben Sie initramfs. Es ist in den Kernel kompiliert - im Moment, dein Kernel, mein Kernel, alle unsere Kernel. Lesen Sie die Kernel-Dokumente - mein gesamter Beitrag war ein Copy-Paste. Sie sind falsch. Wie können Sie die offiziellen Unterlagen anfechten?
mikeserv
1
Ich bestreite die offiziellen Unterlagen nicht, ich bestreite die Schlussfolgerungen, die Sie daraus ziehen. Sie lesen eine Dokumentation, in der die Verwendung von initramfs erläutert wird. Nirgendwo heißt es, dass das initramfs verwendet werden muss.
Gilles 'SO - hör auf, böse zu sein'
@Gilles Wenn dies nicht gut genug ist: "Der 2.6-Kernel-Erstellungsprozess erstellt immer ein gzipptes cpio-Format initramfs-Archiv und verknüpft es mit der resultierenden Kernel-Binärdatei. Standardmäßig ist dieses Archiv leer (verbraucht 134 Bytes auf x86) .... " Das kann ich besser. Das obige war eine 2- oder 3-minütige Websuche.
mikeserv
3
Ich habe die Dokumentation gelesen. Ich mache das für meinen Lebensunterhalt. Es ist keine Ansichtssache. Es gibt immer ein initramfs, aber es wird nicht unbedingt zum Booten verwendet. Ich kann keine anständige Erklärung für die Kernelstruktur für diesen Fall finden, vermutlich, weil es sich um den klassischen Fall handelt, der keine Erklärung verdient. Die Hauptlogik ist in do_mounts.c- spezifisch prepare_namespace, in der saved_root_namedas root=Kommandozeilenargument enthalten ist.
Gilles 'SO - hör auf, böse zu sein'