BIOS + GPT + GRUB + Linux + Windows 折騰筆記

其實從標題就能看出來我有多蛋疼了。我不期望還有別的人和我有同樣的奇怪需求,但是希望本文的一部分或幾部分能對部分折騰者有一定有作用。

一、爲什麼會有這樣的需求

要 BIOS 不要 UEFI

雖說現在的主板都採用 UEFI 了;雖說 BIOS 是很古老的東西了……但是,我實在不喜歡 UEFI 的複雜設計。說是 Unified 但是我感覺它一點也不統一。最重要的是:UEFI 對 Linux 不夠友好。

要 GPT 不要 MBR

雖說嚴格來說 GPT 也是 UEFI 的一部分,但是我對它的印象好多了——MBR 只支持 4 個主分區而 GPT 默認情況就能支持 128 個分區,再也不用小心翼翼地折騰擴展分區和邏輯分區——這也是我所討厭的。

要 Steam.exe 不要 Steam.deb

雖然我已經用慣了 Arch Linux;雖然 Valve 也有出 Steam for Linux 甚至 SteamOS,但是至少到目前爲止,畢竟 Windows 纔是正經的玩遊戲的操作系統。

二、BIOS + GPT

2009 年之後的主板基本是 BIOS + UEFI 雙配置,爲了不讓 UEFI 來瞎搗亂,我在主板設置裏會選擇 BIOS Only 以堵死 UEFI 的路。至於 2009 年以前的那些不支持 UEFI 的主板,倒有些需要小心:雖然理論上,只要不是古董電腦,都能支持 GPT,但是有一小部分有問題的 BIOS 會無法從 GPT 啓動。 GPT 的分區工具首選 gdisk,不要用太舊的版本,默認就能 4k 對齊。

三、GRUB + Linux

雖然受到軟件無政府主義的困擾,但是 GRUB 依舊是一款功能強大且十分流行的引導器。本文所指的 GRUB 一律指 GRUB 版本 2,而不是曾經的 GRUB Legacy。 要想讓 BIOS + GPT + GRUB 工作,你需要一個 EF02 分區。由於沒有了 post-MBR gap,這個分區是給 GRUB 放置它的 core.img 的,不需要文件系統。事實上,把 core.img 放在一個單獨的分區裏比放在 post-MBR gap 裏穩定、整潔多了。在 gdisk 裏新建分區時將分區標識符改爲 EF02 即可,大小的話,2 MiB 足夠了。 創建完 EF02 分區之後,其他的分區正常創建即可,比如我這樣:

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048            6143   2.0 MiB     EF02  BIOS boot partition
   2            6144        20977663   10.0 GiB    8300  Linux filesystem
   3        20977664       230692863   100.0 GiB   8300  Linux filesystem
   4       230692864       500117503   128.5 GiB   0700  Microsoft basic data

然後使用 grub-install 即可自動將 core.img 嵌入那個迷你小分區。 至於 Linux 的安裝,無需多言。

四、+ Windows

如無特別說明,以下提到的 Windows 指 NT 內核 6.0 以上版本。本文以 Windows 8.1 爲例。

傲嬌的 Windows

MSDN 明確指出,Windows 只能安裝於 BIOS + MBR 或是 UEFI + GPT 的組合上,而 BIOS + GPT 和 UEFI + MBR 是不允許的。這實在是太傲嬌了——因爲 BIOS + GPT + GRUB + Linux 是完全沒有問題的。事實上,我的筆記本電腦剛安裝的時候並沒有考慮到往硬盤裏灌 Windows,因此之前一直是 BIOS + GPT + GRUB 的配置,在這樣的情況想讓 Windows 入駐,簡直是逼我上梁山…… 爲什麼 MSDN 聲稱 Windows 不能在 BIOS + GPT 工作?經過我的試驗,發現其實只是 bootmgr 讀不了 GPT 而已。直到 bootmgr 被喚醒之前,一切都是沒有問題的,而 bootmgr 應該去讀取 \Boot\BCD 然後再根據 BCD 去加載 \Windows\System32\winload.exentoskrnl.exe。可是 bootmgr 讀不了 GPT,直接導致它找不到 \Boot\BCD…… 那麼怎麼辦呢?

  • 換一個能讀 GPT 的引導器,讀取 BCD 之後正常加載 Windows 內核。——不好意思,這樣的引導器不存在。在得出這個結論之前,我吃了很多苦。
  • 將 BCD 放在 bootmgr 能讀的地方。——比如一(小)塊 MBR 存儲設備,它不一定要是物理的,也能是虛擬的。在得出這個結論之前,我流了很多淚。

