2020年10月13日 星期二

十分鐘開始測試 UEFI 救命碟

原來製作 UEFI 版開機隨身碟完全不需要什麼特殊安裝動作, 只要把檔案放對位置就可以了! [2022/9/22] 請參考 在 Windows 底下製作 UEFI 版 「貴哥實驗室」 開機隨身碟。 急著測試的話, 可以暫時先省略 iso 檔的部分, 只下載並且 在隨身碟的根目錄 解壓縮 g???-?-uefi-boot-files.tgz 開機相關檔案。 重開機、 按某個鍵進入 UEFI 的開機選單。 在選單裡若看到 「你的隨身碟廠牌名稱」 跟 「UEFI 你的隨身碟廠牌名稱」, 則此時選擇有 UEFI 的那個選項, 應該就可以看到 extlinux.conf 的選單。 如果照著那篇完成 iso 檔案的部分, 下次就可以完整開機。

還可以進一步用 mbootuz.py mkboot /dev/sdx 幫隨身碟安裝 MBR 版的 extlinux, 再重新解一次 uefi-boot-files.tgz 裡面的 boot/syslinux/extlinux.conf 設定檔、 把其中所有的 "-5.4.0-42-generic" 通通刪掉。 那麼你的隨身碟就可以從上述 (有 UEFI 及沒有 UEFI 的) 兩個不同選項開機。 從 MBR 版 (沒有 UEFI) 開機時, 開機選單的背景圖是朝陽空拍圖。 [現在很少人在用 legacy boot 了]

如果不想重開機, 也可以先用 kvm 的 uefi 功能測試。 要先安裝 ovmf 套件。 然後: kvm -m 2048 -pflash /usr/share/qemu/OVMF.fd -hda /dev/sdx 。 測試 ovmf 版的 kvm 時, 如果失敗, kvm 有可能會試著從網路開機, 浪費很多時間。 此時可以:

  1. 在 kvm 命令列上加上 -boot order=c 指定直接從模擬的硬碟 (hda) 開機
  2. 或是在 kvm 命令列上加上 -boot menu=on 然後把握三秒鐘的機會按 ESC 進入韌體再進入開機選單
  3. 或是 -net none 略過網路開機的久等步驟。

也請參考 詳盡的 ovmf 相關選項使用說明 較簡短的這一篇 可略過編譯部分。

* * * * *

接下來重點條列解釋:

  1. 隨身碟可以採 MBR 分割 (type id: c) 或 GPT 分割 (type id: ef00) ; 一定要採用 fat 格式化: mkfs -t vfat /dev/sdx1
  2. 大部分的 UEFI 板子開機時應該要去找隨身碟上的 /EFI/BOOT/startup.nsh 這個 script (文字檔) 來執行。 有點像是古代 DOS 的 autoexec.bat 。
  3. 如果沒有 startup.nsh 的話, 所有的 UEFI 板子應該都會去找隨身碟上的 /EFI/BOOT/BOOTX64.EFI 這個可執行檔來執行。
  4. 可是 kvm 虛擬機的 ovmf 模式並不會自動執行 BOOTX64.EFI 而是會自動進入 UEFI shell 命令列模式。 所以最保險的方法就是在 startup.nsh 裡面簡單寫一句 BOOTX64.EFI 以確保不論由哪一個 UEFI 系統開機, 都會自動執行 BOOTX64.EFI 。
  5. 上述下載檔案中的 BOOTX64.EFI 其實就是 syslinux-efi 套件當中的 /usr/lib/SYSLINUX.EFI/efi64/syslinux.efi 。 /EFI/BOOT/ 目錄裡的其他檔案, 除了圖片與設定檔之外, 其他都來自 syslinux-common 套件當中的 /usr/lib/syslinux/modules/efi64/ 。
  6. 有些 UEFI 板子還會有一個 「進入開機裝置所提供的 UEFI shell」 的選項, 會去執行隨身碟根目錄的 shellx64.efi 。 從 tianocore 官網底下的 這裡 下載來的。 有了這條路, 萬一出問題, 至少還可以手動啟動 fs0:\EFI\BOOT\BOOTX64.EFI , 詳見 這一頁英文 的 「bootloader manually」 那一段、 這一頁簡中 出現很多 「fs0:」 的那一段、 或是較好閱讀的 英文部落格文章。 (目前我只曾在 kvm 的 ovmf 模式下用過這招)
  7. 在 UEFI shell 裡面, 檔名沒分大小寫、 路徑分隔符號是 \ 而不是 / 、 檔案名稱長度有限 (但限制是多少? 不知道)、 不能用 symbolic link。 這逼得我只好把 vmlinuz-5.4.0-42-generic 改名為 vmlinuz 、 把 initrd.img-5.4.0-42-generic 改名為 initrd.img。

再來很重要的一點。 有些文件提到 efibootmgr 指令 (在 debian 系列下, 請安裝同名套件)。 但是... 因為它的主要功能是修改 UEFI 韌體的開機選單, 也就是說會去讀寫主機板上的 UEFI 的 nvram, 所以想要執行這個指令的前提是: 你必須從 UEFI 開機。 (詳見 這個解答/猜想。) 像我這樣在 BIOS (legacy boot) 的模式下開機研究 UEFI, 當然就無法使用這個指令。 反正想要製作 「到處可以開機的隨身碟」 其實並不需要用到 efibootmgr。

有了以上基本知識, 再來讀以下推薦連結就比較容易懂了:

  1. 最早我從 syslinux 的文件 出發, 但它沒提到 startup.nsh, 所以用 kvm 的 ovmf 時卡關。 直到讀到簡潔有力, 一針見血的 這個問答 時才闖關成功。
  2. 黃明華大大 刊在網管人的中文文章 非常豐富, 但他以 grub2 為主, 而且有點太複雜, 看不太懂。
  3. 很後來才發現 Rod Smith 的 "Managing EFI Boot Loaders for Linux" 系列文章, 循序漸進, 非常詳盡, 大推!

UEFI 模式開機後會出現一個 /sys/firmware/efi 目錄。 另外, 在 眾多支援 UEFI 的開機管理員 當中, Rod Smith 推薦 rEFInd。 這兩個東西, 以後再來研究吧。

沒有留言:

張貼留言

因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。