Estou tentando depurar um script init em um sistema Linux; Estou tentando passar init=/bin/sh
para o kernel para iniciá-lo sh
sem iniciar, init
para que eu possa executar manualmente a sequência init.
O que eu descobri é que o kernel está iniciando de init
qualquer maneira. Durante a inicialização, uma das mensagens printk é a linha de comando e isso mostra que a linha está sendo definida corretamente; além disso, posso afetar outras coisas usando a linha de comando do kernel. Eu verifiquei para garantir que o caminho existe; faz.
Este é um sistema de busybox, e o init é um link simbólico para o busybox; portanto, para garantir que o busybox não faça mágica estranha quando seu PID é 1, também tentei executar um programa não-busybox como init; isso também não funcionou. Parece que não importa o que eu faça, o init é executado.
O que poderia estar causando esse comportamento?
init
? Eles podem simplesmente estar ignorando a linha de comando ... você pode examinar o initrd e ver o que os scripts estão realmente fazendo.Respostas:
Observando a fonte do kernel do Linux, vejo que, se o arquivo / init existir, o kernel sempre tentará executá-lo com a suposição de que está executando uma inicialização por ramdisk. Verifique seu sistema para ver se / init existe, se existe, provavelmente esse é seu problema.
fonte
execute_command
primeiro, que vem doinit=
parâmetro de linha de comando do kernel . Se não puder executá-lo, ele imprime um aviso e tenta executarinit
em vários locais. Isso está nainit/main.c
funçãoinit_post()
. Examinei as mensagens do kernel printk e encontrei o aviso na saída do meu kernel, então agora tenho que descobrir por que ele não pode iniciar / bin / sh ou qualquer outra coisa que eu tente iniciar.rdinit
Aparentemente, você deve usar ao inicializar a partir do ramdisk: unix.stackexchange.com/a/430614/32558travessuras initrd
Se você estiver usando initrd ou initramfs, lembre-se do seguinte:
rdinit=
é usado em vez deinit=
se
rdinit=
não é dado, os caminhos padrão tentativas são:/sbin/init
,/etc/init
,/bin/init
e/bin/sh
não, mas/init
Quando não
/init
estiver usando o initrd, é o primeiro caminho tentado, seguido pelos outros.v4.15 RTFS: tudo está contido no arquivo https://github.com/torvalds/linux/blob/v4.15/init/main.c .
Primeiro aprendemos que:
execute_comand
é o que for passado para:init=
ramdisk_execute_command
é o que for passado para:rdinit=
como pode ser visto em:
onde
__setup
é uma maneira mágica de lidar com os parâmetros da linha de comando.start_kernel
, o kernel "ponto de entrada", chamarest_init
, que "chama"kernel_init
em um thread:Então,
kernel_init
faz:e
kernel_init_freeable
faz:TODO: entenda
sys_access
.Observe também que existem outras diferenças entre inits ram e inits não ram, por exemplo, manipulação de console: Diferença na execução do init com initramfs incorporado e externo?
fonte
Em
https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt
Eu encontrei:
Então provavelmente tente ridinit = / bin / sh
fonte
Você pode personalizar seu kernel do Linux e recompilá-lo. Para o kernel 4.9, edite a função "kernel_init" em init / main.c e tente executar a seguinte linha primeiro:
Além disso, pode ser causado pelos parâmetros do kernel passados pelo BootLoader.
fonte