天天看點

讓Grub 2來拯救你的 bootloader

沒有什麼事情比 bootloader 壞掉更氣人的了,充分發揮 Grub 2 的作用,讓 bootloader 安分工作吧。為什麼這麼說?

Grub 2 是最受歡迎的 bootloader ,幾乎用在所有 Linux 發行版上。

bootloader 是一個至關重要的軟體,但是非常容易損壞。

Grub 2 是兼具擴充性和靈活性的一款引導加載程式,提供了大量可定制選項。

Grub 2 是一款功能強大的軟體,它不是 bootloader 界的唯一,但卻最受歡迎,幾乎所有主流的桌面發行版都在使用它。 Grub 的工作有兩個:首先,它用一個菜單展示計算機上所有已經安裝的作業系統供你選擇;其次,當你從啟動菜單中選擇了一個 Linux 作業系統後, Grub 便加載對應版本Linux 的核心,衆所周知,使用 Linux 就離不開 bootloader ,然而它卻是 Linux 發行版内部很少有人充分了解的部分。

1、Grub 2 最重要的部分是一堆文本檔案和兩個腳本檔案,首先需要了解的是

/etc/default/grub

,這是一個文本檔案,你可以在裡面設定通用配置變量和 Grub 2 菜單(見下方 “常見使用者設定” )的其它特性。

2、Grub 2 另一個重要的部分是

/etc/grub.d

檔案夾,定義每個菜單項的所有腳本都放置在這裡,這些腳本的名稱必須有兩位的數字字首,其目的是:在建構 Grub 2 菜單時定義腳本的執行順序以及相應菜單項的順序。舉個栗子:檔案 00_header 首先被讀取,負責解析

配置檔案,然後是 Linux 核心的菜單項,位于 10_linux 檔案中,這個腳本在預設的

/boot

分區為每個核心建立一個正規菜單項和一個恢複菜單項。

3、緊接着的是被第三方應用所調用的腳本,如 30_os-prober 和 40_custom , os-prober 腳本為核心和其它分區裡的作業系統建立菜單項,它能識别安裝的

Linux、 Windows、 BSD

以及

Mac OS X

,當然如果你的硬碟布局比較獨特,使得 os-prober 無法找到已經安裝的發行版,你可以在 40_custom 檔案(見下方 “添加自定義菜單項”)中添加菜單項。

4、Grub 2 不需要你手動維護你的啟動選項的配置檔案:取而代之的是使用 grub2-mkconfig 指令産生

/boot/grub/grub.cfg

檔案。這個功能會解析

目錄中的腳本以及

設定檔案來定義你的設定情況。

圖形化的引導修複

多虧了 Boot Repair的應用,我們隻需要點選按鈕,Grub 2 就能幫我們輕易解決很多問題,這個漂亮而小巧的應用有一個比較直覺的使用者界面,可以掃描并識别多種硬碟布局和分區方案,還能發現并正确識别安裝的作業系統,這個應用既可以處理傳統計算機裡的主引導記錄Master Boot Record (MBR),也可以處理新型 UEFI 計算機中的GUID 分區表GUID Partition Table(GPT)。 Boot Repair 最簡單的使用方式是安裝到 Live Ubuntu 會話中,在一個 bootloader 損壞的機器上啟動 Ubuntu Live 發行版,先通過添加它的 PPA 版本庫來安裝 Boot Repair ,指令如下:

然後重新整理版本庫清單:

安裝應用,如下:

安裝完畢後就啟動應用,在顯示它的界面(由一對按鍵組成)之前它将會掃描你的硬碟,接下來使用者可以根據工具的訓示,隻需按下 Recommended Repair推薦的修複按鈕,即可修複大部分壞掉的 bootloader ,修複 bootloader 之後,這個工具會輸出一個短小的 URL (建議把它記錄下來),這個 URL 包含了硬碟詳盡的資訊:分區資訊以及重要的 Grub 2 檔案(如/etc/default/grub 和 /boot/grub/grub.cfg )的内容,如果工具不能解決 bootloader 的問題,可以把你這個 URL 共享在你的發行版的論壇上,讓其他人可以分析你的硬碟布局以便給你建議。

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 識别出的所有分區,如下:

如你所見,這個指令列出分區的同時一并列出了分區表方案(即 msdos)。 你還可以在每個分區上面使用 ls 來查找你的根檔案系統:

你可以不寫上分區名的 msdos 部分,同樣,如果你忘記了尾部的斜杠trailing slash隻輸入 ls (hd0,5) ,那你将獲得分區的資訊,比如檔案系統類型、總體大小和最後修改時間,如果你有多個分區,可以使用 cat 讀取 /etc/issue 檔案中的内容,來确定發行版,格式如 :

假設你在 (hd0,5) 中找到根檔案系統,請確定它包含 /boot/grub 目錄,以及你想引導進入的核心鏡像,如 vmlinuz-3.13.0-24-generic ,此時輸入以下指令:

