Ich baue ein sehr minimales Linux-System, das nur aus dem Kernel (v4.1-rc5) und einem mit Busybox (v1.23.2) bestückten Initramfs besteht. Es funktioniert größtenteils einwandfrei, aber ich beobachte einen Unterschied im Verhalten der Befehlsausführung in / init, unabhängig davon, ob ich ein eingebettetes initramfs oder ein externes verwende.
Das / init-Skript lautet:
#!/bin/sh
dmesg -n 1
mount -t devtmpfs none /dev
mount -t sysfs none /sys
mount -t proc none /proc
echo "Welcome"
while true
do
setsid cttyhack /bin/sh
done
Dann setze ich entweder die Option CONFIG_INITRAMFS_SOURCE im Kernel .config auf das Verzeichnis, das alle Ordner für die initramfs enthält, oder ich führe aus
find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz
um es zu bauen.
Wenn ich dann den Kernel kompiliere, entweder mit oder ohne CONFIG_INITRAMFS_SOURCE, habe ich zwei Varianten meines Systems:
bzImage mit eingebettetem initramfs
bzImage + rootfs.cpio.gz (externe initramfs)
wenn ich jetzt anfange diese zu benutzen qemu
qemu-system-x86_64 -enable-kvm -kernel bzImage
oder
qemu-system-x86_64 -enable-kvm -kernel bzImage -initrd rootfs.cpio.gz
Ich habe folgenden Verhaltensunterschied:
Mit Version 2 (externes Initramfs) funktioniert alles einwandfrei. "Willkommen" wird angezeigt und ich erhalte eine Eingabeaufforderung. Mit Version 1 (Embedded Initramfs) bekomme ich jedoch die Warnung
unable to open an initial console
"Willkommen" wird nicht angezeigt und ich erhalte meine Eingabeaufforderung.
Soweit ich den Prozess verstehe, sollten diese beiden Versionen von initramfs dieselben Dateien enthalten, da ich sie aus einem identischen Ordner erstelle (oder vom Kernel erstellen lasse).
Ich frage mich, ob mir jemand mit einer Erklärung für dieses Verhalten helfen kann.
* UPDATE *
Wie MikeServ in den Kommentaren sagte, enthält der Kernel standardmäßig ein minimales eingebettetes Initramfs. Dies ist weiterhin vorhanden, wenn Sie ein externes verwenden, wird jedoch überschrieben, wenn Sie Ihr eigenes einbetten. Ich habe festgestellt, dass dies entgegen der Spezifikation zwar nicht leer ist, sondern einen Entwicklungsordner, einen Stammordner und das Gerät / dev / console enthält. Dieses Gerät wird dann bei Verwendung eines externen Initramfs verwendet, aber überschrieben, wenn Sie Ihr eigenes einbetten. Sie müssen also das Gerät / dev / console in Ihre initramfs-Quelle aufnehmen, mknod -m 622 initramfs_src/dev/console c 5 1
wenn Sie Ihr eigenes einbetten.
Vielen Dank an mikeserv, frostschutz und JdeBP, die mir dabei geholfen haben, mich darum zu kümmern!
/dev/console
für Ihre integrierte Version festgelegt? Ich denke, der Unterschied könnte darin bestehen, wer in beiden Fällen die Verpackung übernimmt.Antworten:
Sind sie wirklich identisch?
Die integrierte
/usr/src/linux/usr/initramfs_data.cpio.gz
Version, die Sie in bzImage finden oder daraus extrahieren können, wie hier beschrieben: https://wiki.gentoo.org/wiki/Custom_Initramfs#SalvagingWenn Sie dieses integrierte Gerät verwenden und es stattdessen als externes verwenden, funktioniert es dann?
Wenn es immer noch anders ist, ist der Kernel selbst identisch? (Vergleiche
/proc/config.gz
für beide)Es sollte einen Unterschied geben. Mir ist nicht bewusst, dass es dem Kernel wichtig ist, woher die Initramfs stammen. Ich würde eher vermuten
qemu
, beim Übergeben des-initrd
Parameters andere Einstellungen zu verwenden ...Nebenbei bemerkt, Sie sehen
/init
aus, als würden mir unendlich viele Muscheln erscheinen.setsid
ist nichtexec
. Liege ich falsch?quelle
On a sidenote, your /init looks like its spawning infinite shells to me. setsid is not exec. Am I wrong?
: Die Schleife ahmt getty oder ähnliche Tools nach, da diesh
Blöcke aufgerufen werden, bis diese Shell beendet wird.Vielleicht interessiert Sie auch, wie Buildroot 2018.02 damit umgeht.
Wenn Sie initramfs (
BR2_TARGET_ROOTFS_INITRAMFS=y
) oder initrd (BR2_TARGET_ROOTFS_CPIO=n
) verwenden, wird/init
Ihrem rootfs Folgendes hinzugefügt: https://github.com/buildroot/buildroot/blob/2018.02/fs/cpio/initDie Kopie wird von https://github.com/buildroot/buildroot/blob/2018.02/fs/cpio/cpio.mk erstellt :
Es ist auch nützlich zu wissen, dass der Init-Pfad
/init
für initramfs ist, im Gegensatz zu/sbin/init
anderen: Was kann dazu führen, dass die Übergabe von init = / path / to / program an den Kernel das Programm nicht als init startet?quelle