Próbuję debugować skrypt inicjujący w systemie Linux; Próbuję przejść init=/bin/sh
do jądra, aby uruchomić go sh
bez uruchamiania, init
aby ręcznie uruchomić sekwencję inicjującą.
Odkryłem, że i tak jądro się uruchamia init
. Podczas uruchamiania jeden z komunikatów printk jest wierszem poleceń, który pokazuje, że wiersz jest ustawiony poprawnie; ponadto mogę wpływać na inne rzeczy za pomocą wiersza polecenia jądra. Sprawdziłem, czy ścieżka istnieje; to robi.
To jest system busy, a init jest dowiązaniem symbolicznym do busybox; więc aby upewnić się, że busybox nie robi dziwnej magii, gdy jego PID wynosi 1, próbowałem również uruchomić program, który nie jest zajęty jako init; to też nie działało. Wydaje się, że bez względu na to, co robię, init jest uruchamiany.
Co może być przyczyną takiego zachowania?
init
? Mogą po prostu ignorować wiersz poleceń ... możesz sprawdzić initrd i zobaczyć, co faktycznie robią skrypty.Odpowiedzi:
Patrząc na źródło jądra Linuksa, widzę, że jeśli plik / init istnieje, jądro zawsze będzie próbowało uruchomić go przy założeniu, że wykonuje rozruch z ramdysku. Sprawdź swój system, aby sprawdzić, czy / init istnieje, jeśli tak, to prawdopodobnie jest to twój problem.
źródło
execute_command
najpierw, który pochodzi zinit=
parametru wiersza poleceń jądra . Jeśli nie może go wykonać, drukuje ostrzeżenie i próbuje uruchomić sięinit
w różnych lokalizacjach. To jest winit/main.c
funkcjiinit_post()
. Przejrzałem komunikaty printk jądra i znalazłem ostrzeżenie w wynikach mojego jądra, więc teraz muszę dowiedzieć się, dlaczego nie można go uruchomić / bin / sh lub cokolwiek innego, co próbuję uruchomić.rdinit
podczas uruchamiania z ramdysku najwyraźniej: unix.stackexchange.com/a/430614/32558initrd shenanigans
Jeśli używasz initrd lub initramfs, pamiętaj o następujących kwestiach:
rdinit=
jest używany zamiastinit=
jeśli
rdinit=
nie zostanie podany, próba ścieżki domyślne są:/sbin/init
,/etc/init
,/bin/init
a/bin/sh
jednak nie/init
Gdy nie używasz initrd,
/init
jest wypróbowywana pierwsza ścieżka, a następnie pozostałe.v4.15 RTFS: wszystko jest zawarte w pliku https://github.com/torvalds/linux/blob/v4.15/init/main.c .
Najpierw dowiadujemy się, że:
execute_comand
to cokolwiek jest przekazywane do:init=
ramdisk_execute_command
to cokolwiek jest przekazywane do:rdinit=
jak widać z:
gdzie
__setup
jest magiczny sposób obsługi parametrów wiersza poleceń.start_kernel
, „punkt wejścia” jądra, wywołaniarest_init
, które „wywołują”kernel_init
wątek:Następnie
kernel_init
:i
kernel_init_freeable
robi:DO ZROBIENIA: zrozum
sys_access
.Zauważ też, że istnieją dalsze różnice między jednostkami RAM i nie-RAM, np. Obsługa konsoli: Różnica w wykonaniu init z osadzonymi vs. zewnętrznymi initramfs?
źródło
Na
https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt
Znalazłem:
Więc prawdopodobnie spróbuj ridinit = / bin / sh
źródło
Możesz dostosować jądro Linuksa i skompilować je ponownie. W przypadku jądra 4.9 edytuj funkcję „kernel_init” w pliku init / main.c i spróbuj najpierw uruchomić następujący wiersz:
Ponadto może to być spowodowane parametrami jądra przekazywanymi przez program BootLoader.
źródło