Initramfs integrado en el kernel de Linux personalizado no se está ejecutando

Estoy creando una imagen initramfs personalizada que estoy creando como un archivo CPIO en el kernel de Linux (3.2).

El problema que tengo es que no importa lo que intente, el núcleo no parece siquiera intentar ejecutarse desde initramfs.

Los archivos que tengo en mi archivo CPIO:

cpio -it < initramfs.cpio
.
init
usr
usr/sbin
lib
lib/libcrypt.so.1
lib/libm.so
lib/libc.so.6
lib/libgcc_s.so
lib/libcrypt-2.12.2.so
lib/libgcc_s.so.1
lib/libm-2.12.2.so
lib/libc.so
lib/libc-2.12.2.so
lib/ld-linux.so.3
lib/ld-2.12.2.so
lib/libm.so.6
proc
sbin
mnt
mnt/root
root
etc
bin
bin/sh
bin/mknod
bin/mount
bin/busybox
sys
dev
4468 blocks

Init es muy simple, y solo debe iniciar dispositivos y generar un shell (por ahora):

#!/bin/sh

mount -t devtmpfs none /dev
mount -t proc none /proc
mount -t sysfs none /sys
/bin/busybox --install -s
exec /bin/sh

En el kernel .config tengo:

CONFIG_INITRAMFS_SOURCE="../initramfs.cpio"
CONFIG_INITRAMFS_ROOT_UID=0
CONFIG_INITRAMFS_ROOT_GID=0
CONFIG_BLK_DEV_INITRD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=1
CONFIG_BLK_DEV_RAM_SIZE=32768

El núcleo se construye y el tamaño de uImage es mayor según el tamaño de initramfs, por lo que sé que la imagen se está empaquetando. Sin embargo, obtengo este resultado cuando arranco:

console [netcon0] enabled
netconsole: network logging started
omap_rtc omap_rtc: setting system clock to 2000-01-02 00:48:38 UTC (946774118)
Warning: unable to open an initial console.
Freeing init memory: 1252K
mmc0: host does not support reading read-only switch. assuming write-enable.
mmc0: new high speed SDHC card at address e624
mmcblk0: mmc0:e624 SU08G 7.40 GiB
 mmcblk0: p1
Kernel panic - not syncing: Attempted to kill init!
[<c000d518>] (unwind_backtrace+0x0/0xe0) from [<c0315cf8>] (panic+0x58/0x188)
[<c0315cf8>] (panic+0x58/0x188) from [<c0021520>] (do_exit+0x98/0x6c0)
[<c0021520>] (do_exit+0x98/0x6c0) from [<c0021e88>] (do_group_exit+0xb0/0xdc)
[<c0021e88>] (do_group_exit+0xb0/0xdc) from [<c0021ec4>] (sys_exit_group+0x10/0x18)
[<c0021ec4>] (sys_exit_group+0x10/0x18) from [<c00093a0>] (ret_fast_syscall+0x0/0x2c)

A partir de esa salida, no parece que esté intentando extraer el archivo CPIO como initramfs. Espero ver esta salida de printk, que está presente en el código de Linux init/initramfs.c:

printk(KERN_INFO "Trying to unpack rootfs image as initramfs...\n");

Probé el sistema de archivos una vez que se completó el arranque (usando chroot) y funciona bien... así que creo que el sistema de archivos/bibliotecas están sanos.

¿Alguien podría darme algunos consejos sobre lo que puedo tener incorrecto? ¡Gracias de antemano por cualquier ayuda!

preguntado el 03 de mayo de 12 a las 20:05

Me parece que su núcleo se está bloqueando por una razón probablemente no relacionada, ya sea durante la inicialización de los dispositivos mmcblk o entre eso y lo que sea que genere un mensaje de salida. ¿Puede obtener algunos printk adicionales allí para informar el progreso? ¿Qué tan seguro está de que las fuentes de su kernel son apropiadas para esta placa? ¿Ha realizado cambios para adaptarlas (como la creación de instancias codificadas de las cosas mmcblk) en las que puede haber errores? -

Arranca bien con este núcleo, menos el initramfs (usando el sistema de archivos más grande que he instalado en NAND). Así que dudo que sea un problema de la placa. Estoy trabajando para obtener algunas impresiones allí, pero esperaba que alguien pudiera señalar algo obviamente incorrecto con mi enfoque antes de volverme loco con eso. -

1 Respuestas

Me lo imaginé. Voy a publicar la respuesta en caso de que alguien más tenga este problema.

Me faltaba un dispositivo de consola, esta línea era la pista:

Warning: unable to open an initial console.

Después de agregar printk para comprender mejor la secuencia de inicio, me di cuenta de que el dispositivo de la consola se abre antes de ejecutar el script de inicio. Por lo tanto, el dispositivo de la consola debe estar directamente en el sistema de archivos initramfs y no podemos confiar en el montaje devtmpfs para crearlo.

Creo que cuando se ejecutó el script de inicio, el shell estaba tratando de abrir la consola y falló, es por eso que el kernel estaba generando:

Kernel panic - not syncing: Attempted to kill init!

Ejecutar los siguientes comandos desde el directorio /dev de initramfs en la máquina de compilación del kernel generará los nodos de dispositivo necesarios:

mknod -m 622 console c 5 1
mknod -m 622 tty0 c 4 0

Después de volver a archivar con CPIO el sistema de archivos y reconstruir el kernel, finalmente tengo un sistema de archivos en funcionamiento en initramfs que arrancará el kernel.

contestado el 04 de mayo de 12 a las 19:05

devtmpfs.mount=1 puede ser útil para kernels más nuevos o habilitar CONFIG_DEVTMPFS_MOUNT - tecnosaurio

En Linux 3.17 descubrí que solo console es el único dispositivo que necesitaba tener encendido /dev en el initramfs, pero YMMV. - piraña

¡¡Explicación/Aviso!! linux siempre crea un initramfs. Cuando no especifica el suyo propio, crea un pequeño código auxiliar (~ 134 bytes). Este stub initramfs contiene el /dev/console dispositivo. Entonces, si cambia de un initramfs externo a uno incorporado (que no contiene /dev/console), verás este mensaje. Una solución alternativa es no para incrustar /dev/console pero mkdir /dev; mount /dev -t devtmpfs dev en tu /init. - i336_

(Continuación del comentario anterior) Fuentes: Documentation/filesystems/ramfs-rootfs-initramfs.txt (^F "134") y usr/gen_initramfs_list.sh (^F "consola" - este es el stub initramfs). - i336_

mis sintomas: el kernel arrancó, mostró "no se puede abrir una consola inicial", se colgó... y no entró en pánico. (Estaba usando busybox para /bin/sh y mi propio shell-script /init.) Kernel simplemente se sentó allí. Estaba trabajando en QEMU, y sendkey alt-sysrq-t (a través de ttyS0, el resultado es grande) mostró mi sh proceso sentado allí sin hacer nada. Curiosamente incluso sleep 1; reboot sí logró no trabajo. No investigué por qué, pero sospecho que no pasaba nada porque stdout fue bloqueado. - i336_

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.