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

提供: ArchWiki
ナビゲーションに移動 検索に移動
(→‎mkinitpcio: pacman フックを翻訳して追加)
(→‎mkinitpcio: セキュアブート用の UKI への署名を翻訳して追加)
126行目: 126行目:
   
 
{{Tip|mkinitcpio の繰り返し実行を避けるために、このフックを [[NVIDIA#pacman フック|NVIDIA ドライバー]] のフックなど、カーネルパッケージを監視する他のフックとマージすることを検討してください。}}
 
{{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}} を画像の署名に使いたい鍵ペアのパスに置き換えてください。
   
 
=== kernel-install ===
 
=== kernel-install ===

2023年10月22日 (日) 23:25時点における版

Unified カーネルイメージ は単一の実行ファイルで、UEFI ファームウェアから直接起動したり、ブートローダによってほとんどあるいは全く設定なしで自動的に起動することができます。

Arch がサポートするカーネル自体は UEFI ファームウェアでロードできます が、ユニファイドイメージはそれを組み込むことを可能にします。

出来上がった実行ファイル、つまりこれら全ての要素は、signed で簡単にセキュアブート で使用できるようにすることができます。

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

unified カーネルイメージの準備

mkinitpcio

カーネルコマンドライン

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 ファイル

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

  • マイクロコード が必要な場合は、ALL_microcode=(/boot/*-ucode.img) を追加して、mkinitcpio にその場所を追加します。
  • PRESET_efi_image= PRESETS= の各項目に対して、PRESET_efi_image= パラメータを追加します。default_efi_image="esp/EFI/Linux/archlinux-linux.efi"fallback_efi_image="esp/EFI/Linux/archlinux-linux-fallback.efi" の各項目です。これにより、実行ファイル名が設定されます。
  • オプションとして、各 --splash /usr/share/systemd/bootctl/splash-arch.bmp 行に PRESET_options= を追加して、スプラッシュ画像を追加することも可能です、つまり default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"fallback_options="-S autodetect --splash /usr/share/systemd/bootctl/splash-arch.bmp" のように指定します。

以下は、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"
ALL_microcode=(/boot/*-ucode.img)

PRESETS=('default' 'fallback')

default_image="/boot/initramfs-linux.img"
default_efi_image="esp/EFI/Linux/archlinux-linux.efi"
default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"

fallback_image="/boot/initramfs-linux-fallback.img"
fallback_efi_image="esp/EFI/Linux/archlinux-linux-fallback.efi"
fallback_options="-S autodetect --splash /usr/share/systemd/bootctl/splash-arch.bmp"

この2番目の例では、linux のデフォルトイメージと linux-lts のフォールバックイメージを作成します。

/etc/mkinitcpio.d/linux.preset
ALL_config="/etc/mkinitcpio.conf"
ALL_microcode=(/boot/*-ucode.img)

PRESETS=('default' 'fallback')

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"

fallback_kver="/boot/vmlinuz-linux-lts"
fallback_image="/boot/initramfs-linux-lts-fallback.img"
fallback_efi_image="/boot/EFI/Linux/archlinux-linux-lts-fallback.efi"
fallback_options="-S autodetect --splash /usr/share/systemd/bootctl/splash-arch.bmp"
ヒント: 複数のカーネルを使用している場合は、ESP に十分なスペースがあることを確認してください。mkinitcpio は現在 initramfs-*.img*.efi 実行可能ファイルの両方をビルドし、使用されるスペースを2倍にします。[1] を参照してください。

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'
ヒント: mkinitcpio の繰り返し実行を避けるために、このフックを NVIDIA ドライバー のフックなど、カーネルパッケージを監視する他のフックとマージすることを検討してください。

セキュアブート用の 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 を画像の署名に使いたい鍵ペアのパスに置き換えてください。

kernel-install

systemdkernel-install(8) スクリプトを使用して、カスタムカーネルとカーネルパッケージ (Pacman を使用してインストール) の両方について、UKI 形式のカーネルを esp に自動的にインストールできます。 Pacman フックを mkinitcpio から kernel-install に切り替えます。

kernel-install は initramfs ジェネレータではありませんが、"プラグイン" システムを通じて、パッケージがシステムのカーネルのインストール/生成にフックすることができるフレームワークです。実行中にシステムの適切な initramfs ジェネレータ (例:mkinitcpio) が呼び出されます。プラグインは、カーネルイメージ/initramfs の生成、署名、インストールなどに関与しています。カーネルのインストール中に何をしているか気になる場合は、kernel-install に独自の "プラグイン" をインストールすることで通知できます ("プラグイン" は /usr/lib/kernel/install.d/ に配置されています。)

"layout" のような設定オプションがあり、kernel-install が呼ばれたときにカーネルがインストールされる場所や方法に影響を与えることができます。

mkinitcpio には、適切な画像 (layout=uki の場合は UKI イメージ) を生成する kernel-install プラグインが同梱されています。sbctl のような他のプログラムも kernel-install プラグインと一緒にリリースされています。

UKI を生成するように kernel-install をセットアップするには:

  • カーネルインストールレイアウトを 'uki' に設定します:
    # echo "layout=uki" >> /etc/kernel/install.conf
  • カーネルを直接インストールする 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 を使用していつでも再生成できます。

手動で

使いたいカーネルコマンドラインをファイルに入れて、objcopy(1) でバンドルファイルを作成します。

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

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

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

$ objcopy \
    --add-section .osrel="/usr/lib/os-release" --change-section-vma .osrel=0x20000 \
    --add-section .cmdline="/etc/kernel/cmdline" --change-section-vma .cmdline=0x30000 \
    --add-section .splash="/usr/share/systemd/bootctl/splash-arch.bmp" --change-section-vma .splash=0x40000 \
    --add-section .linux="vmlinuz-file" --change-section-vma .linux=0x2000000 \
    --add-section .initrd="initrd-file" --change-section-vma .initrd=0x3000000 \
    "/usr/lib/systemd/boot/efi/linuxx64.efi.stub" "linux.efi"

この正確な数値が選ばれた理由については、[2] を参照してください。

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

# cp linux.efi esp/EFI/Linux/

起動方法

systemd-boot

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

rEFInd

rEFInd は、EFI システム パーティション上の Unified カーネルイメージを自動検出し、それらをロードできます。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#Unified カーネルイメージをチェインロード で説明されているように EFI UKI をチェーンロードできます。

UEFI から直接起動

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

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

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

ノート: options がブートエントリに存在し、セキュアブート が無効になっている場合、options の値は、EFI に埋め込まれた .cmdline 文字列を上書きします。efi または linux で指定されたイメージ (unified カーネルイメージの準備 を参照) ただし、セキュアブートでは、options (およびブートローダー UI でカーネルコマンドラインに加えられた編集) は無視され、埋め込まれた .cmdline のみが使用されます。

参照