「ユニファイドカーネルイメージ」の版間の差分
細 (→kernel-install: s/mkinitpcio/mkinitcpio/) |
(→ユニファイドカーネルイメージの準備: 同期) |
||
| 9行目: | 9行目: | ||
== ユニファイドカーネルイメージの準備 == |
== ユニファイドカーネルイメージの準備 == |
||
| + | |||
| + | UKI (Unified Kernel Image) イメージを生成し、適切な場所 ("esp/Linux" ディレクトリ) にインストールする方法はいくつかあります。現在、この機能を実行するためのツールがいくつか競合しているので、ニーズと好みに応じて以下のいずれかを選択してください。 |
||
| + | |||
| + | {{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 === |
||
| + | |||
| + | [[mkinitcpio]] は、{{Pkg|systemd-ukify}} がインストールされていない限り、UKI (Unified Kernel Image) を自身で組み立てます。{{Pkg|systemd-ukify}} がインストールされている場合は、{{ic|--no-ukify}} オプションで明示的に無効にしない限り、UKI の作成は "ukify" にオフロードされます。 |
||
==== カーネルコマンドライン ==== |
==== カーネルコマンドライン ==== |
||
| 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 を読み取り、再マウントし、ブート後にそこにリストされているフラグを自動的に適用します。 |
||
| 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 の構築 ==== |
||
| 169行目: | 135行目: | ||
こちらも参照 [[dracut#カーネルのアップグレード時に新しい initramfs を生成]] |
こちらも参照 [[dracut#カーネルのアップグレード時に新しい initramfs を生成]] |
||
| − | |||
| − | === sbctl === |
||
| − | |||
| − | {{Pkg|sbctl}} パッケージを [[インストール]] して下さい。カーネルコマンド ラインを {{ic|/etc/kernel/cmdline}} に保存します。{{ic|--save}} パラメータを指定した {{ic|sbctl bundle}} コマンドを使用してバンドルを作成し、適切なタイミングで Pacman フックによって再生成します。 |
||
| − | |||
| − | # sbctl bundle --save ''esp''/archlinux.efi |
||
| − | |||
| − | 他のカーネルと initramfs イメージ用にさらに EFI バイナリを作成するには、パラメーター {{ic|--kernel-img}} と {{ic|--initramfs}} を指定して上記のコマンドを繰り返します。{{man|8|sbctl|EFI BINARY COMMANDS}} を参照してください。EFI バイナリは、{{ic|sbctl generate-bundles}} を使用していつでも再生成できます。 |
||
=== ukify === |
=== ukify === |
||
2025年2月16日 (日) 01:40時点における版
ユニファイドカーネルイメージ (UKI) は、単一の実行可能ファイルであり、UEFI ファームウェアから直接起動するか、ほとんどまたは全く設定を必要とせずにブートローダーによって自動的に取得されます。これは systemd-stub(7) のような UEFI ブートスタブプログラム、Linux カーネルイメージ、initrd、および その他のリソース を単一の UEFI PE ファイルに組み合わせたものです。
このファイルは、したがってこれらのすべての要素を署名して Secure Boot で使用することが容易になります。
目次
ユニファイドカーネルイメージの準備
UKI (Unified Kernel Image) イメージを生成し、適切な場所 ("esp/Linux" ディレクトリ) にインストールする方法はいくつかあります。現在、この機能を実行するためのツールがいくつか競合しているので、ニーズと好みに応じて以下のいずれかを選択してください。
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
/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 フック
systemd-stub (systemd の一部)、microcode (intel-ucode と amd-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
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 とカーネルイメージ mkinitcpio を使用して、uki イメージを直接生成できます。mkinitcpio を使用して uki イメージを生成したい場合は、
uki_generatorをmkinitcpioに設定します。例:# 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 を生成
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) をご覧ください。