建構USB 多系統開機碟-01_使用 Grub2

其實去年初就曾利用過年期間玩了下在 USB 隨身碟安裝與設定多系統啟動。不過當時都是在 Windows 7 環境下設定的,且偏以可驅動的 Live OS ISO 檔 (如 WinPE、Puppy Linux),以及工具碟為主。(當時研究心得可參考文後「延伸閱讀」的鏈結。)

因為今年我設定了要利用閒暇時間學習 Linux 的底層架構,也包括了學習使用 C++ 的程式撰寫@Linux 的目標;同時我也希望出外時可以只帶 USB 碟,內裝了我可以上網瀏覽、文書處理、開發環境等的行動平台,所以安裝套較輕量如 Puppy Linux,並可以把變動永續 (persistent)寫入到 USB 隨身碟內,而不僅只是 Live 那種唯讀而已。

經過兩三天的實作設定,終於可以作到:

  • 在 USB 碟切割多個磁區 (partition)。
  • 安裝 Arch Linux 於某一磁區,且可以啟動與寫入變動等。
  • 可驅動 Puppy Linux ISO 檔,並且可以將所有操作的變動寫回 USB 磁區內。
  • 可利用 Grub2 驅動各磁區的系統,包括上述 Arch Linux、Puppy Linux、各類 Live ISO 檔 OS等。

我想就對上述的列表,個別整理成主題,來分享下關於實作的心得與個人的註記備忘。本篇就先針對如何安裝 Grub2 於 USB MBR 以及基本的 grub.cfg 設定。同時注意下以下的設定僅先針對 Legacy BIOS 環境下,而並針對 EFI 環境,不過設定仍為類似的步驟。

準備 USB 隨身碟

最好使用 32G 以上空間的隨身碟,USB 2.0 or 3.0 均可。我自己是使用這款 Super Talent USB3.0 64GB 讀速130M隨身碟(終保),當時是買來要玩暗黑3,但現在已不玩該遊戲。
USB 3 隨身碟

準備 Grub2 安裝與設定環境所使用的 Host 系統

使用 Grub2 的原因是現今主流 Linux OS 均支持新一代的開機管理程式,而且它可以支持從 MBR (Legacy) 或 EFI (Advance) 開機啟動,且可以驅動多種檔案系統與多類型的 OS,彈性極大。

要將 Grub2 寫入到 USB 開機區,需要準備已安裝有 Grub2 程式的主機 (Host)環境。以前我是使用 Windows 7 環境,不過後來發現到使用 Linux 系統並使用命令列模式來設定,反而較簡單。

關於如何在 Windows 環境下建置 Grub2,可以參考這一篇:
 o [分享] Windows定製Grub2(包括BIOS和UEFI、自定義Grub2路徑)

而個人所使用的作業環境則為 Arch Linux,因為它的 Grub2 設定文件整理得很好,容易找到相關的參考文件。

我是安裝 Arch Linux 於 Vmware 虛擬機上,如此相對方便設定與測試。關於如何安裝 Arch Linux 於 Vmware/Virtual Box 等虛擬機器內,有太多文章可以參考,例如底下這篇就寫得相當好:
 o A Guide to Installing Arch in VirtualBox。

規劃 USB 磁區 (partition)

我這條 USB 碟是 64G,目前是規劃了3個磁區,參考下圖:
USB 磁區分割情形

/dev/sdb1 檔案系統為 fat32 (20G)。這個磁區設定為預設啟動 (Active)磁區,並且要格式化為 fat32,如此才能被 Grub2 找到;同時我是把從 Puppy ISO 解開的檔案結構放置於同一磁區內,如此方便開機啟動且可將變更寫回該磁區內 (另篇文章會討論 Puppy Linux 的永續性@USB碟 的設定)。

/dev/sdb2 檔案系統為 ext4 (18G)。我是把所有的 Live OS 的 ISO 檔全放置於此;其實也可以考慮格式化為 fat32,這樣方便在 Windows 系統複製 ISO 檔於該分區內。

