Linux GRUB2配置簡介
學(xué)習(xí) GRUB 引導(dǎo)加載程序是如何預(yù)備你的系統(tǒng)并啟動操作系統(tǒng)內(nèi)核的。
自從上個月為我的文章《Linux 引導(dǎo)和啟動過程簡介》做研究開始,我對更深入了解 GRUB2 產(chǎn)生了興趣。這篇文章提供了配置 GRUB2 的簡要介紹。為了簡便起見,我大多數(shù)情況下會使用 GRUB 指代 GRUB2。
GRUB
GRUB 來自 GRand Unified Bootloader 的縮寫。它的功能是在啟動時從 BIOS 接管掌控、加載自身、加載 Linux 內(nèi)核到內(nèi)存,然后再把執(zhí)行權(quán)交給內(nèi)核。一旦內(nèi)核開始掌控,GRUB 就完成了它的任務(wù),也就不再需要了。
GRUB 支持多種 Linux 內(nèi)核,并允許用戶在啟動時通過菜單在其中選擇。我發(fā)現(xiàn)這是一種非常有用的工具,因為我有很多次遇到一個應(yīng)用程序或者系統(tǒng)服務(wù)在特定內(nèi)核版本下失敗的問題。有好幾次,引導(dǎo)到一個較舊的內(nèi)核時就可以避免類似的問題。默認(rèn)情況下,使用 yum 或 dnf 進(jìn)行更新時會保存三個內(nèi)核 - 最新的以及兩個比較舊的。在被包管理器刪除之前所保留的內(nèi)核數(shù)目可以在 /etc/dnf/dnf.conf 或 /etc/yum.conf 文件中配置。我通常把 installonly_limit 的值修改為 9 以便保留 9 個內(nèi)核。當(dāng)我不得不恢復(fù)到低幾個版本的內(nèi)核時這非常有用。
GRUB 菜單
GRUB 菜單的功能是當(dāng)默認(rèn)的內(nèi)核不是想要的時,允許用戶從已經(jīng)安裝的內(nèi)核中選擇一個進(jìn)行引導(dǎo)。通過上下箭頭鍵允許你選中想要的內(nèi)核,敲擊回車鍵會使用選中的內(nèi)核繼續(xù)引導(dǎo)進(jìn)程。
GRUB 菜單也提供了超時機制,因此如果用戶沒有做任何選擇,GRUB 就會在沒有用戶干預(yù)的情況下使用默認(rèn)內(nèi)核繼續(xù)引導(dǎo)。敲擊鍵盤上除了回車鍵之外的任何鍵會停止終端上顯示的倒數(shù)計時器。立即敲擊回車鍵會使用默認(rèn)內(nèi)核或者選中的內(nèi)核繼續(xù)引導(dǎo)進(jìn)程。
GRUB 菜單提供了一個 “救援rescue” 內(nèi)核,用于故障排除或者由于某些原因?qū)е碌某R?guī)內(nèi)核不能完成啟動過程。不幸的是,這個救援內(nèi)核不會引導(dǎo)到救援模式。文章后面會更詳細(xì)介紹這方面的東西。
grub.cfg 文件
grub.cfg 文件是 GRUB 配置文件。它由 grub2-mkconfig 程序根據(jù)用戶的配置使用一組主配置文件以及 grub 默認(rèn)文件而生成。/boot/grub2/grub.cfg 文件在 Linux 安裝時會初次生成,安裝新內(nèi)核時又會重新生成。
grub.cfg 文件包括了類似 Bash 腳本的代碼以及一個按照安裝順序排序的已安裝內(nèi)核列表。例如,如果你有 4 個已安裝內(nèi)核,最新的內(nèi)核索引是 0,前一個內(nèi)核索引是 1,最舊的內(nèi)核索引是 3。如果你能訪問 grub.cfg 文件,你應(yīng)該去看看感受一下它看起來是什么樣。grub.cfg 太大也就沒有包含在這篇文章中。
GRUB 配置文件
grub.cfg 的主要配置文件都在 /etc/grub.d 目錄。該目錄中的每個文件都包含了最終會整合到 grub.cfg 文件中的 GRUB 代碼。這些配置文件的命名模式以排序方式設(shè)計,這使得最終的 grub.cfg 文件可以按正確的順序整合而成。每個文件都有注釋表明該部分的開始和結(jié)束,這些注釋也是最終的 grub.cfg 文件的一部分,從而可以看出每個部分是由哪個文件生成。分隔注釋看起來像這樣:
- ### BEGIN /etc/grub.d/10_linux ###
- ### END /etc/grub.d/10_linux ###
不要修改這些文件,除非你是一個 GRUB 專家并明白更改會發(fā)生什么。無論如何,修改 grub.cfg 文件時你也總應(yīng)該保留一個原始文件的備份。 40_custom 和 41_custom 這兩個特別的文件用于生成用戶對 GRUB 配置的修改。你仍然要注意對這些文件的更改的后果,并保存一份原始 grub.cfg 文件的備份。
你也可以把你自己的文件添加到 /etc/grub.d 目錄。這樣做的一個可能的原因是為非 Linux 操作系統(tǒng)添加菜單行。要注意遵循命名規(guī)則,確保配置文件中額外的菜單選項剛好在 10_linux 條目之前或之后。
GRUB 默認(rèn)文件
老版本 GRUB 的配置非常簡單而明了,我只需要修改 /boot/grub/grub.conf 就可以了。對于新版本的 GRUB2,我雖然還可以通過更改 /boot/grub2/grub.cfg 來修改,但和老版本的 GRUB 相比,新版本相對更加復(fù)雜。另外,安裝一個新內(nèi)核時 grub.cfg 可能會被重寫,因此任何修改都可能消失。當(dāng)然,GNU.org 的 GRUB 手冊確實有過直接創(chuàng)建和修改 /boot/grub2/grub.cfg 的討論。
一旦你明白了如何做,更改 GRUB2 配置就會變得非常簡單。我為之前的文章研究 GRUB2 的時候才明白這個。秘方就在 /etc/default 目錄里面,一個自然而然稱為 grub 的文件,它可以通過簡單的終端命令操作。/etc/default 目錄包括了一些類似 Google Chrome、 useradd、 和 grub 程序的配置文件。
/etc/default/grub 文件非常簡單。這個 grub 默認(rèn)文件已經(jīng)列出了一些有效的鍵值對。你可以簡單地更改現(xiàn)有鍵值或者添加其它文件中還沒有的鍵。下面的列表 1 顯示了一個沒有更改過的 /etc/default/grub 文件。
- 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="rd.lvm.lv=fedora_fedora25vm/root
- rd.lvm.lv=fedora_fedora25vm/swap
- rd.lvm.lv=fedora_fedora25vm/usr rhgb quiet"
- GRUB_DISABLE_RECOVERY="true"
列表 1:Fedora 25 一個原始 grub 默認(rèn)文件。
GRUB 手冊 5.1 章節(jié)包括了所有可以添加到該 grub 文件的鍵的信息。我只需要修改 grub 默認(rèn)文件已經(jīng)有的一些鍵值就夠了。讓我們看看這些鍵值以及一些在 grub 默認(rèn)文件中沒有出現(xiàn)的每個鍵的意義。
- GRUB_TIMEOUT 這個鍵的值決定了顯示 GRUB 選擇菜單的時間長度。GRUB 提供了同時保存多個安裝內(nèi)核并在啟動時使用 GRUB 菜單在其中選擇的功能。這個鍵的默認(rèn)值是 5 秒,但我通常修改為 10 秒使得有更多時間查看選項并作出選擇。
- GRUB_DISTRIBUTOR 這個鍵定義了一個從 /etc/system-release 文件中提取發(fā)行版本的 sed 表達(dá)式。這個信息用于生成出現(xiàn)在 GRUB 菜單中的每個內(nèi)核發(fā)布版的文本名稱,例如 “Fedora” 等。由于不同發(fā)行版之間 system-release 文件結(jié)構(gòu)的差異,在你的系統(tǒng)中這個 sed 表達(dá)式可能有些不同。
- GRUB_DEFAULT 決定默認(rèn)引導(dǎo)哪個內(nèi)核。如果是 saved,這代表最新內(nèi)核。這里的其它選項如果是數(shù)字則代表了 grub.cfg 中列表的索引。使用索引號 3,就會總是加載列表中的第四個內(nèi)核,即使安裝了一個新內(nèi)核之后也是。因此使用索引數(shù)字的話,在安裝一個新內(nèi)核后會加載不同的內(nèi)核。要確保引導(dǎo)特定內(nèi)核版本的唯一方法是設(shè)置 GRUB_DEFAULT 的值為想要內(nèi)核的名稱,例如 4.8.13-300.fc25.x86_64。
- GRUB_SAVEDEFAULT 通常,grub 默認(rèn)文件中不會指定這個選項。當(dāng)選擇不同內(nèi)核進(jìn)行引導(dǎo)時,正常操作下該內(nèi)核只會啟動一次。默認(rèn)內(nèi)核不會改變。當(dāng)其設(shè)置為 true 并和 GRUB_DEFAULT=saved 一起使用時,這個選項會保存一個不同內(nèi)核作為默認(rèn)值。當(dāng)選擇不同內(nèi)核進(jìn)行引導(dǎo)時會發(fā)生這種情況。
- GRUB_DISABLE_SUBMENU 一些人可能會希望為 GRUB 菜單創(chuàng)建一個內(nèi)核的層級菜單結(jié)構(gòu)。這個鍵和 grub.cfg 中一些額外內(nèi)核配置允許創(chuàng)建這樣的層級結(jié)構(gòu)。例如,主菜單中可能有 production 和 test 子菜單,每個子菜單中包括了一些合適的內(nèi)核。設(shè)置它為 false 可以啟用子菜單。
- GRUB_TERMINAL_OUTPUT 一些環(huán)境下可能需要或者必要將輸出重定向到一個不同的顯示控制臺或者終端。默認(rèn)情況下是把輸出發(fā)送到默認(rèn)終端,通常 console 等價于 Intel 系列個人電腦的標(biāo)準(zhǔn)輸出。另一個有用的選擇是在使用串行終端或者 Integrated Lights Out (ILO) 終端連接的數(shù)據(jù)中心或者實驗室環(huán)境中指定 serial。
- GRUB_TERMINAL_INPUT 和 GRUB_TERMINAL_OUTPUT 類似,可能需要或者必要重定向輸入為串行終端或者 ILO 設(shè)備、而不是標(biāo)準(zhǔn)鍵盤輸入。
- GRUB_CMDLINE_LINUX 這個鍵包括了在啟動時會傳遞給內(nèi)核的命令行參數(shù)。注意這些參數(shù)會被添加到 grub.cfg 所有已安裝內(nèi)核的內(nèi)核行。這意味著所有已安裝的內(nèi)核在啟動時都會有相同的參數(shù)。我通常刪除 rhgb 和 quiet 參數(shù)以便我可以看到引導(dǎo)和啟動時內(nèi)核和 systemd 輸出的所有內(nèi)核信息消息。
- GRUB_DISABLE_RECOVERY 當(dāng)這個鍵的值被設(shè)置為 false,GRUB 菜單中就會為每個已安裝的內(nèi)核創(chuàng)建一個恢復(fù)條目。當(dāng)設(shè)置為 true 時就不會創(chuàng)建任何恢復(fù)條目。但不管這個設(shè)置怎樣,最后的內(nèi)核條目總是一個 rescue 選項。不過在 rescue 選項中我遇到了一個問題,下面我會詳細(xì)介紹。
還有一些你可能覺得有用但我沒有在這里介紹的鍵。它們的描述可以在 GRUB 手冊 2 的 5.1 章節(jié)找到。
生成 grub.cfg
完成所需的配置之后,就需要生成 /boot/grub2/grub.cfg 文件。這通過下面的命令完成。
- grub2-mkconfig > /boot/grub2/grub.cfg
這個命令按照順序使用位于 /etc/grub.d 的配置文件構(gòu)建 grub.cfg 文件,然后使用 grub 默認(rèn)文件的內(nèi)容修改輸出以便獲得最終所需的配置。grub2-mkconfig 命令會嘗試定位所有已安裝的內(nèi)核并在 grub.cfg 文件的 10_Linux 部分新建條目。它還創(chuàng)建一個 rescue 條目提供一個用于從 Linux 不能啟動的嚴(yán)重問題中恢復(fù)的方法。
強烈建議你不要手動編輯 grub.cfg 文件,因為任何對該文件的直接修改都會在下一次安裝新內(nèi)核或者手動運行 grub2-mkconfig 時被重寫。
問題
我遇到一個如果沒有意識到就可能導(dǎo)致嚴(yán)重后果的 GRUB2 問題。這個救援內(nèi)核沒有啟動,反而啟動了另外一個內(nèi)核。我發(fā)現(xiàn)那是列表中索引為 1 的內(nèi)核,也就是列表中的第二個內(nèi)核。額外的測試發(fā)現(xiàn)不管使用原始的還是我生成的 grub.cfg 配置文件都會發(fā)生這個問題。我在虛擬機和真實硬件上都嘗試過而且都發(fā)生了這個問題。我只測試了 Fedora 25,因此其它 Fedora 發(fā)行版本可能沒有這個問題。
注意,從救援內(nèi)核生成的 “recovery” 內(nèi)核條目不能引導(dǎo)到維護(hù)模式。
我推薦將 grub 默認(rèn)文件中 GRUB_DISABLE_RECOVERY 的值更改為 “false”,然后生成你自己的 grub.cfg。這會在 GRUB 菜單中為每個已安裝的內(nèi)核生成可用的恢復(fù)條目。這些恢復(fù)配置能像期望那樣工作,從而從那些需要輸入密碼登錄的內(nèi)核條目中引導(dǎo)到運行級別 1,也就是進(jìn)入(不需要密碼的)單用戶維護(hù)模式。你也可以按 Ctrl-D 繼續(xù)正常的引導(dǎo)進(jìn)入默認(rèn)運行級別。
總結(jié)
GRUB 是引導(dǎo) Linux 計算機到可用狀態(tài)過程的一系列事件中,發(fā)生在 BIOS 之后的第一步。理解如何配置 GRUB 對于恢復(fù)或者處理多種類型的問題非常重要。
這么多年來我多次不得不引導(dǎo)到恢復(fù)或者救援模式以便解決多種類型的問題。其中的一些問題確實是類似 /etc/fstab 或其它配置文件中不恰當(dāng)條目導(dǎo)致的引導(dǎo)問題,也有一些是由于應(yīng)用程序或者系統(tǒng)軟件和最新的內(nèi)核不兼容的問題。硬件兼容性問題也可能妨礙特定的內(nèi)核啟動。
我希望這些信息能對你開啟 GRUB 配置之旅有所幫助。
( 題圖 : Internet Archive Book Images. Opensource.com 修改。 CC BY-SA 4.0)