
網路上找到的一些範例說 update-grub 應該在 grub-install 之後運行。其他人則顛倒順序。哪個是對的?
如果我有兩個 Linux 安裝(一個在 sda 上,一個在 sdb 上),如果我在 sda 安裝上執行 update-grub,它將把 sda 安裝放在啟動選單的頂部。如果我在 sdb 安裝上執行 update-grub,它將把 sdb 安裝放在選單頂部。
假設 DEFAULT=0,理論上,這應該允許我透過在 BIOS 中選擇引導裝置來選擇作業系統。 “grub-install /dev/sda”是否會更改 sda 引導選單以對應最後一個“update-grub”,無論它是從 Linux 的 sda 還是 sdb 版本運行?
答案1
update-grub
,至少在 Debian 及其類似版本(如 Ubuntu)中,基本上只是grub-mkconfig
.所以它創建/更新/重新生成 GRUB配置,而不是實際的引導程式本身。
其grub-install
實際作用取決於您正在執行的 GRUB 版本:傳統 BIOS GRUB 還是 UEFI GRUB?
使用傳統的 BIOS GRUB,grub-install
將(重新)寫入嵌入主開機記錄中的 GRUB 部分,並將實體磁碟區編號編碼到其中,以便從其中讀取 GRUB 的下一部分。它還將確定從哪個分割區/boot/grub/grub.cfg
讀取實際的 GRUB 設定檔 ( )。這裡的一個重要因素是/boot/grub/device.map
文件,它告訴 GRUB BIOS(以及 GRUB)的設備編號如何對應到 Linux 磁碟設備。
對於 UEFI GRUB,GRUB 開機載入程式的主要部分將作為檔案位於 EFI 系統分割區中,通常為/boot/efi/EFI/<name of distribution>/grubx64.efi
或類似。此開機載入程式路徑名儲存在 UEFI 開機變數中的系統 NVRAM(= 儲存 BIOS 設定的位置)。 GRUB 的主要部分可能是完全獨立的(如果使用安全引導,則必須是獨立的!),或者它可以將附加功能作為 GRUB 模組加載,通常從/boot/grub
它所屬的 Linux 發行版的目錄中加載。
UEFI 開機變數將識別系統應使用的磁碟來尋找 EFI 系統分割區及其內部的開機載入程式檔案。您可以使用命令自行查看這些變數efibootmgr -v
。該grub-install
命令將更新這些變量,除非您使用該--no-nvram
選項另行指定。
GRUB 運行後,接下來需要確定的是:它應該從哪裡讀取其設定檔?
grub-install
能夠將 GRUBprefix
變數的所需值直接插入 GRUB 的主要部分。這嵌入前綴可以完全指定路徑,也可以使用特定於體系結構的預設值在運行時保留某些部分來確定。
對於傳統的 BIOS GRUB,嵌入的前綴通常會忽略實際的磁碟說明符,因此將使用載入 GRUB 的相同磁碟。在這種情況下,儲存的前綴將是例如安裝GRUB 的磁碟上的第一個主分割區的(,msdos1)/grub
時間 。/boot
對於 UEFI GRUB,嵌入的前綴通常僅指定目錄,然後它引用 EFI 系統分割區 (ESP) 上的發行版目錄。因此,典型的嵌入前綴是/EFI/debian
or/EFI/redhat
或類似的。磁碟和分割區的預設值將是「載入 UEFI GRUB 二進位檔案的相同分割區」。
某些發行版(例如 RHEL)只會將 UEFI GRUB 的實際設定直接放置在 ESP 上。 Debian 和相關發行版通常會做更多的間接操作:grub.cfg
ESP 上的迷你檔案將只包含幾行,這些行將告訴 GRUB 從/boot/grub/grub.cfg
Linux 啟動並安裝所有磁碟後的內容中讀取真正的設定檔。最簡單的,這個迷你配置只有三行:
- 將 GRUB 根設定為指向包含真實 GRUB 設定檔(用於即將執行的
configfile
命令)的檔案系統,在現代發行版中通常使用該search
命令和檔案系統 UUID。該方案最古老的實作實際上可能使用了固定的 GRUB 分區規範,例如set root=(hd0,gpt1)
- 設定 GRUB
prefix
變數(如果安全啟動未生效,則啟用 GRUB 模組自動載入)。如果將載入配置的檔案系統是 Linux 根檔案系統,則此行將為set prefix=($root)'/boot/grub'
;如果/boot
是一個單獨的檔案系統,這一行將是set prefix=($root)'/grub'
configfile $prefix/grub.cfg
使用.讀取實際的 GRUB 設定文件
如果包含 GRUB 設定的檔案系統位於 LVM 邏輯磁碟區、加密磁碟區或軟體 RAID 集上,則第一行將會更加複雜,甚至可能會根據需要新增其他資料列。
因此,無論是傳統 BIOS 還是 UEFI,運行grub-install
都可以更新開機載入程序,以讀取完全不同磁碟上完全不同的 GRUB 設定檔 - 儘管該過程的細節將完全不同。
efibootmgr
使用 UEFI,您實際上可以使用或來從作業系統內部變更啟動裝置選擇grub-install
。但這grub-install
是一個巨大的殺傷力:如果您的安裝都是 UEFI 並且有自己獨立的 ESP 分區,那麼它們將有自己的 UEFI 啟動變量,並且可以輕鬆地在它們之間進行選擇efibootmgr
,或者實際上在UEFI BIOS 設定中完成。
對於傳統的 BIOS,情況有點混亂:您需要確保每個安裝都/boot/grub/device.map
將該特定安裝的磁碟標識為hd0
,而另一個安裝的磁碟則標識為hd1
。然後用於grub-install
僅將引導程式寫入每個安裝自己的磁碟;永遠不要到「相反」的磁碟。這樣,即使另一個磁碟被完全刪除,兩個磁碟也將完全獨立且可引導。如果需要,您可以在每個 GRUB 的設定檔上新增一個選單項,該選單項目將允許您引導「相反」的安裝。或者您可以直接使用 BIOS 選擇啟動磁碟。
您必須知道的是,傳統 BIOS 的開機順序選擇器通常會選擇用於開機 BIOS 功能的「第一」磁碟的磁碟,因此 GRUBhd0
將始終引用「目前在 BIOS 中選擇用於開機的磁碟」 」。
/dev/sda
因此,如果您目前從(BIOS 表示為sda
)啟動hd0
,並且您希望該磁碟上的 GRUB 選單項目切換到 的/dev/sdb
啟動選單,則可以使用類似下列內容的命令:
menuentry "Switch to /dev/sdb"
{
# flip the disk mappings and reload configuration
drivemap -s (hd0) (hd1)
set root=<the identifier for sdb's partition that contains grub.cfg>
configfile /boot/grub/grub.cfg # or just /grub/grub.cfg is /boot is a separate partition
}
……同樣在 /dev/sdb 的 GRUB 設定上也是如此。