/dev/sdb3 檔案系統為 ext4 (16.7G)。該分區主要是當成硬碟區 (USB-HDD)看待,並且把 Arch Linux (未來會成為我在 Linux 撰寫程式的主力系統)安裝於此分區內。

切割與格式化 USB 磁區

在 Windows 環境下切割 USB 磁區的工具,莫過於 Bootice 這個利器。它不僅可以切割磁區,還支持各種開機啟動管理程式 (當然有 Grub2)寫入至 MBR 開機區內。

關於 Bootice 的使用教學以及漢化版下載,可以參考這篇:
 o 【BOOTICE: 啟動維護工具】。

至於在 Arch Linux 下,要切割 USB 開機磁區更是簡單的事。首先檢查下 USB 碟的裝置名稱 (一般應會是 /dev/sdb)。

# lsblk -f

然後使用 cfdisk 指令切割磁區 (參考各安裝文件即有說明):

# cfdisk /dev/sdb

然後進行對各分區的格式化 (format):
在 Arch Linux 先確定有安裝便於格式化 fat/fat32 的工具:

# pacman -S dosfstools

對各分區進行格式化:

# mkfs.vfat -n "volumn name" /dev/sdb1

注意將 USB 碟的分區格式化為 ext4,最好不要有日誌資訊 (jounal),以避免 USB 碟 (SSD 硬碟亦然)過度頻繁的寫入。

# mkfs.ext4 -O "^has_journal" -L "volumn label" /dev/sdb2
# mkfs.ext4 -O "^has_journal" -L "volumn label" /dev/sdb3

安裝 Grub2@Arch Linux

所有相關 Grub2 在 Arch Linux 環境下的安裝與設定,必要的參考官方文件:
 o GRUB2 (正體中文)。

首先 Host 環境 (Arch Linux)要先安裝 Grub2 (for legacy Bios)套件:

# pacman -S grub-bios

安裝 Grub2 至 USB MBR 開機區內

一定要仔細看下這段的設定:#安裝到440位元組MBR啟動區(Install_to_440-byte_MBR_boot_code_region)

我這裡耗了好幾個小時 Try Error,才發現到 grub-install 指令需要加上 --boot-directory 參數,指定要將 Grub Image 寫入到所指定的分區與其目錄內。

我的 Grub2 啟動選單放置於 /dev/sdb1 分區下,所以要先 mount 該分區:

# mount /dev/sdb1 /mnt

然後執行 (只要這兩行即可,多語系檔案會自動複製):

# modprobe dm-mod
# grub-install --boot-directory=/mnt --target=i386-pc --recheck --debug /dev/sdb

安裝完成後,可以檢查啟動分區內是否已新增 /grub 資料夾,並在其內已有下列檔案結構:
Grub2 啟動區的目錄結構

編輯設定 grub.cfg

這一段最麻煩,能否正常啟動位於各分區內的各類 OS,設定內容的正確與否才是最關鍵的。

如何從無到有產生 grub.cfg,可以參考這一段文:
 o 2.1.4 產生GRUB2 BOIS設置檔案(Generate GRUB2 BIOS Config file)。

不過我不喜歡這樣的方式,內容很亂。可以自行從網路找一些 Grub2 的設置檔範本,然後再慢慢「刻」。只是這樣就需要時常查找許多參考文件了。

這裡我先提供一個可以引導 Arch Linux ISO 傳統的 Live OS 啟動的範本:

set SYS_UUID=6AED-F2C3
set ISO_UUID=8973f18b-83ac-4765-9242-a180598af39b
set HDD_UUID=a63bcc35-aabd-4be6-894c-6d9b3e25a6f4
 
if [ -s $prefix/grubenv ]; then
  load_env
fi
if [ "${next_entry}" ] ; then
  set default="${next_entry}"
  set next_entry=
  save_env next_entry
  set boot_once=true
