Buduję bardzo minimalny system Linux, który po prostu składa się z jądra (v4.1-rc5) i initramfs wypełnionego busybox (v1.23.2). W większości działa dobrze, ale obserwuję różnicę w zachowaniu wykonywania poleceń w / init, czy używam osadzonego initramfs vs. zewnętrznego.
Skrypt / init to:
#!/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
Następnie ustawiam opcję CONFIG_INITRAMFS_SOURCE w jądrze .config na katalog zawierający wszystkie foldery dla initramfs lub uruchamiam
find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz
zbudować to.
Kiedy kompiluję jądro, z zestawem CONFIG_INITRAMFS_SOURCE lub bez niego, kończę na dwóch wariantach mojego systemu:
bzImage z osadzonymi initramfs
bzImage + rootfs.cpio.gz (zewnętrzne initramfs)
kiedy teraz zacznę używać qemu
qemu-system-x86_64 -enable-kvm -kernel bzImage
lub
qemu-system-x86_64 -enable-kvm -kernel bzImage -initrd rootfs.cpio.gz
Dostaję następującą różnicę w zachowaniu:
w wersji 2 (zewnętrzne initramfs) wszystko działa dobrze, wyświetla się „Welcome” i pojawia się monit. Jednak w wersji 1 (osadzone initramfs) pojawia się ostrzeżenie
unable to open an initial console
„Witamy” nie jest wyświetlane i pojawia się monit.
O ile rozumiem ten proces, te dwie wersje initramfs powinny zawierać te same pliki, ponieważ tworzę je (lub mam jądro) z identycznego folderu.
Zastanawiam się, czy ktoś może mi pomóc w wyjaśnieniu tego zachowania?
* AKTUALIZACJA *
jak powiedział mikeserv w komentarzach, jądro zawiera domyślnie minimalną liczbę osadzonych initramfs. Jest to nadal obecne, gdy używasz zewnętrznego, ale zostanie zastąpione, jeśli umieścisz własne. Odkryłem, że wbrew specyfikacji, to nie jest rzeczywiście puste, ale zawiera folder dev, folder główny i urządzenie / dev / console. To urządzenie przyzwyczaja się wtedy, gdy używasz zewnętrznego initramfs, ale jest zastępowane, jeśli osadzasz własne. Musisz więc umieścić urządzenie / dev / console w źródle initramfs mknod -m 622 initramfs_src/dev/console c 5 1
podczas osadzania własnego.
Wielkie dzięki dla mikeserv, frostschutz i JdeBP za pomoc w zrozumieniu tego!
/dev/console
na Twoim wbudowanym? Myślę, że różnica może dotyczyć tego, kto zajmuje się pakowaniem w obu przypadkach.Odpowiedzi:
Czy są naprawdę identyczne?
Wbudowany można go znaleźć
/usr/src/linux/usr/initramfs_data.cpio.gz
lub wyodrębnić z bzImage, jak opisano tutaj: https://wiki.gentoo.org/wiki/Custom_Initramfs#SalvagingJeśli użyjesz tego wbudowanego i użyjesz go jako zewnętrznego, czy to działa?
Jeśli nadal jest inaczej, czy samo jądro jest identyczne? (porównaj
/proc/config.gz
dla obu)Powinna być jakaś różnica. Nie wiem, czy jądro dba o to, skąd pochodzi initramfs. Wcześniej podejrzewam, że
qemu
używam różnych ustawień podczas przekazywania-initrd
parametru ...Na marginesie,
/init
wygląda mi na to, że spawnuje nieskończone pociski.setsid
nie jestexec
. Czy się mylę?źródło
On a sidenote, your /init looks like its spawning infinite shells to me. setsid is not exec. Am I wrong?
: Pętla naśladuje getty lub podobne narzędzia, ponieważ wywołująsh
bloki, dopóki ta powłoka nie wyjdzie.Możesz być także zainteresowany tym, jak radzi sobie z tym Buildroot 2018.02.
Ilekroć używasz initramfs (
BR2_TARGET_ROOTFS_INITRAMFS=y
) lub initrd (BR2_TARGET_ROOTFS_CPIO=n
), dodaje następujące elementy/init
do twoich rootfów https://github.com/buildroot/buildroot/blob/2018.02/fs/cpio/initKopia jest wykonywana przez https://github.com/buildroot/buildroot/blob/2018.02/fs/cpio/cpio.mk :
Warto również wiedzieć, że ścieżka inicjująca jest
/init
przeznaczona dla initramfs, w przeciwieństwie do/sbin/init
innych: Co może sprawić, że przekazanie init = / ścieżka / do / programu do jądra nie uruchomi programu jako init?źródło