而 Windows 默認的安裝程序要求又高、功能又弱,根本不會給你選擇啓動文件安裝到哪裏的,所以必須要手工安裝。

要 imagex 不要 Setup.exe

Windows 默認安裝框架是在 Windows PE 裏使用 Setup.exe。該程序會運行一系列煩人的檢查並增加一堆不合理的限定,比如要求 .NET Framework,比如強制添加 300 MiB 的系統分區等。而實際上它所做的事情也不過是:解壓 install.wim 到指定分區、寫入引導扇區、寫入 BCD 這三樣。可是這三件事,能自定義的部分還很少或很麻煩,那爲啥不自己來呢?所以我更喜歡的方法是啓動到 Windows PE 之後手工安裝。

Windows PE 哪裏來?TechNet 提供的方法是從 WAIK 裏生成。但前面說了,Windows 的安裝框架是 Windows PE,而 Windows 安裝鏡像文件也不過就是 Windows PE 和 install.wim 的組合而已,所以直接從安裝鏡像裏就可以釋放一個 Windows PE 出來。用 wimlib 提供的 mkwinpeimg 可以很方便地做到這一點,能直接從 Windows 安裝鏡像中獲取 Windows PE 所需的 boot.wim 並製成可啓動的鏡像文件。如果你懶得自己提取 Windows PE,那麼這裏有我做好的兩份。兩份 Windows PE 除了添加了一個 imagex.exe 之外沒有任何改動,十分純潔乾淨:(其實不添加也行,用更加高大上的 dism 也能釋放文件)

install.wim 哪裏來?Windows 安裝鏡像裏就有,使用 7z e Windows.iso sources/install.wim 即可把它解壓出來。在移動存儲設備裏保存 install.wim 而不是完整的 iso,甚至能省下 500 MiB 以上的空間。

接下來就是安裝了。通過可啓動媒體啓動進 Windows PE,用 diskpart 進行合理的分區。以下爲帶註釋的操作過程:

# 確認當前硬盤情況
DISKPART> list disk
# 假設系統硬盤爲 Disk 0 (Windows 將安裝於此)
# Windows PE 所在的盤爲 Disk 1 (請忽略)
# 過會兒要創建的 VHD 爲 Disk 2 (Windows 啓動文件將安裝於此)
DISKPART> select disk 0
DISKPART> list partition
DISKPART> select partition 4
DISKPART> format label="Windows 8.1" quick
DISKPART> assign letter=c
# 以上命令格式化要安裝 Windows 的分區並分配卷標 C:
# 接下來創建並掛載 VHD
DISKPART> create vdisk file=c:\bootmgr.vhd maximum=32 type=fixed
DISKPART> attach vdisk
# 然後在 VHD 裏創建並激活分區。offset 不是必須的,但是我喜歡
DISKPART> select disk 2
DISKPART> create partition primary offset=1024
DISKPART> active
DISKPART> format label=bootmgr quick
# 分配一個卷標 B:
DISKPART> assign letter=b
# 退出 diskpart
DISKPART> exit

然後就是安裝 Windows 和 Windows 啓動文件了:

# 解壓文件,注意根據實際情況選擇 index,此處爲 1
X:\> imagex /apply install.wim 1 c:
# dism 的等效命令是:(長多了)
X:\> dism /Apply-Image /ImageFile:install.wim /Index:1 /ApplyDir:C:\
# 寫入啓動代碼和啓動文件
X:\> bootsect /nt60 b: /mbr
X:\> bcdboot c:\Windows /s b:

至此 Windows 部分就算完成了,可以在 diskpart 裏 detach vdisk 然後重啓進 Linux 繼續操作。

用 MEMDISK 引導硬盤鏡像

在上一節中,我們得到了一個裝好了 Windows 的分區,以及一塊 32 MiB 的虛擬硬盤鏡像,這塊虛擬硬盤採用 MBR,有且只有一個主分區,主分區裏裝着大約 19 MiB 的 Windows 啓動文件。其實這些啓動文件真正核心的只有不到 1 MiB,其他的都是語言包和字體等,如果你閒得無聊可以掛載來刪除它們,當然硬盤鏡像文件大小不會自動縮小就是了。

那麼,MEMDISK 能直接引導 vhd 麼?我一開始也覺得不能,因此查到了用 VirtualBox 或 QEMU 來把 vhd 轉成 raw image 的方法:VBoxManage clonehd --type raw bootmgr.vhd bootmgr.img。但是後來經 @tjmao 的提醒,我才發現原來當 type=fixed 的時候,vhd 其實就是 raw image 加上 512 字節的 footer。切掉這個尾巴之後,得到的東西和 dd 式的 raw image 是一模一樣的。而就算不切掉尾巴,這一部分也會被認爲是未分區空間從而被忽略掉。所以,其實 type=fixed 的 vhd 是不用轉換,直接可以當 raw image 用餵給 MEMDISK 的。

