29.3. 使用 GRUB 開機

GRUB (Grand Unified Bootloader) 包含兩個階段。第一個階段包含 512 個位元組並寫入 MBR 或硬碟分割區或磁片的開機磁區。接下來,會載入第二個階段。此階段包含實際的程式碼。第一個階段的唯一工作是載入開機載入器的第二個階段。

stage2 可以存取檔案系統。目前支援,Ext2、Ext3、ReiserFS、Minix 和 Winodws 使用的 DOS FAT 檔案系統。對於 JFS、XFS、UFS 以及 BSD 使用的 FFS,也支援到一定的程度。自 0.95 版開始,GRUB 也可以從包含符合 "El Torito" 規格的 ISO 9660 標準檔案系統的 CD 或 DVD 啟動。即使在系統啟動之前,GRUB 可以存取支援的 BIOS 磁碟機 (BIOS 偵測到的磁片或硬碟、CD 光碟機和 DVD 磁碟機) 的系統。因此,對 GRUB 組態檔 (menu.lst) 所做的變更,將不再需要重新安裝開機管理員。啟動系統後,GRUB 會重新載入功能表檔案以及核心或起始 RAM 磁碟 (initrd) 的有效路徑和分割區資料,然後找這些檔案。

GRUB 的實際組態是以下列敘述的三個檔案為基礎:

/boot/grub/menu.lst

此檔案包含可以使用 GRUB 開機的分割區或作業系統,所有的相關資訊。沒有此資訊,系統控制權便無法傳送給作業系統。

/boot/grub/device.map

此檔案會從 GRUB 和 BIOS 表示法,將設備名稱轉譯成 Linux 設備名稱。

/etc/grub.conf

此檔案包含 GRUB 外圍程序正確安裝開機載入器時需要的參數和選項。

GRUB 有多種方法可以控制 。現有組態啟動項目,可以從圖形功能表選取 (開頭顯示畫面)。組態會從檔案 menu.lst 載入。

在 GRUB,開機前可以變更所有開機參數。例如,編輯功能表檔案發生的錯誤,可以用此方法更正。開機指令也可透過輸入提示輸入 (請參閱 節 29.3.1.3, "在開機程序期間編輯功能表項目")。GRUB 提供開機前,判斷核心和 initrd 二者位置的可能性。以此方法,您還可以為開機載入器組態中不存在的項目,啟動安裝的作業系統。

GRUB 外圍程序在安裝的系統中,提供 GRUB 的模組。它可以在實際套用之前,安裝 GRUB 或測試新設定。請參閱 節 29.3.4, "GRUB 外圍程序"

29.3.1. GRUB 開機功能表

圖形開頭顯示畫面以及開機功能表是以 GRUB 組態檔 /boot/grub/menu.lst 為基礎的,它包含可以透過功能表啟動的所有分割區或作業系統,全部的相關資訊。

每次啟動系統時,GRUB 會從檔案系統載入功能表檔案。基於此因素,GRUB 不需要在每次變更檔案後,重新安裝。使用 YaST 開機載入器來修改 GRUB 組態,如 節 29.4, " 使用 YaST 設定開機載入器" 所述一般。

