「ユニファイドカーネルイメージ」の版間の差分
(→unified カーネルイメージの準備: sbctlを翻訳して追加) |
Kusanaginoturugi (トーク | 投稿記録) (→カーネルコマンドライン: 空白を削除) |
||
(2人の利用者による、間の23版が非表示) | |||
1行目: | 1行目: | ||
[[Category:ブートローダー]] |
[[Category:ブートローダー]] |
||
[[en:Unified kernel image]] |
[[en:Unified kernel image]] |
||
+ | [[pt:Unified kernel image]] |
||
− | [https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images Unified カーネルイメージ] は単一の実行ファイルで、UEFI ファームウェアから直接起動したり、ブートローダによってほとんどあるいは全く設定なしで自動的に起動することができます。 |
||
+ | [https://uapi-group.org/specifications/specs/unified_kernel_image ユニファイドカーネルイメージ] (UKI) は、単一の実行可能ファイルであり、[[UEFI]] ファームウェアから直接起動するか、ほとんどまたは全く設定を必要とせずにブートローダーによって自動的に取得されます。これは {{man|7|systemd-stub}} のような UEFI ブートスタブプログラム、Linux [[Arch ブートプロセス#カーネル|カーネルイメージ]]、[[Arch ブートプロセス#initramfs|initrd]]、および [https://uapi-group.org/specifications/specs/unified_kernel_image/#uki-components その他のリソース] を単一の UEFI PE ファイルに組み合わせたものです。 |
||
+ | このファイルは、したがってこれらのすべての要素を[[Unified Extensible Firmware Interface/セキュアブート# EFI バイナリに署名する|署名]]して [[Secure Boot]] で使用することが容易になります。 |
||
− | Arch がサポートするカーネル自体は [[EFISTUB|UEFI ファームウェアでロードできます]] が、ユニファイドイメージはそれを組み込むことを可能にします。 |
||
− | |||
− | * {{man|7|systemd-stub}} のような UEFI スタブローダー。 |
||
− | * [[Arch ブートプロセス#カーネル|kernel イメージ]]です。 |
||
− | * [[Arch ブートプロセス#initramfs|initramfs イメージ]] |
||
− | * [[カーネルコマンドライン]] |
||
− | * オプションでスプラッシュスクリーンを表示します。 |
||
− | |||
− | 出来上がった実行ファイル、つまりこれら全ての要素は、[[セキュアブート|signed]] で簡単に[[セキュアブート]] で使用できるようにすることができます。 |
||
{{Note|記事全体で {{ic|''esp''}} は [[EFI システムパーティション]] のマウントポイントを表します。}} |
{{Note|記事全体で {{ic|''esp''}} は [[EFI システムパーティション]] のマウントポイントを表します。}} |
||
− | == |
+ | == ユニファイドカーネルイメージの準備 == |
=== mkinitpcio === |
=== mkinitpcio === |
||
+ | ==== カーネルコマンドライン ==== |
||
− | 例として実行することで機能をテストできます |
||
+ | [[mkinitcpio]] は、{{ic|/etc/cmdline.d}} ディレクトリ内のコマンドライン ファイルからの[[カーネルパラメータ]]の読み取りをサポートします。Mkinitcpio は、このディレクトリ内の {{ic|.conf}} 拡張子を持つすべてのファイルの内容を連結し、それらを使用してカーネルコマンドラインを生成します。コマンドラインファイル内の ''#'' 文字で始まる行はコメントとして扱われ、mkinitcpio によって無視されます。マイクロコードと initramfs を指す ''エントリを削除'' するように注意してください。 |
||
− | # mkinitcpio -p linux -- --uefi ''esp''/EFI/Linux/test-systemd.efi |
||
+ | 例: |
||
− | これにより、''linux'' プリセットのカーネルイメージが生成されます。 |
||
+ | |||
+ | {{hc|/etc/cmdline.d/root.conf|2= |
||
+ | root=UUID=0a3407de-014b-458b-b5c1-848e92a327a3 rw |
||
+ | }} |
||
+ | |||
+ | {{Tip| |
||
+ | * ルート ファイルシステムがデフォルト以外の Btrfs サブボリューム上にある場合は、必ず必要なマウントフラグを {{ic|rootflags}} に設定してください。[[Btrfs#ルートとしてサブボリュームをマウントする]] を参照してください。 |
||
+ | * たとえば、システムのサブボリューム 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 を読み取り、再マウントし、ブート後にそこにリストされているフラグを自動的に適用します。 |
||
+ | }} |
||
+ | |||
+ | {{hc|/etc/cmdline.d/security.conf|2= |
||
+ | # enable apparmor |
||
+ | lsm=landlock,lockdown,yama,integrity,apparmor,bpf audit=1 audit_backlog_limit=256 |
||
+ | }} |
||
+ | |||
+ | あるいは、{{ic|/etc/kernel/cmdline}} を使用してカーネルコマンドラインを構成することもできます。 |
||
+ | |||
+ | 例: |
||
+ | |||
+ | {{hc|/etc/kernel/cmdline|2= |
||
+ | root=UUID=0a3407de-014b-458b-b5c1-848e92a327a3 rw quiet bgrt_disable |
||
+ | }} |
||
+ | |||
+ | {{Tip| |
||
+ | * root パーティションが [[systemd# GPT パーティションの自動マウント|systemd によって自動マウントされる]] 場合、{{ic|1=root=}} パラメータは省略できます。 |
||
+ | * {{ic|bgrt_disable}} パラメータは、ACPI テーブルのロード後に OEM ロゴを表示しないように Linux に指示します。 |
||
+ | }} |
||
==== .preset ファイル ==== |
==== .preset ファイル ==== |
||
− | ま |
+ | 次に、{{ic|/etc/mkinitcpio.d/linux.preset}}、または使用しているプリセットを、[[EFI システムパーティション]] の適切なマウントポイントを指定して、以下のように変更します: |
+ | * {{ic|1=PRESETS=}} の各項目について、{{ic|1=''PRESET''_uki=}} パラメータのコメントを解除する (つまり {{ic|#}} を削除する)、 |
||
− | * [[マイクロコード]] が必要な場合は、{{ic|1=ALL_microcode=(/boot/*-ucode.img)}} を追加して、[[mkinitcpio]] にその場所を追加します。 |
||
+ | * 冗長な {{ic|initramfs-*.img}} ファイルを保存しないように、{{ic|1=''PRESET''_image=}} をコメントアウトする、 |
||
− | * {{ic|1=''PRESET''_efi_image=}} {{ic|1=PRESETS=}} の各項目に対して、{{ic|1=''PRESET''_efi_image=}} パラメータを追加します。{{ic|1=default_efi_image="''esp''/EFI/Linux/archlinux-linux.efi"}} と {{ic|1=fallback_efi_image="''esp''/EFI/Linux/archlinux-linux-fallback.efi"}} の各項目です。これにより、実行ファイル名が設定されます。 |
||
− | * オプションと |
+ | * オプションとして、スプラッシュイメージを追加したい各 {{ic|1=''PRESET''_options=}} 行に {{ic|--splash}} パラメータを追加またはコメント解除します。 |
− | 以下は |
+ | 以下は {{Pkg|linux}} カーネルと Arch スプラッシュスクリーンの {{ic|linux.preset}} の例です。 |
{{hc|/etc/mkinitcpio.d/linux.preset|2= |
{{hc|/etc/mkinitcpio.d/linux.preset|2= |
||
# mkinitcpio preset file for the 'linux' package |
# mkinitcpio preset file for the 'linux' package |
||
− | ALL_config="/etc/mkinitcpio.conf" |
+ | #ALL_config="/etc/mkinitcpio.conf" |
ALL_kver="/boot/vmlinuz-linux" |
ALL_kver="/boot/vmlinuz-linux" |
||
− | ALL_microcode=(/boot/*-ucode.img) |
||
PRESETS=('default' 'fallback') |
PRESETS=('default' 'fallback') |
||
+ | #default_config="/etc/mkinitcpio.conf" |
||
− | default_image="/boot/initramfs-linux.img" |
||
− | + | #default_image="/boot/initramfs-linux.img" |
|
+ | default_uki="''esp''/EFI/Linux/arch-linux.efi" |
||
− | default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp" |
||
+ | default_options="--splash=/usr/share/systemd/bootctl/splash-arch.bmp" |
||
+ | #fallback_config="/etc/mkinitcpio.conf" |
||
− | fallback_image="/boot/initramfs-linux-fallback.img" |
||
− | + | #fallback_image="/boot/initramfs-linux-fallback.img" |
|
+ | fallback_uki="''esp''/EFI/Linux/arch-linux-fallback.efi" |
||
− | fallback_options="-S autodetect --splash /usr/share/systemd/bootctl/splash-arch.bmp" |
||
+ | fallback_options="-S autodetect" |
||
}} |
}} |
||
+ | {{Tip| |
||
− | この2番目の例では、{{Pkg|linux}} のデフォルトイメージと {{Pkg|linux-lts}} のフォールバックイメージを作成します。 |
||
+ | * 統一されたカーネルイメージからブートしたいだけであれば、[[EFI システムパーティション#典型的なマウントポイント|ESP のマウント]]を {{ic|/efi}} にして、[[ESP]] パーティションに存在する必要があるものだけをマウントすることができます。 |
||
+ | * {{ic|--cmdline /etc/kernel/''fallback_cmdline''}} を {{ic|fallback_options}} に追加することで、フォールバックイメージに上記とは異なる [[Unified カーネルイメージ#カーネルコマンドライン|cmdline]] を使用することができます (例えば {{ic|quiet}} を無くす。) |
||
+ | * カーネルコマンドラインの埋め込みを省略するには、{{ic|--no-cmdline}} を {{ic|1=''PRESET''_options=}} に追加してください。カーネルパラメーターはブートローダー経由で渡す必要があります。 |
||
+ | }} |
||
+ | {{Note| |
||
− | {{hc|/etc/mkinitcpio.d/linux.preset|2= |
||
+ | * {{ic|''PRESET''_uki}} オプションは以前は {{ic|''PRESET''_efi_image}} として知られていました。[https://gitlab.archlinux.org/archlinux/mkinitcpio/mkinitcpio/-/issues/134 2022 年 11 月変更], 古いオプションは非推奨ですが、今のところ動作しています。 |
||
− | ALL_config="/etc/mkinitcpio.conf" |
||
+ | * [[Unified Extensible Firmware Interface# UEFI ファームウェアのビット数|IA32 UEFI]] では、{{ic|--uefistub /usr/lib/systemd/boot/efi/linuxia32.efi.stub}} を {{ic|1=''PRESET''_options=}} に追加してください。 |
||
− | ALL_microcode=(/boot/*-ucode.img) |
||
+ | }} |
||
+ | ==== pacman フック ==== |
||
− | PRESETS=('default' 'fallback') |
||
+ | マイクロコードのアップグレード後に再構築をトリガーするには、[[pacman フック]] が必要です。 |
||
− | default_kver="/boot/vmlinuz-linux" |
||
− | default_image="/boot/initramfs-linux.img" |
||
− | default_efi_image="/boot/EFI/Linux/archlinux-linux.efi" |
||
− | default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp" |
||
+ | {{hc|/etc/pacman.d/hooks/ucode.hook|2= |
||
− | fallback_kver="/boot/vmlinuz-linux-lts" |
||
+ | [Trigger] |
||
− | fallback_image="/boot/initramfs-linux-lts-fallback.img" |
||
+ | Operation=Install |
||
− | fallback_efi_image="/boot/EFI/Linux/archlinux-linux-lts-fallback.efi" |
||
+ | Operation=Upgrade |
||
− | fallback_options="-S autodetect --splash /usr/share/systemd/bootctl/splash-arch.bmp" |
||
+ | 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 ドライバー]] のフックなど、カーネルパッケージを監視する他のフックとマージすることを検討してください。}} |
||
− | {{Tip|複数のカーネルを使用している場合は、[[ESP]] に十分なスペースがあることを確認してください。[[mkinitcpio]] は現在 {{ic|initramfs-*.img}} と{{ic|*.efi}} 実行可能ファイルの両方をビルドし、使用されるスペースを2倍にします。[https://github.com/archlinux/mkinitcpio/issues/77] を参照してください。}} |
||
− | ==== |
+ | ==== セキュアブート用の UKI への署名 ==== |
+ | mkinitcpio ポストフック ({{man|8|mkinitcpio|ABOUT POST HOOKS}}) を使用すると、生成された統合カーネルイメージに [[セキュアブート]] 用に署名できます。次のファイルを [[作成]] し、[[ヘルプ:読み方#実行可能属性の付与|実行可能]] にします。 |
||
− | 次に、[[カーネルパラメータ]] を使用して {{ic|/etc/kernel/cmdline}} を作成します。 |
||
+ | {{hc|/etc/initcpio/post/uki-sbsign|2= |
||
− | # cp /proc/cmdline /etc/kernel/cmdline |
||
+ | #!/usr/bin/env bash |
||
+ | uki="$3" |
||
− | {{Warning|マイクロコードと initramfs を指す {{ic|initrd}} エントリを削除する必要があります。}} |
||
+ | <nowiki>[[ -n "$uki" ]] || exit 0</nowiki> |
||
+ | keypairs=(''/path/to/''db.key ''/path/to/''db.crt) |
||
− | 例: |
||
+ | for (( i=0; i<${#keypairs[@]}; i+=2 )); do |
||
− | {{hc|/etc/kernel/cmdline| |
||
+ | key="${keypairs[$i]}" cert="${keypairs[(( i + 1 ))]}" |
||
− | rw quiet bgrt_disable |
||
+ | 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}} をイメージの署名に使いたい鍵ペアのパスに置き換えてください。 |
||
− | {{Tip|{{ic|bgrt_disable}} パラメータは ACPI テーブルをロードした後に OEM ロゴを表示しないように Linux に指示します。}} |
||
+ | ==== UKI の構築 ==== |
||
− | 最後に、[[initramfs]] を再生成します。 |
||
+ | |||
+ | 最後に、UKI のディレクトリが存在することを確認し、[[mkinitcpio#イメージ作成とアクティベーション|initramfs を再生成]] します。たとえば、''linux'' プリセットの場合は次のようになります。 |
||
+ | |||
+ | # mkdir -p ''esp''/EFI/Linux |
||
+ | # mkinitcpio -p linux |
||
+ | |||
+ | 必要に応じて、残っている {{ic|initramfs-*.img}} を {{ic|/boot}} または {{ic|/efi}} から削除します。 |
||
=== kernel-install === |
=== kernel-install === |
||
− | [[systemd]] の |
+ | [[systemd]] の [[Kernel-install]] スクリプトを使用して、カスタムカーネルとカーネルパッケージ (Pacman を使用してインストール) の両方について、UKI 形式のカーネルを ''esp'' に自動的にインストールできます。 Pacman フックを ''mkinitcpio'' から ''kernel-install'' に切り替える必要があります。 |
+ | 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 イメージ) を生成します。 |
||
− | {{ic|kernel-install}} は initramfs ジェネレータではありませんが、"プラグイン" システムを通じて、パッケージがシステムのカーネルのインストール/生成にフックすることができるフレームワークです。実行中にシステムの適切な initramfs ジェネレータ (例:''mkinitcpio'') が呼び出されます。プラグインは、カーネルイメージ/initramfs の生成、署名、インストールなどに関与しています。カーネルのインストール中に何をしているか気になる場合は、{{ic|kernel-install}} に独自の "プラグイン" をインストールすることで通知できます ("プラグイン" は {{ic|/usr/lib/kernel/install.d/}} に配置されています。) |
||
+ | * kernel-install {{ic|layout}} を {{ic|uki}} に設定します。例えば: {{bc|1=# echo "layout=uki" >> /etc/kernel/install.conf}} |
||
− | "layout" のような設定オプションがあり、{{ic|kernel-install}} が呼ばれたときにカーネルがインストールされる場所や方法に影響を与えることができます。 |
||
+ | * デフォルトでは、レイアウトが 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}} |
||
− | ''mkinitcpio'' には、適切な画像 (layout=uki の場合は UKI イメージ) を生成する {{ic|kernel-install}} プラグインが同梱されています。{{Pkg|sbctl}} のような他のプログラムも {{ic|kernel-install}} プラグインと一緒にリリースされています。 |
||
+ | :{{Note|2024 年 1 月 15 日以降、{{ic|uki_generator}} でない限り、{{pkg|mkinitcpio}} は [https://gitlab.archlinux.org/archlinux/mkinitcpio/mkinitcpio/-/commit/0df979c34970b19a3e56d9a16d79e32830228448 UKI をビルドしなくなりました]}} {{ic|mkinitcpio}} に直接設定されます。以前は、{{pkg|systemd-ukify}} が明示的にインストールされていない場合、暗黙的に設定されていました。}} |
||
− | UKI を生成するように kernel-install をセットアップするには: |
||
− | * カーネルインストールレイアウトを 'uki' に設定します: {{bc|1=# echo "layout=uki" >> /etc/kernel/install.conf}} |
||
* カーネルを直接インストールする Pacman フック:{{bc|<nowiki># ln -s /dev/null /etc/pacman.d/hooks/60-mkinitcpio-remove.hook |
* カーネルを直接インストールする Pacman フック:{{bc|<nowiki># ln -s /dev/null /etc/pacman.d/hooks/60-mkinitcpio-remove.hook |
||
# ln -s /dev/null /etc/pacman.d/hooks/90-mkinitcpio-install.hook |
# ln -s /dev/null /etc/pacman.d/hooks/90-mkinitcpio-install.hook |
||
115行目: | 164行目: | ||
[[dracut#カーネルコマンドラインオプション|コマンドラインパラメータ]] を、例えば {{ic|/etc/dracut.conf.d/cmdline.conf}} に配置します。 |
[[dracut#カーネルコマンドラインオプション|コマンドラインパラメータ]] を、例えば {{ic|/etc/dracut.conf.d/cmdline.conf}} に配置します。 |
||
− | + | イメージを生成する。 |
|
# dracut -f -q --uefi --uefi-splash-image /usr/share/systemd/bootctl/splash-arch.bmp |
# dracut -f -q --uefi --uefi-splash-image /usr/share/systemd/bootctl/splash-arch.bmp |
||
128行目: | 177行目: | ||
他のカーネルと initramfs イメージ用にさらに EFI バイナリを作成するには、パラメーター {{ic|--kernel-img}} と {{ic|--initramfs}} を指定して上記のコマンドを繰り返します。{{man|8|sbctl|EFI BINARY COMMANDS}} を参照してください。EFI バイナリは、{{ic|sbctl generate-bundles}} を使用していつでも再生成できます。 |
他のカーネルと initramfs イメージ用にさらに EFI バイナリを作成するには、パラメーター {{ic|--kernel-img}} と {{ic|--initramfs}} を指定して上記のコマンドを繰り返します。{{man|8|sbctl|EFI BINARY COMMANDS}} を参照してください。EFI バイナリは、{{ic|sbctl generate-bundles}} を使用していつでも再生成できます。 |
||
+ | |||
+ | === ukify === |
||
+ | |||
+ | {{Pkg|systemd-ukify}} パッケージを [[インストール]] します。''ukify'' は単独で initramfs を生成できないため、必要な場合は、[[dracut]]、[[mkinitcpio]]、または [[booster]] を使用して生成する必要があります。 |
||
+ | |||
+ | 最小限の動作例は次のようになります。 |
||
+ | |||
+ | # /usr/lib/systemd/ukify build --linux=''/boot/vmlinuz-linux'' --initrd=''/boot/intel-ucode.img'' \ |
||
+ | --initrd=''/boot/initramfs-linux.img'' \ |
||
+ | --cmdline="''quiet rw''" |
||
+ | |||
+ | {{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| |
||
+ | * 出来上がった EFI 実行ファイルを EFI システムパーティションにコピーするのをスキップするには、{{ic|1=--output=''esp''/EFI/Linux/''filename''.efi}} コマンドラインオプションを ''ukify'' に使用します。 |
||
+ | * {{ic|--cmdline}} オプションを指定する場合、{{ic|1=--cmdline=@''/path/to/cmdline''}} のように {{ic|/etc/kernel/cmdline}} ファイル名の前に {{ic|@}} シンボルを追加することで、カーネルパラメータを読み込むファイル名を指定できます。 |
||
+ | }} |
||
+ | |||
+ | intel ucode および /efi マウント ESP を使用した通常のカーネルイメージの systemd サービスを使用した自動 UKI 構築の例: |
||
+ | |||
+ | {{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}} を [[有効化]] します。 |
||
=== 手動で === |
=== 手動で === |
||
− | 使 |
+ | 使用するカーネルコマンドラインをファイルに記述し、{{man|1|objcopy}} を使用してバンドルファイルを作成します。 |
− | [[マイクロコード]] の場合、まず |
+ | [[マイクロコード]] の場合は、まず次のようにマイクロコードファイルと initrd を連結します。 |
− | $ cat |
+ | $ cat ''esp''/''cpu_manufacturer''-ucode.img ''esp''/initramfs-linux.img > /tmp/combined_initrd.img |
− | + | 統合カーネルイメージを構築するときは、{{ic|/tmp/combined_initrd.img}} を initrd として渡します。このファイルは後で削除できます。 |
|
+ | |||
+ | {{Note|[[Unified Extensible Firmware Interface#UEFI ファームウェアのビット数|IA32 UEFI]] では、以下のコマンドの {{ic|/usr/lib/systemd/boot/efi/linuxx64.efi.stub}} を {{ic|/usr/lib/systemd/boot/efi/linuxia32.efi.stub}} に置き換えてください。}} |
||
{{bc|1= |
{{bc|1= |
||
+ | $ 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 \ |
$ objcopy \ |
||
− | --add-section .osrel="/usr/lib/os-release" --change-section-vma .osrel= |
+ | --add-section .osrel="/usr/lib/os-release" --change-section-vma .osrel=$(printf 0x%x $osrel_offs) \ |
− | --add-section .cmdline="/etc/kernel/cmdline" |
+ | --add-section .cmdline="/etc/kernel/cmdline" \ |
− | + | --change-section-vma .cmdline=$(printf 0x%x $cmdline_offs) \ |
|
− | --add-section . |
+ | --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" |
"/usr/lib/systemd/boot/efi/linuxx64.efi.stub" "''linux''.efi" |
||
}} |
}} |
||
+ | 注意すべき点がいくつかあります: |
||
− | この正確な数値が選ばれた理由については、[https://github.com/systemd/systemd/commit/0fa2cac4f0cdefaf1addd7f1fe0fd8113db9360b#commitcomment-55422970] を参照してください。 |
||
+ | * [https://github.com/systemd/systemd/commit/0fa2cac4f0cdefaf1addd7f1fe0fd8113db9360b#commitcomment-76747223] で推奨されているように、オフセットは動的に計算されるので、セクションが重なることはありません。 |
||
− | イメージを作成したら、EFI システムパーティションにコピーします。 |
||
+ | * セクションは、PE スタブの {{ic|SectionAlignment}} フィールドが示す値 (通常は 0x1000) にアラインメントされます。 |
||
+ | * カーネルイメージは、[https://github.com/systemd/systemd/commit/0fa2cac4f0cdefaf1addd7f1fe0fd8113db9360b#commitcomment-84868898] で述べられているように、インプレース解凍で後続のセクションが上書きされるのを防ぐために、最後のセクションにある必要があります。 |
||
+ | |||
+ | イメージを作成したら、それを EFI システムパーティションにコピーします。 |
||
# cp ''linux''.efi ''esp''/EFI/Linux/ |
# cp ''linux''.efi ''esp''/EFI/Linux/ |
||
== 起動方法 == |
== 起動方法 == |
||
+ | |||
+ | {{Note|[[セキュアブート]] がアクティブな場合、{{ic|.cmdline}} が埋め込まれた統合カーネルイメージは、(ブートエントリを使用するか対話的に) 渡されたすべてのコマンドラインオプションを無視します。セキュアブートがアクティブでない場合、コマンドライン経由で渡されたオプションは、埋め込まれた {{ic|.cmdline}} をオーバーライドします。}} |
||
=== systemd-boot === |
=== systemd-boot === |
||
− | [[systemd-boot#Unified kernel images|systemd-boot]] は {{ic|''esp''/EFI/Linux/}} 内で |
+ | [[systemd-boot#Unified kernel images|systemd-boot]] は {{ic|''esp''/EFI/Linux/}} 内でユニファイドカーネルイメージを検索しますので、それ以上の設定は必要ありません。{{man|7|sd-boot|FILES}} を見て下さい。 |
=== rEFInd === |
=== rEFInd === |
||
− | [[rEFInd]] は、EFI システム パーティション上の |
+ | [[rEFInd]] は、EFI システム パーティション上のユニファイドカーネルイメージを自動検出し、それらをロードできます。{{ic|refind.conf}} で手動で指定することもできます。デフォルトでは次の場所にあります。 |
{{hc|''esp''/EFI/refind/refind.conf|2= |
{{hc|''esp''/EFI/refind/refind.conf|2= |
||
172行目: | 301行目: | ||
イメージが ESP のルートにある場合、rEFInd は次のようにその名前のみを必要とします: {{ic|loader archlinux-linux.efi}} この方法で起動すると、{{ic|''esp''/EFI/refind_linux.conf}} からのカーネルパラメータは渡されません。 |
イメージが ESP のルートにある場合、rEFInd は次のようにその名前のみを必要とします: {{ic|loader archlinux-linux.efi}} この方法で起動すると、{{ic|''esp''/EFI/refind_linux.conf}} からのカーネルパラメータは渡されません。 |
||
+ | |||
+ | === GRUB === |
||
+ | |||
+ | rEFInd と同様に、[[GRUB]] は [[GRUB#ユニファイドカーネルイメージをチェインロード]] で説明されているように EFI UKI をチェーンロードできます。 |
||
=== UEFI から直接起動 === |
=== UEFI から直接起動 === |
||
177行目: | 310行目: | ||
[[efibootmgr]] を使って ''.efi'' ファイルに UEFI ブートエントリを作成することができます。 |
[[efibootmgr]] を使って ''.efi'' ファイルに UEFI ブートエントリを作成することができます。 |
||
− | # efibootmgr --create --disk /dev/ |
+ | # efibootmgr --create --disk /dev/sd''X'' --part ''partition_number'' --label "Arch Linux" --loader '\EFI\Linux\arch-linux.efi' --unicode |
オプションの説明は {{man|8|efibootmgr}} をご覧ください。 |
オプションの説明は {{man|8|efibootmgr}} をご覧ください。 |
||
− | |||
− | {{Note|{{ic|options}} がブートエントリに存在し、[[セキュアブート]] が無効になっている場合、{{ic|options}} の値は、EFI に埋め込まれた {{ic|.cmdline}} 文字列を上書きします。{{ic|efi}} または {{ic|linux}} で指定されたイメージ ([[unified カーネルイメージ#unified カーネルイメージの準備|unified カーネルイメージの準備]] を参照) ただし、セキュアブートでは、{{ic|options}} (およびブートローダー UI でカーネルコマンドラインに加えられた編集) は無視され、埋め込まれた {{ic|.cmdline}} のみが使用されます。}} |
||
== 参照 == |
== 参照 == |
||
+ | * [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] |
2024年4月24日 (水) 20:42時点における最新版
ユニファイドカーネルイメージ (UKI) は、単一の実行可能ファイルであり、UEFI ファームウェアから直接起動するか、ほとんどまたは全く設定を必要とせずにブートローダーによって自動的に取得されます。これは systemd-stub(7) のような UEFI ブートスタブプログラム、Linux カーネルイメージ、initrd、および その他のリソース を単一の UEFI PE ファイルに組み合わせたものです。
このファイルは、したがってこれらのすべての要素を署名して Secure Boot で使用することが容易になります。
目次
ユニファイドカーネルイメージの準備
mkinitpcio
カーネルコマンドライン
mkinitcpio は、/etc/cmdline.d
ディレクトリ内のコマンドライン ファイルからのカーネルパラメータの読み取りをサポートします。Mkinitcpio は、このディレクトリ内の .conf
拡張子を持つすべてのファイルの内容を連結し、それらを使用してカーネルコマンドラインを生成します。コマンドラインファイル内の # 文字で始まる行はコメントとして扱われ、mkinitcpio によって無視されます。マイクロコードと initramfs を指す エントリを削除 するように注意してください。
例:
/etc/cmdline.d/root.conf
root=UUID=0a3407de-014b-458b-b5c1-848e92a327a3 rw
/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
.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"
pacman フック
マイクロコードのアップグレード後に再構築をトリガーするには、pacman フック が必要です。
/etc/pacman.d/hooks/ucode.hook
[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'
セキュアブート用の UKI への署名
mkinitcpio ポストフック (mkinitcpio(8) § ABOUT POST HOOKS) を使用すると、生成された統合カーネルイメージに セキュアブート 用に署名できます。次のファイルを 作成 し、実行可能 にします。
/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
をイメージの署名に使いたい鍵ペアのパスに置き換えてください。
UKI の構築
最後に、UKI のディレクトリが存在することを確認し、initramfs を再生成 します。たとえば、linux プリセットの場合は次のようになります。
# mkdir -p esp/EFI/Linux # mkinitcpio -p linux
必要に応じて、残っている initramfs-*.img
を /boot
または /efi
から削除します。
kernel-install
systemd の Kernel-install スクリプトを使用して、カスタムカーネルとカーネルパッケージ (Pacman を使用してインストール) の両方について、UKI 形式のカーネルを esp に自動的にインストールできます。 Pacman フックを mkinitcpio から kernel-install に切り替える必要があります。
UKI イメージは、mkinitcpio によって直接生成することも、カーネルイメージと生成されたスタンドアロン initramfs イメージを 1 つのファイルに統合する kernel-install によって生成することもできます (kernel-installの ukify ツールによって) 2024 年 1 月 15 日以降、install には、systemd-ukify が必要です。以下を参照してください) mkinitcpio は、適切なイメージ (layout=uki
および uki_generator=mkinitcpio
の UKI イメージ) を生成するために kernel-install によって呼び出されます。それ以外の場合は、ukify のスタンドアロンの initramfs イメージ) を生成します。
- kernel-install
layout
をuki
に設定します。例えば:# echo "layout=uki" >> /etc/kernel/install.conf
- デフォルトでは、レイアウトが uki に設定されている場合、kernel-install は独自の ukify ツールを使用して (ここで systemd-ukify をインストールする必要があります。下記を参照) initramfs とカーネルイメージ mkinitpcio を使用して、uki イメージを直接生成できます。mkinitcpio を使用して uki イメージを生成したい場合は、
uki_generator
をmkinitpcio
に設定します。例:# echo "uki_generator=mkinitcpio" >> /etc/kernel/install.conf
mkinitcpio
に直接設定されます。以前は、systemd-ukify が明示的にインストールされていない場合、暗黙的に設定されていました。}}
- カーネルを直接インストールする Pacman フック:
# ln -s /dev/null /etc/pacman.d/hooks/60-mkinitcpio-remove.hook # ln -s /dev/null /etc/pacman.d/hooks/90-mkinitcpio-install.hook
- kernel-install の Pacman フックを作成します。pacman-hook-kernel-installAUR を使うことができます。
- 使用しているカーネルパッケージを削除して再インストールします。
dracut
コマンドラインパラメータ を、例えば /etc/dracut.conf.d/cmdline.conf
に配置します。
イメージを生成する。
# dracut -f -q --uefi --uefi-splash-image /usr/share/systemd/bootctl/splash-arch.bmp
こちらも参照 dracut#カーネルのアップグレード時に新しい initramfs を生成
sbctl
sbctl パッケージを インストール して下さい。カーネルコマンド ラインを /etc/kernel/cmdline
に保存します。--save
パラメータを指定した sbctl bundle
コマンドを使用してバンドルを作成し、適切なタイミングで Pacman フックによって再生成します。
# sbctl bundle --save esp/archlinux.efi
他のカーネルと initramfs イメージ用にさらに EFI バイナリを作成するには、パラメーター --kernel-img
と --initramfs
を指定して上記のコマンドを繰り返します。sbctl(8) § EFI BINARY COMMANDS を参照してください。EFI バイナリは、sbctl generate-bundles
を使用していつでも再生成できます。
ukify
systemd-ukify パッケージを インストール します。ukify は単独で initramfs を生成できないため、必要な場合は、dracut、mkinitcpio、または booster を使用して生成する必要があります。
最小限の動作例は次のようになります。
# /usr/lib/systemd/ukify build --linux=/boot/vmlinuz-linux --initrd=/boot/intel-ucode.img \ --initrd=/boot/initramfs-linux.img \ --cmdline="quiet rw"
次に、結果のファイルを EFI システムパーティションにコピーします。
# cp filename.efi esp/EFI/Linux/
intel ucode および /efi マウント ESP を使用した通常のカーネルイメージの systemd サービスを使用した自動 UKI 構築の例:
/etc/ukify.conf
[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
/etc/systemd/system/run_ukify.service
[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
/etc/systemd/system/run_ukify.path
[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
次に、run_ukify.path
を 有効化 します。
手動で
使用するカーネルコマンドラインをファイルに記述し、objcopy(1) を使用してバンドルファイルを作成します。
マイクロコード の場合は、まず次のようにマイクロコードファイルと initrd を連結します。
$ cat esp/cpu_manufacturer-ucode.img esp/initramfs-linux.img > /tmp/combined_initrd.img
統合カーネルイメージを構築するときは、/tmp/combined_initrd.img
を initrd として渡します。このファイルは後で削除できます。
$ 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/
起動方法
systemd-boot
systemd-boot は esp/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 と同様に、GRUB は GRUB#ユニファイドカーネルイメージをチェインロード で説明されているように 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) をご覧ください。