「ユニファイドカーネルイメージ」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
 
(3人の利用者による、間の9版が非表示)
10行目: 10行目:
 
== ユニファイドカーネルイメージの準備 ==
 
== ユニファイドカーネルイメージの準備 ==
   
  +
UKI (Unified Kernel Image) イメージを生成し、適切な場所 ("esp/Linux" ディレクトリ) にインストールする方法はいくつかあります。現在、この機能を実行するためのツールがいくつか競合しているので、ニーズと好みに応じて以下のいずれかを選択してください。
=== mkinitpcio ===
 
  +
  +
{{Note|
  +
* 以下のいずれかのサブセクションを実行するだけで済みます。
  +
* UKI を [[Unified Extensible Firmware Interface#Default boot path for removable drives|フォールバックブートパス]] {{ic|''esp''/EFI/BOOT/BOOTx64.EFI}} (または 32 ビット IA32 UEFI の場合は {{ic|BOOTIA32.EFI}}) に配置することも可能です。フォールバックブートパスを使用すると、NVRAM に UEFI ブートエントリを明示的に作成する必要がなくなります。
  +
}}
  +
  +
=== mkinitcpio ===
  +
  +
[[mkinitcpio]] は、{{Pkg|systemd-ukify}} がインストールされていない限り、UKI (Unified Kernel Image) を自身で組み立てます。{{Pkg|systemd-ukify}} がインストールされている場合は、{{ic|--no-ukify}} オプションで明示的に無効にしない限り、UKI の作成は "ukify" にオフロードされます。
   
 
==== カーネルコマンドライン ====
 
==== カーネルコマンドライン ====
   
[[mkinitcpio]] は、{{ic|/etc/cmdline.d}} ディレクトリ内のコマンドライン ファイルからの [[カーネルパラメータ]] の読み取りをサポートします。Mkinitcpio は、このディレクトリ内の {{ic|.conf}} 拡張子を持つすべてのファイルの内容を連結し、それらを使用してカーネルコマンドラインを生成します。コマンドラインファイル内の ''#'' 文字で始まる行はコメントとして扱われ、mkinitcpio によって無視されます。マイクロコードと initramfs を指す ''エントリを削除'' するように注意してください。
+
[[mkinitcpio]] は、{{ic|/etc/cmdline.d}} ディレクトリ内のコマンドライン ファイルからの[[カーネルパラメータ]]の読み取りをサポートします。Mkinitcpio は、このディレクトリ内の {{ic|.conf}} 拡張子を持つすべてのファイルの内容を連結し、それらを使用してカーネルコマンドラインを生成します。コマンドラインファイル内の ''#'' 文字で始まる行はコメントとして扱われ、mkinitcpio によって無視されます。マイクロコードと initramfs を指す ''エントリを削除'' するように注意してください。
   
 
例:
 
例:
23行目: 32行目:
   
 
{{Tip|
 
{{Tip|
* ルート ファイルシステムがデフォルト以外の Btrfs サブボリューム上にある場合は、必ず必要なマウントフラグを {{ic|rootflags}} に設定してください。[[Btrfs#ルートとしてサブボリュームをマウントする]] を参照してください。
+
* ルート ファイルシステムがデフォルト以外の Btrfs サブボリューム上にある場合は、必ず必要なマウントフラグを {{ic|rootflags}} に設定してください。[[Btrfs#サブボリュームをルートとしてマウントする]] を参照してください。
 
* たとえば、システムのサブボリューム ID が {{ic|256}} の場合 (サブボリューム ID は、{{ic|btrfs subvolume list ''btrfs_mountpoint''}} を使用して確認できます。または、{{ic|/etc/fstab}}) でフラグを見ることができます、カーネルコマンドラインに {{ic|1=rootflags=subvolid=256}} を追加する必要があります。
 
* たとえば、システムのサブボリューム ID が {{ic|256}} の場合 (サブボリューム ID は、{{ic|btrfs subvolume list ''btrfs_mountpoint''}} を使用して確認できます。または、{{ic|/etc/fstab}}) でフラグを見ることができます、カーネルコマンドラインに {{ic|1=rootflags=subvolid=256}} を追加する必要があります。
 
* {{ic|rootflags}} は起動時にのみ使用されるため、{{ic|/etc/fstab}} 内のすべてのフラグをコピーする必要はありません。Systemd は fstab を読み取り、再マウントし、ブート後にそこにリストされているフラグを自動的に適用します。
 
* {{ic|rootflags}} は起動時にのみ使用されるため、{{ic|/etc/fstab}} 内のすべてのフラグをコピーする必要はありません。Systemd は fstab を読み取り、再マウントし、ブート後にそこにリストされているフラグを自動的に適用します。
33行目: 42行目:
 
}}
 
}}
   
あるいは、{{ic|/etc/kernel/cmdline}} を使用してカーネルコマンドラインを構成することもできます。
+
あるいは、{{ic|/etc/kernel/cmdline}} を使用してカーネルコマンドラインを設定することもできます。
   
 
例:
 
例:
42行目: 51行目:
   
 
{{Tip|
 
{{Tip|
* root パーティションが [[systemd# GPT パーティションの自動マウント|systemd によって自動マウントされる]] 場合、{{ic|1=root=}} パラメータは省略できます。
+
* root パーティションが [[systemd#GPT パーティションの自動マウント|systemd によって自動マウントされる]] 場合、{{ic|1=root=}} パラメータは省略できます。
 
* {{ic|bgrt_disable}} パラメータは、ACPI テーブルのロード後に OEM ロゴを表示しないように Linux に指示します。
 
* {{ic|bgrt_disable}} パラメータは、ACPI テーブルのロード後に OEM ロゴを表示しないように Linux に指示します。
 
}}
 
}}
88行目: 97行目:
 
==== pacman フック ====
 
==== pacman フック ====
   
  +
systemd-stub ({{pkg|systemd}} の一部)、microcode ({{pkg|intel-ucode}} と {{pkg|amd-ucode}} の両方)、および {{pkg|linux}} カーネルの更新は、自動的に UKI (Unified Kernel Image) の再構築をトリガーします。ただし、{{ic|/etc/pacman.d/hooks/}} ディレクトリにある他の [[pacman フック]] (例えば、[[NVIDIA#pacman hook|NVIDIA ドライバー]] のものなど) を確認することをお勧めします。
マイクロコードのアップグレード後に再構築をトリガーするには、[[pacman フック]] が必要です。
 
 
{{hc|/etc/pacman.d/hooks/ucode.hook|2=
 
[Trigger]
 
Operation=Install
 
Operation=Upgrade
 
Operation=Remove
 
Type=Package
 
# Change to appropriate microcode package
 
Target=amd-ucode
 
# Change the linux part above and in the Exec line if a different kernel is used
 
Target=linux
 
 
[Action]
 
Description=Update Microcode module in initcpio
 
Depends=mkinitcpio
 
When=PostTransaction
 
NeedsTargets
 
Exec=/bin/sh -c 'while read -r trg; do case $trg in linux) exit 0; esac; done; /usr/bin/mkinitcpio -P'
 
}}
 
 
{{Tip|mkinitcpio の繰り返し実行を避けるために、このフックを [[NVIDIA#pacman フック|NVIDIA ドライバー]] のフックなど、カーネルパッケージを監視する他のフックとマージすることを検討してください。}}
 
 
==== セキュアブート用の UKI への署名 ====
 
 
mkinitcpio ポストフック ({{man|8|mkinitcpio|ABOUT POST HOOKS}}) を使用すると、生成された統合カーネルイメージに [[セキュアブート]] 用に署名できます。次のファイルを [[作成]] し、[[ヘルプ:読み方#実行可能属性の付与|実行可能]] にします。
 
 
{{hc|/etc/initcpio/post/uki-sbsign|2=
 
#!/usr/bin/env bash
 
 
uki="$3"
 
<nowiki>[[ -n "$uki" ]] || exit 0</nowiki>
 
 
keypairs=(''/path/to/''db.key ''/path/to/''db.crt)
 
 
for (( i=0; i<${#keypairs[@]}; i+=2 )); do
 
key="${keypairs[$i]}" cert="${keypairs[(( i + 1 ))]}"
 
if ! sbverify --cert "$cert" "$uki" &>/dev/null; then
 
sbsign --key "$key" --cert "$cert" --output "$uki" "$uki"
 
fi
 
done
 
}}
 
 
{{ic|''/path/to/''db.key}} と {{ic|''/path/to/''db.crt}} をイメージの署名に使いたい鍵ペアのパスに置き換えてください。
 
   
 
==== UKI の構築 ====
 
==== UKI の構築 ====
144行目: 110行目:
 
=== kernel-install ===
 
=== kernel-install ===
   
  +
確実に kernel-install が [[Kernel-install#自動で|正しく設定されている]] ことを確認してください。
[[systemd]] の [[Kernel-install]] スクリプトを使用して、カスタムカーネルとカーネルパッケージ (Pacman を使用してインストール) の両方について、UKI 形式のカーネルを ''esp'' に自動的にインストールできます。 Pacman フックを ''mkinitcpio'' から ''kernel-install'' に切り替える必要があります。
 
   
  +
UKI を生成するには、{{Pkg|systemd-ukify}} をインストールし、{{ic|kernel-install}} の layout を {{ic|uki}} に設定します。
UKI イメージは、''mkinitcpio'' によって直接生成することも、カーネルイメージと生成されたスタンドアロン initramfs イメージを 1 つのファイルに統合する ''kernel-install'' によって生成することもできます (''kernel-install''の ''ukify'' ツールによって) 2024 年 1 月 15 日以降、''install'' には、{{pkg|systemd-ukify}} が必要です。以下を参照してください) ''mkinitcpio'' は、適切なイメージ ({{ic|1=layout=uki}} および {{ic|1=uki_generator=mkinitcpio}} の UKI イメージ) を生成するために ''kernel-install'' によって呼び出されます。それ以外の場合は、''ukify'' のスタンドアロンの initramfs イメージ) を生成します。
 
   
* kernel-install {{ic|layout}} を {{ic|uki}} に設定します。例えば: {{bc|1=# echo "layout=uki" >> /etc/kernel/install.conf}}
+
{{hc|/etc/kernel/install.conf|
  +
2=layout=uki}}
   
  +
{{Note|[[mkinitcpio]] が initrd を作成し、その後 [[#ukify]] が UKI を生成します。}}
* デフォルトでは、レイアウトが uki に設定されている場合、''kernel-install'' は独自の ''ukify'' ツールを使用して (ここで {{pkg|systemd-ukify}} をインストールする必要があります。下記を参照) initramfs とカーネルイメージ mkinitpcio を使用して、uki イメージを直接生成できます。mkinitcpio を使用して uki イメージを生成したい場合は、{{ic|uki_generator}} を {{ic|mkinitpcio}} に設定します。例: {{bc|1=# echo "uki_generator=mkinitcpio" >> /etc/kernel/install.conf}}
 
   
  +
[[#ukify]] の設定は、[[kernel-install]] で使用するために、{{ic|/etc/kernel/uki.conf}} で行う必要があります。例:
:{{Note|2024 年 1 月 15 日以降、{{ic|uki_generator}} でない限り、{{pkg|mkinitcpio}} は [https://gitlab.archlinux.org/archlinux/mkinitcpio/mkinitcpio/-/commit/0df979c34970b19a3e56d9a16d79e32830228448 UKI をビルドしなくなりました]}} {{ic|mkinitcpio}} に直接設定されます。以前は、{{pkg|systemd-ukify}} が明示的にインストールされていない場合、暗黙的に設定されていました。}}
 
   
  +
{{hc|/etc/kernel/uki.conf|
* カーネルを直接インストールする Pacman フック:{{bc|<nowiki># ln -s /dev/null /etc/pacman.d/hooks/60-mkinitcpio-remove.hook
 
  +
2=[UKI]
# ln -s /dev/null /etc/pacman.d/hooks/90-mkinitcpio-install.hook
 
  +
Splash=/usr/share/systemd/bootctl/splash-arch.bmp
</nowiki>}}
 
  +
}}
* ''kernel-install'' の Pacman フックを作成します。{{AUR|pacman-hook-kernel-install}} を使うことができます。
 
* 使用しているカーネルパッケージを削除して再インストールします。
 
   
  +
{{Tip|{{ic|/usr/lib/kernel/uki.conf}} から {{ic|/etc/kernel/uki.conf}} にテンプレートをコピーし、セクションタイトルと役立つ行をコメントアウトすることもできます。このファイルにカーネルコマンドラインを設定しないでください。無視されます。[[Kernel-install#カーネルコマンドライン]] を使用してください。}}
=== dracut ===
 
   
  +
あるいは、mkinitcpio が UKI を生成するように、それをデフォルトの {{ic|uki_generator}} として設定します。
[[dracut#カーネルコマンドラインオプション|コマンドラインパラメータ]] を、例えば {{ic|/etc/dracut.conf.d/cmdline.conf}} に配置します。
 
   
  +
{{hc|/etc/kernel/install.conf|
イメージを生成する。
 
  +
2=layout=uki
  +
uki_generator=mkinitcpio}}
   
  +
この場合、{{Pkg|systemd-ukify}} は不要です。別の {{ic|initrd_generator}} を設定することもできます。{{Man|8|kernel-install}} を参照してください。
# dracut -f -q --uefi --uefi-splash-image /usr/share/systemd/bootctl/splash-arch.bmp
 
   
  +
変更を有効にするには、使用しているカーネルパッケージを再インストールしてください。
こちらも参照 [[dracut#カーネルのアップグレード時に新しい initramfs を生成]]
 
   
=== sbctl ===
+
=== dracut ===
 
{{Pkg|sbctl}} パッケージを [[インストール]] して下さい。カーネルコマンド ラインを {{ic|/etc/kernel/cmdline}} に保存します。{{ic|--save}} パラメータを指定した {{ic|sbctl bundle}} コマンドを使用してバンドルを作成し、適切なタイミングで Pacman フックによって再生成します。
 
 
# sbctl bundle --save ''esp''/archlinux.efi
 
   
  +
こちらを参照して下さい [[dracut#ユニファイドカーネルイメージ]] と [[dracut#カーネルのアップグレード時に新しい initramfs を生成]]
他のカーネルと initramfs イメージ用にさらに EFI バイナリを作成するには、パラメーター {{ic|--kernel-img}} と {{ic|--initramfs}} を指定して上記のコマンドを繰り返します。{{man|8|sbctl|EFI BINARY COMMANDS}} を参照してください。EFI バイナリは、{{ic|sbctl generate-bundles}} を使用していつでも再生成できます。
 
   
 
=== ukify ===
 
=== ukify ===
184行目: 148行目:
 
最小限の動作例は次のようになります。
 
最小限の動作例は次のようになります。
   
# /usr/lib/systemd/ukify build --linux=''/boot/vmlinuz-linux'' --initrd=''/boot/intel-ucode.img'' \
+
# ukify build --linux=''/boot/vmlinuz-linux'' \
--initrd=''/boot/initramfs-linux.img'' \
+
--initrd=''/boot/initramfs-linux.img'' \
--cmdline="''quiet rw''"
+
--cmdline="''quiet rw''"
   
 
{{Note|[[マイクロコード#早期ロード|外部マイクロコード initramfs イメージ]] を使用する場合 ({{ic|/boot/amd-ucode.img}} または {{ic|/boot/intel-ucode.img}}) を使用する必要があります。常にメインの initramfs イメージの前に ''最初に'' 配置します (例: {{ic|/boot/initramfs-linux.img}})}}
 
{{Note|[[マイクロコード#早期ロード|外部マイクロコード initramfs イメージ]] を使用する場合 ({{ic|/boot/amd-ucode.img}} または {{ic|/boot/intel-ucode.img}}) を使用する必要があります。常にメインの initramfs イメージの前に ''最初に'' 配置します (例: {{ic|/boot/initramfs-linux.img}})}}
 
次に、結果のファイルを EFI システムパーティションにコピーします。
 
 
# cp ''filename''.efi ''esp''/EFI/Linux/
 
   
 
{{Tip|
 
{{Tip|
198行目: 158行目:
 
* {{ic|--cmdline}} オプションを指定する場合、{{ic|1=--cmdline=@''/path/to/cmdline''}} のように {{ic|/etc/kernel/cmdline}} ファイル名の前に {{ic|@}} シンボルを追加することで、カーネルパラメータを読み込むファイル名を指定できます。
 
* {{ic|--cmdline}} オプションを指定する場合、{{ic|1=--cmdline=@''/path/to/cmdline''}} のように {{ic|/etc/kernel/cmdline}} ファイル名の前に {{ic|@}} シンボルを追加することで、カーネルパラメータを読み込むファイル名を指定できます。
 
}}
 
}}
  +
  +
詳細については、{{man|1|ukify}}を参照してください。
   
 
intel ucode および /efi マウント ESP を使用した通常のカーネルイメージの systemd サービスを使用した自動 UKI 構築の例:
 
intel ucode および /efi マウント ESP を使用した通常のカーネルイメージの systemd サービスを使用した自動 UKI 構築の例:
   
  +
{{Note|カーネル、マイクロコード、または initramfs が変更されたときに UKI が自動的に更新されるようにするには、例えば [[kernel-install]] や [[mkinitcpio]] と共に ukify を使用するだけです。詳細については、上記のセクション [[#kernel-install]] および [[#mkinitcpio]] を参照してください。}}
{{hc|/etc/ukify.conf|2=
 
[UKI]
 
Linux=/boot/vmlinuz-linux
 
Initrd=/boot/intel-ucode.img /boot/initramfs-linux.img
 
Cmdline=@/etc/kernel/cmdline
 
OSRelease=@/etc/os-release
 
Splash=/usr/share/systemd/bootctl/splash-arch.bmp
 
}}
 
 
{{Note|initramfs ジェネレーターが mkinitcpio などの CPU マイクロコードをデフォルトですでにバンドルしている場合は、{{ic|1=Initrd=/boot/initramfs-linux.img}} で initramfs イメージのみを指定します。}}
 
 
{{hc|/etc/systemd/system/run_ukify.service|2=
 
[Unit]
 
Description=Run systemd ukify
 
[Service]
 
Type=oneshot
 
ExecStart=/usr/lib/systemd/ukify build --config=/etc/ukify.conf --output ''esp''/EFI/Linux/archlinux-linux.efi
 
}}
 
 
{{hc|/etc/systemd/system/run_ukify.path|2=
 
[Unit]
 
Description=Run systemd ukify
 
[Path]
 
PathChanged=/boot/initramfs-linux.img
 
PathChanged=/boot/intel-ucode.img
 
Unit=run_ukify.service
 
[Install]
 
WantedBy=multi-user.target
 
}}
 
 
次に、{{ic|run_ukify.path}} を [[有効化]] します。
 
   
 
=== 手動で ===
 
=== 手動で ===
281行目: 213行目:
   
 
# cp ''linux''.efi ''esp''/EFI/Linux/
 
# cp ''linux''.efi ''esp''/EFI/Linux/
  +
  +
== セキュアブート 用の UKI への署名 ==
  +
  +
=== sbctl ===
  +
  +
{{Pkg|sbctl}} は、更新されたバイナリに署名するための [[kernel-install]] スクリプト、[[mkinitcpio]] ポストフック、および pacman フックを提供します。
  +
  +
=== mkinitcpio ===
  +
  +
[[mkinitcpio#ポストフック|mkinitcpio ポストフック]] を使用することで、生成された Unified Kernel Image に [[セキュアブート]] 用の署名を付けることができます。以下のファイルを作成し、[[ヘルプ:読み方#実行可能属性の付与|実行可能]]にしてください。
  +
  +
{{hc|/etc/initcpio/post/uki-sbsign|2=
  +
#!/usr/bin/env bash
  +
  +
uki="$3"
  +
<nowiki>[[ -n "$uki" ]] || exit 0</nowiki>
  +
  +
keypairs=(''/path/to/''db.key ''/path/to/''db.crt)
  +
  +
for (( i=0; i<${#keypairs[@]}; i+=2 )); do
  +
key="${keypairs[$i]}" cert="${keypairs[(( i + 1 ))]}"
  +
if ! sbverify --cert "$cert" "$uki" &>/dev/null; then
  +
sbsign --key "$key" --cert "$cert" --output "$uki" "$uki"
  +
fi
  +
done
  +
}}
  +
  +
{{ic|''/path/to/''db.key}} と {{ic|''/path/to/''db.crt}} を、イメージの署名に使用するキーペアのパスに置き換えてください。
  +
  +
=== ukify ===
  +
  +
{{Pkg|sbsigntools}} をインストールし、{{ic|/etc/kernel/uki.conf}} で {{ic|--secureboot-private-key}} と {{ic|--secureboot-certificate}} を指定します。
   
 
== 起動方法 ==
 
== 起動方法 ==
   
 
{{Note|[[セキュアブート]] がアクティブな場合、{{ic|.cmdline}} が埋め込まれた統合カーネルイメージは、(ブートエントリを使用するか対話的に) 渡されたすべてのコマンドラインオプションを無視します。セキュアブートがアクティブでない場合、コマンドライン経由で渡されたオプションは、埋め込まれた {{ic|.cmdline}} をオーバーライドします。}}
 
{{Note|[[セキュアブート]] がアクティブな場合、{{ic|.cmdline}} が埋め込まれた統合カーネルイメージは、(ブートエントリを使用するか対話的に) 渡されたすべてのコマンドラインオプションを無視します。セキュアブートがアクティブでない場合、コマンドライン経由で渡されたオプションは、埋め込まれた {{ic|.cmdline}} をオーバーライドします。}}
  +
  +
=== Limine ===
  +
  +
[[Limine]] は Unified Kernel Image (UKI) を自動的に検出しません。ただし、{{ic|limine.conf}} を手動で構成して UKI をロードできます。
  +
  +
'''例 1: デフォルトの EFI システムパーティションから UKI を起動する'''
  +
  +
UKI ファイルが {{ic|''esp''/EFI/Linux/}} に保存されている場合は、次の設定を {{ic|limine.conf}} に追加します。
  +
  +
{{hc|limine.conf|2=
  +
/Arch Linux
  +
protocol: efi_chainload
  +
image_path: boot():/EFI/Linux/arch-linux.efi
  +
}}
  +
  +
'''例 2: 別の EFI パーティションから UKI を起動する'''
  +
  +
UKI ファイルが別のディスク上の別の EFI パーティションにある場合は、{{ic|uuid(''partition UUID'')}} を使用します。
  +
  +
{{Note|パーティション UUID はファイルシステム UUID '''ではありません'''。{{ic|PARTUUID}} としてパーティション UUID を見つけるには、次を使用します。
  +
$ lsblk -o NAME,FSTYPE,PARTUUID,PARTTYPENAME,MOUNTPOINT,SIZE,LABEL
  +
}}
  +
  +
{{hc|limine.conf|2=
  +
/Arch Linux
  +
protocol: efi_chainload
  +
image_path: uuid(''xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx''):/EFI/Linux/arch-linux.efi
  +
}}
  +
  +
サポートされているパスと設定オプションの詳細については、[https://github.com/limine-bootloader/limine/blob/v8.x/CONFIG.md#Paths Limine Paths ドキュメント] を参照してください。
   
 
=== systemd-boot ===
 
=== systemd-boot ===
304行目: 298行目:
 
=== GRUB ===
 
=== GRUB ===
   
rEFInd と同様に、[[GRUB]] は [[GRUB#Unified カーネルイメージをチェインロード]] で説明されているように EFI UKI をチェーンロードできます。
+
rEFInd と同様に、[[GRUB]] は [[GRUB#ユニファイドカーネルイメージをチェインロード]] で説明されているように EFI UKI をチェーンロードできます。
   
 
=== UEFI から直接起動 ===
 
=== UEFI から直接起動 ===
316行目: 310行目:
 
== 参照 ==
 
== 参照 ==
   
  +
* [https://www.youtube.com/watch?v=7UhwK3g99_0 All Systems Go! talk on UKIs]
 
* [https://uapi-group.org/specifications/specs/unified_kernel_image/ Unified kernel image specification]
 
* [https://uapi-group.org/specifications/specs/unified_kernel_image/ Unified kernel image specification]
 
* [https://linderud.dev/blog/mkinitcpio-v31-and-uefi-stubs/ mkinitcpio v31 and UEFI stubs]
 
* [https://linderud.dev/blog/mkinitcpio-v31-and-uefi-stubs/ mkinitcpio v31 and UEFI stubs]

2025年6月8日 (日) 22:03時点における最新版

ユニファイドカーネルイメージ (UKI) は、単一の実行可能ファイルであり、UEFI ファームウェアから直接起動するか、ほとんどまたは全く設定を必要とせずにブートローダーによって自動的に取得されます。これは systemd-stub(7) のような UEFI ブートスタブプログラム、Linux カーネルイメージinitrd、および その他のリソース を単一の UEFI PE ファイルに組み合わせたものです。

このファイルは、したがってこれらのすべての要素を署名して Secure Boot で使用することが容易になります。

ノート: 記事全体で espEFI システムパーティション のマウントポイントを表します。

ユニファイドカーネルイメージの準備

UKI (Unified Kernel Image) イメージを生成し、適切な場所 ("esp/Linux" ディレクトリ) にインストールする方法はいくつかあります。現在、この機能を実行するためのツールがいくつか競合しているので、ニーズと好みに応じて以下のいずれかを選択してください。

ノート:
  • 以下のいずれかのサブセクションを実行するだけで済みます。
  • UKI を フォールバックブートパス esp/EFI/BOOT/BOOTx64.EFI (または 32 ビット IA32 UEFI の場合は BOOTIA32.EFI) に配置することも可能です。フォールバックブートパスを使用すると、NVRAM に UEFI ブートエントリを明示的に作成する必要がなくなります。

mkinitcpio

mkinitcpio は、systemd-ukify がインストールされていない限り、UKI (Unified Kernel Image) を自身で組み立てます。systemd-ukify がインストールされている場合は、--no-ukify オプションで明示的に無効にしない限り、UKI の作成は "ukify" にオフロードされます。

カーネルコマンドライン

mkinitcpio は、/etc/cmdline.d ディレクトリ内のコマンドライン ファイルからのカーネルパラメータの読み取りをサポートします。Mkinitcpio は、このディレクトリ内の .conf 拡張子を持つすべてのファイルの内容を連結し、それらを使用してカーネルコマンドラインを生成します。コマンドラインファイル内の # 文字で始まる行はコメントとして扱われ、mkinitcpio によって無視されます。マイクロコードと initramfs を指す エントリを削除 するように注意してください。

例:

/etc/cmdline.d/root.conf
root=UUID=0a3407de-014b-458b-b5c1-848e92a327a3 rw
ヒント:
  • ルート ファイルシステムがデフォルト以外の Btrfs サブボリューム上にある場合は、必ず必要なマウントフラグを rootflags に設定してください。Btrfs#サブボリュームをルートとしてマウントする を参照してください。
  • たとえば、システムのサブボリューム ID が 256 の場合 (サブボリューム ID は、btrfs subvolume list btrfs_mountpoint を使用して確認できます。または、/etc/fstab) でフラグを見ることができます、カーネルコマンドラインに rootflags=subvolid=256 を追加する必要があります。
  • rootflags は起動時にのみ使用されるため、/etc/fstab 内のすべてのフラグをコピーする必要はありません。Systemd は fstab を読み取り、再マウントし、ブート後にそこにリストされているフラグを自動的に適用します。
/etc/cmdline.d/security.conf
# enable apparmor
lsm=landlock,lockdown,yama,integrity,apparmor,bpf audit=1 audit_backlog_limit=256

あるいは、/etc/kernel/cmdline を使用してカーネルコマンドラインを設定することもできます。

例:

/etc/kernel/cmdline
root=UUID=0a3407de-014b-458b-b5c1-848e92a327a3 rw quiet bgrt_disable
ヒント:
  • root パーティションが systemd によって自動マウントされる 場合、root= パラメータは省略できます。
  • bgrt_disable パラメータは、ACPI テーブルのロード後に OEM ロゴを表示しないように Linux に指示します。

.preset ファイル

次に、/etc/mkinitcpio.d/linux.preset、または使用しているプリセットを、EFI システムパーティション の適切なマウントポイントを指定して、以下のように変更します:

  • PRESETS= の各項目について、PRESET_uki= パラメータのコメントを解除する (つまり # を削除する)、
  • 冗長な initramfs-*.img ファイルを保存しないように、PRESET_image= をコメントアウトする、
  • オプションとして、スプラッシュイメージを追加したい各 PRESET_options= 行に --splash パラメータを追加またはコメント解除します。

以下は linux カーネルと Arch スプラッシュスクリーンの linux.preset の例です。

/etc/mkinitcpio.d/linux.preset
# mkinitcpio preset file for the 'linux' package

#ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"

PRESETS=('default' 'fallback')

#default_config="/etc/mkinitcpio.conf"
#default_image="/boot/initramfs-linux.img"
default_uki="esp/EFI/Linux/arch-linux.efi"
default_options="--splash=/usr/share/systemd/bootctl/splash-arch.bmp"

#fallback_config="/etc/mkinitcpio.conf"
#fallback_image="/boot/initramfs-linux-fallback.img"
fallback_uki="esp/EFI/Linux/arch-linux-fallback.efi"
fallback_options="-S autodetect"
ヒント:
  • 統一されたカーネルイメージからブートしたいだけであれば、ESP のマウント/efi にして、ESP パーティションに存在する必要があるものだけをマウントすることができます。
  • --cmdline /etc/kernel/fallback_cmdlinefallback_options に追加することで、フォールバックイメージに上記とは異なる cmdline を使用することができます (例えば quiet を無くす。)
  • カーネルコマンドラインの埋め込みを省略するには、--no-cmdlinePRESET_options= に追加してください。カーネルパラメーターはブートローダー経由で渡す必要があります。
ノート:
  • PRESET_uki オプションは以前は PRESET_efi_image として知られていました。2022 年 11 月変更, 古いオプションは非推奨ですが、今のところ動作しています。
  • IA32 UEFI では、--uefistub /usr/lib/systemd/boot/efi/linuxia32.efi.stubPRESET_options= に追加してください。

pacman フック

systemd-stub (systemd の一部)、microcode (intel-ucodeamd-ucode の両方)、および linux カーネルの更新は、自動的に UKI (Unified Kernel Image) の再構築をトリガーします。ただし、/etc/pacman.d/hooks/ ディレクトリにある他の pacman フック (例えば、NVIDIA ドライバー のものなど) を確認することをお勧めします。

UKI の構築

最後に、UKI のディレクトリが存在することを確認し、initramfs を再生成 します。たとえば、linux プリセットの場合は次のようになります。

# mkdir -p esp/EFI/Linux
# mkinitcpio -p linux

必要に応じて、残っている initramfs-*.img/boot または /efi から削除します。

kernel-install

確実に kernel-install が 正しく設定されている ことを確認してください。

UKI を生成するには、systemd-ukify をインストールし、kernel-install の layout を uki に設定します。

/etc/kernel/install.conf
layout=uki
ノート: mkinitcpio が initrd を作成し、その後 #ukify が UKI を生成します。

#ukify の設定は、kernel-install で使用するために、/etc/kernel/uki.conf で行う必要があります。例:

/etc/kernel/uki.conf
[UKI]
Splash=/usr/share/systemd/bootctl/splash-arch.bmp
ヒント: /usr/lib/kernel/uki.conf から /etc/kernel/uki.conf にテンプレートをコピーし、セクションタイトルと役立つ行をコメントアウトすることもできます。このファイルにカーネルコマンドラインを設定しないでください。無視されます。Kernel-install#カーネルコマンドライン を使用してください。

あるいは、mkinitcpio が UKI を生成するように、それをデフォルトの uki_generator として設定します。

/etc/kernel/install.conf
layout=uki
uki_generator=mkinitcpio

この場合、systemd-ukify は不要です。別の initrd_generator を設定することもできます。kernel-install(8) を参照してください。

変更を有効にするには、使用しているカーネルパッケージを再インストールしてください。

dracut

こちらを参照して下さい dracut#ユニファイドカーネルイメージdracut#カーネルのアップグレード時に新しい initramfs を生成

ukify

systemd-ukify パッケージを インストール します。ukify は単独で initramfs を生成できないため、必要な場合は、dracutmkinitcpio、または booster を使用して生成する必要があります。

最小限の動作例は次のようになります。

# ukify build --linux=/boot/vmlinuz-linux \
              --initrd=/boot/initramfs-linux.img \
              --cmdline="quiet rw"
ノート: 外部マイクロコード initramfs イメージ を使用する場合 (/boot/amd-ucode.img または /boot/intel-ucode.img) を使用する必要があります。常にメインの initramfs イメージの前に 最初に 配置します (例: /boot/initramfs-linux.img)
ヒント:
  • 出来上がった EFI 実行ファイルを EFI システムパーティションにコピーするのをスキップするには、--output=esp/EFI/Linux/filename.efi コマンドラインオプションを ukify に使用します。
  • --cmdline オプションを指定する場合、--cmdline=@/path/to/cmdline のように /etc/kernel/cmdline ファイル名の前に @ シンボルを追加することで、カーネルパラメータを読み込むファイル名を指定できます。

詳細については、ukify(1)を参照してください。

intel ucode および /efi マウント ESP を使用した通常のカーネルイメージの systemd サービスを使用した自動 UKI 構築の例:

ノート: カーネル、マイクロコード、または initramfs が変更されたときに UKI が自動的に更新されるようにするには、例えば kernel-installmkinitcpio と共に ukify を使用するだけです。詳細については、上記のセクション #kernel-install および #mkinitcpio を参照してください。

手動で

使用するカーネルコマンドラインをファイルに記述し、objcopy(1) を使用してバンドルファイルを作成します。

マイクロコード の場合は、まず次のようにマイクロコードファイルと initrd を連結します。

$ cat esp/cpu_manufacturer-ucode.img esp/initramfs-linux.img > /tmp/combined_initrd.img

統合カーネルイメージを構築するときは、/tmp/combined_initrd.img を initrd として渡します。このファイルは後で削除できます。

ノート: IA32 UEFI では、以下のコマンドの /usr/lib/systemd/boot/efi/linuxx64.efi.stub/usr/lib/systemd/boot/efi/linuxia32.efi.stub に置き換えてください。
$ align="$(objdump -p /usr/lib/systemd/boot/efi/linuxx64.efi.stub | awk '{ if ($1 == "SectionAlignment"){print $2} }')"
$ align=$((16#$align))
$ osrel_offs="$(objdump -h "/usr/lib/systemd/boot/efi/linuxx64.efi.stub" | awk 'NF==7 {size=strtonum("0x"$3); offset=strtonum("0x"$4)} END {print size + offset}')"
$ osrel_offs=$((osrel_offs + "$align" - osrel_offs % "$align"))
$ cmdline_offs=$((osrel_offs + $(stat -Lc%s "/usr/lib/os-release")))
$ cmdline_offs=$((cmdline_offs + "$align" - cmdline_offs % "$align"))
$ splash_offs=$((cmdline_offs + $(stat -Lc%s "/etc/kernel/cmdline")))
$ splash_offs=$((splash_offs + "$align" - splash_offs % "$align"))
$ initrd_offs=$((splash_offs + $(stat -Lc%s "/usr/share/systemd/bootctl/splash-arch.bmp")))
$ initrd_offs=$((initrd_offs + "$align" - initrd_offs % "$align"))
$ linux_offs=$((initrd_offs + $(stat -Lc%s "initrd-file")))
$ linux_offs=$((linux_offs + "$align" - linux_offs % "$align"))

$ objcopy \
    --add-section .osrel="/usr/lib/os-release" --change-section-vma .osrel=$(printf 0x%x $osrel_offs) \
    --add-section .cmdline="/etc/kernel/cmdline" \
    --change-section-vma .cmdline=$(printf 0x%x $cmdline_offs) \
    --add-section .splash="/usr/share/systemd/bootctl/splash-arch.bmp" \
    --change-section-vma .splash=$(printf 0x%x $splash_offs) \
    --add-section .initrd="initrd-file" \
    --change-section-vma .initrd=$(printf 0x%x $initrd_offs) \
    --add-section .linux="vmlinuz-file" \
    --change-section-vma .linux=$(printf 0x%x $linux_offs) \
    "/usr/lib/systemd/boot/efi/linuxx64.efi.stub" "linux.efi"

注意すべき点がいくつかあります:

  • [1] で推奨されているように、オフセットは動的に計算されるので、セクションが重なることはありません。
  • セクションは、PE スタブの SectionAlignment フィールドが示す値 (通常は 0x1000) にアラインメントされます。
  • カーネルイメージは、[2] で述べられているように、インプレース解凍で後続のセクションが上書きされるのを防ぐために、最後のセクションにある必要があります。

イメージを作成したら、それを EFI システムパーティションにコピーします。

# cp linux.efi esp/EFI/Linux/

セキュアブート 用の UKI への署名

sbctl

sbctl は、更新されたバイナリに署名するための kernel-install スクリプト、mkinitcpio ポストフック、および pacman フックを提供します。

mkinitcpio

mkinitcpio ポストフック を使用することで、生成された Unified Kernel Image に セキュアブート 用の署名を付けることができます。以下のファイルを作成し、実行可能にしてください。

/etc/initcpio/post/uki-sbsign
#!/usr/bin/env bash

uki="$3"
[[ -n "$uki" ]] || exit 0

keypairs=(/path/to/db.key /path/to/db.crt)

for (( i=0; i<${#keypairs[@]}; i+=2 )); do
    key="${keypairs[$i]}" cert="${keypairs[(( i + 1 ))]}"
    if ! sbverify --cert "$cert" "$uki" &>/dev/null; then
        sbsign --key "$key" --cert "$cert" --output "$uki" "$uki"
    fi
done

/path/to/db.key/path/to/db.crt を、イメージの署名に使用するキーペアのパスに置き換えてください。

ukify

sbsigntools をインストールし、/etc/kernel/uki.conf--secureboot-private-key--secureboot-certificate を指定します。

起動方法

ノート: セキュアブート がアクティブな場合、.cmdline が埋め込まれた統合カーネルイメージは、(ブートエントリを使用するか対話的に) 渡されたすべてのコマンドラインオプションを無視します。セキュアブートがアクティブでない場合、コマンドライン経由で渡されたオプションは、埋め込まれた .cmdline をオーバーライドします。

Limine

Limine は Unified Kernel Image (UKI) を自動的に検出しません。ただし、limine.conf を手動で構成して UKI をロードできます。

例 1: デフォルトの EFI システムパーティションから UKI を起動する

UKI ファイルが esp/EFI/Linux/ に保存されている場合は、次の設定を limine.conf に追加します。

limine.conf
/Arch Linux
  protocol: efi_chainload
  image_path: boot():/EFI/Linux/arch-linux.efi

例 2: 別の EFI パーティションから UKI を起動する

UKI ファイルが別のディスク上の別の EFI パーティションにある場合は、uuid(partition UUID) を使用します。

ノート: パーティション UUID はファイルシステム UUID ではありませんPARTUUID としてパーティション UUID を見つけるには、次を使用します。
$ lsblk -o NAME,FSTYPE,PARTUUID,PARTTYPENAME,MOUNTPOINT,SIZE,LABEL
limine.conf
/Arch Linux
  protocol: efi_chainload
  image_path: uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx):/EFI/Linux/arch-linux.efi

サポートされているパスと設定オプションの詳細については、Limine Paths ドキュメント を参照してください。

systemd-boot

systemd-bootesp/EFI/Linux/ 内でユニファイドカーネルイメージを検索しますので、それ以上の設定は必要ありません。sd-boot(7) § FILES を見て下さい。

rEFInd

rEFInd は、EFI システム パーティション上のユニファイドカーネルイメージを自動検出し、それらをロードできます。refind.conf で手動で指定することもできます。デフォルトでは次の場所にあります。

esp/EFI/refind/refind.conf
menuentry Linux {
    loader esp/EFI/Linux/archlinux-linux.efi
}

イメージが ESP のルートにある場合、rEFInd は次のようにその名前のみを必要とします: loader archlinux-linux.efi この方法で起動すると、esp/EFI/refind_linux.conf からのカーネルパラメータは渡されません。

GRUB

rEFInd と同様に、GRUBGRUB#ユニファイドカーネルイメージをチェインロード で説明されているように EFI UKI をチェーンロードできます。

UEFI から直接起動

efibootmgr を使って .efi ファイルに UEFI ブートエントリを作成することができます。

# efibootmgr --create --disk /dev/sdX --part partition_number --label "Arch Linux" --loader '\EFI\Linux\arch-linux.efi' --unicode

オプションの説明は efibootmgr(8) をご覧ください。

参照