大多數 Linux 計算機使用 Grand Unified Bootloader (GRUB) — 更具體的講是 GRUB 2 — 來控制從計算機的固件到內核的轉移。GRUB 2 提供了復雜的引導時用戶交互功能,為您提供了控制引導過程的能力。您可能不想每天都使用這些功能,但它們在處理問題的時候很重要,比如計算機在執行內核升級、磁盤更換或其他系統更改後無法引導的時候。一些技巧和 GRUB 命令可幫助您在這些情形下引導計算機,節省寶貴的時間。您也可以使用緊急引導磁盤引導您正常的 Linux 系統,即使在引導裝載程序激活的常規初始階段出現問題,也可以這樣做。
一般來講,GRUB 恢復能解決兩種類型的問題:可使用 GRUB 的內置 shell 解決的問題和需要外部工具的問題。本文將介紹這兩種類型的問題,並使用 Super GRUB2 Disk 作為一個可在必要時使用的外部工具的例子。(本文著重介紹了 GRUB 2,但這裡提供的一些信息也適用於 GRUB Legacy。從 “遷移到 GRUB 2” 中,可以了解 GRUB Legacy 與 GRUB 2 之間的區別。)
在深入了解恢復細節之前,您應了解 GRUB 工作原理的一些基本知識。計算機的引導過程很復雜,如果引導過程偏離了引導路徑,那麼對引導路徑有一定的了解可以幫助您解決問題。我首先將介紹引導代碼和 GRUB 文件位於計算機上何處,以便您可找到它們,或者在某個缺少的文件導致出現問題時識別可能缺少了哪個文件。GRUB 配置文件格式的完整描述不屬於本文的討論范圍,但我會介紹該配置的基本知識,幫助您更正簡單的錯誤(比如錯誤指定的引導文件系統)。
大多數使用基本輸入/輸出系統 (BIOS) 的計算機上的引導過程都涉及到存儲在磁盤上各個位置的代碼。這些位包括主引導記錄 (Master Boot Record, MBR)、未正式分配的磁盤扇區和分區的引導扇區(也稱為分區引導記錄 [Partition Boot Record, PBR])。這些記錄可由其他引導裝載程序改寫,由病毒或具有與 GRUB 沖突的需求的低級磁盤改寫,或者由於誤用 dd 等低級實用程序而遭到損壞。在出現這些損壞時,GRUB 不太可能完全啟動,您可能需要使用一個工具,比如 Super GRUB2 Disk。
許多較新的計算機使用的是可擴展固件接口 (Extensible Firmware Interface, EFI) 而不是 BIOS。在這些系統上,GRUB 代碼未存儲在 MBR、PBR 或未正式分配的磁盤扇區中。它們位於 EFI 系統分區 (ESP) 上一個具有 .efi 擴展名的 EFI 引導裝載程序文件中,ESP 是一個通常出現在磁盤開頭並具有文件分配表 (File Allocation Table, FAT) 格式的分區。EFI 系統不易受到與 BIOS 系統相同類型的低級引導裝載程序的破壞,但它們可能由於對計算機的非易失性 RAM (NVRAM) 設置的更改而發生故障。在這些情況下,您可能需要執行一次緊急引導,然後使用 efibootmgr 實用程序還原 GRUB,用它作為默認的引導裝載程序。
除了低級 BIOS 或 EFI 引導文件之外,GRUB 2 還依賴於 /boot/grub 中的傳統文件。這些文件包括文件系統驅動程序、視頻驅動程序、字體和 GRUB 配置文件 (grub.cfg)。因為這些文件位於正常的 Linux 文件系統中,所以早期引導階段必須包含至少一個基本的 Linux 文件系統驅動程序。如果這些文件被損壞,GRUB 可能會正常啟動,但無法啟動您的操作系統;或者 GRUB 可能啟動並且只顯示一個 grub> 提示符。
在大多數系統上,GRUB 2 配置文件是 /boot/grub/grub.cfg 或 /boot/grub2/grub.cfg。但是,一些基於 EFI 的系統將它放在 ESP 上的一個目錄中。這個目錄可能是 /boot/efi/EFI/grub/grub.cfg 或其他類似位置。但在大多數情況下,不能直接對 grub.cfg 文件進行編輯;它是由腳本拼湊起來的。您可以在 /etc/grub.d 目錄中找到一些組成片段。如果需要更改您的標准 GRUB 2 配置,那麼可以編輯這些文件。
無論它是如何構建的,grub.cfg 都包含全局選項和特定於操作系統或內核的引導代碼節 (stanza)。Linux 發行版可針對大多數計算機正確設置其全局 GRUB 2 配置。如果您有一個不常見的配置,那麼您可能需要分析全局 GRUB 2 配置來查找問題的原因。
GRUB 2 的引導選項定義了各個操作系統或內核。這些引導代碼節通常位於 grub.cfg 文件的後半部分。清單 1 顯示了一個示例:
menuentry 'Ubuntu, with Linux 3.2.0-24-generic-pae' { recordfail gfxmode $linux_gfx_mode insmod gzio insmod part_gpt insmod reiserfs set root='(hd0,gpt6)' search --no-floppy --fs-uuid --set=root 313324f5-a9ed-4e80-b541-dc9e5eeb89fc linux /vmlinuz-3.2.0-23-generic-pae root=/dev/sda7 ro quiet splash $vt_handoff initrd /initrd.img-3.2.0-23-generic-pae }
清單 1 中的內容的一些關鍵點包括:
insmod 命令加載驅動程序模塊。
set root 行識別從中讀取內核和初始 RAM 磁盤的分區,但 search 行隨後會改寫此值,並根據它包含的文件系統的通用惟一識別碼 (UUID) 編號查找該分區。
linux 行標識一個 Linux 內核,並設置傳遞給它的選項。
initrd 行標識一個傳遞給內核的初始 RAM 磁盤文件。
為了能夠修復問題,您首先需要了解正常引導過程和可調整它的方式。通常,您可以使用 GRUB 2 的內置編輯器調整引導選項來修復較小的問題。有時可使用 GRUB 2 的內置 shell 從更嚴重的問題中恢復。
在傳統上,GRUB 顯示了一個文本模式菜單(類似於圖 1 中所示的菜單)來顯示您的引導選項。(在如今的許多安裝中,GRUB 隱藏了這個菜單,但可以通過一個按鍵調出它。)
在正常引導過程中,可使用上下箭頭鍵導航該菜單,然後按下 Enter 鍵選擇想要的選項。在 Linux 系統上,GRUB 隨後會加載內核和初始 RAM 磁盤,並將計算機的控制權轉交給內核。
如果您看到一個類似 圖 1 的 GRUB 選項,但您的選項尚未生效,那麼可能是引導選項出了問題。GRUB 包含一個簡單的文本編輯器,可在運行時使用它臨時更改您的引導代碼節。要更改引導選項,可在 GRUB 菜單中選擇最接近您想要實現的目標的選項,然後按下 e 鍵。結果類似於圖 2:
圖 2 中的各行與 清單 1 中的引導代碼節中的各行相同。您可以編輯這些選項,就像使用 Linux 中的文本模式編輯器一樣。您在此編輯器中執行的所有更改都是臨時性的。
在文本編輯器中編輯引導代碼節通常是為了執行一次性引導更改。例如,假設您希望引導到單用戶模式來執行低級維護,但 GRUB 中沒有單用戶選項。要實現此目的,可編輯引導代碼節,並將 single 添加到 linux 行末尾。完成上述操作後,按下 Ctrl-x 或 F10 來進行引導,就像屏幕底部給出的提示一樣。
如果創建一個新 GRUB 選項但它無法啟動,那麼您可以檢查此引導選項來發現問題。或許該選項包含錄入錯誤,比如寫成了 linu 而不是 linux。或許您省略了 initrd 行。或許您指定了錯誤的引導文件系統。一般而言,可使用您的系統和 GRUB 2 配置的知識來更正這類問題。但是,在其他情況下,您可能缺乏相關的重要知識。例如,您可能需要了解引導文件系統的標識符是什麼。在這些情況下,或者在問題變得更嚴重的時候,您可以使用 GRUB 2 shell。
GRUB 包含它自己的內置 shell,您可在其中鍵入與 Bash 或其他 Linux 文本模式 shell 中鍵入的命令類似的命令。根據 Linux 標准,GRUB shell 很簡單,但使用它來應對許多緊急維護任務已經足夠。要從 GRUB 主菜單進入該 shell(圖 1),可按下 c。要從 GRUB 編輯器進入該 shell(圖 2),可按下 Ctrl-c 或 F2。結果類似於圖 3:
GRUB 2 shell 支持一系列命令,其中許多命令與 grub.cfg 中用於控制菜單驅動的引導過程的命令類似或等同。如果非常熟悉 GRUB 2 配置文件格式,那麼您可以在 shell 中鍵入命令來引導計算機。實際上,很可能會使用 shell 執行恢復操作。表 1 提供了在此方面更可能有用的一些命令。GRUB 2 支持其他許多命令,您可以通過 GRUB 文檔 了解它們。
可能促使您使用 GRUB 命令行的一個問題是,GRUB 無法找到它自己的配置文件。重新安裝 GRUB(如本文的 執行永久修復 一節中所述)是長期的解決方案。但是,與此同時,您可以發出一些命令來調出常規 GRUB 菜單並引導 Linux。首先,必須識別要安裝 GRUB 的分區,這一點可借助 ls 命令來完成。如果在使用該命令時不帶任何選項,ls 會顯示 GRUB 可檢測的磁盤和分區。然後您可以指定設備的名稱和一個結尾斜槓 (/),以查看特定分區的內容,如清單 2 所示:
grub> ls (hd0) (hd0,gpt5) (hd0,gpt4) (hd0,gpt3) (hd0,gpt2) (hd0,gpt1) grub> ls (hd0,gpt5)/ abi-3.2.0-22-generic grub/ initrd.img-3.2.0-22-generic memtest86+bin System.map-3.2.0-22-generic vmcoreinfo-3.2.0-22-generic vmlinuz-3.2.0-22-generic
 
