2021-05-12 14:32:11
Grub 2:拯救你的 bootloader
沒有什麼事情比 bootloader 壞掉更讓氣人的了。充分發揮 Grub 2 的作用,讓 bootloader 安分工作吧。
為什麼這麼說?
- Grub 2 是最受歡迎的 bootloader ,幾乎用在所有 Linux 發行版上。
- bootloader 是一個至關重要的軟體,但是非常容易損壞。
- Grub 2 是兼具擴充套件性和靈活性的一款引導載入程式,提供了大量可客製化選項。
Grub 2 是一款精彩的功能強大的軟體。它不是 bootloader 界的一枝獨秀,但卻最受歡迎,幾乎所有主要的桌面發行版都在使用它。 Grub 的工作有兩個。首先,它用一個選單展示計算機上所有已經安裝的作業系統供你選擇。其次,當你從啟動選單中選擇了一個 Linux 作業系統, Grub 便載入這個 Linux 的核心。
你知道,如果使用 Linux ,你就離不開 bootloader 。然而它卻是 Linux 發行版內部最鮮為人知的部分。在這篇文章裡,我們將帶你熟悉 Grub 2 一些著名的特性,強化你相關技能,使你在 bootloader 跑飛的時候能夠自行處理。
Grub 2 最重要的部分是一堆文字檔案和兩個指令碼檔案。首先需要了解的是 /etc/default/grub
。這是一個文字檔案,你可以在裡面設定通用設定變數和 Grub 2 選單(見下方 “常見使用者設定” )的其它特性。
Grub 2 另一個重要的部分是 /etc/grub.d
資料夾。定義每個選單項的所有指令碼都放置在這裡。這些指令碼的名稱必須有兩位的數位字首。其目的是,在構建 Grub 2 選單時定義指令碼的執行順序以及相應選單項的順序。檔案 00_header
首先被讀取,負責解析 /etc/default/grub
組態檔。然後是 Linux 核心的選單項,位於 10_linux
檔案中。這個指令碼在預設的 /boot
分割區為每個核心建立一個正規選單項和一個恢復選單項。
緊接著的是為第三方應用所用的指令碼,如 30_os-prober
和 40_custom
。 os-prober 指令碼為核心和其它分割區裡的作業系統建立選單項。它能識別安裝的 Linux、 Windows、 BSD 以及 Mac OS X 。 如果你的硬碟布局比較獨特,使得 os-prober 無法找到已經安裝的發行版,你可以在 40_custom
檔案(見下方 “新增自定義選單項”)中新增選單項。
Grub 2 不需要你手動維護你的啟動選項的組態檔:取而代之的是使用 grub2-mkconfig
命令產生 /boot/grub/grub.cfg
檔案。這個功能會解析 /etc/grub.d
目錄中的指令碼以及 /etc/default/grub
設定檔案來定義你的設定情況。
圖形化的引導修復
多虧了 Boot Repair 應用,只需要點選按鈕,Grub 2 許許多多的問題都能輕易解決。這個漂亮小巧的應用有一個直觀的使用者介面,可以掃描並識別多種硬碟布局和分割區方案,還能發現並正確識別安裝在其中的作業系統。這個應用可以處理傳統計算機裡的主開機記錄(Master Boot Record) (MBR),也可以處理新型 UEFI 計算機中的GUID 分割區表(GUID Partition Table)(GPT)。
Boot Repair 最簡單的使用方式是安裝到 Live Ubuntu 對談中。在一個 bootloader 損壞的機器上啟動 Ubuntu Live 發行版,先通過新增它的 PPA 版本庫來安裝 Boot Repair ,命令如下:
sudo add-apt-repository ppa:yannubuntu/BootRepair
然後重新整理版本庫列表:
sudoapt-get update
安裝應用,如下:
sudoapt-get install -y BootRepair
安裝完畢後就啟動應用。在顯示它的介面(由一對按鍵組成)之前將會掃描你的硬碟。根據工具的指示,只需按下 Recommended Repair(推薦的修復)按鈕,即可修復大部分壞掉的 bootloader 。修復 bootloader 之後,這個工具會輸出一個短小的 URL ,你應該把它記錄下來。這個 URL 包含了硬碟詳盡的資訊:分割區資訊以及重要的 Grub 2 檔案(如
/etc/default/grub
和/boot/grub/grub.cfg
)的內容。如果工具不能解決 bootloader 的問題,可以把你這個 URL 共用在你的發行版的論壇上,讓其他人可以分析你的硬碟布局以便給你建議。Boot Repair 也可以讓你客製化 Grub 2 的選項。
Bootloader 急救
Grub 2 引導問題會讓系統處於幾種不同狀態。螢幕(如你所想,本該顯示 bootloader 選單的地方)所展示的文字會指示出系統的當前狀態。如果系統中止於 grub> 提示符,表明 Grub 2 模組已經被載入,但是找不到 grub.cfg 檔案。當前是完全版的 Grub 2 命令列 shell,你可以通過多種方式解決此問題。如果你看到的是 grub rescue> 提示符,表明 bootloader 不能找到 Grub 2 模組或者找不到任何引導檔案(boot files )。然而,如果你的螢幕只顯示 ‘GRUB’ 一詞,表明 bootloader 找不到通常位於主開機記錄(Master Boot Record )裡的最基本的資訊。
你可以通過使用 live CD 或者在 Grub 2 shell 中修正此類錯誤。如果你夠幸運, bootloader 出現了 grub> 提示符,你就能獲得 Grub 2 shell 的支配權,來幫助你排錯。
接下來幾個命令工作在 grub> 和 grub rescue> 提示符下。 set pager=1 命令設定顯示分頁( pager ),防止文字在螢幕上一滾而過。你還可以使用 ls 命令列出 Grub 識別出的所有分割區,如下:
grub>ls
(hd0)(hd0,msdos5)(hd0,msdos6)(hd1,msdos1)
如你所見,這個命令列出分割區的同時一併列出了分割區表方案(即 msdos)。
你還可以在每個分割區上面使用 ls 來查詢你的根檔案系統:
grub>ls(hd0,5)/
lost+found/var/ etc/ media/ bin/ initrd.gz
boot/ dev/ home/selinux/ srv/ tmp/ vmlinuz
你可以不寫上分割區名的 msdos 部分。同樣,如果你忘記了尾部的斜槓( trailing slash )只輸入 ls (hd0,5)
,那你將獲得分割區的資訊,比如檔案系統型別、總體大小和最後修改時間。如果你有多個分割區,可以使用 cat
讀取 /etc/issue
檔案中的內容,來確定發行版,格式如 cat (hd0,5)/etc/issue
。
假設你在 (hd0,5) 中找到根檔案系統,請確保它包含 /boot/grub
目錄,以及你想引導進入的核心映象,如 vmlinuz-3.13.0-24-generic 。此時輸入以下命令:
grub>set root=(hd0,5)
grub> linux /boot/vmlinuz-3.13.0-24-generic root=/dev/sda5
grub> initrd /boot/initrd.img-3.13.0-24-generic
第一個命令把 Grub 指向我們想引導進入的發行版所在的分割區。接著第二個命令告知 Grub 核心映象在分割區中的位置,以及根檔案系統的位置。最後一行設定虛擬檔案系統( initial ramdisk )檔案的位置。你可以使用 tab 補全功能補全核心名字和虛擬檔案系統( initrd: initial ramdisk )的名字,節省時間和精力。
輸入完畢,在下一個 grub> 提示符後輸入 boot
, Grub 將會引導進入指定的作業系統。
如果你在 grub rescue> 提示符下,情況會有些許不同。因為 bootloader 未能夠找到並載入任何必需的模組,你需要手動新增這些模組:
grub rescue>set root=(hd0,5)
grub rescue>insmod(hd0,5)/boot/grub/normal.mod
grub rescue> normal
grub>insmod linux
如上所示,跟之前一樣,使用 ls
命令列出所有分割區之後,使用 set
命令標記起來。然後新增 normal 模組,此模組啟用時將會恢復到標準 grub> 模式。如果 linux 模組沒載入,接下來的命令會進行新增。如果這個模組已經載入,你可以跟之前一樣,把引導載入程式指向核心映象和虛擬檔案系統( initrd )檔案,然後使用 boot
啟動發行版,完美收官。
一旦成功啟動發行版,別忘了為 Grub 重新產生新的組態檔,使用
grub-mkconfig -o /boot/grub/grub.cfg
命令。你還需要往 MBR 裡安裝一份 bootloader 的拷貝,使用
sudo grub2-install /dev/sda
命令。
想要禁用 /etc/grub.d
目錄下的指令碼,你只需移除其可執行位,比如使用 chmod -x /etc/grub.d/20_memtest86+
就能將 ‘Memory Test’ 選項從選單中移除。
Grub 2 和 UEFI
在支援 UEFI 的機器(最近幾年上市的機器大部分都是)偵錯壞掉的 Grub 2 增加了另一複雜的層次。恢復安裝在 UEFI 機器上的 Grub 2 的和安裝在非 UEFI 機器上的並沒多大區別,只是新的韌體處理方式不一樣,從而導致了很多種恢復結果。
對於基於 UEFI 的系統,不要在 MBR 上安裝任何東西。相反,你要在 EFI 系統分割區(EFI System Partition)( ESP )裡安裝 Linux EFI bootloader,並且藉助工具把它設定為 EFI 的預設啟動程式,這個工具對於 Linux 使用者是
efibootmgr
,對於 window 使用者則是bcdedit
。照目前情況看,在安裝任何與 Windows 8 相容的主流桌面 Linux 發行版前,應該正確安裝好 Grub 2。然而,如果 bootloader 損壞,你可以使用 live 發行版修復機器。在啟動 live 媒介之時,請確保是以 UEFI 模式啟動。計算機每個可移動驅動器的啟動選單將會有兩個: 一個普通的和一個以 EFI 標記的。使用後者會用到 /sys/firmware/efi/ 檔案中的 EFI 變數。
在 live 環境中,掛載教學前面所提的安裝掛掉系統的根檔案系統。除此之外,還需要掛載 ESP 分割區。假設分割區是 /dev/sda1 ,你可以如下所示掛載:
sudomount/dev/sda1 /mnt/boot/efi
接著在 chroot 到安裝完畢的發行版前之前,使用
modprobe efivars
載入 efivars 模組。在這裡, Fedora 使用者可以使用如下命令重新安裝 bootloader
yum reinstall grub2-efi shim
但在此之前,需要使用
grub2-mkconfig -o /boot/grub2/grub.cfg
來產生新的組態檔。 Ubuntu 使用者則改用以下命令
apt-get install --reinstall grub-efi-amd64
一旦 bootloader 正確就位,退出 chroot ,解除安裝所有分割區,重新啟動到 Grub 2 選單。
夥計,我的 Grub 哪去了?
Grub 2 最好的特性是可以隨時重新安裝。因此,當其它像 Windows 之類的系統用它們自己的 bootloader 替換後,導致 Grub 2 丟失,你可以使用 live 發行版,寥寥數步即可重灌 Grub 。假設你在 /dev/sda5
安裝了一個發行版,若要重灌 Grub ,你只需首先使用以下命令為發行版建立一個掛載目錄:
sudomkdir-p /mnt/distro
然後掛載分割區,如下:
mount/dev/sda5 /mnt/distro
接著就能重灌 Grub 了,如下:
grub2-install --root-directory=/mnt/distro /dev/sda
這個命令會改寫 /dev/sda
裝置上的 MBR 資訊,指向當前 Linux 系統,並重寫一些 Grub 2 檔案,如 grubenv 和 device.map 。
另一個問題常見於裝有多個發行版的計算機上。當你安裝了新的 Linux 發行版,它的 bootloader 應當要能找到所有已經安裝的發行版。一旦不行,只要引導進入新安裝的發行版,並執行
grub2-mkconfig
在執行這個命令之前,請確保啟動選單中缺失的發行版的 root 分割區已經掛載。如果你想新增的發行版有單獨的 /root
和 /home
分割區,在執行 grub2-mkconfig
之前,只需掛載包含 /root
的分割區。
雖然 Grub 2 能夠找到大部分發行版,但是在 Ubuntu 中嘗試新增安裝的 Fedora 系統需要額外的一個步驟。如果你以預設設定安裝了 Fedora ,則發行版的安裝器已經建立了 LVM 分割區。此時你需要使用發行版的包管理系統安裝 lvm2 驅動,如下
sudoapt-get install lvm2
才能使得 Grub 2 的 os-prober
指令碼能夠找到並將 Fedora 新增進啟動選單。
常見使用者設定
Grub 2 有很多可設定變數。 這裡有一些
/etc/default/grub
檔案中你最可能會修改到的常見變數。 GRUB_DEFAULT 變數指定預設的啟動項,可以設定為數位值,比如 0 ,表示第一個選單項,或者設定為 “saved” ,將指向上一次啟動時選中的選單項。 GRUB_TIMEOUT 變數指定啟動預設選單項之前的停留時間。 GRUB_CMDLINE_LINUX 列出了要傳遞給所有 Linux 選單項的核心命令列引數。如果 GRUB_DISABLE_RECOVERY 變數設定為 true ,那麼將不生成恢復模式選單項。這些選單項會以單使用者模式啟動發行版,這種模式下允許你利用命令列工具修復系統。 GRUB_GFXMODE 變數同樣有用,它指定了選單上文字顯示的解析度,它可以設定為你的顯示卡所支援的任何數值。
Grub 2 有個命令列模式,通過在 bootloader 選單上按 C 進入。
徹底的修復
如果 grub2-install
命令不能正常運作,使得你無法引導進入 Linux ,你需要完整地重灌以及重新設定 bootloader 。為此目的,需要用到強大的 chroot 功能將執行環境從 live CD 環境切換至我們想修復的 Linux 的安裝位置。任何擁有 chroot 工具的 Linux live CD 都可以實現這個目的。不過需要確保 live 媒介的系統架構和硬碟上系統的架構一致。因此當你希望 chroot 到 64 位系統,你必須使用 amd64 live 發行版。
啟動進入 live 發行版之後,首先需要檢查機器上的分割區。使用 fdisk -l
列出磁碟上所有分割區,記錄你想修復的 Grub 2 系統所在的分割區。
假設我們希望從安裝在 /dev/sda5
中的發行版中恢復 bootloader 。啟動終端使用如下命令掛載分割區:
sudomount/dev/sda5 /mnt
此時需要繫結(bind)Grub 2 bootloader 需要進入的目錄,以便檢測其它作業系統:
$ sudomount--bind /dev /mnt/dev
$ sudomount--bind /dev/pts /mnt/dev/pts
$ sudomount--bind /proc /mnt/proc
$ sudomount--bind /sys /mnt/sys
此時可以離開 live 環境進入安裝在 /dev/sda5 分割區中的發行版了,通過 chroot :
$ sudochroot/mnt /bin/bash
現在可以安裝、檢測、以及升級 Grub 了,跟之前一樣,使用
sudo grub2-install /dev/sda
命令來重灌 bootloader 。因為 grub2-install 命令不能建立grub.cfg 檔案,需要手動建立,如下
sudo grub-mkconfig -o /boot/grub/grub.cfg
這樣應該就可以了。現在你就有了 Grub 2 的一份全新拷貝,羅列了機器上所有的作業系統和發行版。在重新啟動電腦之前,你需要依次退出 chroot 系統,解除安裝所有分割區,如下所示:
$ exit
$ sudoumount/mnt/sys
$ sudoumount/mnt/proc
$ sudoumount/mnt/dev/pts
$ sudoumount/mnt/dev
$ sudoumount/mnt
現在你可以安全地重新啟動電腦了,而它應該會回退到 Grub 2 的控制之中,你已經修好了這個 bootloader。
新增自定義選單項
如果希望往 bootloader 選單裡新增選單項,你需要在 40_custom 檔案裡新增一個啟動段( boot stanza )。例如,你可以使用它展示一個選單項來啟動安裝在可移動 USB 驅動裡的 Linux 發行版。假設你的 USB 驅動器是 sdb1 ,並且 vmlinuz 核心映象和虛擬檔案系統( initrd )都位於根 (/)目錄下,在 40_custom 檔案中新增以下內容:
menuentry “Linux on USB”{
set root=(hd1,1)
linux /vmlinuz root=/dev/sdb1 ro quiet splash
initrd /initrd.img
}
相比使用裝置和分割區名,使用它們的 UUID 可以獲得更精確結果,比如
set root=UUID=54f22dd7-eabe
使用
sudoblkid
來獲得所有已連線的驅動器和分割區的 UUID 。你還可以為你磁碟上沒被 os-prober 指令碼找到的發行版新增選單項,只要你知道該發行版的安裝位置以及其核心和虛擬檔案系統( initrd )的位置即可。
via: https://www.linuxvoice.com/grub-2-heal-your-bootloader/
作者:Mayank Sharma 譯者:soooogreen 校對:wxy
本文永久更新連結地址:http://www.linuxidc.com/Linux/2016-01/127542.htm
相關文章