如何配置并排除GNU引導(dǎo)加載程序(GRUB)故障
由于 LFCS 考試需求的變動已于 2016 年 2 月 2 日生效,因此我們向 LFCS 系列 添加了一些必要的話題。為了準(zhǔn)備認(rèn)證考試,我們也強(qiáng)烈推薦你去看看 LFCE 系列。
本文將會向你介紹 GRUB 的知識,并會說明你為什么需要一個(gè)引導(dǎo)加載程序,以及它是如何給系統(tǒng)增加功能的。
Linux 引導(dǎo)過程 是從你按下你的電腦電源鍵開始,直到你擁有一個(gè)全功能的系統(tǒng)為止,整個(gè)過程遵循著這樣的主要步驟:
- 一個(gè)叫做 POST(上電自檢)的過程會對你的電腦硬件組件做全面的檢查。
- 當(dāng) POST 完成后,它會把控制權(quán)轉(zhuǎn)交給引導(dǎo)加載程序,接下來引導(dǎo)加載程序會將 Linux 內(nèi)核(以及 initramfs)加載到內(nèi)存中并執(zhí)行。
- 內(nèi)核首先檢查并訪問硬件,然后運(yùn)行初始化進(jìn)程(主要以它的通用名 init 而為人熟知),接下來初始化進(jìn)程會啟動一些服務(wù),***完成系統(tǒng)啟動過程。
在該系列的第七講(“SysVinit、Upstart 和 Systemd”)中,我們介紹了現(xiàn)代 Linux 發(fā)行版使用的一些服務(wù)管理系統(tǒng)和工具。在繼續(xù)學(xué)習(xí)之前,你可能想要回顧一下那一講的知識。
GRUB 引導(dǎo)裝載程序介紹
在現(xiàn)代系統(tǒng)中,你會發(fā)現(xiàn)有兩種主要的 GRUB 版本(一種是有時(shí)被稱為 GRUB Legacy 的 v1 版本,另一種則是 v2 版本),雖說多數(shù)***版本的發(fā)行版系統(tǒng)都默認(rèn)使用了 v2 版本。如今,只有 紅帽企業(yè)版 Linux 6 及其衍生系統(tǒng)仍在使用 v1 版本。
因此,在本指南中,我們將著重關(guān)注 v2 版本的功能。
不管 GRUB 的版本是什么,一個(gè)引導(dǎo)加載程序都允許用戶:
- 通過指定使用不同的內(nèi)核來修改系統(tǒng)的行為;
- 從多個(gè)操作系統(tǒng)中選擇一個(gè)啟動;
- 添加或編輯配置區(qū)塊來改變啟動選項(xiàng)等。
如今,GNU 項(xiàng)目負(fù)責(zé)維護(hù) GRUB,并在它們的網(wǎng)站上提供了豐富的文檔。當(dāng)你在閱讀這篇指南時(shí),我們強(qiáng)烈建議你看下 GNU 官方文檔。
當(dāng)系統(tǒng)引導(dǎo)時(shí),你會在主控制臺看到如下的 GRUB 畫面。最開始,你可以根據(jù)提示在多個(gè)內(nèi)核版本中選擇一個(gè)內(nèi)核(默認(rèn)情況下,系統(tǒng)將會使用***的內(nèi)核啟動),并且可以進(jìn)入 GRUB 命令行模式(使用 c 鍵),或者編輯啟動項(xiàng)(按下 e 鍵)。
GRUB 啟動畫面
你會考慮使用一個(gè)舊版內(nèi)核啟動的原因之一是之前工作正常的某個(gè)硬件設(shè)備在一次升級后出現(xiàn)了“怪毛病(acting up)”(例如,你可以參考 AskUbuntu 論壇中的這條鏈接)。
在啟動時(shí)會從 /boot/grub/grub.cfg 或 /boot/grub2/grub.cfg 文件中讀取GRUB v2 的配置文件,而 GRUB v1 使用的配置文件則來自 /boot/grub/grub.conf 或 /boot/grub/menu.lst。這些文件不應(yīng)該直接手動編輯,而應(yīng)通過 /etc/default/grub 的內(nèi)容和 /etc/grub.d 目錄中的文件來更新。
在 CentOS 7 上,當(dāng)系統(tǒng)最初完成安裝后,會生成如下的配置文件:
- GRUB_TIMEOUT=5
- GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
- GRUB_DEFAULT=saved
- GRUB_DISABLE_SUBMENU=true
- GRUB_TERMINAL_OUTPUT="console"
- GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet"
- GRUB_DISABLE_RECOVERY="true"
除了在線文檔外,你也可以使用下面的命令查閱 GNU GRUB 手冊:
- # info grub
如果你對 /etc/default/grub 文件中的可用選項(xiàng)特別感興趣的話,你可以直接查閱配置一節(jié)的幫助文檔:
- # info -f grub -n 'Simple configuration'
使用上述命令,你會發(fā)現(xiàn) GRUB_TIMEOUT 用于設(shè)置啟動畫面出現(xiàn)和系統(tǒng)自動開始啟動(除非被用戶中斷)之間的時(shí)間。當(dāng)該變量值為 -1 時(shí),除非用戶主動做出選擇,否則不會開始啟動。
當(dāng)同一臺機(jī)器上安裝了多個(gè)操作系統(tǒng)或內(nèi)核后,GRUB_DEFAULT 就需要用一個(gè)整數(shù)來指定 GRUB 啟動畫面默認(rèn)選擇啟動的操作系統(tǒng)或內(nèi)核條目。我們既可以通過上述啟動畫面查看啟動條目列表,也可以使用下面的命令:
在 CentOS 和 openSUSE 系統(tǒng)上
- # awk -F\' '$1=="menuentry " {print $2}' /boot/grub2/grub.cfg
在 Ubuntu 系統(tǒng)上
- # awk -F\' '$1=="menuentry " {print $2}' /boot/grub/grub.cfg
如下圖所示的例子中,如果我們想要使用版本為 3.10.0-123.el7.x86_64 的內(nèi)核(第四個(gè)條目),我們需要將 GRUB_DEFAULT 設(shè)置為 3(條目從零開始編號),如下所示:
- GRUB_DEFAULT=3
使用舊版內(nèi)核啟動系統(tǒng)
***一個(gè)需要特別關(guān)注的 GRUB 配置變量是 GRUB_CMDLINE_LINUX,它是用來給內(nèi)核傳遞選項(xiàng)的。我們可以在 內(nèi)核變量文件 和 man 7 bootparam 中找到能夠通過 GRUB 傳遞給內(nèi)核的選項(xiàng)的詳細(xì)文檔。
我的 CentOS 7 服務(wù)器上當(dāng)前的選項(xiàng)是:
- GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet"
為什么你希望修改默認(rèn)的內(nèi)核參數(shù)或者傳遞額外的選項(xiàng)呢?簡單來說,在很多情況下,你需要告訴內(nèi)核某些由內(nèi)核自身無法判斷的硬件參數(shù),或者是覆蓋一些內(nèi)核檢測的值。
不久之前,就在我身上發(fā)生過這樣的事情,當(dāng)時(shí)我在自己已用了 10 年的老筆記本上嘗試了衍生自 Slackware 的 Vector Linux。完成安裝后,內(nèi)核并沒有檢測出我的顯卡的正確配置,所以我不得不通過 GRUB 傳遞修改過的內(nèi)核選項(xiàng)來讓它工作。
另外一個(gè)例子是當(dāng)你需要將系統(tǒng)切換到單用戶模式以執(zhí)行維護(hù)工作時(shí)。為此,你可以直接在 GRUB_CMDLINE_LINUX 變量中直接追加 single 并重啟即可:
- GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet single"
編輯完 /etc/default/grub 之后,你需要運(yùn)行 update-grub (在 Ubuntu 上)或者 grub2-mkconfig -o /boot/grub2/grub.cfg (在 CentOS 和 openSUSE 上)命令來更新 grub.cfg 文件(否則,改動會在系統(tǒng)啟動時(shí)丟失)。
這條命令會處理早先提到的那些啟動配置文件來更新 grub.cfg 文件。這種方法可以確保改動持久化,而在啟動時(shí)刻通過 GRUB 傳遞的選項(xiàng)僅在當(dāng)前會話期間有效。
修復(fù) Linux GRUB 問題
如果你安裝了第二個(gè)操作系統(tǒng),或者由于人為失誤而導(dǎo)致你的 GRUB 配置文件損壞了,依然有一些方法可以讓你恢復(fù)并能夠再次啟動系統(tǒng)。
在啟動畫面中按下 c 鍵進(jìn)入 GRUB 命令行模式(記住,你也可以按下 e 鍵編輯默認(rèn)啟動選項(xiàng)),并可以在 GRUB 提示中輸入 help 命令獲得可用命令:
修復(fù) Linux 的 Grub 配置問題
我們將會著重關(guān)注 ls 命令,它會列出已安裝的設(shè)備和文件系統(tǒng),并且我們將會看看它查找到的東西。在下面的圖片中,我們可以看到有 4 塊硬盤(hd0 到 hd3)。
貌似只有 hd0 已經(jīng)分區(qū)了(msdos1 和 msdos2 可以證明,這里的 1 和 2 是分區(qū)號,msdos 則是分區(qū)方案)。
現(xiàn)在我們來看看能否在***個(gè)分區(qū) hd0(msdos1)上找到 GRUB。這種方法允許我們啟動 Linux,并且使用高級工具修復(fù)配置文件,或者如果有必要的話,干脆重新安裝 GRUB:
- # ls (hd0,msdos1)/
從高亮區(qū)域可以發(fā)現(xiàn),grub2 目錄就在這個(gè)分區(qū):
查找 Grub 配置
一旦我們確信了 GRUB 位于 (hd0, msdos1),那就讓我們告訴 GRUB 該去哪兒查找它的配置文件并指示它去嘗試啟動它的菜單:
- set prefix=(hd0,msdos1)/grub2
- set root=(hd0,msdos1)
- insmod normal
- normal
查找并啟動 Grub 菜單
然后,在 GRUB 菜單中,選擇一個(gè)條目并按下回車鍵以使用它啟動。一旦系統(tǒng)成功啟動后,你就可以運(yùn)行 grub2-install /dev/sdX 命令修復(fù)問題了(將 sdX 改成你想要安裝 GRUB 的設(shè)備)。然后啟動信息將會更新,并且所有相關(guān)文件都會得到恢復(fù)。
- # grub2-install /dev/sdX
其它更加復(fù)雜的情景及其修復(fù)建議都記錄在 Ubuntu GRUB2 故障排除指南 中。該指南中闡述的概念對于其它發(fā)行版也是有效的。
總結(jié)
本文向你介紹了 GRUB,并指導(dǎo)你可以在何處找到線上和線下的文檔,同時(shí)說明了如何面對由于引導(dǎo)加載相關(guān)的問題而導(dǎo)致系統(tǒng)無法正常啟動的情況。
幸運(yùn)的是,GRUB 是文檔支持非常豐富的工具之一,你可以使用我們在文中分享的資源非常輕松地獲取已安裝的文檔或在線文檔。