閱讀928 返回首頁    go 技術社區[雲棲]


LFCS 係列第十三講:如何配置並排除 GNU 引導加載程序(GRUB)故障

由於 LFCS 考試需求的變動已於 2016 年 2 月 2 日生效,因此我們向 LFCS 係列 添加了一些必要的話題。為了準備認證考試,我們也強烈推薦你去看看 LFCE 係列

LFCS 係列第十三講:配置並排除 Grub 引導加載程序故障。

本文將會向你介紹 GRUB 的知識,並會說明你為什麼需要一個引導加載程序,以及它是如何給係統增加功能的。

Linux 引導過程 是從你按下你的電腦電源鍵開始,直到你擁有一個全功能的係統為止,整個過程遵循著這樣的主要步驟:

  • 1. 一個叫做 POST上電自檢)的過程會對你的電腦硬件組件做全麵的檢查。
  • 2. 當 POST 完成後,它會把控製權轉交給引導加載程序,接下來引導加載程序會將 Linux 內核(以及initramfs)加載到內存中並執行。
  • 3. 內核首先檢查並訪問硬件,然後運行初始化進程(主要以它的通用名 init 而為人熟知),接下來初始化進程會啟動一些服務,最後完成係統啟動過程。

在該係列的第七講(“SysVinit、Upstart 和 Systemd”)中,我們介紹了現代 Linux 發行版使用的一些服務管理係統和工具。在繼續學習之前,你可能想要回顧一下那一講的知識。

GRUB 引導裝載程序介紹

在現代係統中,你會發現有兩種主要的 GRUB 版本(一種是有時被稱為 GRUB Legacy 的 v1 版本,另一種則是 v2 版本),雖說多數最新版本的發行版係統都默認使用了 v2 版本。如今,隻有 紅帽企業版 Linux 6 及其衍生係統仍在使用 v1 版本。

因此,在本指南中,我們將著重關注 v2 版本的功能。

不管 GRUB 的版本是什麼,一個引導加載程序都允許用戶:

  1. 通過指定使用不同的內核來修改係統的行為;
  2. 從多個操作係統中選擇一個啟動;
  3. 添加或編輯配置區塊來改變啟動選項等。

如今,GNU 項目負責維護 GRUB,並在它們的網站上提供了豐富的文檔。當你在閱讀這篇指南時,我們強烈建議你看下 GNU 官方文檔

當係統引導時,你會在主控製台看到如下的 GRUB 畫麵。最開始,你可以根據提示在多個內核版本中選擇一個內核(默認情況下,係統將會使用最新的內核啟動),並且可以進入 GRUB 命令行模式(使用 c 鍵),或者編輯啟動項(按下 e 鍵)。

GRUB 啟動畫麵

GRUB 啟動畫麵

你會考慮使用一個舊版內核啟動的原因之一是之前工作正常的某個硬件設備在一次升級後出現了“怪毛病(acting up)”(例如,你可以參考 AskUbuntu 論壇中的這條鏈接)。

在啟動時會從 /boot/grub/grub.cfg 或 /boot/grub2/grub.cfg 文件中讀取GRUB v2 的配置文件,而GRUB v1 使用的配置文件則來自 /boot/grub/grub.conf 或 /boot/grub/menu.lst。這些文件不應該直接手動編輯,而應通過 /etc/default/grub 的內容和 /etc/grub.d 目錄中的文件來更新。

在 CentOS 7 上,當係統最初完成安裝後,會生成如下的配置文件:


  1. GRUB_TIMEOUT=5
  2. GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
  3. GRUB_DEFAULT=saved
  4. GRUB_DISABLE_SUBMENU=true
  5. GRUB_TERMINAL_OUTPUT="console"
  6. 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"
  7. GRUB_DISABLE_RECOVERY="true"

除了在線文檔外,你也可以使用下麵的命令查閱 GNU GRUB 手冊:


  1. # info grub

如果你對 /etc/default/grub 文件中的可用選項特別感興趣的話,你可以直接查閱配置一節的幫助文檔:


  1. # info -f grub -n 'Simple configuration'

使用上述命令,你會發現 GRUB_TIMEOUT 用於設置啟動畫麵出現和係統自動開始啟動(除非被用戶中斷)之間的時間。當該變量值為 -1 時,除非用戶主動做出選擇,否則不會開始啟動。

當同一台機器上安裝了多個操作係統或內核後,GRUB_DEFAULT 就需要用一個整數來指定 GRUB 啟動畫麵默認選擇啟動的操作係統或內核條目。我們既可以通過上述啟動畫麵查看啟動條目列表,也可以使用下麵的命令:

