Загрузка ядра напрямую из UEFI

Загрузка ядра напрямую из UEFI

Я хочу загрузить Arch Linux напрямую из UEFI.

Моя идея — создать загрузочную запись с помощью инструмента efibootmgr; я использовал эту команду:

efibootmgr --create --label "arch-test" --loader /vmlinuz-linux --unicode 'root=PARTUUID=f2083749-8bbc-570b-ab3b-e79d72fa08ac rw initrd=\initramfs-linux.img' --verbose

Я последовал застраница Arch Wiki на EFISTUBи я создал запись, но когда я пытаюсь загрузиться с нее, система зависает на очень ранней стадии загрузки с этим сообщением:

VFS: unable to mount root fs on unknown-block(0,0)

PS: Я хочу, чтобы это работало как аварийный/спасательный инструмент; т. е. последнее systemdобновление сломало менеджер загрузки (systemd-boot), сделав мою машину непригодной для использования; я смог восстановить свою систему благодаря внешнему USB-накопителю. Я хочу ИЗБЕЖАТЬ этого в будущем!


ОБНОВЛЕНИЯ:
1. с косой чертой или обратной косой чертой или без нее, перед этим initrdне имеет значения
2. пробовал и с UUID, и PARTUUID, ничего не меняется
3. мой /bootвключен, /dev/sda1покакореньна /dev/sda3
4. и /bootэто ESP, а также

    # fdisk -l /dev/sda
    [...]
    Disklabel type: gpt
    [...]

    Device         Start       End   Sectors   Size Type
    /dev/sda1       2048   2099199   2097152     1G EFI System
    /dev/sda2    2099200  18874367  16775168     8G Linux swap
    /dev/sda3   18874368 104857599  85983232    41G Linux filesystem
    [...]
    # minfo -i /dev/sda1 :: | grep 'disk type'
    disk type="FAT32   "
  1. после ваших комментариев я попробовалОболочка UEFI. Я оставил этот вариант как последний, так как на моем компьютере нет внутренней оболочки UEFI (Является ли это возможным?). В любом случае, у меня есть:

    • скачал один изтианокор
    • помещён Shell.efiв/boot/EFI/Boot/
    • добавил запись с

      efibootmgr --create --label "TIANO-0" --loader /EFI/Boot/Shell.efi --verbose
      
    • перезагрузился в эту оболочку, набрал fs0:иvmlinuz-linux root=/dev/sda3

    • в результате возникает та же ошибка:

      VFS: unable to mount root fs on unknown-block(0,0)
      
  2. похоже, initrdэто обязательно (по крайней мере для Arch Linux);
    команда vmlinuz-linux initrd=initramfs-linux.img root=/dev/sda3творит волшебство

  3. Моя система — ноутбук Dell XPS 9343, и я обнаружил, что он страдает от ошибки: невозможно загрузить EFISTUB, о которой сообщается в ArchWiki.здесь.
    Я думаю, это объясняетотказ(первой упомянутой) правильной процедуры!
    На странице ArchWiki также предлагается обходной путь, но на данный момент я уже попробовал его.


решение1

   -l | --loader NAME
              Specify a loader (defaults to \\elilo.efi)

Ядро с EFI-заглушкой все еще незагрузчик. Для загрузки из BIOS это должен быть EFI-приложение. Все загрузчики имеют суффикс .EFI. Я думаю, что можно превратить ядро ​​в такой непосредственно загружаемый объект, но обычно запускается один из загрузчиков (с предложением выбора или без него).

Но вы можете использоватьОболочка UEFI(в современных системах) как интерактивный загрузчик. Это идеально для тестирования. Вы активируете его как загрузочное устройство в BIOS, cdв fs0:, который является ESP, и затем вы можете

fs0:> bzImage root=/dev/sda3 

Я только что скомпилировал первый bzImage несколько дней назад. Сначала я забыл CONFIG_EFI_STUB, и оболочка UEFI обработала ядро ​​как недвоичное. Вторая версия загрузилась, без всякого initrd=. Помимо EFI_STUB=y я просто отключил несколько опций и оставил значения по умолчанию.

Но это правда, что большинство дистрибутивов имеют ядра, которые делают этонетесть базовые драйверы блочных устройств — им нужна эта initrd=IMAGEопция.


Я использую Uefi Shell в качестве загрузчика. Это не суперэлегантно, но очень просто и гибко. И как экстренный вариант я думаю, это идеальный вариант, потому что Uefi Shell встроен, а загрузчик на разделе можно удалить.


Это изДокументация/efi-stub.txt

> Passing kernel parameters from the EFI shell
> --------------------------------------------
> 
> Arguments to the kernel can be passed after bzImage.efi, e.g.::
> 
>     fs0:> bzImage.efi console=ttyS0 root=/dev/sda4

У меня тот же Uefi Shell prompt fs0:>, но я обнаружил, что все обычные дистрибутивы имеют ядра EFI_STUB, и имя вообще не имеет значения. Наиболее распространенным является "vmlinuz" (= загрузчик вокруг сжатого vmlinux).

Если убрать опции «.efi» и «console=", то останется следующее:

fs0:> bzImage root=/dev/sda4

Что является той же минимальной командой загрузки, за исключением того, что у меня есть sda3: Uefi Shell запускает bzImage с помощью stub, ядро ​​распаковывается и запускается, а встроенные модули распознают диск SATA. Если устройство root=недействительно, вы получаете эту VFS: unable to mountпанику.


Мне не удалось запустить bzImage (или vmlinuz, или ...) из BIOS напрямую, как grub64.EFI.


UEFI - Приложения (википедия):

Помимо загрузки ОС, UEFI может запускать приложения UEFI, которые находятся в виде файлов на системном разделе EFI. Их можно запускать из командной оболочки UEFI,менеджером загрузки прошивки, или другими приложениями UEFI. Приложения UEFI могут разрабатываться и устанавливаться независимо от производителя системы.

Тип приложения UEFI — это загрузчик ОС, такой как GRUB, rEFInd, Gummiboot и Windows Boot Manager; который загружает файл ОС в память и выполняет его. Также загрузчик ОС может предоставлять пользовательский интерфейс, позволяющий выбрать другое приложение UEFI для запуска. Такие утилиты, как оболочка UEFI, также являются приложениями UEFI..

Это подтверждает мою точку зрения, что UEFI Shell находится между загрузчиком прошивки и ядром.


Похожие примеры есть и в Gentoo: они настаивают на именовании ядра с суффиксом .EFI.

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

...

Однако некоторые реализации UEFIпохоже, не поддерживает передачу параметровиз NVRAM в ядро-заглушку EFI.

решение2

Похоже, что некоторые старые машины со старой прошивкой UEFI не передают аргументы командной строки в двоичные файлы EFI (например, ядро ​​Linux с поддержкой EFISTUB). Это делает невозможным передачу важных параметров, таких как root=и initrd=в ядро ​​во время загрузки.

Я использовал точно такую ​​же процедуру для загрузки ядра напрямую из UEFI (в частности, ту, которая описана вhttps://wiki.debian.org/EFIStub, но на самом деле я делал это на Ubuntu) на двух разных машинах. На моей трехлетней материнской плате ASrock это работало безупречно. На моем одиннадцатилетнем ноутбуке Dell это просто игнорирует аргументы командной строки ядра.

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

Связанный контент