第一個指令把 Grub 指向我們想引導進入的發行版所在的分區,接着第二個指令告知 Grub 核心鏡像在分區中的位置,以及根檔案系統的位置,最後一行設定虛拟檔案系統initial ramdisk檔案的位置,你可以使用 tab 補全功能補全核心名字和虛拟檔案系統initrd: initial ramdisk的名字,節省時間和精力,輸入完畢,在下一個 grub> 提示符後輸入 boot , Grub 将會引導進入指定的作業系統。 如果你在 grub rescue> 提示符下,情況會有些許不同。因為 bootloader 未能夠找到并加載任何必需的子產品,你需要手動添加這些子產品:

如上所示,跟之前一樣,使用 ls 指令列出所有分區之後,使用 set 指令标記起來,然後添加 normal 子產品,此子產品激活時将會恢複到标準 grub> 模式,如果 linux 子產品沒加載,接下來的指令會進行添加,如果這個子產品已經加載,你可以跟之前一樣,把引導加載程式指向核心鏡像和虛拟檔案系統initrd檔案,然後使用 boot 啟動發行版,prefect! 一旦成功啟動發行版,别忘了為 Grub 重新産生新的配置檔案,使用指令:

你還需要往 MBR 裡安裝一份 bootloader 的拷貝,使用指令:

如果想要禁用 /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 ,你可以如下所示挂載:

接着在 chroot 到安裝完畢的發行版前之前,使用 modprobe efivars 加載 efivars 子產品。 Fedora 使用者可以使用如下指令重新安裝 bootloader

grub2-mkconfig -o /boot/grub2/grub.cfg 指令是來産生新的配置檔案。 Ubuntu 使用者則改用以下指令

一旦 bootloader 正确就位,退出 chroot ,解除安裝所有分區,重新開機到 Grub 2 菜單。

Grub 丢失

Grub 2 最好的特性是可以随時重新安裝,是以,當其它像 Windows 之類的系統用它們自己的 bootloader 替換後,導緻 Grub 2 丢失,你可以使用 live 發行版,寥寥數步即可重裝 Grub ,假設你在/dev/sda5 安裝了一個發行版,若要重裝 Grub ,你隻需首先使用以下指令為發行版建立一個挂載目錄:

然後挂載分區,如下:

接着就能重裝 Grub 了,如下:

這個指令會改寫 /dev/sda 裝置上的 MBR 資訊,指向目前 Linux 系統,并重寫一些 Grub 2 檔案,如 grubenv 和device.map ,另一個問題常見于裝有多個發行版的計算機上:當你安裝了新的 Linux 發行版,它的 bootloader 應當要能找到所有已經安裝的發行版,一旦不行,隻要引導進入新安裝的發行版,并運作

在運作這個指令之前,請確定啟動菜單中缺失的發行版的 root 分區已經挂載,如果你想添加的發行版有單獨的 /root和 /home 分區,在運作 grub2-mkconfig 之前,隻需挂載包含 /root 的分區,雖然 Grub 2 能夠找到大部分發行版,但是在 Ubuntu 中嘗試添加安裝的 Fedora 系統需要額外的一個步驟:如果你以預設設定安裝了 Fedora ,則發行版的安裝器已經建立了 LVM 分區,此時你需要使用發行版的包管理系統安裝 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 進入。

徹底的修複bootloader

如果 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 。啟動終端使用如下指令挂載分區:

此時需要綁定bindGrub 2 bootloader 需要進入的目錄,以便檢測其它作業系統:

此時可以離開 live 環境進入安裝在 /dev/sda5 分區中的發行版了,通過 chroot :

現在可以安裝、檢測、以及更新 Grub 了,跟之前一樣,使用如下指令來重裝 bootloader :

因為 grub2-install 指令不能建立grub.cfg 檔案,需要手動建立,如下

這樣應該就可以了,現在你就有了 Grub 2 的一份全新拷貝,羅列了機器上所有的作業系統和發行版,在重新開機電腦之前,你需要依次退出 chroot 系統,解除安裝所有分區,如下所示:

現在你可以安全地重新開機電腦了,而它應該會回退到 Grub 2 的控制之中,你已經修好了這個 bootloader。

添加自定義菜單項

如果希望往 bootloader 菜單裡添加菜單項,你需要在 40_custom 檔案裡添加一個啟動段boot stanza,例如,你可以使用它展示一個菜單項來啟動安裝在可移動 USB 驅動裡的 Linux 發行版,假設你的 USB 驅動器是 sdb1 ,并且 vmlinuz 核心鏡像和虛拟檔案系統initrd都位于根 (/)目錄下,在 40_custom 檔案中添加以下内容:

相比使用裝置和分區名,使用它們的 UUID 可以獲得更精确結果,比如

使用如下指令來獲得所有已連接配接的驅動器和分區的 UUID :

你還可以為你磁盤上沒被 os-prober 腳本找到的發行版添加菜單項,隻要你知道該發行版的安裝位置以及其核心和虛拟檔案系統initrd的位置即可。

本文轉自Linux就該這麼學部落格園部落格,原文連結:http://www.cnblogs.com/linuxprobe/p/5444327.html,如需轉載請自行聯系原作者

繼續閱讀