In den Kerneldokumenten wird erklärt, wie ein Bild in den Kernel selbst gepackt wird. Von kernel.org :
Was ist rootfs?
Rootfs
ist eine spezielle Instanz von ramfs
(oder tmpfs
, falls diese aktiviert ist), die
in 2.6-Systemen immer vorhanden ist. Sie können die Bereitstellungrootfs
aus ungefähr demselben Grund nicht aufheben, aus dem Sie den Init-Prozess nicht beenden können. Anstatt speziellen Code zum Suchen 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 mounten einfach ein anderes Dateisystem rootfs
und ignorieren es. Der Platz, den eine leere Instanz von Ramfs einnimmt, ist winzig.
Wenn CONFIG_TMPFS aktiviert ist, rootfs
wird tmpfs
anstelle ramfs
von standardmäß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 imkomprimiertenFormat, in das rootfs
beim Booten des Kernels extrahiert wird. Nach dem Extrahieren prüft der Kernel, obrootfs
eine Datei enthalten ist"init"
, und führt sie in diesemFallals PID 1 aus. Wenn sie gefunden wird, ist dieserinit
Prozess dafür verantwortlich, dass das System den Rest des Weges nach oben bringt, einschließlich des Lokalisierens und Mountens des realen Root-Geräts ( wenn überhaupt). Wennrootfs
dasinit
Programm nach dem Extrahieren des eingebettetencpio
ArchivskeinProgrammenthält, wird der Kernel auf den älteren Code zurückgreifen, um eine Root-Partition zu suchen und bereitzustellen, und anschließend eine Variante davon/sbin/init
ausführen.
All dies unterscheidet sich in mehreren Punkten 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 zum Generieren dieses Archivs während des Builds.)
Die alte initrd-Datei war ein komprimiertes Dateisystem-Image (in einem Dateiformat wie ext2, für das ein im Kernel integrierter Treiber erforderlich war), während das neue initramfs-Archiv ein komprimiertes cpio-Archiv ist (wie tar nur einfacher, siehe cpio (1)). und Documentation / Early-Userspace / Buffer-Format.txt). Der CPIO-Extraktionscode des Kernels ist nicht nur extrem klein, sondern enthält auch __init Text und Daten, die während des Startvorgangs verworfen werden können.
Das vom alten initrd ausgeführte Programm (das / initrd, nicht / init genannt wurde) hat einige Einstellungen vorgenommen und ist dann zum Kernel zurückgekehrt, während das init-Programm von initramfs nicht zum Kernel zurückkehren soll. (Wenn / init die Steuerung übergeben muss, kann es / mit einem neuen Root-Gerät überhängen und ein anderes Init-Programm ausführen. Siehe das Dienstprogramm switch_root unten.)
Beim Wechseln eines anderen Root-Geräts würde initrd pivot_root ausführen und dann die Ramdisk umhängen. Aber initramfs ist rootfs: Sie können pivot_root rootfs weder anheben noch aushängen. Löschen Sie stattdessen alles aus rootfs, um Speicherplatz freizugeben (find -xdev / -exec rm '{}' ';'), und überlagern Sie rootfs mit dem neuen root (cd / newmount; mount --move. /; Chroot.). hänge stdin / stdout / stderr an die neue / dev / console an und führe den neuen init aus.
Da dies ein bemerkenswert hartnäckiger Prozess ist (und das Löschen von Befehlen beinhaltet, bevor Sie sie ausführen können), hat das klibc-Paket ein Hilfsprogramm (utils / run_init.c) eingeführt, um all dies für Sie zu erledigen. Die meisten anderen Pakete (z. B. Busybox) haben diesen Befehl "switch_root" genannt.
Initramfs füllen:
Der Kernel-Build-Prozess 2.6 erstellt immer ein initramfs-Archiv im komprimierten cpio-Format 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 (im allgemeinen Setup in menuconfig,
und im Leben in usr/Kconfig
) kann eine Quelle für das
initramfs
Archiv angegeben werden, die automatisch in die resultierende Binärdatei integriert wird. Diese Option kann auf ein * vorhandenes gzipped 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 dem Kernel-Build) aus , um eine Verwendungsnachricht zu erhalten, die das obige Dateiformat dokumentiert.
Ein Vorteil der Konfigurationsdatei besteht darin, dass root
kein Zugriff erforderlich ist, um Berechtigungen festzulegen oder Geräteknoten im neuen Archiv zu erstellen.
(Beachten Sie, dass diese beiden Beispieleinträge "Datei" erwarten, dass Dateien mit den Namen " init.sh
" und " busybox
" in einem Verzeichnis mit dem Namen " initramfs
" unter dem linux
Verzeichnis -2.6. * Gefunden werden. Weitere Informationen finden Sie unter Dokumentation / Early-Userspace / README .)
Der Kernel ist nicht von externen cpio
Tools abhängig . Wenn Sie ein Verzeichnis anstelle einer Konfigurationsdatei angeben, erstellt die Build-Infrastruktur des Kernels eine Konfigurationsdatei aus diesem Verzeichnis ( usr/Makefile
Aufrufe scripts/gen_initramfs_list.sh
) und packt dieses Verzeichnis mithilfe der Konfigurationsdatei (indem Sie es an usr/gen_init_cpio
dieusr/gen_init_cpio.c
Datei senden , aus der es erstellt wurde ). Der Build-Time- cpio
Erstellungscode des Kernels ist vollständig in sich geschlossen, und der Boot-Time-Extraktor des Kernels ist (offensichtlich) auch in sich geschlossen.