Вопрос по linux – Initramfs, встроенный в собственное ядро Linux, не работает

19

Я создаю собственный образ initramfs, который я создаю как архив CPIO в ядре Linux (3.2).

У меня проблема в том, что независимо от того, что я пытаюсь, ядро, похоже, даже не пытается запустить из initramfs.

Файлы, которые у меня есть в моем архиве CPIO:

<code>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
</code>

Init очень прост, и должен просто инициализировать устройства и порождать оболочку (пока):

<code>#!/bin/sh

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

В ядре .config у меня есть:

<code>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
</code>

Сборки ядра и размер uImage больше в зависимости от размера initramfs, поэтому я знаю, что изображение упаковывается. Однако я получаю этот вывод при загрузке:

<code>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)
</code>

Из этого вывода не похоже, что он даже пытается извлечь архив CPIO как initramfs. Я ожидаю увидеть этот вывод printk, который присутствует в linux-коде init / initramfs.c:

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

Я попробовал файловую систему после завершения загрузки (с помощью chroot), и она работает нормально ... поэтому я считаю, что файловая система / библиотеки нормальны.

Может ли кто-нибудь дать мне несколько советов о том, что я могу иметь неправильно? Спасибо заранее за любую помощь!

Мне кажется, что ваше ядро выходит из строя по вероятной не связанной причине, либо во время инициализации устройств mmcblk, либо между этим и всем, что будет дальше генерировать выходное сообщение. Можете ли вы получить дополнительные распечатки, чтобы сообщить о прогрессе? Насколько вы уверены, что исходные коды вашего ядра подходят для этой платы - вносили ли вы изменения, чтобы адаптировать их (например, жестко запрограммированное создание экземпляра mmcblk), в котором могут быть ошибки? Chris Stratton
Он прекрасно загружается с этим ядром, за исключением initramfs (используя большую файловую систему, которую я поместил в NAND). Поэтому я сомневаюсь, что это вопрос платы. Я работаю над тем, чтобы получить там несколько принтов, но надеялся, что кто-то может указать на что-то явно неправильное в моем подходе, прежде чем я сойду с ума от этого. dag

Ваш Ответ

1   ответ
32

Мне не хватало консольного устройства, эта строка была подсказкой:

Warning: unable to open an initial console.

После добавления printk, чтобы я лучше понимал последовательность запуска, я понял, что консольное устройство открывается перед запуском сценария инициализации. Следовательно, консольное устройство должно быть непосредственно в файловой системе initramfs, и мы не можем полагаться на монтирование devtmpfs для его создания.

Я думаю, что когда скрипт init запустился, оболочка пыталась открыть консоль и потерпела неудачу, поэтому ядро выводило:

Kernel panic - not syncing: Attempted to kill init!

Выполнение следующих команд из каталога / dev файла initramfs на машине сборки ядра создаст необходимые узлы устройства:

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

После повторного CPIO архивирования файловой системы и перестройки ядра у меня наконец-то есть рабочая файловая система в initramfs, которая будет загружаться ядром.

+1. это сэкономило мне часы работы!
(Продолжение вышеупомянутого комментария) Источники:Documentation/filesystems/ramfs-rootfs-initramfs.txt (^ F "134") иusr/gen_initramfs_list.sh (^ F «консоль» - это заглушка initramfs).
devtmpfs.mount = 1 может быть полезно для более новых ядер или включить CONFIG_DEVTMPFS_MOUNT
В Linux 3.17 я обнаружил, что толькоconsole это единственное устройство, которое мне нужно было иметь на/dev на initramfs, но YMMV.
Explanation/Notice!! Linux always creates an initramfs. When you do not specify your own, it creates a tiny stub one (~134 bytes). This stub initramfs contains the /dev/console device. So, if you switch from an external initramfs to a built-in one (который не содержит/dev/console), you will see this message. Альтернативное исправлениеnot встраивать/dev/console ноmkdir /dev; mount /dev -t devtmpfs dev в вашем/init.

Похожие вопросы