在 CentOS 和 openSUSE 係統上


  1. # awk -F\' '$1=="menuentry " {print $2}' /boot/grub2/grub.cfg

在 Ubuntu 係統上


  1. # awk -F\' '$1=="menuentry " {print $2}' /boot/grub/grub.cfg

如下圖所示的例子中,如果我們想要使用版本為 3.10.0-123.el7.x86_64 的內核(第四個條目),我們需要將 GRUB_DEFAULT 設置為 3(條目從零開始編號),如下所示:


  1. GRUB_DEFAULT=3

使用舊版內核啟動係統

使用舊版內核啟動係統

最後一個需要特別關注的 GRUB 配置變量是 GRUB_CMDLINE_LINUX,它是用來給內核傳遞選項的。我們可以在 內核變量文件 和 man 7 bootparam 中找到能夠通過 GRUB 傳遞給內核的選項的詳細文檔。

我的 CentOS 7 服務器上當前的選項是:


  1. 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"

為什麼你希望修改默認的內核參數或者傳遞額外的選項呢?簡單來說,在很多情況下,你需要告訴內核某些由內核自身無法判斷的硬件參數,或者是覆蓋一些內核檢測的值。

不久之前,就在我身上發生過這樣的事情,當時我在自己已用了 10 年的老筆記本上嚐試了衍生自 Slackware的 Vector Linux。完成安裝後,內核並沒有檢測出我的顯卡的正確配置,所以我不得不通過 GRUB 傳遞修改過的內核選項來讓它工作。

另外一個例子是當你需要將係統切換到單用戶模式以執行維護工作時。為此,你可以直接在GRUB_CMDLINE_LINUX 變量中直接追加 single 並重啟即可:


  1. 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 之後,你需要運行 update-grub (在 Ubuntu 上)或者 grub2-mkconfig -o /boot/grub2/grub.cfg (在 CentOS 和 openSUSE 上)命令來更新 grub.cfg 文件(否則,改動會在係統啟動時丟失)。

這條命令會處理早先提到的那些啟動配置文件來更新 grub.cfg 文件。這種方法可以確保改動持久化,而在啟動時刻通過 GRUB 傳遞的選項僅在當前會話期間有效。

修複 Linux GRUB 問題

如果你安裝了第二個操作係統,或者由於人為失誤而導致你的 GRUB 配置文件損壞了,依然有一些方法可以讓你恢複並能夠再次啟動係統。

在啟動畫麵中按下 c 鍵進入 GRUB 命令行模式(記住,你也可以按下 e 鍵編輯默認啟動選項),並可以在 GRUB 提示中輸入 help 命令獲得可用命令:

修複 Linux 的 Grub 配置問題

修複 Linux 的 Grub 配置問題

我們將會著重關注 ls 命令,它會列出已安裝的設備和文件係統,並且我們將會看看它查找到的東西。在下麵的圖片中,我們可以看到有 4 塊硬盤(hd0 到 hd3)。

貌似隻有 hd0 已經分區了(msdos1 和 msdos2 可以證明,這裏的 1 和 2 是分區號,msdos 則是分區方案)。

現在我們來看看能否在第一個分區 hd0msdos1)上找到 GRUB。這種方法允許我們啟動 Linux,並且使用高級工具修複配置文件,或者如果有必要的話,幹脆重新安裝 GRUB:


  1. # ls (hd0,msdos1)/

從高亮區域可以發現,grub2 目錄就在這個分區:

查找 Grub 配置

查找 Grub 配置

一旦我們確信了 GRUB 位於 (hd0, msdos1),那就讓我們告訴 GRUB 該去哪兒查找它的配置文件並指示它去嚐試啟動它的菜單:


  1. set prefix=(hd0,msdos1)/grub2
  2. set root=(hd0,msdos1)
  3. insmod normal
  4. normal

查找並啟動 Grub 菜單

查找並啟動 Grub 菜單

然後,在 GRUB 菜單中,選擇一個條目並按下回車鍵以使用它啟動。一旦係統成功啟動後,你就可以運行grub2-install /dev/sdX 命令修複問題了(將 sdX 改成你想要安裝 GRUB 的設備)。然後啟動信息將會更新,並且所有相關文件都會得到恢複。


  1. # grub2-install /dev/sdX

其它更加複雜的情景及其修複建議都記錄在 Ubuntu GRUB2 故障排除指南 中。該指南中闡述的概念對於其它發行版也是有效的。

原文發布時間為:2016-09-04

本文來自雲棲社區合作夥伴“Linux中國”

最後更新:2017-06-07 17:03:56

  上一篇:go  MySQL 中你應該使用什麼數據類型表示時間?
  下一篇:go  LFCS 係列第十四講: Linux 進程資源用量監控和按用戶設置進程限製