EFI スタブ

From Gentoo Wiki
Jump to:navigation Jump to:search
This page is a translated version of the page EFI stub and the translation is 100% complete.
Other languages:
Resources
This article has some todo items:
  • CONFIG_PM_STD_PARTITION for hibernation

多くのコンピュータに存在する (U)EFI ファームウェアはブートマネージャとして機能し、対応した EFI ブートローダを使用してシステムをブートすることができます。カーネル 自体をこのようなブートローダ (EFI スタブと呼ばれます) にすることで、2 次ブートローダを必要とせずにブートすることができます。この記事では、カーネルを設定して、EFI モードで実行中のコンピュータの EFI システムパーティション (ESP) にインストールするための手順を提供します。

警告
UEFI の実装はベンダーによって異なっており、すべての UEFI システムで EFI スタブによるブートの動作が保証されているわけではありません。EFI スタブによる(自動)ブートを試す前に、バックアップのブート方法を必ず確保してください。

カーネル設定

EFI スタブサポート

以下のカーネル設定オプションが有効化されていなくてはなりません:

カーネル カーネル 6.1+ に対して EFI スタブサポートを有効化する
Processor type and features  --->
    [*] EFI runtime service support
    [*]     EFI stub support
    [ ]     EFI mixed-mode support (OPTIONAL)
メモ
EFI mixed-mode support は、CPU が 64 ビットモードに対応しており、EFI handover が有効化されている場合に、32 ビットファームウェアから 64 ビットカーネルをブートするためにのみ必要です。
メモ
ディストリビューションカーネル (gentoo-kernel-bin を除く) では、カーネル設定はsavedconfig または /etc/kernel/config.d に保存されます。

インストール

ヒント
省略可能: EFI システムパーティション (ESP) が存在しない場合は、先にそれを構築するための手順に従ってください。

自動

EFI スタブによる自動ブートは、efistub USE フラグが有効化されている場合、sys-kernel/installkernel によって提供されます。これにより、通常のブートレイアウトが /boot から EFI System Partition 上の EFI/Gentoo へと変更され、インストール・削除されたカーネルのブートエントリを追加・削除するために app-emulation/virt-firmwarekernel-bootcfg が実行されます。Installkernel は、カーネルの make install または Distribution Kernel の post-install フェーズによって自動的に実行されます。したがって、新しいカーネルをインストールした際に特別な操作は不要ですが、新しいカーネルでのブートに成功した時に永続的な項目を自動的に作成するには、app-emulation/virt-firmwarekernel-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 が生成される際に同じファイルから読み込まれます。

メモ
sys-kernel/installkernelefistub USE フラグは systemd USE フラグを必要とします。しかし、この systemd フラグは systemd init システムへの依存関係を強制しません。この systemd フラグによる依存関係は、sys-apps/systemd-utilsboot 及び kernel-install フラグがあれば満たされるため、これは OpenRC システムでも動作します。

手動

EFI スタブサポートを付けてカーネルを設定したら (ESP/efi にマウントされていると仮定して)。システムによっては /efi/efi が既に存在することがあり、その場合はそれを使用しなくてはなりません。/efi/EFI (または /efi/efi が既に存在する場合はそちら) の下に個別のディレクトリを作成することが推奨されます。以下では example の名前を使用します:

root #mkdir -p /efi/EFI/example

カーネルは現在のカーネルディレクトリから作成され、新しいディレクトリにコピーされます。これはカーネルを /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: カーネル内で設定する =
カーネル カーネル 6.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"
パーティションの PARTUUID はファイルシステムの UUID とは異なります。UUID は一意なファイルシステムパーティションを指し、initramfs で使用する必要があるもので、PARTUUID はディスクパーティションを指し、カーネルをブートするときに使用することができるものです。
選択肢 2: UEFI 内で設定する

カーネルコマンドライン引数付きのエントリを追加するには:

root #efibootmgr --create --disk /dev/sda --label "Gentoo EFI Stub" --loader "\EFI\example\bzImage.efi" -u "root=/dev/sda3"
重要
ルートの場所は PARTUUID を使用して、または initramfs を使用する場合には (ファイルシステムの) UUID を使用して設定するほうが、一般的により好ましく間違いを起こしにくいです。

EFI ファームウェア設定

カーネルファイルが /efi/EFI/example/bzImage.efi にある場合は、ブートエントリは以下で追加することができます:

root #efibootmgr --create --disk /dev/sda --label "Gentoo EFI Stub" --loader "\EFI\example\bzImage.efi"

さらなる例を efibootmgr で見つけることができます。

追加可能: 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 が更新されるたびにカーネルをビルドしなおす必要があります。具体的には、以下のことに注意する必要があります:
  • カーネルを再ビルドする前に
    root #make clean
    を実行しない場合、最後のビルドから残っているキャッシュされた initramfs CPIO アーカイブを削除するために
    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 で置き換える必要があります。

カーネル カーネルに initramfs を埋め込む
General Setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    (/usr/src/initramfs) Initramfs source file(s)

すべて正しく機能していることを確認するには、カーネルを initrd コマンドライン引数を付けずに起動します。

バックアップカーネル

バックアップのカーネルを常に用意しておくことをおすすめします。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 エントリを受け付けないことがあります。この場合はリムーバブルメディアパスを使用する方法がしばしば動作します。詳細については Efibootmgr #removable media を参照してください。例えば、このコマンドは64ビット UEFI 用のカーネルをコピーします:
root #cp /usr/src/linux/arch/x86/boot/bzImage /efi/EFI/boot/bootx64.efi
これは、(EFI ブートエントリを使用して設定されている)内部ドライブ上の (U)EFI ブートの選択を回避してしまう点で、(U)EFI の仕様に反していることを知っておいてください。
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'

関連項目

外部資料

参照