J'essaie de déboguer un script d'initialisation sur un système Linux; J'essaie de passer init=/bin/sh
au noyau pour le faire démarrer sh
sans démarrer init
afin que je puisse exécuter manuellement la séquence d'initialisation.
Ce que j'ai trouvé, c'est que le noyau démarre de init
toute façon. Lors du démarrage, l'un des messages printk est la ligne de commande, ce qui montre que la ligne est définie correctement; en plus, je peux affecter d'autres choses en utilisant la ligne de commande du noyau. J'ai vérifié pour m'assurer que le chemin existe; Cela fait.
Il s'agit d'un système busybox et init est un lien symbolique vers busybox; donc pour m'assurer que busybox ne fait pas de magie étrange lorsque son PID est 1, j'ai également essayé d'exécuter un programme non occupé comme init; cela n'a pas fonctionné non plus. Il semble que peu importe ce que je fais, init est lancé.
Quelle pourrait être la cause de ce comportement?
init
? Ils peuvent simplement ignorer la ligne de commande ... vous voudrez peut-être examiner l'initrd et voir ce que les scripts font réellement.Réponses:
En regardant la source du noyau Linux, je vois que si le fichier / init existe, le noyau tentera toujours de l'exécuter en supposant qu'il effectue un démarrage sur disque virtuel. Vérifiez votre système pour voir si / init existe, si c'est le cas, alors c'est probablement votre problème.
la source
execute_command
abord, qui provient duinit=
paramètre de ligne de commande du noyau . S'il ne peut pas l'exécuter, il affiche un avertissement et essaie de s'exécuterinit
à divers emplacements. C'estinit/main.c
dans la fonctioninit_post()
. J'ai parcouru les messages printk du noyau et trouvé l'avertissement dans la sortie de mon noyau, alors maintenant je dois comprendre pourquoi il ne peut pas démarrer / bin / sh ou toute autre chose que j'essaie de démarrer.rdinit
lors du démarrage à partir de ramdisk apparemment: unix.stackexchange.com/a/430614/32558initrd shenanigans
Si vous utilisez initrd ou initramfs, gardez à l'esprit les points suivants:
rdinit=
est utilisé à la place deinit=
si
rdinit=
n'est pas donné, les chemins par défaut concernées sont:/sbin/init
,/etc/init
,/bin/init
et/bin/sh
non/init
Lorsque vous n'utilisez pas initrd,
/init
le premier chemin est-il essayé, suivi des autres.v4.15 RTFS: tout est contenu dans le fichier https://github.com/torvalds/linux/blob/v4.15/init/main.c .
Nous apprenons d'abord que:
execute_comand
est tout ce qui est transmis à:init=
ramdisk_execute_command
est tout ce qui est transmis à:rdinit=
comme on peut le voir sur:
où
__setup
est un moyen magique de gérer les paramètres de ligne de commande.start_kernel
, le noyau "point d'entrée", appellerest_init
, qui "appelle"kernel_init
sur un thread:Ensuite,
kernel_init
fait:et
kernel_init_freeable
fait:TODO: comprenez
sys_access
.Notez également qu'il existe d'autres différences entre les inits ram et non-ram, par exemple la gestion de la console: Différence dans l'exécution d'init avec des initramfs intégrés et externes?
la source
Sur
https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt
J'ai trouvé:
Essayez donc probablement ridinit = / bin / sh
la source
Vous pouvez personnaliser votre noyau Linux et le recompiler. Pour le noyau 4.9, modifiez la fonction "kernel_init" dans init / main.c et essayez d'exécuter la ligne suivante en premier:
De plus, cela peut être dû aux paramètres du noyau transmis par BootLoader.
la source