else
  set default="0"
fi
 
if [ x"${feature_menuentry_id}" = xy ]; then
  menuentry_id_option="--id"
else
  menuentry_id_option=""
fi
 
export menuentry_id_option
 
if [ "${prev_saved_entry}" ]; then
  set saved_entry="${prev_saved_entry}"
  save_env saved_entry
  set prev_saved_entry=
  save_env prev_saved_entry
  set boot_once=true
fi
 
function savedefault {
if [ -z "${boot_once}" ]; then
  saved_entry="${chosen}"
  save_env saved_entry
fi
}
 
function load_video {
if [ x$feature_all_video_module = xy ]; then
  insmod all_video
else
  insmod efi_gop
  insmod efi_uga
  insmod ieee1275_fb
  insmod vbe
  insmod vga
  insmod video_bochs
  insmod video_cirrus
fi
}
 
set menu_color_normal=light-blue/black
set menu_color_highlight=light-cyan/blue
 
if [ x$feature_default_font_path = xy ] ; then
  font=unicode
else
  insmod part_msdos
  insmod ext2  
  search --no-floppy --fs-uuid --set=root $SYS_UUID
  font="/grub/fonts/unicode.pf2"
fi
 
if loadfont $font ; then
  set gfxmode=auto
  load_video
  insmod gfxterm
  set locale_dir=$prefix/locale
  set lang=zh_TW
  insmod gettext
fi
terminal_input console
terminal_output gfxterm
set timeout=30
 
menuentry "Arch Linux Live ISO" {
  insmod ext2  
 
  set isofile="/archlinux-2015.03.01-dual.iso"  
  loopback loop (hd0,2)$isofile
  # echo "Loopback iso file: $isofile"
 
  linux (loop)/arch/boot/x86_64/vmlinuz archisolabel=ARCH_201503 img_dev=/dev/disk/by-uuid/$ISO_UUID img_loop=$isofile earlymodules=loop
 
  echo 'Loading Linux core repo kernel ...'
  initrd (loop)/arch/boot/x86_64/archiso.img
}

上述範本的設定中,最關鍵的地方在於 uuid 的設定。也就是說,每一個 USB 碟的分區都有各自一個唯一的識別號碼;使用該號碼會比使用如 /dev/sdXX 這樣的裝置名稱更能正確找到該分區,因為需要考量的是 USB 會隨時插入各硬體主機內,如此就不一定有一個唯一的裝置名稱,但 UUID 則經格式化後則是唯一的。

使用 lsblk -f 或 blkid 可以查到 USB 碟各分區的 UUID。
USB 碟各分區的 UUID

再來注意的是,因為我的 Arch Linux ISO 檔是位於 ext4 格式的磁區內 (/dev/sdb2),Grub2 要引導到該磁區必須下達「insmod ext2」 陳述,以事先載入 ext2 模組 (可以辨識 ext2,3,4 格式)。

測試從 USB 開機啟動 Arch Linux Live ISO

每次設定好若都要重啟電腦那豈不是超麻煩? 可以下載 Plop Boot Manager,然後利用 Vmware 啟動,它即會顯示從 CD-ROM 或從 USB 碟開機的選項,並且它同時有支援 BIOS/EFI 的開機模式。(「延伸閱讀」我的第二篇文章有說明如何使用 Plop@Vmware)

從 Arch Linux 的下載區下載最新版的 ISO 檔,然後複製至存放 ISO 檔案的 USB 分區 (我放在 /dev/sdb2)

執行 Plop Boot Manager,選擇 USB 開機,啟動後的 Grub2 開機選單畫面:
Grub2 BootManager from USB Flash Disk

※ 延伸閱讀
 o [實作筆記] 製作 USB 多系統雙啟動開機碟-01
 o [實作筆記] 製作 USB 多系統雙啟動開機碟-02

文章導覽

   

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。