Estou construindo um sistema Linux muito minimalista que consiste apenas no kernel (v4.1-rc5) e em um initramfs preenchido com o busybox (v1.23.2). Na maioria das vezes, funciona bem, mas observo uma diferença no comportamento de execução de comandos no / init, se estou usando um initramfs incorporado versus um externo.
O script / init é:
#!/bin/sh
dmesg -n 1
mount -t devtmpfs none /dev
mount -t sysfs none /sys
mount -t proc none /proc
echo "Welcome"
while true
do
setsid cttyhack /bin/sh
done
Em seguida, defino a opção CONFIG_INITRAMFS_SOURCE no kernel .config para o diretório que contém todas as pastas do initramfs ou executei
find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz
para construí-lo.
Quando eu compilo o kernel, com ou sem o conjunto CONFIG_INITRAMFS_SOURCE, acabo com duas variantes do meu sistema:
bzImage com o initramfs incorporado
bzImage + rootfs.cpio.gz (initramfs externo)
quando agora começo aqueles que usam qemu
qemu-system-x86_64 -enable-kvm -kernel bzImage
ou
qemu-system-x86_64 -enable-kvm -kernel bzImage -initrd rootfs.cpio.gz
Eu recebo a seguinte diferença de comportamento:
com a versão 2 (initramfs externo) tudo funciona bem, "Welcome" é exibido e recebo um prompt. Porém, com a versão 1 (initramfs incorporado), recebo o aviso
unable to open an initial console
"Bem-vindo" não é exibido e recebo minha solicitação.
Tanto quanto eu entendo o processo, essas duas versões do initramfs devem conter os mesmos arquivos, pois eu o construo (ou o kernel o constrói) a partir de uma pasta idêntica.
Gostaria de saber se alguém pode me ajudar com uma explicação para esse comportamento?
* ATUALIZAÇÃO *
como mikeserv disse nos comentários, o kernel inclui um initramfs incorporado mínimo por padrão. Isso ainda está presente ao usar um externo, mas é substituído se você incorporar o seu. Eu descobri que, ao contrário da especificação, isso realmente não está vazio, mas contém uma pasta dev, uma pasta raiz e o dispositivo / dev / console. Este dispositivo é usado quando se usa um initramfs externo, mas sobrescrito se você incorporar o seu. Portanto, você deve incluir o dispositivo / dev / console na fonte initramfs mknod -m 622 initramfs_src/dev/console c 5 1
ao incorporar o seu.
Muito obrigado a mikeserv, frostschutz e JdeBP por me ajudarem a entender isso!
/dev/console
no seu incorporado? Eu acho que a diferença pode ser sobre quem faz as malas nos dois casos.Respostas:
Eles são realmente idênticos?
O que você pode encontrar
/usr/src/linux/usr/initramfs_data.cpio.gz
ou extrair do bzImage, conforme descrito aqui: https://wiki.gentoo.org/wiki/Custom_Initramfs#SalvagingSe você usar esse embutido e usá-lo como externo, funciona?
Se ainda for diferente, o próprio kernel é idêntico? (compare
/proc/config.gz
para ambos)Deve haver alguma diferença. Não sei que o kernel se importa de onde vieram os initramfs. Eu suspeitaria antes
qemu
de usar configurações diferentes ao passar o-initrd
parâmetro ...Em uma nota de rodapé, você
/init
parece com suas conchas infinitas gerando para mim.setsid
não éexec
. Estou errado?fonte
On a sidenote, your /init looks like its spawning infinite shells to me. setsid is not exec. Am I wrong?
: O loop imita o getty ou ferramentas similares, desde a chamada dossh
blocos até a saída do shell.Você também pode estar interessado em saber como o Buildroot 2018.02 lida com isso.
Sempre que você usa initramfs (
BR2_TARGET_ROOTFS_INITRAMFS=y
) ou initrd (BR2_TARGET_ROOTFS_CPIO=n
), ele adiciona o seguinte/init
ao seu rootfs https://github.com/buildroot/buildroot/blob/2018.02/fs/cpio/initA cópia é feita em https://github.com/buildroot/buildroot/blob/2018.02/fs/cpio/cpio.mk :
Também é útil saber que o caminho do init é
/init
para o initramfs, diferentemente do/sbin/init
contrário: O que pode fazer com que a passagem de init = / path / to / program para o kernel não inicie o programa como init?fonte