Ich versuche, ein Init-Skript auf einem Linux-System zu debuggen. Ich versuche, init=/bin/sh
an den Kernel zu übergeben, damit er startet, sh
ohne gestartet zu werden, init
damit ich die Initialisierungssequenz manuell durchlaufen kann.
Was ich gefunden habe ist, dass der Kernel init
sowieso startet . Während des Startvorgangs ist eine der printk-Meldungen die Befehlszeile, die anzeigt, dass die Zeile richtig eingestellt ist. Außerdem kann ich über die Kernel-Befehlszeile andere Dinge beeinflussen. Ich habe überprüft, ob der Pfad existiert. es tut.
Dies ist ein Busybox-System, und init ist ein Symlink zu busybox. um sicherzustellen, dass busybox keine seltsame Magie ausführt, wenn die PID 1 ist, habe ich auch versucht, ein Nicht-Busybox-Programm als init auszuführen. das hat auch nicht geklappt. Es scheint, dass, egal was ich tue, init ausgeführt wird.
Was könnte dieses Verhalten verursachen?
init
? Möglicherweise ignorieren sie einfach die Befehlszeile. Vielleicht möchten Sie die initrd untersuchen und sehen, was die Skripte tatsächlich tun.Antworten:
Wenn ich mir die Linux-Kernelquelle anschaue, sehe ich, dass der Kernel, wenn die Datei / init existiert, immer versucht, sie auszuführen, unter der Annahme, dass ein RAM-Disk-Boot ausgeführt wird. Überprüfen Sie Ihr System, um festzustellen, ob / init vorhanden ist. Wenn dies der Fall ist, liegt dies wahrscheinlich an Ihrem Problem.
quelle
execute_command
zuerst geprüft , welcher Wert vom Kernel-Befehlszeilenparameter stammtinit=
. Wenn es nicht ausgeführt werden kann, wird eine Warnung ausgegeben und versucht,init
an verschiedenen Orten ausgeführt zu werden. Dies istinit/main.c
in der Funktioninit_post()
. Ich habe die Kernel-Printk-Meldungen durchgesehen und die Warnung in der Ausgabe meines Kernels gefunden. Jetzt muss ich herausfinden, warum / bin / sh nicht gestartet werden kann oder was ich sonst noch zu starten versuche.rdinit
beim Booten von Ramdisk anscheinend verwenden: unix.stackexchange.com/a/430614/32558initrd shenanigans
Wenn Sie initrd oder initramfs verwenden, beachten Sie Folgendes:
rdinit=
wird anstelle von verwendetinit=
wenn
rdinit=
nicht angegeben, sind die versuchten Standardpfade:/sbin/init
,/etc/init
,/bin/init
und ,/bin/sh
aber nicht/init
Wenn initrd nicht verwendet wird,
/init
wird der erste Pfad ausprobiert, gefolgt von den anderen.v4.15 RTFS: Alles ist in der Datei https://github.com/torvalds/linux/blob/v4.15/init/main.c enthalten.
Zuerst lernen wir, dass:
execute_comand
ist was auch immer übergeben wird an:init=
ramdisk_execute_command
ist was auch immer übergeben wird an:rdinit=
wie man sieht aus:
Wo
__setup
ist ein magischer Weg, um Kommandozeilenparameter zu verarbeiten.start_kernel
ruft der Kernel "Einstiegspunktrest_init
"kernel_init
auf, der einen Thread "aufruft" :Dann
kernel_init
macht:und
kernel_init_freeable
macht:TODO: Verstehe
sys_access
.Beachten Sie auch, dass es weitere Unterschiede zwischen RAM-Inits und Nicht-RAM-Inits gibt, z. B. beim Konsolen-Handling: Unterschied bei der Ausführung von init mit eingebetteten vs. externen Initramfs?
quelle
Auf
https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt
Ich fand:
Also versuchen Sie wahrscheinlich ridinit = / bin / sh
quelle
Sie können Ihren Linux-Kernel anpassen und neu kompilieren. Bearbeiten Sie für 4.9-Kernel die Funktion "kernel_init" in init / main.c und versuchen Sie zuerst, die folgende Zeile auszuführen:
Darüber hinaus kann dies an den von BootLoader übergebenen Kernel-Parametern liegen.
quelle