Linux 上製作多啟動 U 盤

KZ25T發表於2024-06-26

Linux 上製作多啟動 U 盤

方法一 Ventoy

參考官網

方法二 手動安裝 grub 後分別分割槽

我本人也曾經長期使用過 Ventoy,這個工具對於新手來說確實容易上手,而且工具功能豐富。不過隨著探索的深入,我現在也不是很喜歡 Ventoy,原因可能有很多,比如說工具複雜、原始碼看不懂一點(因為我菜)、想要自己看看什麼樣的配置能完成多啟動 U 盤的構造,畢竟在前 Ventoy 時代的人的做法似乎已經幾乎在網際網路上失傳。而且我感覺 Ventoy 的做法看起來不太美觀,我自己想 keep it simple,當然我認為對於大部分人來說,使用 Ventoy 仍然是一個最方便、穩妥、好用的選擇。

系統環境

你需要一臺 x86_64 的電腦,安裝有 Linux 作業系統。

準備啟動 iso

這裡的啟動 iso 包括 Windows PE、Linux Livecd、Linux 安裝 CD(其實也是 Livecd)等。我準備的包括:

首先是 Windows PE,市面上的 Windows PE 很多,功能類似,但映象目錄結構好像千差萬別。甚至有的用 windows boot manager 管理啟動,有的用 grub 管理啟動(這裡什麼 grub1 grub2 grub4dos 的我都見過),我也沒做過,也不懂。我準備了現在比較常用的微PEFirPE,他倆下載之後都是 exe 檔案,選擇生成 iso 之後得到兩個 iso 檔案,就是 PE 映象。

其次是 Linux livecd,這個就簡單了,因為我做過(可以參考我的製作方法),而且都是 grub 引導。這裡我用的是我自己做的 livecd,別的沒測試過,但我感覺應該都沒問題。

前兩個 win PE 的 iso,一個是 udf 檔案系統,一個是 iso9660 檔案系統;一個是 windows boot manager 引導,一個是 grub1 引導,不過最後還是都啟動成功了。

另外還要計算每個 iso 的大小,可以用 ls -l 檢視之後算出有多少 MB(1024進位制),向上取整。

U 盤分割槽

如果你的 U 盤是空白 U 盤,或者內容都不要了,那麼執行

sudo gparted

啟動之後刪除你的 U 盤上的分割槽,新建分割槽。如果有 N 個 iso,那麼需要新建 N+1 個:

  • 第一個分割槽:fat32 格式,建議幾十到幾百 MB,用於安裝 grub
  • 後邊的分割槽,按照上文算出的 MB 數分割槽,分割槽格式選已清空或者未格式化(其實怎麼選都行)

如果 U 盤有資料,那麼需要在 gparted 裡擠出來一部分空間(前後都行)使得至少能完成前文所述的分割槽。當然,安裝 grub 的分割槽也不一定是第一個,注意下面的掛載即可。

另外,如有需要,比如 U 盤剩餘空間做常規儲存空間,那麼也可以新增別的分割槽。

(我這裡 sda3 是用來存放其他資料的)

調整之後點選對鉤完成更改。

燒錄 iso

把幾個 iso 分別燒錄到每個分割槽:

sudo dd if=debian.iso of=/dev/sda2 status=progress
sudo dd if=wepe.iso of=/dev/sda4 status=progress
sudo dd if=firpe.iso of=/dev/sda5 status=progress

然後 gparted 就會變成這樣:

檢視各個檔案系統

每個燒錄了 iso 分割槽的 U 盤,分別檢視其引導檔案。

對於 windows 來說,一般是 /boot/efi/bootx64.efi;對於 linux 來說,一般是 /boot/efi/grubx64.efi,但也可能有不一樣的,比如大小寫不一樣,這種時候需要自己試試。

# 對每個 iso 的分割槽執行類似的操作
sudo mount /dev/sda2 /mnt/mobile # 掛載點自選
ls /mnt/mobile/boot/efi/grubx64.efi # 嘗試找找有沒有這樣的檔案,並且記下來此時的路徑
sudo umount /mnt/mobile

然後使用 blkid 命令檢視各個分割槽的 uuid;

經過測試,我的三個 iso 的啟動檔案分別是:

Debian Live       UUID: 2024-02-24-22-40-00-00   /EFI/boot/grubx64.efi
WEPE              UUID: xxxxx                    /EFI/BOOT/bootx64.efi
FirPE             UUID: xxxxx                    /efi/boot/bootx64.efi

安裝、配置 grub

安裝 grub:

sudo mount /dev/sda1 /mnt/mobile # 最後一個掛載點自己選
sudo mkdir /mnt/mobile/boot
sudo mkdir /mnt/mobile/EFI
sudo grub-install --target=x86_64-efi --removable --boot-directory=/mnt/mobile/boot --efi-directory=/mnt/mobile /dev/sda # 記得檢查有沒有報錯

配置:

sudo touch /mnt/mobile/boot/grub/grub.cfg
sudoedit /mnt/mobile/boot/grub/grub.cfg

檔案內容為:

insmod all_video
insmod gfxterm
insmod chain
menuentry "Debian Live" {
    search --fs-uuid --set=root 2024-02-24-22-40-00-00
    chainloader /EFI/boot/grubx64.efi
}
menuentry "WEPE" {
    set root=(hd0,gpt4)
    chainloader /EFI/BOOT/bootx64.efi
}
menuentry "FirPE" {
    set root=(hd0,gpt5)
    chainloader /efi/boot/bootx64.efi
}

需要注意的是:

  1. 經過我的嘗試,那倆 windows PE 的 UUID 在 grub 裡是讀取不到的,而且 label 貌似也有問題,總之就是嘗試各種辦法也沒能找到什麼好的設定 root 的辦法,於是只能硬寫 root 為分割槽編號了。分割槽編號可以在 grub 介面進入 grub 命令列輸入 ls 檢視到。

  2. 如果有多個 linux livecd,不能直接用 chainloader:

    man live-boot
    

    可以發現,即使有多個 livecd,系統啟動尋找根檔案系統時並不會按照 grub 裡 root 的位置尋找,而是挨個尋找各個分割槽。所以這時候需要找到每個 livecd 的 grub 的啟動引數:

    sudo mount /dev/sda2 /mnt/kali
    cat /mnt/kali/boot/grub/grub.cfg
    # 找到 grub 裡每個啟動項 linux 那一行的啟動引數,比如
    menuentry "Kali Live" --hotkey=l {
            linux   /live/vmlinuz boot=live components quiet splash noeject findiso=${iso_path}
            initrd  /live/initrd.img
    }
    

    那就需要給啟動引數加上 bootfrom=/dev/sdXY 指定啟動分割槽在哪,由此寫入 U 盤啟動分割槽的 grub 裡:

    menuentry "Kali Live" --hotkey=l {
            search --fs-uuid --set=root xxxx-xx-xx-xx-xx-xx-xx-xx
            linux   /live/vmlinuz boot=live bootfrom=/dev/sda2 components quiet splash noeject findiso=${iso_path}
            initrd  /live/initrd.img
    }
    

    才能正常啟動。

chainloader 真是好東西,後邊的東西記得按照自己之前搜尋到的檔案目錄進行配置。萬能引導器果然萬能,甚至可以用 grub2 引導 grub1,grub2,grub4dos,windows boot manager。

配置完成之後解除掛載

sudo umount /mnt/mobile

重啟按照你的電腦配置,選擇 USB 啟動即可使用這些 iso 映象。

相關文章