1. 程式人生 > >Ubuntu下grub配置詳解

Ubuntu下grub配置詳解

1 Grub簡介

1.1 GNU GRUB

GNU GRUB(簡稱“GRUB”)是一個來自GNU專案的啟動載入程式. GRUB是多啟動規範的實現,它允許使用者可以在計算機內同時擁有多個作業系統,並在計算機啟動時選擇希望執行的作業系統。GRUB可用於選擇作業系統分割槽上的不同核心,也可用於向這些核心傳遞啟動引數.

GNU GRUB的前身為Grand Unified Bootloader。它主要用於類Unix系統;同大多Linux發行版一樣,GNU系統也採用GNU GRUB作為它的啟動器。Solaris從10 1/06版開始在x86系統上也採用GNU GRUB作為啟動器。

1.2 grub Legacy和grub 2

注意:目前 GRUB 分成 GRUB legacy 和 GRUB 2。版本號是 0.9x 以及之前的版本都稱為 GRUB Legacy ,從 1.x 開始的就稱為 GRUB 2

  • 目前 GRUB Legacy 已經停止開發了,只是出於一個修復漏洞的狀態,不再增加新的功能了,所有的開發都轉移到 GURB 2 之上了

  • GRUB 2 是源自於一個名為 PUPA 的專案,目的是建立下一代的 boot loader

GRUB 2 幾乎是從零開始開始開發的,它和 GRUB Legacy 不同的地方有很多,例如支援 scripts、國際化語言、動態載入模組、帶有 resuce 模式等等,這些都是 GRUB Legacy 所沒有的

雖然grub2是重寫的grub,但是他借鑑了grub的一些特徵,grub2改進如下:

  1. 引導配置檔案採用新名字grub.cfg,新的語法,加入許多新的命令

  2. grub.cfg 是用grub-mkconfig自動產生的,由update-grub維護,在執行update-grub之前修改的配置都不會 生效,這樣可以很容易的應對核心升級這樣情況。

  3. grub2中的分割槽號不再是以0開始,而是以1開始。

  4. 配置檔案是不可寫的,而是修改檔案後用命令自動更新

  5. grub2有更可靠的方法在磁碟上有多系統時發現檔案和目標核心,可以用命令發現系統裝置號或者UUID。

  6. 更多的檔案系統支援,如ext4 hfs ntfs

  7. grub2可以直接從lvm和raid讀取檔案

  8. 在grub中的stage1 stage1.5 stage2已經被取消

  9. grub2引入很多裝置模組,允許core映象更小

  10. 支援指令碼,包括簡單的語法

  11. 在啟動時沒有選擇選單的話,按住shift即可強制顯示選單

可以使用grub-install -v來檢視系統的grub版本

grub版本

1.3 GRUB2與GRUB的區別

  1. GRUB2引導選單啟動項是從/boot自動生成的,不是有menu.lst配置的

  2. 執行grub-update之後會自動更新啟動項列表,自動新增有效的作業系統專案

  3. 分割槽編號發生變化:第一個分割槽現在是1而不是0,但第一個裝置仍然以0開始計數,如hd0

  4. 配置檔案的不同更為明顯:

配置檔案
/boot/grub/menu.lst - 已經被/boot/grub/grub.cfg代替
/boot/grub.cfg - 即使是root也不要編輯它,它在每次update-grub後自動生成
/etc/default/grub - 改變引導選單外觀的主要配置檔案
/etc/grub.d/ - 各種用於生成grub.cfg的指令碼檔案,每次update-grub時會執行裡面的檔案

2 選項與文件

2.1 啟動選項

如果您安裝了Ubuntu/linux作業系統和Windows 7/8/10系統組成雙系統.那麼您的Grub啟動選項應該為如下

Ubuntu GNU/Linux  Ubuntu作業系統的啟動項
Advabced options for Ubuntu GNU/Linux 高階選項,進入此處可以選擇啟動的核心版本.
memtest86 #記憶體測試,可以進入此模式執行行一些很耗系統資源的程式,測試系統在高負載的情況下主機是否執行穩定
Windows 7 (loader) (on /dev/sd**) ## /dev/sd**對應你Windows系統所在的分割槽

