直接從 UEFI 啟動內核

直接從 UEFI 啟動內核

我想直接從 UEFI 啟動 Arch Linux。

我的想法是使用該工具建立啟動項efibootmgr;我使用了這個指令:

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

我跟著EFISTUB 上的 Arch Wiki 頁面我創建了該條目,但是當我嘗試從該條目啟動時,系統在很早的階段就陷入啟動狀態,並顯示以下訊息:

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

PS:我想把它當作緊急/救援工具;即最新的systemd升級破壞了啟動管理器(systemd-boot),使我的機器無法使用;借助外部即時 USB,我能夠恢復我的系統。我想以後避免這種情況!


更新:
1. 有或沒有/斜杠或反斜杠,之前initrd並不重要
2.嘗試同時使用UUIDand PARTUUID,沒有任何變化
3. my /bootis on /dev/sda1while4./dev/sda3
也是/bootESP

    # 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 (是否可以?)。無論如何,我有:

    • 從下載了一份天諾核心
    • 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-stub 的核心仍然不是一個裝載機。要從 BIOS 啟動,它必須是 EFI-應用。所有引導程式都有 .EFI 後綴。我認為可以將核心變成這樣一個直接可引導的對象,但通常它是啟動的引導程式之一(提供或不提供選擇)。

但你可以使用UEFI外殼(在現代系統上)作為互動式引導程式。這非常適合測試。你像BIOS中的啟動設備一樣啟動它,cd也就是fs0:ESP,然後你就可以

fs0:> bzImage root=/dev/sda3 

幾天前我剛編譯了第一個bzImage。首先,我忘記了 CONFIG_EFI_STUB 並且 UEFI shell 將核心視為非二進位。第二個版本確實啟動了,但沒有任何 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 提示符fs0:>,但我發現所有常用的發行版都有 EFI_STUB 內核,而且名稱根本不重要。最常見的是「vmlinuz」(= 圍繞壓縮的 vmlinux 的載入程式)。

如果您保留“.efi”和“console=”選項,則留下:

fs0:> bzImage root=/dev/sda4

這是相同的最小引導命令,除了我有sda3: Uefi Shell 透過 啟動 bzImage stub,核心被解壓縮並啟動,內建模組識別 SATA 磁碟。如果root=設備無效,您就會感到VFS: unable to mount恐慌。


我無法像 grub64.EFI 那樣直接從 BIOS 啟動 bzImage(或 vmlinuz,或...)。


UEFI - 應用程式(維基百科):

除了載入作業系統之外,UEFI 還可以運行 UEFI 應用程序,這些應用程式會作為檔案駐留在 EFI 系統分割區上。它們可以從 UEFI 命令 shell 執行,透過韌體的啟動管理器,或其他 UEFI 應用程式。 UEFI 應用程式可以獨立於系統製造商進行開發和安裝。

UEFI 應用程式的一種是作業系統載入程序,例如 GRUB、rEFInd、Gummiboot 和 Windows Boot Manager;它將作業系統檔案載入到記憶體中並執行它。此外,作業系統載入程式可以提供使用者介面以允許選擇另一個要執行的 UEFI 應用程式。 UEFI shell 等實用程式也是 UEFI 應用程式

這證實了我的觀點,即 UEFI Shell 位於韌體引導程式和核心之間。


Gentoo也有類似的例子;他們堅持用 .EFI 後綴命名核心。

如果由於某種原因需要 initramfs,它可以嵌入到核心中或用作單獨的檔案。

然而,一些 UEFI 實現好像不支援傳遞參數從 NVRAM 到 EFI 存根核心。

答案2

似乎某些具有舊 UEFI 韌體的舊機器不會將命令列參數傳遞給 EFI 二進位(例如啟用 EFISTUB 的 Linux 核心)。這使得在啟動時無法將諸如root=和 之類的重要參數傳遞initrd=給核心。

我使用了完全相同的過程直接從 UEFI 啟動核心(具體來說,是在https://wiki.debian.org/EFIStub,但我實際上是在兩台不同的機器上的 Ubuntu 上進行的。在我用了三年的華擎主機板上,它運作得非常完美。在我用了 11 年的戴爾筆記型電腦上,它只是忽略內核命令列參數。

因此,如果您的韌體不支援命令列參數,您可能會運氣不好。我將繼續嘗試,如果我找到解決方法,我將發布後續內容。

相關內容