開機管理員我一直偏好用 extlinux 因為它的設定比 grub 簡單, 錯誤訊息也很清楚, 採用 UEFI模式從硬碟或隨身碟開機 也沒有問題。 唯一的問題是: 想要用 extlinux 做 UEFI 版的 iso 開機映象檔, 卻一直失敗。 看了 這一頁比較表, 決定試試看 rEFInd。 成功的用它製作 g22B 版的貴哥實驗室 iso 檔, 趕快筆記大推一下。 注意: rEFInd 只有 64 bit 版, 沒有 32 bit 版!
一、 把 refind 安裝在隨身碟上
第一個重點是: 不要用 debian 系列提供的套件。 不知道為什麼, 用 apt install refind 安裝的版本一直失敗。
- [2024/3] 保護好你的 UEFI 的 nvram!
- [2024/3] 到 官網 下載最新版 (我下載的是 refind-bin-0.14.0.2.zip ) 並解壓縮。 如果你下載的是 .deb 版, 而且你的 debian 系統較舊, 那就可能需要 把新版 zst 壓縮改成舊版 xz 壓縮。
- 下載我打包的 refind-example.tgz 並且在隨身碟的根目錄解壓縮。 其中最重要的就是 EFI/BOOT/startup.nsh 跟 EFI/BOOT/refind.conf 兩個文字檔, 以及 EFI/BOOT/bootx64.efi 這個二進位檔 (其實就是官網版解壓縮裡面的 refind/refind_x64.efi )
- 把官網版解壓縮裡面的 refind/icons/ 子目錄也整個 copy 到 EFI/BOOT/ 底下。
- 下載 CorePure64、 slitaz-rolling-core64、 grml64-small 等等幾個 iso 檔其中至少一個, 都必須選 64 bit 的版本。 幫每個 distro 在隨身碟的根目錄底下各自建一個獨立的目錄, 並且把各自的最重要兩個或三個檔案複製過去。
最後隨身碟上面的檔案長得像以下這樣。 其中比較大的幾個二進位檔, 我列出他們的 md5sum 前6位, 方便檢查確認。 又, grml64-small.squashfs 被我改名為 root.squashfs 。
V ./EFI/BOOT/startup.nsh V ./EFI/BOOT/refind.conf f4fab7 ./EFI/BOOT/bootx64.efi ./EFI/BOOT/icons/arrow_left.png ./EFI/BOOT/icons/arrow_right.png ./EFI/BOOT/icons/boot_linux.png ./EFI/BOOT/icons/... ./EFI/BOOT/bg/alien-city.jpg ./EFI/BOOT/bg/... ab7181 ./core/vmlinuz64 3bf1a8 ./core/corepure64.gz a575a4 ./slitaz/bzImage64 b4c21b ./slitaz/rootfs.gz afd887 ./grml/vmlinuz 49e7ef ./grml/initrd.img c38c97 ./grml/root.squashfs
然後就可以 用 kvm 開 uefi 虛擬機測試 啦!
設定檔 refind.conf 裡面的 log_level 1
這一句的目的是要在 bootx64.efi
的同一目錄底下產生 log 檔 refind.log、 協助除錯。
例如我曾經試著用 refind 啟動 32bit 版的 core linux 跟 slitaz,
就是靠著這個 log 檔裡面抱怨 「invalid loader file」 之類的訊息而發現問題的。
要注意的是: 開機失敗之後所產生的 log 檔採用 utf16 編碼, 所以必須這樣閱讀:
iconv -f UTF-16LE -t UTF-8 refind.log
。
成功開機之後, 可以把 log_level 1
那一句註解掉或是改成
log_level 0
。
其實也可以省略設定檔裡面的各個 menuentry, 把子目錄裡面的 drivers_x64/ext4_x64.efi 連同子目錄 一起複製到 EFI/BOOT:
... f4fab7 ./EFI/BOOT/bootx64.efi 81b517 ./EFI/BOOT/drivers_x64/ext4_x64.efi ...
如此 refind 便會自動尋找每個 ext4 分割區上面某些特定目錄底下所安裝的 linux。 不過官網建議: 沒打算用到的檔案系統驅動程式最好不要複製過來, 以免浪費開機偵測時間, 甚至造成當機。 因為我現在都把系統根目錄放在 btrfs 的 subvolume 裡面, 覺得 refind 不太可能找得到 (還沒測試過) 所以還是習慣只用寫死的 menuentry 比較清楚簡單。
二、 把 refind 安裝在 .iso 映象檔裡
再來就拿 grml64-small_2021.07.iso 作練習, 把它原本 (內含 EFI 版 grub boot loader) 的 boot/efi.img 換掉。 請先檢視 vmlinuz 跟 initr.img 的大小, 自行決定要留多少空間(例如60M?)給映象檔。 以 root 的身份:
fallocate -l 60M refind.img mkfs -t vfat refind.img mount refind.img /mnt/t1 cp ... /mnt/t1 umount /mnt/t1
其中 cp 那一句代表要複製以下檔案:
V ./EFI/BOOT/startup.nsh V ./EFI/BOOT/refind.conf f4fab7 ./EFI/BOOT/bootx64.efi ./EFI/BOOT/bg/alien-city.jpg ./EFI/BOOT/icons/arrow_left.png ./EFI/BOOT/icons/... 49e7ef ./grml/initrd.img afd887 ./grml/vmlinuz
而 refind.conf 的內容如下:
timeout 20 banner bg/alien-city.jpg menuentry "grml to RAM" { icon /EFI/BOOT/icons/os_grml.png loader /grml/vmlinuz initrd /grml/initrd.img options "boot=live live-media-path=/live/grml64-small/ toram=grml64-small.squashfs ignore_bootid" }
最後把 refind.img 包進 iso 檔裡面:
export GRML_PATH=...
export OUT_PATH=...
cp refind.img $GRML_PATH/boot/
xorriso -as mkisofs -o $OUT_PATH/grml64-new.iso -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin -eltorito-alt-boot -e boot/refind.img -no-emul-boot $GRML_PATH
其中 $GRML_PATH 子目錄底下包含的就是從 grml64-small_2021.07.iso
裡面 copy 過來的所有檔案。 或是也可以採用
overlayfs 的方式, 在原始的 iso 檔上面架一層薄薄的可寫檔案系統。
如果這樣測試: kvm -m 2048 -pflash /usr/share/qemu/OVMF.fd
-cdrom $OUT_PATH/grml64-new.iso
就會看到 refind 的開機選單;
如果這樣測試: kvm -m 2048 -cdrom $OUT_PATH/grml64-new.iso
則會看到原始的 isolinux 的開機選單。
特別注意: UEFI 光碟的開機途徑必須有自己的 vmlinuz 與 initrd.img 放在 refind.img 裡面, 因為 refind 的程式碼看不到外面對應的這兩個檔案。 至於作為 root file system 的 *.squashfs 則是由 initrd.img 所載入的, 所以只需要放一份。 我把 drivers_x64/iso9660_x64.efi 加到 refind.img 裡面去, 仍舊無法看到外面的這幾個開機檔案。 沒關係, 至少現在已經知道如何客製化 UEFI 開機光碟了, 耶!
沒有留言:
張貼留言
因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。