2.2 相關文件

3 grub元件

grub2的元件為grub-pc, 同時grub-common也會預設被安裝,grub2是過渡期的虛擬元件,會被安全移除。

3.1 grub工具命令

工具包 功能
grub-install 一個完整的grub配置指令碼
update-grub update-grub主要是在每次配置檔案有更新後生成新的grub.cfg, 其實update-grub是呼叫grub-mkconfig,在系統中還有一個update-grub2,發現他是呼叫update-grub
grub-mkconfig 呼叫grub-mkdevicemap和grub-probe生成grub.cfg
grub-set-default 設定在下次進入系統時從哪個核心選項進去
grub-mkdevicemap 為grub自動產生新的device.map,grub-mkdevicemap程式可以建立device.map檔案,在執行grub-install時會自動執行他以建立映像關係,如果檔案不存在,則會讀取/boot/grub/devicd.map這個檔案,如果映像檔案存在,則grub讀取他建立BIOS drives to OS drives
grub-setup 被grub_install呼叫,安裝grub
grub-probe 從給定的裝置上探測裝置資訊

其中grub-install完成如下工作

  1. 安裝grub到裝置中,如果需要會建立/boot/grub目錄

  2. 他會把.mod、.lst、*.img從 /usr/lib/grub/i386-pc/ 目錄複製到/boot/grub目錄下,他會覆蓋已有檔案

  3. 然後會呼叫grub_probe掃描計算機並收集磁碟和分割槽資訊

  4. 接著呼叫grub_mkimage構建一個新的new.img

  5. 最後呼叫grub_setup把grub的boot.img寫入MBR中,把core.img寫進裝置的第一個扇區。

注意

grub_install並不執行grub_mkconfig

示例

grub-install -v

顯示版本號

grub-install /dev/sda

這表示你希望把grub安裝進/dev/sda(把boot.img寫進第一塊硬碟的MBR),如果由於某些原因你想把grub安裝到單獨的boot分割槽,可以使用/dev/sdaX,grub2不建議這樣,因為他會減小grub的可靠性,或者其他使用者用grub-install把grub裝進了錯誤的分割槽導致作業系統的危險性。

grub-install –root-directory=/media/grub2 /dev/sda

建立一個大約60M的分割槽,用檔案系統格式化分割槽,把他掛載到/media/grub2,/dev/sda是指把stage1寫入MBR

mke2fs /dev/fd0
mount -t ext2 /dev/fd0 /mnt
mkdir /mnt/boot
grub-install --boot-directory=/mnt/boot /dev/fd0
umount /dev/fd0

建立一個軟碟機啟動盤

注意

grub-install只是一個指令碼,內部真正執行工作的是grub-mkimage和grub-setup,因此你也可以直接用著兩個命令安裝grub,建議還是用grub-install,除非你非常熟悉grub內部

grub2有兩中不同的引導方法,一個是直接載入作業系統,一個是連鎖(chain-load)到另一個boot load,然後再從另一個boot load載入系統,一般來說第一個更常用,但是假如grub不支援所有的作業系統就需要這種方法

3.2 Grub映象

grub2的映象檔案包括