清單 2 中的示例顯示了一個具有單個磁盤 (hd0) 的計算機,該磁盤包含 5 個全局惟一標識符 (GUID) 分區表 (GPT) 分區。(hd0,gpt5) 的內容好像是一個 Linux /boot 分區,包含一個 GRUB 配置目錄 (grub/)。您可能需要查看其他分區的內容,然後才能找到您的 Linux /boot 分區。如果您的系統未使用單獨的 /boot 分區,則必須查找您的 Linux 引導 (/) 分區。
識別 GRUB 配置文件所在位置後,可以設置 prefix 和 root 環境變量,告訴 GRUB 在何處找到配置文件。這些變量分別識別 grub.cfg 所在的目錄和它所在的分區:
grub> set prefix=(hd0,gpt5)/grub
grub> set root=(hd0,gpt5)
從這裡,您可加載 normal 模塊並啟動它來調出 GRUB 菜單:
grub> insmod normal
grub> normal
Super GRUB2 Disk 是一個僅適用於 BIOS 的工具。如果您在 EFI 模式下正常引導,Super GRUB2 Disk 幫不上忙。EFI 模式引導不依賴於 MBR 或磁盤的引導扇區中存儲的代碼,這些代碼區域(如果損壞)會使得 Super GRUB2 Disk 大有作為。對於 EFI 引導問題,您的固件的引導管理器或一個輔助程序(比如 rEFInd)可幫助您從損壞的 NVRAM 設置導致的問題中恢復。我還建議您備份 EFI 計算機的 ESP 中的文件,以防分區被損壞。因為 EFI 不依賴於隱藏的代碼,所以您可使用一個簡單的文件拷貝操作來還原 ESP。(內幕披露:我在維護 rEFInd。)
在某些情況下,GRUB 甚至未提供 grub> 提示符,您可能甚至在使用該提示符解決問題時遇到麻煩。在這些情況下,Super GRUB2 Disk 營救工具可提供幫助。
即使現在可以成功引導,我仍然建議您創建 Super GRUB2 Disk 的副本,以便在需要時直接使用它。Super GRUB2 DISK 下載 是一個具有 .iso 擴展名的混合鏡像文件。可使用 dd 將此文件復制到軟盤、CompactFlash (CF) 磁盤、通用串行總線 (USB) 閃存盤或者某種類型的磁盤中。也可以使用 cdrecord 或一個 GUI 光碟工具將該文件刻錄到 CD-R 中。
創建引導介質後,我建議對它執行測試(理想情況下,在多個計算機上執行測試),以熟悉該工具並確認它在您使用的硬件上是否有效。
准備一個 Super GRUB2 Disk 後,您可像其他任何可引導磁盤一樣引導它。在某些情況下,您可能需要在引導過程中按下某個鍵來更改引導順序。常用的鍵包括 F2、F10 和 F12,您應該查閱計算機的手冊,了解相關的詳細信息。在執行 Super GRUB2 Disk 引導時,您會看到一個類似圖 4 的顯示屏幕,其中包括檢測操作系統或啟用各種類型的支持的選項:
如果您的計算機使用了獨立磁盤冗余陣列 (RAID) 或邏輯卷管理 (Logical Volume Management, LVM),或者依賴於舊的並行 ATA (PATA) 磁盤或外部 USB 磁盤,那麼您可能需要選擇這些功能並按下 Enter 來激活它們。完成上述操作之後,您可以嘗試檢測選項。我發現 “Detect any GRUB2 configuration file (grub.cfg)” 和 “Detect any GRUB2 installation (even if the MBR is overwritten)” 選項一般最適合恢復損壞的 GRUB 安裝。但是 “Detect any Operating System” 選項可能也值得一試。
如果檢測成功,您應該看到一個新的 GRUB 選項菜單。在單操作系統安裝中,此菜單可能僅包含一個選項,它使用路徑來識別 GRUB 配置文件,就像 (hd0,gpt5)/grub/grub.cfg 中一樣。在選中此選項時,應顯示您的安裝的正常 GRUB 屏幕。(字體和顏色可能不同,但菜單選項應該能夠正常工作。)
執行永久修復
到目前為止,我介紹的修復都是永久性的。您可能已成功引導 Linux,但是,只要重新引導,就會看到原始的 GRUB 屏幕。要讓您的更改永久生效,需要采取額外的步驟。
其中最簡單的步驟是修改 GRUB 配置文件。盡管 可以直接編輯 grub.cfg 來修改您的設置,但此方法不可取,因為只要升級您的發行版提供的內核,自動化的腳本就可以從其他文件重新構建該文件。相反,您需要編輯 /etc/grub.d 中的文件和 /etc/default/grub 中的默認全局設置。然後可以使用 grub-mkconfig,從 Linux 命令提示符生成一個新的 grub.cfg 文件:
grub-mkconfig -o /boot/grub/grub.cfg
如果您的問題是 GRUB 僅顯示了一個 grub> 提示符或完全未啟動,那麼您必須將 GRUB 重新安裝到您硬盤上:
grub-install /dev/sda
在某些情況下,您可能需要將 GRUB 安裝到 /dev/sda 以外的設備,比如 /dev/sdb。一般不建議將 GRUB 2 安裝到某個分區。如果將 GRUB 安裝到一個基於 BIOS 的計算機上的 GPT 磁盤,請確保該計算機包含一個 BIOS 引導分區。沒有該分區,GRUB 可能拒絕安裝或者可能不可靠。如果您將 GRUB 安裝到一個基於 EFI 的計算機,那麼可以省略設備規范,確保您的 ESP 掛載在 /boot/efi 上。grub-install 自動將必要的文件復制到這個目錄(進而布置到 ESP)。如果 GRUB 由於不當的 NVRAM 設置而未在基於 EFI 的計算機上啟動,那麼您可能可以在固件自身內修復這些問題,但不同實現的細節可能有所不同。如果可以在 EFI 模式下引導一個應急系統,那麼可以使用 efibootmgr 還原您的引導裝載程序:
efibootmgr -c -l \\EFI\\loaderdir\\loadername.efi -L MenuName
GRUB 2 是一個直接引導 Linux(和其他一些)操作系統內核的靈活工具。但是由於引導過程中的漏洞和 GRUB 自身的復雜性,可能會出現一些問題,導致系統無法引導。在這些情況下,知道如何編輯各個 GRUB 代碼段、如何使用 GRUB 命令行和如何使用 Super GRUB2 Disk 都是寶貴的技能。通過使用這些技術,您可以從各種引導問題中恢復並引導到您的正常安裝中。此時,您可以編輯 GRUB 2 配置文件或重新安裝引導裝載程序讓修復永久生效。