Вопрос или проблема
Я задавал этот вопрос на 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
}
Применение
-
Проверка наличия initramfs: Необходимо убедиться в том, что у вас имеется initramfs, который содержит драйверы для работы с вашим жестким диском:
- Скопируйте initramfs в загрузочную директорию рядом с ядром.
- Включите в конфигурацию GRUB следующую строку:
initrd /путь_к_initramfs
.
-
Корректировка конфигурации GRUB: Вместо явного указания корневого раздела попробуйте использовать команду поиска:
- Обновите конфигурацию GRUB, чтобы использовать:
search --set=root --file /vmlinuz
, что обеспечит динамическое определение раздела.
- Обновите конфигурацию GRUB, чтобы использовать:
-
Компоненты ядра: Проверьте, что все необходимые драйверы для вашего оборудования скомпилированы непосредственно в ядро, а не как модули (необходимо использовать значение "y" вместо "m" в конфигурации ядра).
-
Альтернативный способ чрезмерной зависимости от initramfs: Как было предложено, использование ядра Fedora может быть временным решением для диагностики и устранения причины, так как в его конфигурации могут быть встроены все необходимые модули для работы с вашим оборудованием.
Заключительными комментариями будет рекомендация тщательного рассмотрения конфигурации ядра Yocto и, при необходимости, ее пересборка с учетом специфики вашего оборудования, предотвращая излишнюю зависимость от initramfs.