映象 描述
boot.img 在PC BIOS系統中,boot.img在grub啟動的第一部分,他被寫入MBR或者boot分割槽,因為PC的boot扇區只有512bytes,所以此檔案精確到只有512bytes,他唯一的功能是從本地磁碟讀取核心映象第一個扇區位置然後跳到核心映象,因為檔案大小的限制,boot.img不能識別任何檔案系統,所以當安裝grub時,grub-setup把核心映象第一個扇區的位置硬編碼進boot.img中
diskboot.img 當從硬碟引導時此映象作為核心映象的第一個扇區的內容,他把剩餘的核心映象讀入記憶體中然後啟動核心
cdboot.img 原理同上
pxeboot.img 當從網路用PXE引導時用次映象啟動核心映象
kernel.img 此映象包含grub執行時包含的基本工具,框架驅動、檔案控制代碼、環境變數、安全模式命令列解析器等,他可以直接使用,但是編譯進所有的核心映象中了
core.img 這是grub的核心映象,他被grub-mkimage程式從kernel.img和一些模組動態編譯而成,一般情況下他已經包含足夠的模組去訪問/boot/grub,模組機制可以使得核心映象保持很小
*.mod 其餘的一切是可以動態載入的一些模組,當需要他們時,他們是被自動載入編譯進核心映象的,但也可以使用insmod手動載入

grub legacy的映象檔案

映象 描述
stage1 他非常像grub2中的boot.img,他們有一樣的功能
*_stage1_5 在grub legacy中,stage1_5的作用是包含足夠的系統程式碼從而可以使更大的stage2從普通系統上讀入,他有點像grub2中的core.img但是core.img比他功能強多了,grub legacy可以只使用stage1和stage2在一些受限制的情況下工作,但是grub2沒有core.img就不能工作
stage2 grub2沒有stage2映象,代替的是他執行時從/boot/grub載入模組

4 配置Grub

在早期的Ubuntu版本中,使用grub1作為預設的啟動載入程式,如果想要修改系統啟動選單,直接編輯/boot/grub/menu.lst即可。

從9.10開始, Ubuntu使用grub2作為預設啟動載入程式, 相對於grub的第一個版本,grub2改動很大。 grub2的新特性主要有:支援圖形化介面,支援主題,模組化載入,跨平臺相容等,總而言之,功能的加強也使得grub2的配置變得更加複雜了

4.1 grub配置檔案組成

grub2包含一個完全修改過的配置檔案及目錄,menu.list不再使用

grub2採用模組化的設計,主要配置檔案是/boot/grub/grub.cfg,但是這個檔案的許可權是444,連root也不讓修改,這是刻意為之的,不要修改檔案許可權,grub.cfg的內容更新由update-grub命令來更新,其實就是執行grub-mkconfig -o /boot/grub/grub.cfg來更新,此檔案會在更新核心自動更新, 在/boot/grub目錄下有很多模組檔案,以在按需時自動載入模組每段模組配置的載入以### BEGIN xxx ###開始,以### END xxx ###結尾。

grub2主要有三部分組成:

配置檔案 描述
/etc/default/grub grub的預設配置檔案,可以修改一些常見的引數
/etc/grub.d 這個資料夾下面是一些生成grub.cfg檔案的可執行指令碼,可以修改
/boot/grub/grub.cfg 系統引導時讀取的檔案之一,由其他檔案生成的,一般不在這裡修改

4.2 /etc/default/grub

此檔案包含menu.list的前半部分內容,以及每行核心配置後面追加的配置, 在更新時會合併到grub.cfg中

/etc/default/grub控制grub-mkconfig的操作,grub裡面是以鍵值對存在的選項,如果值有空格或者其他字元需要用引號引起來,引數如下

