GRUB/技巧和竅門
其它安裝方式[編輯 | 編輯原始碼]
安裝到 U 盤[編輯 | 編輯原始碼]
BIOS[編輯 | 編輯原始碼]
假設 U 盤的第一個分區是 FAT32格式,其分區是/dev/sdy1
# mkdir -p /mnt/usb # mount /dev/sdy1 /mnt/usb # grub-install --target=i386-pc --debug --boot-directory=/mnt/usb/boot /dev/sdy # grub-mkconfig -o /mnt/usb/boot/grub/grub.cfg
可以選擇將配置備份到 grub.cfg
:
# mkdir -p /mnt/usb/etc/default # cp /etc/default/grub /mnt/usb/etc/default # cp -a /etc/grub.d /mnt/usb/etc
# sync; umount /mnt/usb
EFI[編輯 | 編輯原始碼]
在你運行 grub-install
的時候使用 --removable
選項,就可以讓 GRUB 把它的 EFI 映像寫入到 /boot/efi/EFI/BOOT/BOOTX64.efi
,這樣啟動固件就可以在沒有 UEFI 啟動條目的的情況下找到。
安裝到分區上或者無分區磁盤上[編輯 | 編輯原始碼]
下面的命令將會將 GRUB 安裝到分區扇區或者無分區磁盤(也稱作超級軟盤),或者安裝到軟盤上。下面例子中以 /dev/sdaX
作為 /boot
分區。
# chattr -i /boot/grub/i386-pc/core.img # grub-install --target=i386-pc --debug --force /dev/sdaX # chattr +i /boot/grub/i386-pc/core.img
/dev/sdaX
僅用作示例。--target=i386-pc
令grub-install
僅為 BIOS 系統安裝。建議總是使用這個選項來排除 grub-install 命令中的模糊性。
你應該使用 --force
選項來啟用對 blocklists(塊列表)的支持,而不應該使用 --grub-setup=/bin/true
,後者類似於單純地生成 core.img
。
grub-install
會生成以下警告,來提醒你哪裏有可能出現問題。
/sbin/grub-setup: warn: Attempting to install GRUB to a partitionless disk or to a partition. This is a BAD idea. /sbin/grub-setup: warn: Embedding is not possible. GRUB can only be installed in this setup by using blocklists. However, blocklists are UNRELIABLE and their use is discouraged.
不使用 --force
選項則可能會出現以下錯誤,並且 grub-setup
不會將啟動代碼安裝到啟動扇區上:
/sbin/grub-setup: error: will not proceed with blocklists
而指定了 --force
,會出現:
Installation finished. No error reported.
grub-setup
默認不啟用這個選項,是因為在分區或者無分區磁盤上,grub
依賴於嵌入分區引導扇區的塊列表 (blocklists) 來定位 /boot/grub/i386-pc/core.img
和前綴目錄 /boot/grub
。而 core.img
在分區上的扇區位置很有可能隨着分區文件系統的更改而變化(複製文件,刪除文件等)。詳情請參考 https://bugzilla.redhat.com/show_bug.cgi?id=728742 和 https://bugzilla.redhat.com/show_bug.cgi?id=730915.
臨時解決方案是給 /boot/grub/i386-pc/core.img
文件加「不可變」(immutable) 標誌(按照上面提過的,使用 chattr
命令)。這樣 core.img
文件的位置就不會變。只有當將 GRUB 安裝到分區啟動扇區或者無分區磁盤上時才需要給 /boot/grub/i386-pc/core.img
加上「不可變」標誌,在安裝到 MBR 或者單純地生成 core.img
而不嵌入到其他引導扇區裏的時候,就不用添加(正如上面所述)。
然而即使沒有報錯,生成的 grub.cfg
文件也不會包含正確的 UUID。參考 https://bbs.archlinux.org/viewtopic.php?pid=1294604#p1294604 。
要解決這個問題,使用如下命令:
# mount /dev/sdxY /mnt #Your root partition. # mount /dev/sdxZ /mnt/boot #Your boot partition (if you have one). # arch-chroot /mnt
現在,安裝linux包,然後:
# grub-mkconfig -o /boot/grub/grub.cfg
只生成 core.img[編輯 | 編輯原始碼]
通過添加 --grub-setup=/bin/true
選項,grub-install
命令會填充 /boot/grub
文件夾並生成 /boot/grub/i386-pc/core.img
,但是不會將 GRUB 啟動引導代碼嵌入到 MBR、MBR 後部區域或者分區引導扇區中。
# grub-install --target=i386-pc --grub-setup=/bin/true --debug /dev/sda
/dev/sda
僅是示例。--target=i386-pc
令grub-install
僅為 BIOS 系統安裝。建議總是使用這個選項來排除 grub-install 命令中的模糊性。
生成後,Grub Legacy 或者 syslinux 就可以通過鏈式加載 GRUB 的 core.img
來間接加載 Linux 內核或者多啟動內核了。參閱Syslinux#鏈式加載。
圖形化配置工具[編輯 | 編輯原始碼]
- grub-customizer — GRUB 或者 BURG 的 GTK 定製器
視覺配置[編輯 | 編輯原始碼]
GRUB 默認支持改變菜單外觀。如果你沒有初始化,請務必以視頻模式 gfxmode 初始化 GRUB 圖形終端 gfxterm。此視頻模式由 GRUB 通過 gfxpayload 傳遞給 Linux 內核,任何視覺配置都需要這種模式才能夠有效果。
設置幀緩衝解像度[編輯 | 編輯原始碼]
GRUB 既可以為自己,也可以為內核設定幀緩衝。現在已經不使用老的 vga=
配置了,推薦方法是在 /etc/default/grub
文件中按照下面的例子編輯,來設定寬度(像素)x高度(像素)x顏色深度:
GRUB_GFXMODE=1024x768x32 GRUB_GFXPAYLOAD_LINUX=keep
可以指定多種解像度,包括默認的 auto
,所以建議你編輯成這個樣:GRUB_GFXMODE=心儀的解像度,後備解像度比如 1024x768,auto
。更多信息請見 GRUB gfxmode 文檔。 gfxpayload 屬性可以確保內核也保持該解像度。
- 只有顯卡通過 VESA BIOS 拓展支持的模式才能用。要查看所支持的模式列表,安裝 hwinfo包 然後以 root 權限運行
hwinfo --framebuffer
。或者進入 GRUB 命令行運行videoinfo
命令。 - 早期版本的 NVIDIA 專有驅動(使用顯卡 GeForce GTX 970,驅動 nvidia 370 進行了測試)支持的
GRUB_GFXMODE
格式為寬x高-色深
(例如1920x1200-24
,而不是1920x1200x24
)。這應該不會影響新的顯卡和驅動。使用比較新的驅動的 Pascal 顯卡(以 GeForce GTX 1060 顯卡和 nvidia 381.22 驅動測試)沒法使用上文建議的格式,而且會引發嚴重的問題,包括但不限於系統崩潰以及 hard lock。當前的驅動和顯卡最好使用標準的寬x高x色深
格式來配置GRUB_GFXMODE
。 - 確保在修改完後運行
grub-mkconfig -o /boot/grub/grub.cfg
。
這種方法不管用的話,可以試試老的 vga=
方法。將它添加到 /etc/default/grub
文件中的 "GRUB_CMDLINE_LINUX_DEFAULT="
一行就行了。比如 "GRUB_CMDLINE_LINUX_DEFAULT="quiet splash vga=792"
可以將系統的解像度設定為 1024x768
。
915resolution 破解[編輯 | 編輯原始碼]
有些時候,Intel 顯卡無法通過 # hwinfo --framebuffer
或 vbeinfo
顯示你需要的解像度。這種情況下,你可以使用 915resolution
破解。這種破解會臨時性的修改顯卡 BIOS 來添加所需的解像度。詳情請參考915resolution 主頁[失效連結 2022-09-18 ⓘ]。這個包可以在這裏找到:915resolutionAUR
首先,找一個你想要修改的視頻模式。為此需要在 GRUB 命令行模式下運行:
sh:grub> 915resolution -l
Intel 800/900 Series VBIOS Hack : version 0.5.3 [...] Mode 30 : 640x480, 8 bits/pixel [...]
然後,使用 1440x900
解像度覆蓋 Mode 30
:
/etc/grub.d/00_header
[...] 915resolution 30 1440 900 # Inserted line set gfxmode=${GRUB_GFXMODE} [...]
最後按照之前描述的方式設置 GRUB_GFXMODE
,再重新生成 GRUB 配置文件,重啟並測試是否生效。
背景圖像和點陣字體[編輯 | 編輯原始碼]
GRUB 原生支持設置背景圖像和 pf2
格式的點陣字體。grub包 包中包含了 unifont 字體,名為unicode.pf2
,(也有可能只包含名為 ascii.pf2
的ASCII字符字體),運行pacman -Ql grub | grep pf2
來得到對應的文件路徑。
在載入正確的模塊之後,GRUB 支持的圖像格式有 tga, png 和 jpeg。所支持的最大圖像解像度跟硬件有關。
請確保你已經設定了合適的幀緩衝解像度。
按如下方式編輯 /etc/default/grub
:
GRUB_BACKGROUND="/boot/grub/myimage" #GRUB_THEME="/path/to/gfxtheme" GRUB_FONT="/path/to/font.pf2"
grub.cfg
文件中會自動將 /boot/grub/myimage
改成 /grub/myimage
。需要重新生成 grub.cfg
來讓修改起作用。如果成功添加了背景圖片,用戶會在運行命令的終端中看到 "Found background image..."
。如果句話沒有出現,你設定的圖像信息可能沒有成功添加進 grub.cfg
文件。
如果圖像沒有正確顯示,執行如下檢查:
- 在
/etc/default/grub
文件中,圖像的路徑和名字要正確 - 圖像的大小和格式要合適 (tga, png, 8-bit jpg)
- 圖像需要以 RGB 模式存儲,而且沒有索引
/etc/default/grub
文件裏面開啟了 console 模式- 需要執行
grub-mkconfig
命令以將圖像信息寫入/boot/grub/grub.cfg
文件 grub-mkconfig
腳本不會對grub.cfg
文件中所寫的文件名添加引號,所以要確保這些名字裏沒有空格
主題[編輯 | 編輯原始碼]
下面的例子將展示如何使用 GRUB 包裏面的 Starfield 主題:
編輯 /etc/default/grub
GRUB_THEME="/usr/share/grub/themes/starfield/theme.txt"
需要重新生成 grub.cfg
來讓修改起作用。如果配置成功的話,在重生成配置過程中,會在終端裡出現 Found theme: /usr/share/grub/themes/starfield/theme.txt
。
一旦使用了主題,你設置的背景圖像通常就不起作用了。
菜單顏色[編輯 | 編輯原始碼]
GRUB 支持設置菜單顏色。可使用的顏色能從 GRUB 手冊裏面找到。示例如下:
編輯 /etc/default/grub
:
GRUB_COLOR_NORMAL="light-blue/black" GRUB_COLOR_HIGHLIGHT="light-cyan/blue"
隱藏菜單[編輯 | 編輯原始碼]
GRUB 特性之一就是支持隱藏/跳過菜單,可以在需要的時候按 Esc
來取消隱藏/跳過。同時還支持設置是否顯示 timeout 計時器。
按照你的想法來編輯 /etc/default/grub
。添加下面的幾行可以啟動這個功能,其中計時器被設定為 5 秒鐘,而且可以被用戶看到:
GRUB_TIMEOUT=5 GRUB_TIMEOUT_STYLE='countdown'
GRUB_TIMEOUT
是設置顯示菜單前等待幾秒。
禁用 framebuffer[編輯 | 編輯原始碼]
使用 NVIDIA 私有驅動的用戶可能希望禁用 GRUB 的 framebuffer,因為它會導致驅動錯誤。
要禁用 framebuffer,只要在 /etc/default/grub
中取消下面這行的註釋:
GRUB_TERMINAL_OUTPUT=console
如果你想保留 GRUB 的 framebuffer,解決方法是在 GRUB 載入內核前進入文字模式。可以通過在 /etc/default/grub
中進行如下修改:
GRUB_GFXPAYLOAD_LINUX=text
通過 GRUB 直接啟動 ISO9660 映像文件[編輯 | 編輯原始碼]
GRUB 支持通過 loopback 設備直接從 ISO 映像啟動,例如參考 Multiboot USB drive#Using GRUB and loopback devices。
用密碼保護 GRUB 菜單[編輯 | 編輯原始碼]
/boot
又處於一個沒有加密的分區上面,那他就可以非常簡單地通過編輯 GRUB 設置文件來繞過下面的這些。參考GRUB#/boot 加密和Security#磁盤加密。如果你想禁止其他人改變啟動參數或者使用 GRUB 命令行,可以給 GRUB 的配置文件關聯一個用戶名/密碼。只需
運行 grub-mkpasswd-pbkdf2
,輸入密碼然後確認:
grub-mkpasswd-pbkdf2
[...] Your PBKDF2 is grub.pbkdf2.sha512.10000.C8ABD3E93C4DFC83138B0C7A3D719BC650E6234310DA069E6FDB0DD4156313DA3D0D9BFFC2846C21D5A2DDA515114CF6378F8A064C94198D0618E70D23717E82.509BFA8A4217EAD0B33C87432524C0B6B64B34FBAD22D3E6E6874D9B101996C5F98AB1746FE7C7199147ECF4ABD8661C222EEEDB7D14A843261FFF2C07B1269A
修改/etc/grub.d/40_custom
的權限以確保只有root能夠查看該文件的內容,然後將下面的內容添加到此文件:
/etc/grub.d/40_custom
set superusers="用戶名" password_pbkdf2 用戶名 密碼
這裏的 密碼
是由 grub-mkpasswd_pbkdf2
所生成的那個字符串。
然後重新生成主配置文件,現在你的 GRUB 命令行、啟動參數和所有的啟動條目都得到保護了。
可以參考 GRUB 手冊中的 "Security" 部分來將設置放寬或者針對多用戶進行更複雜的定製。
只針對編輯 GRUB 和控制台選項進行密碼保護[編輯 | 編輯原始碼]
對一個菜單條目添加 --unrestricted
選項將會允許所有的用戶啟動這個作業系統,但卻不能修改這個條目,也不能進入 GRUB 命令行控制台。
只有超級用戶或者由 --user
開關指定的用戶才能修改這個菜單條目。
/boot/grub/grub.cfg
menuentry 'Arch Linux' --unrestricted --class arch --class gnu-linux --class os ...
要給 Linux 啟動條目添加 --unrestricted
,可以修改 /etc/grub.d/10_linux
文件開頭的 CLASS
變量。
/etc/grub.d/10_linux
CLASS="--class gnu-linux --class gnu --class os --unrestricted"
在沒有按着 SHIFT 鍵時隱藏 GRUB 界面[編輯 | 編輯原始碼]
為了獲取更快的啟動速度,而不用等 GRUB 倒計時,可以命令 GRUB 在啟動時隱藏目錄,僅在 Shift
被按住的時候才顯示。
將如下行添加到/etc/default/grub
來啟動這個功能:
GRUB_FORCE_HIDDEN_MENU="true"
然後創建/etc/grub.d/31_hold_shift
文件並寫入以下連結中的內容:[1],給它可執行權限,然後重新生成主配置文件:
# chmod a+x /etc/grub.d/31_hold_shift # grub-mkconfig -o /boot/grub/grub.cfg
將 UUID 和基礎腳本結合使用[編輯 | 編輯原始碼]
如果你想要使用 UUID 來避免不可靠的 BIOS 設備命名或者正在研究 GRUB 語法,這裏有個使用了 UUID 的啟動菜單項,和一個讓 GRUB 使用你系統中正確的磁盤分區的小腳本。如果你想要將其移植到自己的系統上,只需要把 UUID 改成你的系統上的就行了。這個例子假設系統的 boot 和 root 文件系統是在不同的分區上,如果你還有其他分區,請相應地修改 GRUB 設置。
menuentry "Arch Linux 64" { # Set the UUIDs for your boot and root partition respectively set the_boot_uuid=ece0448f-bb08-486d-9864-ac3271bd8d07 set the_root_uuid=c55da16f-e2af-4603-9e0b-03f5f565ec4a # (Note: This may be the same as your boot partition) # Get the boot/root devices and set them in the root and grub_boot variables search --fs-uuid $the_root_uuid --set=root search --fs-uuid $the_boot_uuid --set=grub_boot # Check to see if boot and root are equal. # If they are, then append /boot to $grub_boot (Since $grub_boot is actually the root partition) if [ $the_boot_uuid == $the_root_uuid ] ; then set grub_boot=($grub_boot)/boot else set grub_boot=($grub_boot) fi # $grub_boot now points to the correct location, so the following will properly find the kernel and initrd linux $grub_boot/vmlinuz-linux root=/dev/disk/by-uuid/$the_root_uuid ro initrd $grub_boot/initramfs-linux.img }
多個啟動條目[編輯 | 編輯原始碼]
取消子菜單[編輯 | 編輯原始碼]
如果你安裝了多個內核,比如說 linux 和 linux-lts,那麼 grub-mkconfig
默認會把他們分成一組建立一個子菜單。如果你不想這樣,可以在 /etc/default/grub
文件裡添加下面這行來回到僅有一個菜單的情形:
GRUB_DISABLE_SUBMENU=y
調用之前的啟動條目[編輯 | 編輯原始碼]
GRUB 能夠記住你最近一次使用的啟動項,並且在下次啟動時將其作為默認項。當你使用多個內核或作業系統時(比如當前的 Arch 和一個用來做後備選項的 LTS 內核),這個特性很有用。要開啟這個功能,編輯 /etc/default/grub
中的 GRUB_DEFAULT
選項:
GRUB_DEFAULT=saved
上面的命令會告訴 GRUB 使用記住的啟動項為默認啟動項。要想讓 GRUB 記住當前選擇的啟動項,將下面的行添加到 /etc/default/grub
:
GRUB_SAVEDEFAULT=true
僅當 /boot 不是 btrfs 文件系統的時候才能用,因為 GRUB 沒法對 btrfs 進行寫入操作。但它會生成一個容易誤導人的錯誤信息:"sparse file not allowed. Press any key to continue."
/etc/grub.d/40_custom
或 /boot/grub/custom.cfg
中,比如添加 Windows 啟動項,需要先添加savedefault
選項。修改默認菜單條目[編輯 | 編輯原始碼]
可以通過修改 /etc/default/grub
中的 GRUB_DEFAULT
值來改變默認啟動項:
使用菜單標題:
GRUB_DEFAULT='Advanced options for Arch Linux>Arch Linux, with Linux linux'
GRUB_DEFAULT
之上添加 LANG=C
(會導致 GRUB 主菜單使用英文) 或者根據實際生成的菜單標題修改 GRUB_DEFAULT
,如 GRUB_DEFAULT='Arch Linux 的高級選項>Arch Linux,使用 Linux linux'
。使用數字編號:
GRUB_DEFAULT="1>2"
GRUB 啟動項序號從 0
開始計數,0
代表第一個啟動項,也是上述選項的默認值,1
表示第二個啟動項,以此類推。主菜單和子菜單項之間用 >
隔開。
上面的例子啟動的是主菜單項 'Advanced options for Arch Linux' 下子菜單的第三項。
自動啟動非默認啟動條目(僅一次)[編輯 | 編輯原始碼]
如果你想在下一次啟動的時候啟動一個非默認的啟動項,命令 grub-reboot
非常有用。當系統下一次啟動時,GRUB 會自動載入這個命令後的第一個參數所指的那個啟動項,而以後再次啟動時,GRUB 會回到正常狀態加載默認條目。這樣就不用修改配置文件或者在啟動時進行手動選擇了。
/etc/default/grub
中設定 GRUB_DEFAULT=saved
,然後重新生成grub.cfg
;或者在手動生成的 grub.cfg
中, 使用 set default="${saved_entry}"
。演奏一曲[編輯 | 編輯原始碼]
通過修改 GRUB_INIT_TUNE
變量,你可以在啟動時(在引導菜單顯示之前)讓揚聲器播放音樂。比如要演奏柏遼茲《幻想交響曲》「妖魔夜宴」樂章片段(大管部分),你可以添加下面的設置:
GRUB_INIT_TUNE="312 262 3 247 3 262 3 220 3 247 3 196 3 220 3 220 3 262 3 262 3 294 3 262 3 247 3 220 3 196 3 247 3 262 3 247 5 220 1 220 5"
你可以通過創建以下文件,然後重新運行grub-mkconfig
,添加一個菜單項來播放這些常見的GRUB_INIT_TUNE
。
/etc/grub.d/91_tune_demo
#!/bin/sh exec tail -n +3 $0 menuentry "INIT_TUNE Demos" { echo "Close Encounters/5 Tone" play 480 900 2 1000 2 800 2 400 2 600 3 echo "Fur Elise (note long)" play 480 420 1 400 1 420 1 400 1 420 1 315 1 370 1 335 1 282 3 180 1 215 1 282 1 315 3 213 1 262 1 315 1 335 3 213 1 420 1 400 1 420 1 400 1 420 1 315 1 370 1 335 1 282 3 180 1 215 1 282 1 315 3 213 1 330 1 315 1 282 3 echo "Berlioz's extract from Sabbath Night of Symphonie Fantastique" play 312 262 3 247 3 262 3 220 3 247 3 196 3 220 3 220 3 262 3 262 3 294 3 262 3 247 3 220 3 196 3 247 3 262 3 247 5 220 1 220 5 echo "Oldskool Batman tune" play 380 120 1 140 1 160 1 200 8 190 4 echo "Legend of Zelda tune" play 12000 440 100 0 1 329 150 440 50 0 1 440 25 493 25 523 25 587 25 659 200 echo "Super Mario" play 1000 334 1 334 1 0 1 334 1 0 1 261 1 334 1 0 1 392 2 0 4 196 2 echo "Super Mario Alternate" play 480 165 2 165 2 165 3 554 1 587 1 554 2 370 1 554 1 523 2 349 1 523 1 494 3 165 2 165 2 165 2 echo "Mario Mushroom" play 1750 523 1 392 1 523 1 659 1 784 1 1047 1 784 1 415 1 523 1 622 1 831 1 622 1 831 1 1046 1 1244 1 1661 1 1244 1 466 1 587 1 698 1 932 1 1175 1 1397 1 1865 1 1397 1 echo "Star Wars Imperial Death March" play 480 440 4 440 4 440 4 349 3 523 1 440 4 349 3 523 1 440 8 659 4 659 4 659 4 698 3 523 1 415 4 349 3 523 1 440 8 echo "My Little Pony" play 2400 587 18 554 4 587 8 659 12 587 16 0 10 587 4 659 4 740 8 587 4 784 12 740 8 659 8 587 4 740 20 587 40 echo "Wolfenstein 3D" play 300 131 1 196 1 196 1 196 1 294 1 196 1 294 1 196 1 131 1 echo "Mall (Nothing Special)" play 180 440 1 554 1 659 1 echo "Final Countdown" play 480 554 1 494 1 554 4 370 6 10 3 587 1 554 1 587 2 554 2 494 6 echo "Xie-Jelei's Tune" play 2000 400 4 0 1 500 4 0 1 600 4 0 1 800 6 echo "Random tune" play 480 220 1 277 1 330 1 440 1 185 1 220 1 277 1 370 1 294 1 370 1 440 1 587 1 330 1 415 1 494 1 659 1 echo "Fleetwood Mac: The Chain Bass Riff (about 5 seconds)" play 304 55 5 0 1 55 1 62 1 65 2 62 1 55 1 49 1 55 1 62 2 41 8 echo "Fleetwood Mac: The Chain Bass Riff Extended Version (WARNING, 25 SECONDS)" play 9120 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 360 0 120 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 360 0 60 41 12 42 3 43 3 44 3 45 3 46 6 47 3 48 3 49 6 50 3 51 3 52 6 53 3 54 3 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 240 82 20 0 10 82 26 0 4 82 26 0 4 82 26 0 4 82 56 0 4 82 60 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 360 0 120 }
更多相關信息可以查看 info grub -n play
。
為早期啟動手動配置核心映像[編輯 | 編輯原始碼]
如果你需要用一個特殊的鍵盤佈局,或者要讓 GRUB 環境訪問 /boot
的配置步驟太過複雜,導致 GRUB 沒法自動配置,你可以自己生成一個核心映像。在 UEFI 系統上,核心映像就是在啟動時需要被固件載入的 grubx64.efi
文件。自己建立一個核心映像,就可以嵌入在早期啟動過程中需要用到的所有模塊,以及用來引導 GRUB 配置腳本。
首先,假設在一個 UEFI 系統中,我們需要在早期啟動過程中載入 dvorak
鍵盤佈局,以輸入 /boot
加密分區的密碼。
從生成的 /boot/grub/grub.cfg
文件中查看需要使用哪些模塊來掛載加密的 /boot
分區。例如在你的 menuentry
一項中你應該看到類似下面的內容:
insmod diskfilter cryptodisk luks gcry_rijndael gcry_rijndael gcry_sha256 insmod ext2 cryptomount -u 1234abcdef1234abcdef1234abcdef set root='cryptouuid/1234abcdef1234abcdef1234abcdef'
把這些模塊都記下來,他們都應該被包含到核心映像裏面。現在把你的鍵盤佈局打包,它應該作為一個 memdisk 來嵌入到核心映像裡:
# grub-kbdcomp -o dvorak.gkb dvorak # tar cf memdisk.tar dvorak.gkb
現在創建需要在 GRUB 核心映像中使用的配置文件。這和正常的 GRUB 配置文件的格式是一樣的,但只需要簡單幾行來載入 /boot
分區裏的主配置文件就可以了:
early-grub.cfg
set root=(memdisk) set prefix=($root)/ terminal_input at_keyboard keymap /dvorak.gkb cryptomount -u 1234abcdef1234abcdef1234abcdef set root='cryptouuid/1234abcdef1234abcdef1234abcdef' set prefix=($root)/grub configfile grub.cfg
最後,生成核心映像,列出在 grub.cfg
文件中所需要的所有模塊,再加上 early-grub.cfg
腳本中所使用的模塊。上例中需要的模塊有 memdisk
, tar
, at_keyboard
, keylayouts
和 configfile
。
# grub-mkimage -c early-grub.cfg -o grubx64.efi -O x86_64-efi -m memdisk.tar diskfilter cryptodisk luks gcry_rijndael gcry_sha256 ext2 memdisk tar at_keyboard keylayouts configfile
生成的 EFI 核心映像可以和由 grub-install
所自動生成的一樣使用,把它放在你的 EFI 分區,然後使用 efibootmgr
來啟用它,或者依照你的系統固件來適當地進行配置。
另請參閱 Debian cryptsetup docs.
UEFI 延伸閱讀[編輯 | 編輯原始碼]
下面是關於通過 UEFI 安裝 Arch 的其他相關信息。
另一種安裝方法[編輯 | 編輯原始碼]
通常,不管 EFI 系統分區掛載到哪,GRUB 都會將所有文件包括配置文件放到 /boot
。
如果你想將所有的文件放在 EFI 系統分區中,請給 grub-install 命令添加 --boot-directory=esp
選項:
# grub-install --target=x86_64-efi --efi-directory=esp --bootloader-id=grub --boot-directory=esp --debug
這個命令會將 GRUB 文件放在 esp/grub
而不是 /boot/grub
中。使用這個方法,請確保 grub-mkconfig 將配置文件放在與上面一樣的目錄裡:
# grub-mkconfig -o esp/grub/grub.cfg
其他的配置是完全一樣的。
UEFI 固件解決方案[編輯 | 編輯原始碼]
請參閱 GRUB#缺省/後備啟動路徑
在固件啟動管理器中創建 GRUB 條目[編輯 | 編輯原始碼]
grub-install
會自動嘗試在啟動管理器中創建 GRUB 條目。如果沒有成功,請參考 Unified Extensible Firmware Interface#efibootmgr,裏面有如何使用 efibootmgr
創建啟動目錄條目的介紹。一般來說,這個問題都是因為你沒有以 UEFI 模式啟動 CD/USB 造成的。請參考 Unified Extensible Firmware Interface#從 ISO 創建 UEFI 可啟動 USB。
獨立的 GRUB[編輯 | 編輯原始碼]
本節假設你要為 x86_64 系統 (x86_64-efi) 創建一個獨立的 GRUB。至於 32 位 (IA32) EFI 系統,適當地將 x86_64-efi
修改成 i386-efi
就可以了。
你可以建立一個 grubx64_standalone.efi
應用,這個 UEFI 應用將所有的模組嵌入應用內部的一個 tar 包中,所以就不需要使用單獨的目錄來存放 GRUB UEFI 模組和其他相關文件了。使用 grub包 包裡的 grub-mkstandalone
命令按照下面的方法操作來實現這個功能:
# echo 'configfile ${cmdpath}/grub.cfg' > /tmp/grub.cfg # grub-mkstandalone -d /usr/lib/grub/x86_64-efi/ -O x86_64-efi --modules="part_gpt part_msdos" --locales="en@quot" --themes="" -o "esp/EFI/grub/grubx64_standalone.efi" "boot/grub/grub.cfg=/tmp/grub.cfg" -v
然後把 GRUB 配置文件複製到 esp/EFI/grub/grub.cfg
,再使用 efibootmgr 為 esp/EFI/grub/grubx64_standalone.efi
創建一個 UEFI 啟動管理器條目。
${cmdpath}
功能正常工作,--modules="part_gpt part_msdos"
選項(包含引號)是必要的。${cmdpath}
的時候漏掉一個斜槓(比如把 (hd1,msdos2)/EFI/Boot
寫成 (hd1,msdos2)EFI/Boot
),你就會發現 grub.cfg
文件沒法讀取,然後被迫進入 GRUB 命令行中。如果出現這樣的問題,檢查 ${cmdpath}
設置成了什麼 (echo ${cmdpath}
),然後手工載入配置文件(例如 configfile (hd1,msdos2)/EFI/Boot/grub.cfg
)。技術信息[編輯 | 編輯原始碼]
GRUB EFI 文件總是要配置文件放在 ${prefix}/grub.cfg
。當然在獨立的 GRUB EFI 文件中,${prefix}
位於一個 tar 包的內部,嵌入在 GRUB EFI 文件自身之中(在 GRUB 環境中,這被稱作 (memdisk)
)。這個 tar 包包含了所有在正常的 GRUB EFI 下存儲在 /boot/grub
中的文件。
因為將 /boot/grub
中的內容嵌入到了獨立映像的內部,它就不再對任何實際的(外部的) /boot/grub
有任何依賴了。因此在獨立 GRUB EFI 文件的情形下 ${prefix}==(memdisk)/boot/grub
,而且獨立的 GRUB EFI 文件認為其配置文件存放於 ${prefix}/grub.cfg==(memdisk)/boot/grub/grub.cfg
。
因此要讓獨立的 GRUB EFI 文件讀取存儲在與 EFI 文件相同目錄(在 GRUB 環境中用 ${cmdpath}
表示)下的外部 grub.cfg
時,我們創建一個簡單的 /tmp/grub.cfg
來讓 GRUB 使用 ${cmdpath}/grub.cfg
來做其配置文件。(在 (memdisk)/boot/grub/grub.cfg
中使用 configfile ${cmdpath}/grub.cfg
命令。)然後我們給 grub-mkstandalone 添加 "boot/grub/grub.cfg=/tmp/grub.cfg"
選項,把這個 /tmp/grub.cfg
文件複製到 ${prefix}/grub.cfg
(事實上就是 (memdisk)/boot/grub/grub.cfg
)。
這樣,獨立的 GRUB EFI 文件和這個 grub.cfg
可以存放在 EFI 系統分區中的任何一個目錄裡,只有它們處在同一個目錄中就可以。這樣它們就變得可移植了。
加快GRUB中的LUKS解密速度[編輯 | 編輯原始碼]
在啟動時,GRUB在某些情況下可能需要很長的時間來驗證密碼。這可能是由於PBKDF的迭代次數太多,你可以按以下方法檢查:
# cryptsetup luksDump /dev/sda3
問題是,給定的密鑰槽的迭代次數是在添加鑰匙時產生的,這個迭代次數需要確保既足夠高來防止暴力攻擊,也要使你的計算機儘可能快的推導出密鑰。然而,當GRUB啟動時,它可能沒有同樣的計算資源在手,因此推導速度會大大降低。
如果你的密碼本身能提供足夠的熵來對抗常見的攻擊,你可以降低迭代次數。
# cryptsetup luksChangeKey --pbkdf-force-iterations 1000 /dev/sda3
根據RFC 2898,建議至少1000次迭代,但如果可以的話,你應該儘可能使用更高的數值(攻擊者的成本以及密鑰推導的時間是線性擴展的)。
--key-slot
選項來明確指定一個密鑰槽。