GRUB/技巧和竅門 - Arch Linux 中文维基

跳至內容

# GRUB/技巧和竅門

出自 Arch Linux 中文维基
< 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 極不推薦 將其安裝到分區啟動扇區或者無分區磁碟上（Grub Legacy 和 syslinux 相反）。這種安裝方式不安全，當升級時可能會損壞。Arch 開發人員也 不支持 這種方式.

下面的命令將會將 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 定製器

  https://launchpad.net/grub-customizer || grub-customizer包

## 視覺配置

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 安裝在單獨的分區上，`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 菜單

警告：如果有人能對你的機器進行物理上的訪問，而且可以使用 Live USB 或磁碟啟動（例如 BIOS 允許從外接磁碟啟動），而 `/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 ...

本文或本章節的事實準確性存在爭議。

原因： `/etc/grub.d/10_linux` 文件不應該被手工編輯，每次升級 grub包 包都會自動把它覆蓋掉。（在 Talk:GRUB/技巧和竅門 中討論）

要給 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

注意：這個設置使用 keystatus 來檢測按鍵事件，所以可能在某些機器上不能用。

## 將 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'

注意：如果你使用的是非英語 locale，生成的菜單標題可能和上述例子不一致。可以考慮在 `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 延伸閱讀

本文或本章節的語言、語法或風格需要改進。參考：幫助:風格

原因：本節還可以更加簡明有序。（在Talk:GRUB/技巧和竅門討論）

下面是關於通過 UEFI 安裝 Arch 的其他相關信息。

### 另一種安裝方法

這篇文章的某些內容需要擴充。

原因：將GRUB的所有文件放在ESP中的原因是什麼？ (在 Talk:GRUB/技巧和竅門 中討論)

通常，不管 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解密速度

警告：在閱讀本節之前，請確保你了解高熵密碼的重要性。關於如何生成安全密碼的信息可以在Wikipedia:Password strength找到。

在啟動時，GRUB在某些情況下可能需要很長的時間來驗證密碼。這可能是由於PBKDF的迭代次數太多，你可以按以下方法檢查:

    # cryptsetup luksDump /dev/sda3

問題是，給定的密鑰槽的迭代次數是在添加鑰匙時產生的，這個迭代次數需要確保既足夠高來防止暴力攻擊，也要使你的計算機儘可能快的推導出密鑰。然而，當GRUB啟動時，它可能沒有同樣的計算資源在手，因此推導速度會大大降低。

如果你的密碼本身能提供足夠的熵來對抗常見的攻擊，你可以降低迭代次數。

    # cryptsetup luksChangeKey --pbkdf-force-iterations 1000 /dev/sda3

根據RFC 2898，建議至少1000次迭代，但如果可以的話，你應該儘可能使用更高的數值（攻擊者的成本以及密鑰推導的時間是線性擴展的）。

提示：GRUB依次嘗試啟用密鑰槽。在添加密鑰時，可以使用`--key-slot`選項來明確指定一個密鑰槽。

## 參考資料

- GRUB 2主題教程

分類：​

- 啟動加載程序
- 包含失效連結的頁面
- 使用「模板:風格」標記的頁面或章節

隱藏分類：​

- 使用「模板:準確性」標記的頁面或章節

GRUB/技巧和竅門
新增話題