引數 描述
GRUB_DEFAULT 預設的選單選擇項,值可以是數字,預設從0開始,值也可以是title後面的字串,當值是‘saved’時有特殊含義:預設的選單選則項會被儲存在GRUB_SAVEDEFAULT中,下次啟動時會從這個值啟動。當值為saved是可以用grub-set-default和grub-reboot來設定預設啟動項,grub-set-default直到下次修改前都有效,grub-reboot下次啟動時生效
GRUB_SAVEDEFAULT 只有這個值是true,GRUB_DEFAULT是saved時才會起作用
GRUB_TIMEOUT 選擇選單的顯示時間,預設是5,值是0表示不顯示選單選項,值是-1表示無限期的等待做出選擇
GRUB_HIDDEN_TIMEOUT grub2第一次執行時會尋找其他作業系統,如果沒有檢測到則會將選單隱藏,如果有其他作業系統才會顯示選單,如果引數大於0,則會等待響應的秒數,但是不會顯示選單,可以按住shift顯示選單
GRUB_DISTRIBUTOR 選單中的描述名稱,採用命令lsb_release判斷,應該是紅帽系列的,如果不是就歸為Debian
GRUB_CMDLINE_LINUX 此行將追加到所有的linux 定義核心行的後面,不論是救援模式還是一般模式
GRUB_CMDLINE_LINUX_DEFAULT 次選項只會追加在一般模式後面,同上
GRUB_TERMINAL=console 啟用console,預設註釋狀態
GRUB_DISABLE_LINUX_UUID=true 在grub中指定root時可以使用UUID,預設註釋
GRUB_GFXMODE=640x480 圖形化選單的解析度,預設註釋
GRUB_DISABLE_LINUX_RECOVERY=true 禁止顯示救援模式

定製自己的/etc/default/grub配置檔案, 如下所示

# If you change this file, run 'update-grub' afterwards to update


GRUB_DEFAULT=0
#設定預設啟動項,按menuentry順序如果要預設從第四個選單項啟動,數字改為3,若改為 saved,則預設為上次啟動項



GRUB_TIMEOUT="10"
#設定進入預設啟動項的等候時間,預設值10秒,按自己需要修改,單位為秒改改為零和負值為無限等待操作

GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` #獲得發行版名稱(比如Ubuntu, Debian

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
#選擇啟動的環境,“quiet splash”為影象介面,“text”為文字介面

#GRUB_CMDLINE_LINUX="noresume" 
#手動新增核心啟動引數,比如 acpi=off noapic 等可在這裡新增
# Uncomment to disable graphical terminal (grub-pc only)

#GRUB_TERMINAL=console
#設定是否使用圖形介面。前面有#註釋(使用圖形介面),前面沒有#註釋(僅使用控制檯終端,不使用圖形介面) )

# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command `vbeinfo'
#GRUB_GFXMODE=640x480
#設定圖形介面解析度,如不使用預設。把前面#去掉,把解析度改為800x600或1024x768

# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux
#GRUB_DISABLE_LINUX_UUID=true
#取消註釋以阻止GRUB將傳遞引數 "root=UUID=xxx" 傳遞給 Linux核心

# Uncomment to disable generation of recovery mode menu entrys
#GRUB_DISABLE_LINUX_RECOVERY="true"
#定是否建立修復模式選單項,前面有#註釋(建立修復模式).前面沒有#註釋(不建立修復模式

# Uncomment to get a beep at grub start
#GRUB_INIT_TUNE="480 440 1" #當GRUB選單出現時發出鳴音提醒,戶無法看到螢幕特別有用,預設關閉

4.3 /etc/grub.d/目錄

update-grub命令執行時會讀取此目錄下的檔案,並將配置合併至grub.cfg中,grub.cfg中的選單順序是由此目錄中的檔案順序決定的,檔案開頭數字較小的會先執行,全英文名字的檔案將會在最後執行,自定義選項在40_custom中定義,或者建立一個新檔案,此目錄下的檔案必須有執行許可權才會被update-grub讀取,並把配置合併到grub.cfg中。

配置檔案 描述
00_header 配置初始的顯示專案,如預設選項,時間限制等,一般由/etc/default/grub匯入,一般不需要配置
05_debian_theme 配置引導畫面,文字顏色等主題
10_linux 定位當前作業系統使用中的root裝置核心的位置
30_os-prober 用來搜尋linux和其他系統,此指令碼中的變數用來指定在/boot/grub/grub.cfg 和 grub2選單中的名稱顯示方式,可以修改/etc/default/grub光比這個指令碼
40_custom 用來加入使用者自定義的選單樣板,將會在執行update-grub時更新至grub.cfg中
41_custom 判斷custom.cfg此配置檔案是否存在,如果存在就載入它

ls /etc/grub.d

4.4 /boot/grub/grub.cfg

