Изображение Yocto не загружается.

Вопрос или проблема

Я задавал этот вопрос на StackOverflow раньше, но мне сказали, что здесь правильное место для его задавания.

Поскольку я новичок в Yocto, я столкнулся с некоторыми проблемами при попытке загрузить мой intel-corei7-64 core-image-minimal с HDD. Я использовал dd, чтобы записать его на жесткий диск, но при загрузке система останавливается с Kernel panic:

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown block (0,0)

Я попробовал много всего и искал решение. Прежде всего, мне пришлось сделать grub-install и настроить файл grub.cfg в загрузочном разделе, чтобы добавить Image в GRUB, но я не продвинулся дальше этого. На некоторых форумах говорилось, что это означает отсутствие initramfs. Я не думаю, что с образом что-то не так, потому что он работает с USB флешки.

Мой grub.cfg выглядит так:

set default="0"
set timeout="30"

menuentry 'Yocto' {
        insmod part_msdos
        insmod part_gpt
        insmod ext2
        insmod all_video
        set root="(hd0,gpt2)"
        linux /boot/bzImage-4.19.40-intel-pk-standard root=/dev/sda2
}

Будет здорово, если вы поможете мне исправить ошибку загрузки. Я в полном замешательстве на данном этапе.

С уважением

Алекс

bzImage-4.19.40-intel-pk-standard root=/dev/sda2

Это могло бы быть способом запустить из Uefi shell напрямую. Но на самом деле initrd= отсутствует! У меня была точно такая же проблема: модули SATA/SCSI не находятся в ядре, они являются модулями в initramfs (в основном). Скопируйте initrd/initramfs рядом с вашим ядром и добавьте опцию initrd=initram-cpio.gz (адаптируйте имя “image”!) в командную строку.

Ошибка VFS говорит: корень (/dev/sda2), который вы мне дали, находится на блоковом устройстве, которое я не могу прочитать.


После ознакомления с “yocto” я хочу добавить: вы должны настроить необходимые модули как встроенные (“y”), а не как модули (“m”). Таким образом, вам не понадобится initrd, и это, кажется, идея этого “встроенного” проекта.


добавлено после дополнительного изучения yocto…

Это yocto (и ваш вопрос) не оставляли меня в покое. Я нашел это на конференции/статье 2016 года (на lwn.net):

На базовом уровне […] Yocto и Buildroot могут обоих дать
вам тот же конечный продукт: образ файловой системы корня для вашего встроенного
устройства, ядро, загрузчик и совместимую инструментальную цепочку.

Как я вижу, вы скорее хотите использовать “make”, чтобы скомпилировать ядро, плюс модули, плюс initrd, если хотите.

Можете рассказать мне, почему вы написали следующее:

Я использовал dd, чтобы записать [образ ядра] на жесткий диск

Теперь это очень запутывает меня. Как если бы вы сделали dd ... of=/dev/sda. Я бы сказал: я скопировал образ ядра в папку на разделе x.

Итак, вы прошли весь процесс сборки Yocto, bitbaked ядро и initrd, а теперь не знаете, как загрузить ядро Linux?!?


Я начал с нового мини-ПК комплекта, так что диск был пуст. Я решил использовать GPT и Uefi. Мой последний опыт был с MBR давно. Сначала я загрузил установщик Slackware с USB флешки.

С помощью fdisk я сделал несколько разделов, включая тип “EFI” или “ESP”. Я разумно сделал его 2 ГБ. Некоторые рекомендуют всего 100 МБ. ESP требует форматирования в vfat, так как он читается также BIOS.

Единственное (скомпилированное) ядро Linux, которое я нашел, было внутри ISO образов установщиков и живых систем. Из системы opensuse live usb я мог монтировать любой ISO, затем монтировать squashs rootfs с двумя файлами: ядро и initrd.

Эти два файла (ядро и начальный RAM-диск) я скопировал на свой 2 ГБ ESP. Ядро составляет 3 до 8 МБ, initrd 10 до 30 МБ.

Я настроил BIOS для загрузки в Uefi shell, где я могу запустить ядро, вводя его имя как команду Uefi shell.

Все это заняло у меня некоторое время, чтобы выяснить, так что когда я получил kernel panic это было большим успехом.

fs0: vmlinuz

Так я запускаю ядро с именем “vmlinuz” из uefi prompt, из ESP который является “fs0”.

Поскольку root= отсутствует, это должно также вызвать панику. Вскоре я попробовал:

fs0: vmlinuz root=/dev/sda2

И это привело меня к описанной вами kernel panic:

VFS: unable to mount rootfs…

Отсюда вы можете пойти по двум путям: используйте initrd, который “идет вместе” с ядром, добавив initrd=...cpio.gz как опцию KCL (kernel command line). Или используйте ядро Fedora 29 — это было единственное, которое смогло смонтировать мое устройство sda. Причина в том, что оно имеет несколько опций Kconfig встроенными, в то время как все остальные дистрибутивы помещают их как модули в initrd (sata, scsi, sd-mod).

Хотя я весьма доволен быстрой установкой archlinux, я действительно думаю, что “должен” скомпилировать ядро сам, чтобы я мог загружаться без initrd. Ядро должно быть способно монтировать файловую систему корня самостоятельно.

Видите: без компиляции или yocto, без grub, просто углубившись в ISO из дистрибутивов, я смог делать много экспериментов. Это параметры загрузки, которые важны:

