EFI スタブ
- CONFIG_PM_STD_PARTITION for hibernation
この記事では EFI スタブカーネル、つまり、UEFI から直接実行可能なカーネルについて記載します。
EFI スタブ ( EFI ブートスタブ とも) [1] は、それ自身が EFI 実行可能形式である、つまり、UEFI ファームウェアから直接ブートすることができるカーネルです。これはつまり、EFI スタブのためのブートローダが不要であるということです。(ですが、ブートローダを使用することもできます。)
カーネル設定
EFI スタブサポート
以下のカーネル設定オプションが有効化されていなくてはなりません:
Processor type and features --->
[*] EFI runtime service support Search for <code>CONFIG_EFI</code> to find this item.
[*] EFI stub support Search for <code>CONFIG_EFI_STUB</code> to find this item.
[ ] EFI mixed-mode support (OPTIONAL) Search for <code>CONFIG_EFI_MIXED</code> to find this item.
EFI mixed-mode support は、CPU が 64 ビットモードに対応しており、EFI handover が有効化されている場合に、32 ビットファームウェアから 64 ビットカーネルをブートするためにのみ必要です。
インストール
自動
UEFI の実装はベンダーによって異なっており、すべての UEFI システムで EFI スタブによるブートの動作が保証されているわけではありません。EFI スタブによる(自動)ブートを試す前に、バックアップのブート方法を必ず確保してください。
EFI スタブによる自動ブートは、 efistub USE フラグが有効化されている場合、 sys-kernel/installkernel-38 以降のバージョンによって提供されます。これにより、通常のブートレイアウトが /boot から EFI System Partition 上の EFI/Gentoo へと変更されます。
systemd kernel-install
sys-kernel/installkernel に対して efistub と systemd の両方の USE フラグが有効化されている場合、 kernel-install はインストール・削除されたカーネルのブートエントリを追加・削除するために、 app-emulation/virt-firmware の kernel-bootcfg を実行します。 Installkernel は、カーネルの make install または Distribution Kernel の post-install フェーズによって自動的に実行されます。したがって、新しいカーネルをインストールした際に特別な操作は不要ですが、新しいカーネルでのブートに成功した時に永続的な項目を自動的に作成するには、 app-emulation/virt-firmware の kernel-bootcfg-boot-successful init サービスを有効にしてください。
systemd システムでは:
root
#
systemctl enable --now kernel-bootcfg-boot-successful.service
OpenRC システムでは:
root
#
rc-update add kernel-bootcfg-boot-successful default
登録されるカーネルイメージが Unified Kernel Image ではない場合、新しい項目のカーネルコマンドラインは以下の順番で読み込まれます:
- /etc/kernel/cmdline
- /usr/lib/kernel/cmdline
- /proc/cmdline
さらに、カーネルのインストール中に initramfs が生成された場合、カーネルコマンドライン引数 initrd= が自動的に追加されます。一方、登録されるカーネルが Unified Kernel Image の場合、新しいエントリにはコマンドラインは追加されません。代わりに Unified Kernel Image に組み込まれているコマンドラインが使用されますが、この組み込みコマンドラインの内容も通常は UKI が生成される際に同じファイルから読み込まれます。
initramfs と同じく、カーネルコマンドラインもカーネルに組み込むことができます。詳細については以下の節を見てください。
伝統的な installkernel
sys-kernel/installkernel に対して、 efistub USE フラグ が有効化されているが、 systemd USE フラグが無効化されている場合、 Installkernel は UEFI 構成を動的に更新するために sys-boot/uefi-mkconfig の uefi-mkconfig を呼び出します。 shim EFI 実行可能形式がカーネルイメージと同じディレクトリ内に存在する場合、カーネルは shim を経由してチェインロードされるでしょう。
手動
ESP が /efi にマウントされていると仮定すると、個別のディレクトリは /efi/EFI の下に作成することが推奨されます。 EFI スタブサポートを付けてカーネルを設定したら、 /efi/EFI の下に個別のディレクトリを作成します:
root
#
mkdir -p /efi/EFI/example
一部のシステムでは、( ESP が /efi にマウントされていると仮定して) /efi/EFI または /efi/efi (小文字) が既に存在していることがあります。 EFI System Partition (ESP) の FAT ファイルシステムは大文字と小文字を厳密に区別しませんが、それらの違いを保持します (VFAT)。VFAT のデフォルトのマウントオプションを使っていれば、上のコマンドはどちらの場合でも動作するでしょう。詳細については FAT の記事の大文字と小文字の区別節 を参照してください。
カーネルは現在のカーネルディレクトリから作成され、新しいディレクトリにコピーされます。これはカーネルを /efi/EFI/example/bzImage.efi にインストールします:
/usr/src/linux #
make && make modules_install && cp arch/x86/boot/bzImage /efi/EFI/example/bzImage.efi
カーネルをアップグレードするときには、動作することが分かっている古いバージョンを残しておくことが推奨されます:
user
$
tree -L 3 /efi
/efi
└── EFI
└── example
├── bzImage-6.1.67.efi
└── bzImage-6.1.70.efi
ルートパーティション設定
UEFI から直接ブートするためには、ブートするシステムのルート ( / ) パーティションがどこにあるのかをカーネルまたは initramfs が認識していなくてはなりません。grub などのブートマネージャを使用する場合は、カーネルはルートパーティションをどこから探せばよいかの情報を、ブートマネージャからコマンドライン引数を介して取得します。スタブカーネルを使用する場合は、カーネルにこの情報を渡すために使用できる方法として 2 つの選択肢 があります - これらの選択肢から一方を選択してください:
選択肢 1: カーネル内で設定する
Processor type and features --->
[*] Built-in kernel command line
(root=PARTUUID=adf55784-15d9-4ca3-bb3f-56de0b35d88d ro)
値 adf55784-15d9-4ca3-bb3f-56de0b35d88d は例であり、実際のルートパーティションの値で置き換えなくてはなりません。これは blkid コマンドを使用して得ることができます:
root
#
blkid | grep sda3
/dev/sda3: UUID="d1e0c1e0-3a40-42c5-8931-cfa2c7deae32" TYPE="ext4" PARTUUID="adf55784-15d9-4ca3-bb3f-56de0b35d88d"
選択肢 2: UEFI 内で設定する
カーネルコマンドライン引数付きのエントリを追加するには:
root
#
efibootmgr --create --disk /dev/sda --label "Gentoo EFI Stub" --loader "\EFI\example\bzImage.efi" -u "root=/dev/sda3"
ルートの場所は PARTUUID を使用して、または initramfs を使用する場合には (ファイルシステムの) UUID を使用して設定するほうが、一般的により好ましく間違いを起こしにくいです。
さらなる例を ブートエントリを作成する で見つけることができます。
省略可能: initramfs とともに併用する
外部の (CPIO アーカイブの) initramfs とともにカーネルを使用する場合、追加の手順が必要です。dist-kernel をビルドする場合または genkernel を使用する場合は、必ず initramfs が作成されます。dist-kernel を使用する場合、この initramfs は "initrd" という名前が付けられ、 /usr/src/linux-6.1.57-gentoo-dist/arch/x86/boot/initrd に置かれます。このファイルを ESP にコピーする必要があります:
root
#
cp /path/to/my/initramfs/myinitrd.cpio.gz /efi/EFI/example/initrd.cpio.gz
カーネルは initramfs をどこから探すべきかの情報を必要とし、initramfs はルートパーティションをどこから探すべきかの情報を必要とします。UEFI は両方の情報を与えなくてはなりません:
root
#
efibootmgr -c -d /dev/sda -p 1 -L "Gentoo EFI Stub" -l '\EFI\example\bzImage.efi' -u 'root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx initrd=\EFI\example\initrd.cpio.gz'
フォーラム投稿はそれについてより詳しく説明しています - さらにユーザのエラーをいくつか修正しています:
Forums topic - Booting UEFI without Grub
Early Userspace Mounting を使用する場合は、 Generating the Initramfs および Using a Stub Kernel の節でそれについて詳しく説明しています。
省略可能: 埋め込み initramfs
また、initramfs をカーネルに直接組み込むこともできます。利点としては、 Secure Boot がカーネルを検証する際に initfamfs も検証されること、ブートプロセスや EFI パーティションが単純になること、(呼出元で initfamfs を指定する必要がないため)簡単に手動でカーネルを読み込めることなどがあります。欠点は、柔軟性が低くなること、ミスが起こりやすいこと、一般的でないブート構成を使用することなどです。
initramfs に Microcode が含まれている場合、更新を受け取ることがセキュリティ上重要です。initramfs は、カーネルに組み込まれている場合は独立して更新することができないため、 initramfs が更新されるたびにカーネルをビルドしなおす必要があります 。具体的には、以下のことに注意する必要があります:
-
カーネルを再ビルドする前に
を実行しない場合、最後のビルドから残っているキャッシュされた initramfs CPIO アーカイブを削除するために
root #make cleanを実行してください。root #rm usr/initramfs_data.cpio - initramfs に更新がある場合、カーネルを再ビルド・再インストールしてください。
- initramfs が sys-apps/portage によって管理されている場合、initramfs をカーネルより 前に 更新するようにしてください。
カーネルは、(例えば Dracut で生成されるような) CPIO ファイルと、CPIO アーカイブに圧縮されるソースディレクトリの両方をサポートしています。以下では後者を /usr/src/initramfs として表していますが、前者を選択した場合(あなたが Custom Initramfs を使用しているのでなければ、通常はこちらです)、 /path/to/my/initramfs/myinitrd.cpio.gz で置き換える必要があります。
General Setup --->
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
(/usr/src/initramfs) Initramfs source file(s)
EFI ファームウェア設定
すべて正しく機能していることを確認するには、カーネルを initrd コマンドライン引数を付けずに起動します。
Unified カーネルイメージのエントリを作成するには:
root
#
efibootmgr --create --disk /dev/sda --label "Gentoo EFI Stub" --loader "\EFI\example\bzImage.efi"
バックアップカーネル
バックアップのカーネルを常に用意しておくことをおすすめします。grub はスタブカーネルを通常のカーネルと同様に起動することができるため、grub のようなブートマネージャーが既にインストールされているのであればそれをアンインストールしないようにしてください。2つめの選択肢は、予備の UEFI エントリを用意することです。新しいカーネルをインストールする前に、現在のものを /efi/EFI/example/ から /efi/EFI/backup へコピーしておきます。2つめの UEFI エントリも efibootmgr で作成しておきます。この例では、異なる名前が使用されています:
root
#
efibootmgr
BootCurrent: 0002 Timeout: 1 seconds BootOrder: 0002,0000,0001 Boot0000* Secure HD(1,GPT,0adcbfee-21aa-42ea-9a9a-2e53bd05e6a2,0x800,0x7f800)/File(\EFI\secure\bzImage.efi) Boot0001* gentoo HD(1,GPT,0adcbfee-21aa-42ea-9a9a-2e53bd05e6a2,0x800,0x7f800)/File(\EFI\gentoo\grubx64.efi) Boot0002* Backup HD(1,GPT,0adcbfee-21aa-42ea-9a9a-2e53bd05e6a2,0x800,0x7f800)/File(\EFI\backup\bzImage.efi)
マイクロコードのロード
initramfs を使わないカーネルを使用する場合は、以下の記事に記載されているようにマイクロコードをロードすることが推奨されます:
省略可能: セキュアブートのために署名する
このカーネルを セキュアブートする 場合は、 app-crypt/sbsigntools に含まれる sbsign を使用して署名しなくてはなりません:
root
#
sbsign --key {db key} --cert {db cert} /efi/EFI/example/bzImage.efi
さらなる情報が Secure Boot で確認できます。
通常の EFI スタブには必要な .sbat sbat セクションがないため、 sys-boot/shim 経由で EFI スタブを起動することはできません。そのため、Secure Boot を有効にした状態で EFI スタブを起動するには、使用した署名鍵を UEFI ファームウェアで直接登録する必要があります。 shim 経由での起動もサポートする EFI スタブの代替的な起動方法については、 Unified Kernel Image のウィキページを参照してください。
トラブルシューティング
(U)EFI の実装によっては稀に、個別の EFI エントリを受け付けないことがあります。この場合は リムーバブルメディアパス を使用する方法がしばしば動作します。詳細については EFI System Partition #removable media を参照してください。例えば、このコマンドは64ビット UEFI 用のカーネルをコピーします:
root
#
cp /usr/src/linux/arch/x86/boot/bzImage /efi/EFI/boot/bootx64.efi
- gcc:10 でコンパイルされた古いカーネルは ブート時にクラッシュする ことがありました ( bug #721734#c4 )。
-
sys-kernel/gentoo-kernel-bin
を使用している場合は、
efibootmgr
を使用して
root=パラメータでルートパーティションパスを指定することができます:
root
#
efibootmgr -c -L "Gentoo Linux" -l '\EFI\Gentoo\bootx64.efi' -u 'root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
- efibootmgr で、スワップパーティションへのハイバネーションに対応したブートエントリを作成するには:
root
#
efibootmgr -c -L "Gentoo Linux" -l '\EFI\Gentoo\bootx64.efi' -u 'root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX resume=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
関連項目
- UEFI — a firmware standard for boot ROM designed to provide a stable API for interacting with system hardware. On x86 it replaced the legacy BIOS .
- Efibootmgr — UEFI ブートエントリを管理するためのツールです。
- アーキテクチャ固有のカーネルコンフィグ (AMD64 ハンドブック)
- REFInd — rEFIt からフォークした後継の EFI および UEFI プラットフォーム向けブートマネージャ
- Unified Kernel Image — a single executable which can be booted directly from UEFI firmware , or automatically sourced by boot-loaders with little or no configuration.
外部資料
- EFI スタブに関する Linux カーネルドキュメンテーション
- EFI Stub - booting without a bootloader この記事は部分的にこのブログポストに基づいています。
- EFI bootloaders (U)EFI システムをブートする他の方法のリスト。
- Gentoo Forums: Suspend and Hibernate with UEFI
- http://www.kroah.com/log/blog/2013/09/02/booting-a-self-signed-linux-kernel/