那麼怎麼喂呢?根據調用 MEMDISK 的方法不同,具體的語法也有一定差別,完整的敘述可在這裏找到。以下是 GRUB 的方法:

menuentry "bootmgr.vhd" {
  linux16 /boot/syslinux/memdisk harddisk
  initrd16 /boot/bootmgr.vhd
}

把這一段複製到 /boot/grub/grub.cfg 中即可使用。如果要使它可在 grub-mkconfig 後自動生成的話,複製到 /etc/grub.d/40_custom 中即可。

至此 Windows 的引導就算是做好了。重啓計算機在 GRUB 菜單中選擇對應的 menuentry 即可進入。第一次進入的時候會自動安裝驅動等,安裝完自動重啓,然後就功德圓滿了。

五、一些可以改動的部分

如導言中所說,有和我完全一樣的需求的人應該不存在,但是本文的思路可用於一些別的折騰過程中。以下列舉了部分可以改動的部分,適用於不同的具體情況。

Linux 不是必須的

如果你只是想安裝 BIOS + GPT 的 Windows,自然不用裝 Linux。但是你可能需要備一個 Notepad.exe 在 Windows PE 環境中,用來編輯引導器的配置文件。

GRUB 可以換成別的

如果不裝 Linux 了,那單獨裝個 GRUB 也沒啥意思,還不如換點別的引導器。諸如 Syslinux, Grub4Dos 等,都可以用來加載 MEMDISK。具體的語法依然戳這裏。不過如果換成別的啓動器的話,那個啓動器得要像 GRUB 一樣對 GPT 有支持……

VHD 的大小問題

在想到 VHD 的方法之前,我曾試過的是把裝的引導分區的 U 盤整個 dd_rescue 複製下來。這是一個較老的 U 盤,容量只有 4 GB,但是就這樣產生的鏡像文件也太大了,無法被 MEMDISK 正確加載。雖然最後我成功地把這個鏡像掛載之後縮小文件系統和分區使它「瘦身」,但步驟較複雜。想到 VHD 的方法之後就簡單了,直接創建一個小一點的 VHD 然後在裏面操作即可。現在已知鏡像文件不能太大,否則 MEMDISK 加載不了,那麼它最小能多小呢?

核心的 Windows 啓動文件只有 bootmgrBoot\BCD 這兩個,加起來不到 1 MiB。我也試過,引導分區裏只放這兩個文件,依然能正常引導,但是實際上 VHD 不能只有 1 MiB。這是因爲:

  • bcdboot 複製啓動文件的時候,默認會複製那些語言包和字體,總共 19 MiB 左右
  • NTFS 分區最小需要 8 MiB

我實驗成功的最小大小是 10 MiB 的 VHD,裏面裝着一個 8 MiB 的 NTFS。

當代的計算機大部分都是 4 GB 和 8 GB 的內存了,所以不用剋扣這麼一點點空間(畢竟它引導完就被釋放掉了),所以創建 VHD 時選擇 32 MiB 是個比較好的選擇。記得 type=fixed 就行。

六、吐槽和尾巴

好久沒寫有關 Windows 的博文了。本來以爲自己的對 Windows 的需求在 VirtualBox 裏就能完全滿足了,因此筆記本電腦安裝系統的時候並沒有爲 Windows 考慮過,直接就是 BIOS + GPT + Linux 的組合了。可是自從 2014 年初在迷上了 Call of Duty 之後就入了 Steam 的大坑了,因此對獨立的 Windows OS 的需求再次浮現。之前嘗試 BIOS + GPT + Linux 既有配置下再塞個 Windows 怎麼都沒成功,因此選擇了 Windows To Go 的解決方案——將整個 Windows 及其引導文件裝到外置 USB 硬盤裏。可是 USB 機械硬盤的速度又怎麼能和 Samsung 840 Pro SSD 相比……於是發憤圖強,努力研究,終於實現了 Windows 本體安裝在 GPT SSD 裏而把引導文件裝到 MBR U 盤裏的方法。慢慢地這樣的方法又不能滿足我的要求了,於是繼續發憤圖強,在各種來源都說這是不可能的情況下,我最終還是曲線救國成功了。

於是便有了本文。

轉載請註明出處: https://wzyboy.im/post/1049.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章