Estoy construyendo un sistema Linux muy mínimo que solo consta del kernel (v4.1-rc5) y un initramfs poblado con busybox (v1.23.2). Funciona bien en su mayor parte, pero observo una diferencia en el comportamiento de la ejecución del comando en / init si estoy usando un initramfs incrustado frente a uno externo.
El script / init es:
#!/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
Luego configuro la opción CONFIG_INITRAMFS_SOURCE en el kernel .config en el directorio que contiene todas las carpetas para initramfs, o ejecuto
find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz
para construirlo
Cuando compilo el núcleo, con o sin el conjunto CONFIG_INITRAMFS_SOURCE, termino con dos variantes de mi sistema:
bzImage con initramfs incrustado
bzImage + rootfs.cpio.gz (initramfs externo)
cuando ahora empiezo a usar qemu
qemu-system-x86_64 -enable-kvm -kernel bzImage
o
qemu-system-x86_64 -enable-kvm -kernel bzImage -initrd rootfs.cpio.gz
Tengo la siguiente diferencia de comportamiento:
con la versión 2 (initramfs externo) todo funciona bien, se muestra "Bienvenido" y aparece un mensaje. Sin embargo, con la versión 1 (initramfs incrustado) recibo la advertencia
unable to open an initial console
"Bienvenido" no se muestra y recibo mi mensaje.
Hasta donde entiendo el proceso, esas dos versiones de initramfs deberían contener los mismos archivos, ya que lo compilo (o hago que el núcleo lo construya) desde una carpeta idéntica.
Me pregunto si alguien puede ayudarme con una explicación de este comportamiento.
* ACTUALIZACIÓN *
Como dijo mikeserv en los comentarios, el núcleo incluye un mínimo de initramfs incrustado por defecto. Esto todavía está presente cuando se usa uno externo, pero se sobrescribe si incrusta el suyo. Descubrí que, contrario a la especificación, esto no está vacío, sino que contiene una carpeta de desarrollo, una carpeta raíz y el dispositivo / dev / console. Este dispositivo luego se usa cuando se usa un initramfs externo, pero se sobrescribe si incrusta el suyo. Por lo tanto, debe incluir el dispositivo / dev / console en su fuente initramfs mknod -m 622 initramfs_src/dev/console c 5 1
cuando incruste el suyo.
¡Muchas gracias a mikeserv, frostschutz y JdeBP por ayudarme a entenderlo!
/dev/console
en su uno incorporado? Creo que la diferencia podría estar en quién empaca en los dos casos.Respuestas:
¿Son realmente idénticos?
El incorporado puede encontrarlo
/usr/src/linux/usr/initramfs_data.cpio.gz
o extraerlo de bzImage como se describe aquí: https://wiki.gentoo.org/wiki/Custom_Initramfs#SalvagingSi usa ese incorporado y lo usa como externo, ¿funciona?
Si aún es diferente, ¿el núcleo en sí es idéntico? (comparar
/proc/config.gz
para ambos)Debería haber alguna diferencia. No soy consciente de que al núcleo le importa de dónde provienen los initramfs. Prefiero sospechar
qemu
de usar diferentes configuraciones al pasar el-initrd
parámetro ...En una nota al margen, me
/init
parece que está generando infinitas conchas para mí.setsid
no esexec
. ¿Me equivoco?fuente
On a sidenote, your /init looks like its spawning infinite shells to me. setsid is not exec. Am I wrong?
: El bucle imita a getty o herramientas similares, ya que llama a lossh
bloques hasta que sale ese shell.También puede interesarle cómo Buildroot 2018.02 trata esto.
Cada vez que usa initramfs (
BR2_TARGET_ROOTFS_INITRAMFS=y
) o initrd (BR2_TARGET_ROOTFS_CPIO=n
), agrega lo siguiente/init
a sus rootfs https://github.com/buildroot/buildroot/blob/2018.02/fs/cpio/initLa copia la realiza https://github.com/buildroot/buildroot/blob/2018.02/fs/cpio/cpio.mk :
También es útil saber que la ruta de inicio es
/init
para initramfs, a diferencia de lo/sbin/init
contrario: ¿qué puede hacer que pasar init = / path / to / program al kernel no inicie el programa como init?fuente