initrd=...img

Оригинальная документация ядра от 1996-2000 годов вводит в заблуждение в некоторых местах. Но Almesberger ясно определяет: его initrd “позволяет” процессу загрузки происходить в два этапа. И: скрипт rdinit= внутри RAM-диска может монтировать ‘настоящий’ корень и switch_root к нему. Есть ситуации, когда этот двухэтапный процесс загрузки необходим.

Я следил за “VFS:” kernel panic в исходниках ядра. Функция “prepare_namespace” является ключевой. Эта часть, где ядро монтирует root=, пропускается, когда указывается initrd=; в исходниках содержится комментарий “если есть initrd, пусть она выполнит всю работу”.

root=/dev/xxyy

без initrd=, это указывает ядру прямо в какое (блочное) устройство оно должно “загрузиться”. С initrd его можно использовать для switch_root к нему. root=/dev/ram0 имеет особое значение: это делает начальный RAM-диск реальным корнем с самого начала. Это полезно для многих встроенных систем, я полагаю: rootfs находится в файле cpio и не на разделе.

init=/sbin/init

Это последняя вещь, которую ядро делает при загрузке: вызывает первый процесс. Как и в случае с root=, если вы указываете initrd=, это лежит на RAM-диске, чтобы обработать этот аргумент. Обратите внимание, что ядро может понимать “https://unix.stackexchange.com/” только после того, как root= будет смонтирован.

Как только ваш BIOS переключен на “Uefi shell”, а ваш диск отформатирован как GPT (или имеет гибридный/защитный MBR), и вы добавили маленький (но не слишком маленький) ESP vfat раздел, вы готовы к запуску ядра плюс initrd.

Мой план сейчас заключается в том, чтобы просто скомпилировать ядро, которое сможет монтировать мои стандартные SSD разделы, так что мне не понадобится initrd. Мне не нужны ни yocto, ни grub, чтобы делать какую-то “легкую” встроенность. Если только я не захочу компилировать исходник свежего ядра дважды в месяц… но, хей, я хочу скомпилировать ядро, а не создавать свой собственный дистрибутив!

Я остановлюсь здесь и надеюсь, кто-то сможет получить некоторые идеи о загрузке Linux из моих приключений с параметрами командной строки ядра.

Наконец, мне удалось загрузить мой Yocto Image!

Если у кого-то те же трудности с его загрузкой, вот как я это сделал.

Сначала я сделал grub-install, как обычно, и добавил grub.cfg в /boot/grub/ в разделе EFI (для меня это /dev/sda1). После этого я добавил search --set=root --file /vmlinuz вместо set root=(blabla) в файл grub.cfg. Затем я скопировал vmlinuz из Fedora 30 на мой корневой раздел (/dev/sda2) по совету sam68 и добавил linux /vmlinuz /dev/sda2 в мой grub.cfg. Мне потребовались дни, чтобы дойти до этого момента, так что надеюсь, это поможет кому-то!

Ответ или решение

Для решения проблемы с загрузкой Yocto Image на платформе intel-corei7-64, необходимо рассмотреть несколько возможных причин возникновения проблемы и предложить соответствующие решения.

Теория

Ошибка "Kernel panic – not syncing: VFS: Unable to mount root fs on unknown block (0,0)" указывает на то, что ядро не может найти и смонтировать корневую файловую систему. Это может быть связано с отсутствием initramfs, неправильной конфигурацией загрузчика GRUB или отсутствием необходимых модулей в ядре для доступа к блочным устройствам.

Пример

Вы указали, что образ Yocto успешно загружается с USB-накопителя, но не с жесткого диска. Это может свидетельствовать о проблемах с конфигурацией загрузчика или недостающими модулями для работы с жестким диском. Ваша текущая конфигурация GRUB выглядит следующим образом:

set default="0"
set timeout="30"

menuentry 'Yocto' {
    insmod part_msdos
    insmod part_gpt
    insmod ext2
    insmod all_video
    set root="(hd0,gpt2)"
    linux /boot/bzImage-4.19.40-intel-pk-standard root=/dev/sda2
}

Применение

  1. Проверка наличия initramfs: Необходимо убедиться в том, что у вас имеется initramfs, который содержит драйверы для работы с вашим жестким диском:

    • Скопируйте initramfs в загрузочную директорию рядом с ядром.
    • Включите в конфигурацию GRUB следующую строку: initrd /путь_к_initramfs.
  2. Корректировка конфигурации GRUB: Вместо явного указания корневого раздела попробуйте использовать команду поиска:

    • Обновите конфигурацию GRUB, чтобы использовать: search --set=root --file /vmlinuz, что обеспечит динамическое определение раздела.
  3. Компоненты ядра: Проверьте, что все необходимые драйверы для вашего оборудования скомпилированы непосредственно в ядро, а не как модули (необходимо использовать значение "y" вместо "m" в конфигурации ядра).

  4. Альтернативный способ чрезмерной зависимости от initramfs: Как было предложено, использование ядра Fedora может быть временным решением для диагностики и устранения причины, так как в его конфигурации могут быть встроены все необходимые модули для работы с вашим оборудованием.

Заключительными комментариями будет рекомендация тщательного рассмотрения конфигурации ядра Yocto и, при необходимости, ее пересборка с учетом специфики вашего оборудования, предотвращая излишнюю зависимость от initramfs.

Оцените материал
Добавить комментарий

Капча загружается...