主要配置檔案是/boot/grub/grub.cfg

ls_boot_grub

但是這個檔案的許可權是444,連root也不讓修改,這是刻意為之的,不要修改檔案許可權

grub.cfg的內容更新由update-grub命令來更新, 我們從下圖中看到系統中/boot中安裝了4.2.0-42版本的核心, 而我們update-grub就會發現他們

update-grub命令來更新

grub.cfg的內容更新由update-grub命令來更新, 其實就是執行如下操作

  1. 備份/boot/grub/menu.lst檔案到/boot/grub/menu.lst~, 以防止出錯後無法恢復

  2. 讀取系統中安裝的所有核心(一般在/boot目錄下), 然後生成.lst檔案

  3. 生成grub.cfg, 其實就是執行grub-mkconfig -o /boot/grub/grub.cfg來更新

    • 首先讀取/etc/default/grub設定基本的設定資訊
    • /boot/grub.d目錄下有很多模組檔案,以在按需時自動載入模組. 依照/etc/grub.d中的各段生成grub.cfg的基本資訊, 每段模組配置的載入以### BEGIN xxx ###開始,以### END xxx ###結尾
    • 讀取menu.lst設定載入的核心的資訊

degin and end

在更新核心時會呼叫update-grub自動更新grub.cfg檔案

5 常見問題

5.1 修改等待時間

sudo gedit /etc/default/grub

修改檔案中的:GRUB_TIMEOUT=10 (預設是為10秒的)

修改為:GRUB_TIMEOUT=X (X表示你要設定的秒數,設定為負數為一直等待操作) 修改後儲存。終端輸入:

5.2 生成grub.cfg

一般來說, update-grub會更新grub並生成grub.cfg

sudo update-grub

當然也可以

sudo grub-mkconfig -o /boot/grub/grub.cfg

5.3 修改預設啟動系統

sudo gedit /etc/default/grub

修改檔案中的GRUB_DEFAULT=0

GRUB_DEFAULT=0 (0預設啟動第1項,如果你的win是第5項,把這個0改為4) 儲存檔案後終端輸入:

5.4 修改預設解析度

sudo gedit /etc/default/grub

修改檔案中的 #GRUB_GFXMODE=640x480
把前面#去掉,把解析度改為800x600或1024x768(或者修改為你螢幕的解析度,但前提是解析度為常見解析度

補充:深度作業系統2014下還需要同時修改 /var/cache/deepin/grub2.json 檔案中的解析度值,如 “Resolution”:”1024x768”

5.5 修復損壞的grub引導

方法一

建議事先備份sda 的grub:

dd if=/dev/sda of=./mbr.bak bs=512 count=1 

這樣子是把你現有的分割槽跟引導資訊儲存下來了。找個linux的live進入linux,然後把剛才的mbr.bak還原回去。

dd if=./mbr.bak of=/dev/sda  bs=446 count=1

方法二
重灌Grub

5.6 GRUB2降級到Grub legacy

備份主要的 Grub2 目錄及檔案。

sudo cp /etc/default/grub /etc/default/grub.old
sudo cp -R /etc/grub.d /etc/grub.d.old
sudo cp -R /boot/grub /boot/grub.old

移除 Grub2

sudo apt-get purge grub2 grub-pc

此時,系統在另一啟動裝載程式前將無法啟動。 當這些軟體包被移除後,許多檔案還會殘留在“/boot/grub”目錄下。
安裝 Grub Legacy

sudo apt-get install grub

Grub 安裝後,使用者仍需通過執行以下命令來建立 menu.lst 和 stage1/stage2 檔案:

sudo update-grub

這一步可以生成 menu.lst 檔案。

sudo grub-install /dev/sdX

選擇正確的裝置(sda、sdb、sdc),通常為你的深度作業系統所在的磁碟。在 /boot/grub 目錄下建立 stage1 和 stage2 檔案並寫入 MBR。執行這一命令來阻止其自動升級:

echo "grub hold" | sudo dpkg --set-selections