Я пытаюсь отладить сценарий инициализации в системе Linux; Я пытаюсь перейти init=/bin/sh
к ядру, чтобы оно запустилось sh
без запуска, init
чтобы я мог запустить последовательность инициализации вручную.
Я обнаружил, что ядро init
все равно запускается. Во время загрузки одно из сообщений printk является командной строкой, и это показывает, что строка установлена правильно; кроме того, я могу влиять на другие вещи, используя командную строку ядра. Я проверил, чтобы убедиться, что путь существует; оно делает.
Это система busybox, а init - это символическая ссылка на busybox; поэтому, чтобы убедиться, что busybox не выполняет странную магию, когда его PID равен 1, я также попытался запустить программу non-busybox в качестве init; это тоже не сработало. Кажется, что независимо от того, что я делаю, init запускается.
Что может быть причиной такого поведения?
init
? Возможно, они просто игнорируют командную строку ... вы можете изучить initrd и посмотреть, что на самом деле делают скрипты.Ответы:
Глядя на исходный код ядра Linux, я вижу, что если файл / init существует, ядро всегда будет пытаться запустить его, исходя из предположения, что оно выполняет загрузку с виртуального диска. Проверьте вашу систему, чтобы увидеть, если / init существует, если он существует, то это, вероятно, ваша проблема.
источник
execute_command
сначала проверяет , что происходит из параметра командной строки ядраinit=
. Если он не может выполнить его, он печатает предупреждение и пытается запуститьinit
в разных местах. Этоinit/main.c
в функцииinit_post()
. Я просмотрел сообщения printk ядра и нашел предупреждение в выводе моего ядра, так что теперь я должен выяснить, почему он не может запустить / bin / sh или что-либо еще, что я пытаюсь запустить.rdinit
при загрузке с ramdisk: unix.stackexchange.com/a/430614/32558initrd shenanigans
Если вы используете initrd или initramfs, имейте в виду следующее:
rdinit=
используется вместоinit=
если
rdinit=
не задан, пытавшиеся пути по умолчанию являются:/sbin/init
,/etc/init
,/bin/init
и ,/bin/sh
но не/init
Когда не используется initrd,
/init
используется первый путь, за которым следуют другие.v4.15 RTFS: все содержится в файле https://github.com/torvalds/linux/blob/v4.15/init/main.c .
Сначала мы узнаем, что:
execute_comand
это то, что передается:init=
ramdisk_execute_command
это то, что передается:rdinit=
как видно из:
где
__setup
магический способ обработки параметров командной строки.start_kernel
, ядро "точка входа", вызовыrest_init
, которые "вызывают"kernel_init
в потоке:Затем
kernel_init
:и
kernel_init_freeable
делает:ТОДО: понять
sys_access
.Также обратите внимание, что существуют дополнительные различия между начальными и начальными частями , например, консольная обработка: разница в выполнении init со встроенными и внешними initramfs?
источник
На
https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt
Я нашел:
Так что, вероятно, попробуйте Ridinit = / bin / sh
источник
Вы можете настроить свое ядро Linux и перекомпилировать его. Для ядра 4.9 отредактируйте функцию «kernel_init» в init / main.c и попробуйте сначала выполнить следующую строку:
Кроме того, это может быть вызвано параметрами ядра, переданными BootLoader.
источник