功能表檔案包含指令。語法相當簡單。每一行包含一個指令,後面是由像外圍程序中的空格所分開的選用參數。基於歷史因素,部份指令可以允許 = 放在第一個參數前面。註解是以井字號 (#) 開頭。

要識別功能表概觀中的功能表項目,為每一個項目指定標題。關鍵字標題後面的文字 (包括任何空格) 會在功能表中顯示成可選取的選項。下一個標題的所有指令,會在選取此功能表項目時執行。

最簡單的案例是重新導向至其他作業系統的開機載入器。指令是 chainloader 及引數通常是 GRUB 區塊表示法中,其他分割區的開機區塊。例如:

chainloader (hd0,3)+1

GRUB 中的設備名稱會在 節 29.3.1.1, "硬碟和分割區的命名慣例" 說明。上述範例指定第一個硬碟中,第四個分割區的第一個區塊。

使用指令 kernel 來指定核心影像。第一個引數是分割區中,核心影像的路徑。其他引數會傳送到指令行上的核心。

如果核心沒有內建的驅動程式可存取根分割區,initrd 必須以個別的 GRUB 指令來指定,它唯一的引數是 initrd 檔案的路徑。因為 initrd 的載入位址是記錄於載入的核心影像,所以指令 initrd 必須立即接在 kernel 指令的後面。

指令 root 會簡化核心和 initrd 檔案的指定。root 的唯一引數是 GRUB 設備或 GRUB 設備上的分割區。此設備是用於所有核心、initrd 或其它檔案路徑,就檔案路徑而言,直到下一個 root 指令下達時,才會明確指定設備。此指令不是用於安裝時產生的 menu.lst 檔案。它只是利於手動編輯。

boot 指令會在每一個功能表項目最後暗示,所以它不需要寫入功能表檔案。不過,如果您使用互動式 GRUB 來開機,必須在最後輸入 boot 指令。指令本身沒有引數。它只是啟動載入的核心影像或指定的鏈結載入器。

撰寫所有功能表項目之後,將其中一個定義為預設項目。否則,會使用第一個 (項目 0) 做為預設項目。您也可以指定預設項目要在幾秒後開機。timeoutdefault 通常在功能表項目前面。節 29.3.1.2, "範例功能表檔案" 會敘述一個範例檔案。

29.3.1.1. 硬碟和分割區的命名慣例

硬碟和分割區使用的命名慣例 GRUB 與一般 Linux 設備使用的命名慣例不同。在 GRUB,分割區的編號會從 0 開始。因此,(hd0,0) 是第一個硬碟的第一個分割區。與一般桌上型機器的 primary master 硬碟對應的 Linux 設備名稱是 /dev/hda1

四個可能的主要分割區會指定分割區編號 03。邏輯分割區是從 4 開始編號:

(hd0,0)   第一個硬碟的主分割區
(hd0,1)   第二個主分割區
(hd0,2)   第三個主分割區
(hd0,3)   第四個主分割區 (一般是擴充分割區)
(hd0,4)   第一個邏輯分割區
(hd0,5)   第二個邏輯分割區
    

GRUB 不會區分 IDE、SCSI 和 RAID 設備。BIOS 或其他控制器識別的所有硬碟,會按照 BIOS 的開機順序編號。

可惜的是 GRUB 無法將 Linux 設備名稱正確對應至 BIOS 設備名稱。它會透過演算法的協助來產生此對應,然後儲存至檔案 device.map,需要時可以編輯它。如需關於檔案 device.map 的資訊,請參閱 節 29.3.2, "檔案 device.map"

完整 GRUB 路徑包含放在括號中的設備名稱,以及指定分割區中檔案系統的檔案路徑。路徑開頭是一個斜線。例如,如果系統有一個 IDE 硬碟,它的第一個分割區包含 Linux,則可以使用下列方式設定核心:

(hd0,0)/boot/vmlinuz

29.3.1.2. 範例功能表檔案

以下範例顯示 GRUB 功能表檔案的結構。範例安裝包含 /dev/hda5 下的 Linux 開機分割區、/dev/hda7 下的根分割區,以及 /dev/hda1 下的 Windows 安裝。

gfxmenu (hd0,4)/message 
color white/blue black/light-gray 
default 0
timeout 8 

title linux 
   kernel (hd0,4)/vmlinuz root=/dev/hda7 vga=791 
   initrd (hd0,4)/initrd 

title windows 
   chainloader(hd0,0)+1 

title floppy
   chainloader(fd0)+1 

title failsafe 
   kernel (hd0,4)/vmlinuz.shipped root=/dev/hda7 ide=nodma \ 
   apm=off acpi=off vga=normal nosmp maxcpus=0 3 
   initrd (hd0,4)/initrd.shipped

第一個區塊定義開頭顯示畫面的組態:

gfxmenu (hd0,4)/message

背景影像 message 是位在 /dev/hda5

color white/blue black/light-gray

色彩配置:白色 (前景)、藍色 (背景),黑色 (選擇項目),以及淺灰色 (選擇項目的背景)。色彩配置對於開頭顯示畫面沒有作用,只對您可以存取而且可以自訂的 GRUB 功能表有作用 (您可以使用 Esc,結束開頭顯示畫面)。

default 0

第一個功能表項目 title linux 是預設要啟動的項目。

timeout 8

沒有任何用者輸入,經過 8 秒後,GRUB 會自動啟動預設項目。若要關閉自動開機,刪除 timeout。如果設定為 timeout 0,GRUB 會馬上啟動預設項目。

第二個 (最大的) 區塊會列示各種可開機的作業系統。個別作業系統的章節是由 title 開始。

  • 第一個項目 (title linux) 負責啟動 SUSE Linux。核心 (vmlinuz) 是位在第一個硬碟的第一個邏輯分割區 (開機分割區)。核心參數,例如根分割區和 VGA 模式,會在此添加。根分割區是根據 Linux 命名慣例 (/dev/hda7/) 指定的,因為此資訊是由核心讀取,與 GRUB 無關。initrd 也是位在第一個硬碟的第一個邏輯分割區。

  • 第二個項目負責載入 Windows。Windows 是從第一個硬碟的第一個分割區開機 (hd0,0)。指令 chainloader +1 會造成 GRUB 載入並執行指定分割區的第一個磁區。

  • 下一個項目允許從磁片開機,無需修改 BIOS 設定。

  • 開機選項 failsafe 會以選擇的核心參數來啟動 Linux,可以啟動發生問題的 Linux 系統。

若有需要可自行變更功能表檔案。GRUB 會在下次開機時使用修改的設定。使用 YaST 或選擇的編輯器,永久地編輯檔案。另一種方法是,使用 GRUB 的編輯功能,以互動方式暫時變更。請參閱 節 29.3.1.3, "在開機程序期間編輯功能表項目"

29.3.1.3. 在開機程序期間編輯功能表項目

在圖形化 GRUB 開機功能表中,可以使用方向鍵選取要開機的作業系統。如果選取 Linux 系統,可以在開機提示時輸入其他開機參數。要完全直接編輯個別功能表,按 Esc 結束開頭顯示畫面,然後按 E。用此方式所做的變更,只會套用至目前的開機程序,不會永久變更。

[Important]開機程序期間的鍵盤配置

US 鍵盤配置是開機時唯一可以使用的鍵盤配置。

啟動編輯模式之後,使用方向鍵選取功能表項目來編輯組態。要讓組態變成可以編輯,再按 E 一次。使用此方法,在對於開機程序產生負面影響之前,編輯錯誤的分割區或路徑指定。按 Enter,結束編輯模式並返回功能表。然後按 B 來啟動此項目。底下的說明文字會顯示進一步可行的動作。

要永久地輸入變更的開機選項,然後傳送至核心,以 root 身份開啟檔案 menu.lst,然後將各自的核心參數添加至現有的行,以空格分隔:

title linux 
   kernel (hd0,0)/vmlinuz root=/dev/hda3 additional parameter
   initrd (hd0,0)/initrd

GRUB 會在下次啟動系統時,使用新參數。另一種方法是,使用 YaST 開機載入器模組做此變更。將新參數添加至現有的行,由空格分開。

29.3.1.4. 使用萬用字元以選取開機核心

特別是在開發或使用自訂核心時,您必須變更 menu.lst 中的項目,或是編輯指令行以反映目前核心及 initrd 的檔案名稱。若要簡化此程序,請使用萬用字元以動態更新 GRUB 的核心清單。 接著會將所有符合特定型式的核心影像都自動加入可開機影像的清單。請注意,未提供此功能的技術支援。

menu.lst 中輸入其他的功能表項目以啟動萬用字元選項。為了使用上的便利,所有的核心和 initrd 影像必須具有共同的基礎名稱以及符合核心與其相關 initrd 的識別碼。請思考以下設定:

initrd-default
initrd-test
vmlinuz-default
vmlinuz-test

在此狀況中,您可以在一個 GRUB 組態中同時新增兩個開機影像。若要取得功能表項目 linux-defaultlinux-test,將需要 menu.lst 中的下列項目:

title linux-*
   wildcard (hd0,4)/vmlinuz-*
   kernel (hd0,4)/vmlinuz-* root=/dev/hda7 vga=791 
   initrd (hd0,4)/initrd-* 

在此範例中,GRUB 會搜尋分割區 (hd0,4) 以尋找符合萬用字元的項目。這些項目會用來產生新的 GRUB 功能表項目。在前述的範例中,GRUB 的行為方式將如同下列項目存在於 menu.lst 一般:

title linux-default
   wildcard (hd0,4)/vmlinuz-default
   kernel (hd0,4)/vmlinuz-default root=/dev/hda7 vga=791 
   initrd (hd0,4)/initrd-default 
title linux-test
   wildcard (hd0,4)/vmlinuz-test
   kernel (hd0,4)/vmlinuz-test root=/dev/hda7 vga=791 
   initrd (hd0,4)/initrd-test 
    

如果所使用的檔案名稱不一致,或是如果其中一個已展開的檔案 (例如,initrd 影像) 已遺失,此組態就會發生問題。

29.3.2. 檔案 device.map

檔案 device.map 會將 GRUB 設備名稱對應至 Linux 設備名稱。在包含 IDE 和 SCSI 硬碟的混合系統中,GRUB 必須透過特定程序來判斷開機順序,因為 GRUB 不會存取 BIOS 的開機順序資訊。GRUB 儲存分析的結果至檔案 /boot/grub/device.map。在 BIOS 中的開機順序設定成 IDE 在 SCSI 前面的系統,檔案 device.map 會顯示如下:

(fd0)  /dev/fd0 
(hd0)  /dev/hda 
(hd1)  /dev/sda

因為 IDE、SCSI 和其他硬碟的順序取決於各種因素,而且 Linux 無法識別對應,所以檔案 device.map 可以手動設定。如果您在開機時發生問題,請檢查此檔案中的順序是否與 BIOS 中的順序一致,然後在需要時使用 節 29.3.4, "GRUB 外圍程序" 中所描述的 GRUB 外圍程序來修改它。啟動 Linux 系統之後,檔案 device.map 可以透過 YaST 開機載入器或其他選擇的編輯器,永久性編輯。

在手動變更檔案 device.map 之後,執行以下指令來重新安裝 GRUB。此指令會造成檔案 device.map 重新載入,並以 grub.conf 列示的指令執行:

 
grub --batch < /etc/grub.conf

29.3.3. 檔案 /etc/grub.conf

除了 menu.lstdevice.map 之外,第三個重要的 GRUB 組態檔是 /etc/grub.conf。此檔案包含指令 grub 正確安裝開機載入器時,需要的參數和選項:

 
root (hd0,4) 
   install /grub/stage1 d (hd0) /grub/stage2 0x8000 (hd0,4)/grub/menu.lst 
   quit

個別項目的意義如下:

root (hd0,4)

此指令告訴 GRUB 將以下指令套用至第一個硬碟的第一個邏輯分割區 (開機檔案的位置)。

nstall 參數

指令 grub 應該與參數 install 一起執行。開機載入器的 stage1 應該安裝在第一個硬碟的 MBR (/grub/stage1 d (hd0))。stage2 應該載入記憶體位址 0x8000 (/grub/stage2 0x8000)。最後項目 ((hd0,4)/grub/menu.lst) 告訴 GRUB 到什麼地方尋找功能表檔案。

29.3.4. GRUB 外圍程序

GRUB 實際上有兩個版本:當成開機載入器以及當成 /usr/sbin/grub 的一般 Linux 程式。此程式稱為 GRUB 外圍程序。將 GRUB 安裝成硬碟或磁片上的開機載入器,這種功能是以指令 installsetup 的形式,整合在 GRUB。Linux 載入時,可以在 GRUB 外圍程序使用此指令。

不過,指令 setupinstall 也可以在 Linux 啟動前的開機程序中使用。這可利於修復無法再開機的缺陷系統,因為開機載入器錯誤的組態檔,可以手動輸入參數,便得以解決。在開機程序期間手動輸入參數,對於測試新設定但可避免損壞原始系統,有很大的幫助。只要使用像 menu.lst 的語法,輸入實驗性組態檔就可以了。測試此項目的功能,無需變更現有的組態檔。例如,要測試新核心,輸入指令 kernel 以及新核心的路徑。如果開機程序失敗,下次啟動時,可以繼續使用未受損的 menu.lst。同樣地,指令行介面也可以用來輸入正確的參數,即使 menu.lst 檔案錯誤,也可以啟動系統。正在執行的系統中,正確的參數可以輸入在 menu.lst,讓系統變成可永久開機。

GRUB 設備與 Linux 設備名稱的對應,只有將 GRUB 外圍程序當成 Linux 程式執行時,才會發生關係 (輸入 grub,如 節 29.3.2, "檔案 device.map" 所述一般)。基於此目的,程式會讀取檔案 device.map。如需更多資訊,請參閱 節 29.3.2, "檔案 device.map"

29.3.5. 設定開機密碼

即使作業系統啟動之前,GRUB 也可以存取檔案系統。沒有 root 許可權的使用者,在此時可以存取 Linux 系統中的檔案 (這些檔案在系統啟動後,他們並無法存取)。要封鎖此類型的存取或者防止使用者啟動特定作業系統,可以設定開機密碼。

[Important]開機密碼和開頭顯示畫面

如果您在 GRUB 使用開機密碼,將不會顯示一般的開頭顯示畫面。

按照以下方式,以使用者 root 的身份設定開機密碼:

  1. 在根提示時,輸入 grub

  2. 在 GRUB 外圍程序加密密碼:

    grub> md5crypt 
    Password: **** 
    Encrypted: $1$lS2dv/$JOYcdxIn7CJk9xShzzJVw/
  3. 將加密字串貼到檔案 menu.lst 的全域段落:

    gfxmenu (hd0,4)/message 
    color white/blue black/light-gray 
    default 0
    timeout 8 
    password --md5 $1$lS2dv/$JOYcdxIn7CJk9xShzzJVw/

    現在 GRUB 指令只可以在按 P 並輸入密碼後的開機提示時執行。不過,使用者仍然可以從開機功能表,啟動所有作業系統。

  4. 要防止一或多個作業系統從開機功能表啟動,將項目 lock 新增至沒有密碼便不可以開機的 menu.lst 每一個段落。例如:

    title linux 
    kernel (hd0,4)/vmlinuz root=/dev/hda7 vga=791 
    initrd (hd0,4)/initrd 
    lock

    重新啟動系統並從開機功能表選取 Linux 之後,會顯示以下錯誤:

    Error 32: Must be authenticated

    Enter 進入功能表。然後按 P,取得密碼提示。輸入密碼並按 Enter 之後,選取的作業系統 (本案例為 Linux) 應該會啟動。