EFI システムパーティション

提供: ArchWiki
2022年9月18日 (日) 16:12時点におけるAshMyzk (トーク | 投稿記録)による版 (TranslationStatus)
ナビゲーションに移動 検索に移動

関連記事

EFI System Partition (ESP とも呼ばれます) は UEFI ファームウェアによって起動される EFI ブートローダ、アプリケーション、ドライバの格納場所として機能する OS に依存しないパーティションです。UEFI ブートには必須です。

既存のパーティションの確認

例えば Windows 10 のようなオペレーティングシステムがインストールされている UEFI 対応のコンピュータに Arch Linux をインストールする場合、既に EFI システムパーティションがある可能性が非常に高いと言えます。

ディスクパーティションスキームとシステムパーティションを調べるには、起動したいディスクの root で fdisk を使用します:

# fdisk -l /dev/sdx

このコマンドは以下を返します。

  • ディスクのパーティションテーブル:パーティションテーブルが GPT の場合は Disklabel type: gpt を、MBR の場合は Disklabel type: dos を示します。
  • ディスク上のパーティションのリスト:EFIシステムパーティションは通常100MiB以上の大きさで、タイプは EFI System または EFI (FAT-12/16/32) になっています。これが ESP であることを確認するには、ESP をマウントし、EFI という名前のディレクトリがあるかどうかをチェックします。
ヒント: FAT12、FAT16、FAT32のいずれかのファイルシステムかどうかを調べるには、FAT#どの FAT かを調べる に従ってください。
警告: デュアルブートする場合、ESPを再フォーマットすることは避けてください。他のオペレーティングシステムの起動に必要なファイルが含まれている可能性があるからです。

既存の EFI システムパーティションが見つかった場合は、#パーティションのマウントに進んでください。見つからなかった場合はパーティションを作成する必要があります。#パーティションの作成に進んでください。

パーティションの作成

以下のセクションでは EFI System Partition (ESP) を作成する方法を説明しています。

警告: EFI システムパーティションはディスクのメインパーティションテーブル上の物理パーティションでなければなりません。LVM やソフトウェア RAID などではいけません。

ESP のサイズは、起動に必要なファイルとブートローダを格納するために十分な大きさである必要があります。

他のオペレーティングシステムとの相互運用上の問題を回避するには[1][2]、ESP は少なくとも 300 MiB にすることが推奨されます。初期の/バグのある UEFI 実装では、ESP は少なくとも 512 MiB が必要かもしれません。[3] これらが問題とならない場合、パーティションのサイズは 2 MiB まで小さくできます。この場合、ブートローダ以外は格納できません。

GPT でパーティションされたディスク

GUID パーティションテーブル上の EFI システムパーティションはパーティションタイプ GUID C12A7328-F81F-11D2-BA4B-00A0C93EC93B で識別されます。

GPT でパーティションされたディスクに ESP を作成する場合、以下の方法の一つを使って下さい:

  • fdisk: パーティションタイプ EFI System のパーティションを作成してください。
  • gdisk: パーティションタイプ EF00 のパーティションを作成してください。
  • GNU Parted: ファイルシステム fat32 のパーティションを作成し、esp フラグをセットしてください。

パーティション作成後、ファイルシステムでフォーマットする必要があります。以下の #パーティションのマウント セクションに従ってください。

MBR でパーティションされたディスク

ノート:
  • Windows Setup によりサポートされていないため一部のファームウェアは UEFI/MBR の起動をサポートしていないかもしれないので、GPT を使うことが推奨されます。
  • bootctl は MBR でパーティショニングされたディスクへの systemd-boot のインストールをサポートしていません; systemd issue 1125 を参照してください。

一般的な GPT の利点は パーティショニング#GPT か MBR の選択 を参照してください。

Master Boot Record パーティションテーブル上の EFI システムパーティションは パーティションタイプ ID EF により識別されます。

MBR でパーティションされたディスクに ESP を作成する場合、以下の方法の一つを使って下さい:

  • fdisk: パーティションタイプ EFI (FAT-12/16/32) のプライマリパーティションを作成してください。
  • GNU Parted: ファイルシステム fat32 のプライマリパーティションを作成し、esp フラグをセットしてください。

パーティション作成後、ファイルシステムでフォーマットする必要があります。以下の #パーティションのマウント セクションに従ってください。

パーティションのフォーマット

UEFI 仕様は FAT12、FAT16、FAT32 ファイルシステムのサポートを義務付けています(UEFI specification version 2.9, section 13.3.1.1 を参照)。しかし、準拠したベンダーは任意で追加のファイルシステムをサポートできます。例えば、Apple Mac のファームウェアは HFS+ ファイルシステムをサポートします。

他のオペレーティングシステムとの潜在的な問題を回避するために、また UEFI 仕様では UEFI は「システムパーティションに FAT32、リームバブルメディアに FAT12 と FAT16 の使用を包含する」[4]とあるので、FAT32 を使用することが推奨されます。dosfstoolsmkfs.fat(8) ユーティリティを使用してください:

# mkfs.fat -F 32 /dev/sdxY

WARNING: Not enough clusters for a 32 bit FAT! というメッセージが発生した場合、mkfs.fat -s2 -F32 ...-s1 でクラスタのサイズを減らしてください。さもないと、パーティションは UEFI によって読み込めません。サポートされるクラスタサイズは mkfs.fat(8) を見てください。

32 MiB よりも小さいパーティションでは、FAT32 を使うことはできません。この場合、FAT16 か FAT12 でフォーマットしてください。例えば、2 MiB の ESP は FAT12 しかサポートできません:

# mkfs.fat -F 12 /dev/sdxY

パーティションのマウント

システムの起動に成功するには、カーネル、initramfs ファイル、そして殆どの場合プロセッサのマイクロコードは、ブートローダーか UEFI それ自体からアクセスできる必要があります。なので、セットアップをシンプルにしたい場合、EFI システムパーティションのマウントポイントはブートローダの選択により制限されます。

典型的なマウントポイント

EFI システムパーティションをマウントする最も単純な方法は:

  • ESP を /bootマウントする。これは最もストレートな方法です。
    • こうすることでシステムメンテナンスが容易になります。/boot は、マイクロコードのパッケージが CPU のマイクロコード initramfs ファイルを配置し、mkinitcpioカーネルinitramfs イメージを配置するデフォルトのパスだからです。
    • こうすることで、上記のファイルがほとんどのブートローダーからアクセス可能になることを保証できます。しかし、すべてのブートローダーが他のボリューム上のファイルにアクセスできるわけではありません。
  • ESP を /efiマウントする。
    • これは、他の場所 (典型的には /boot) に保存されているカーネルやファイルにアクセスできるファイルシステムドライバを持つ ブートローダーや、Unified カーネルイメージ において便利です。
    • EFI バイナリ (ブートローダー (と任意でドライバ) や Unified カーネルイメージ) のみを ESP に保存します。こうすることでストレージの容量を節約できます。
  • ESP を /efiマウントし、さらに "Extended Boot Loader Partition" (XBOOTLDR) を /boot にマウントする。これは、先に作成しておいた ESP が、複数のブートローダーやカーネルを保存するには小さすぎるが、ESP を容易には拡張できない場合に便利です (そのような場合として、デュアルブートするために Windows のあとに Linux をインストールした場合などがあります)。この方法は、少なくとも systemd-boot によってサポートされています。
ヒント:
  • /efi は、歴史的で現在は推奨されていない ESP マウントポイント /boot/efi の代替[5]です。
  • /efi ディレクトリはデフォルトで存在しません。そこへ ESP をマウントする前に mkdir(1) を使って先にそのディレクトリを作成する必要があります。

代替のマウントポイント

#典型的なマウントポイント のシンプルな方法を使わない場合、ブートファイルを ESP にコピーする必要があります(以後、ESP は esp と表記します)。

# mkdir -p esp/EFI/arch
# cp -a /boot/vmlinuz-linux esp/EFI/arch/
# cp -a /boot/initramfs-linux.img esp/EFI/arch/
# cp -a /boot/initramfs-linux-fallback.img esp/EFI/arch/
ノート: マイクロコードもブートエントリの場所にコピーする必要があります。

さらに、今後のカーネルアップデートの際に ESP 上のファイルを最新に保つ必要があります。これに失敗するとシステムが起動不能になる可能性があります。以下のセクションでは、これを自動化する方法をいくつか説明しています。

この記事またはセクションの正確性には問題があります。
理由: systemd-gpt-auto-generator(8) は、/efi が存在する場合、そのディレクトリをデフォルトのマウントポイントとして使用します。それが存在しない場合は /boot を使います。 (議論: トーク:EFI システムパーティション#)
ノート: ESP が /boot にマウントされていない場合、systemd による自動マウントメカニズム(そして systemd-gpt-auto-generator(8))に頼らないようにしてください。システムやカーネルのアップデートの前に必ず ESP を手動でマウントしてください。さもないと、アップデート後に ESP をマウントできなくなり、現在実行中のカーネルから締め出されて ESP 上のカーネルのコピーをアップデートできなくなる場合があります。

あるいは、必要なカーネルモジュールを起動時にプリロードしてください。例えば:

/etc/modules-load.d/vfat.conf
vfat
nls_cp437
nls_ascii

バインドマウントを使う

ESP を /boot にマウントする代わりに、バインドマウントを使うことで ESP のディレクトリを /boot にマウントすることができます (mount(8) を参照)。これによって ESP を自由に扱えるようにしつつ pacman が直接カーネルを更新できるようにすることができます。ファイルをコピーする他の方法よりもずっとシンプルな方法になります。

ノート: バインドマウントを利用するには FAT32 に対応するカーネルブートローダーが必要です。通常の Arch のインストールでは問題になりませんが、他のディストリビューションでは問題になることがあります (つまり /boot/ にシンボリックリンクを必要とするディストリビューション)。フォーラムのこの投稿 を見て下さい。

#代替のマウントポイントに書かれているように、ESP のディレクトリに全てのブートファイルをコピーしますが、ESP は /bootにマウントします。そしてディレクトリをバインドマウントします:

# mount --bind esp/EFI/arch /boot

これがうまく行ったことを確認したら、fstab を編集して永続化させます:

/etc/fstab
esp/EFI/arch /boot none defaults,bind 0 0

systemd を使う

systemd はイベントトリガーのタスクを特徴としています。この場合特に、パス内の変更を検出する機能は、/boot/ 内で EFISTUB カーネルと initramfs ファイルがアップデートされたときにそれらを同期するのに使用されます。変更を監視するファイルは initramfs-linux-fallback.img です。なぜなら、このファイルは mkinitcpio により最後にビルドされるからです。なので、このファイルを監視すれば、コピーを開始する前にすべてのファイルがビルド済みであることを保証できます。作成する systemd パスとサービスファイルは:

/etc/systemd/system/efistub-update.path
[Unit]
Description=Copy EFISTUB Kernel to EFI system partition

[Path]
PathChanged=/boot/initramfs-linux-fallback.img

[Install]
WantedBy=multi-user.target
WantedBy=system-update.target
/etc/systemd/system/efistub-update.service
[Unit]
Description=Copy EFISTUB Kernel to EFI system partition

[Service]
Type=oneshot
ExecStart=/usr/bin/cp -af /boot/vmlinuz-linux esp/EFI/arch/
ExecStart=/usr/bin/cp -af /boot/initramfs-linux.img esp/EFI/arch/
ExecStart=/usr/bin/cp -af /boot/initramfs-linux-fallback.img esp/EFI/arch/

作成後、efistub-update.path有効化起動してください。

ヒント: 自身のキーを用いるセキュアブートの場合、sbsigntools を使ってイメージに署名するようサービスを設定できます:
ExecStart=/usr/bin/sbsign --key /path/to/db.key --cert /path/to/db.crt --output esp/EFI/arch/vmlinuz-linux /boot/vmlinuz-linux

ファイルシステムイベントを使う

ファイルシステムイベントは、カーネルのアップデート後に EFISTUB カーネルを同期させるスクリプトを実行するのに利用できます。以下は incron を使った例です。

/usr/local/bin/efistub-update
#!/bin/sh
cp -af /boot/vmlinuz-linux esp/EFI/arch/
cp -af /boot/initramfs-linux.img esp/EFI/arch/
cp -af /boot/initramfs-linux-fallback.img esp/EFI/arch/
ノート: 最初のパラメータ /boot/initramfs-linux-fallback.img は監視するファイルです。2つ目のパラメータ IN_CLOSE_WRITE は監視するアクションです。3つ目のパラメータ /usr/local/bin/efistub-update は実行するスクリプトです。
/etc/incron.d/efistub-update.conf
/boot/initramfs-linux-fallback.img IN_CLOSE_WRITE /usr/local/bin/efistub-update

この方法を使うには、incrond.service有効化してください。

mkinitcpio フックを使う

Mkinitcpio はシステムレベルのデーモンを必要としないフックを生成できます。コピーする前に vmlinuzinitramfs-linux.imginitramfs-linux-fallback.img の生成を待機するバックグラウンドプロセスを生成します。

/etc/mkinitcpio.conf 内のフックのリストに efistub-update を追加してください。

/etc/initcpio/install/efistub-update
#!/usr/bin/env bash
build() {
	/usr/local/bin/efistub-copy $$ &
}

help() {
	cat <<HELPEOF
This hook waits for mkinitcpio to finish and copies the finished ramdisk and kernel to the ESP
HELPEOF
}
/usr/local/bin/efistub-copy
#!/bin/sh

if [ "$1" -gt 0 ]
then
	while [ -e /proc/"$1" ]
	do
		sleep .5
	done
fi

rsync -a /boot/ esp/

echo "Synced /boot with ESP"

mkinitcpio プリセットを使う

/etc/mkinitcpio.d/ 内のプリセットはシェルスクリプトをサポートするので、カーネルと initramfs は、そのプリセットを編集するだけでコピーできます。

上記の mkinitcpio フックを置き換える

/etc/mkinitcpio.d/linux.preset ファイルを編集してください:

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

# Directory to copy the kernel, the initramfs...
ESP_DIR="esp/EFI/arch"

ALL_config="/etc/mkinitcpio.conf"
ALL_kver="${ESP_DIR}/vmlinuz-linux"
cp -af /boot/vmlinuz-linux "${ESP_DIR}/"
[[ -e /boot/intel-ucode.img ]] && cp -af /boot/intel-ucode.img "${ESP_DIR}/"
[[ -e /boot/amd-ucode.img ]] && cp -af /boot/amd-ucode.img "${ESP_DIR}/"

PRESETS=('default' 'fallback')

#default_config="/etc/mkinitcpio.conf"
default_image="${ESP_DIR}/initramfs-linux.img"
default_options=""

#fallback_config="/etc/mkinitcpio.conf"
fallback_image="${ESP_DIR}/initramfs-linux-fallback.img"
fallback_options="-S autodetect"

テストするには以下を実行してください:

# rm /boot/initramfs-linux-fallback.img /boot/initramfs-linux.img
# mkinitcpio -p linux
もう一つの例
/etc/mkinitcpio.d/linux.preset
ESP_DIR="esp/EFI/arch"
cp -f "/boot/vmlinuz-linux$suffix" "$ESP_DIR/"
ALL_config="/etc/mkinitcpio.conf"
ALL_kver="$ESP_DIR/vmlinuz-linux$suffix"
PRESETS=('default')
default_config="/etc/mkinitcpio.conf"
default_image="$ESP_DIR/initramfs-linux$suffix.img"
/etc/mkinitcpio.d/linux-zen.preset
suffix='-zen'
source /etc/mkinitcpio.d/linux.preset

pacman フックを使う

最後の選択肢は、トランザクションの最後に実行する pacman フック です。

最初のファイルは、関連するファイルを監視するフックで、ファイルが前のトランザクションで変更された場合に実行されます。

/etc/pacman.d/hooks/999-kernel-efi-copy.hook
[Trigger]
Type = Path
Operation = Install
Operation = Upgrade
Target = usr/lib/modules/*/vmlinuz
Target = usr/lib/initcpio/*
Target = boot/*-ucode.img

[Action]
Description = Copying linux and initramfs to EFI directory...
When = PostTransaction
Exec = /usr/local/bin/kernel-efi-copy.sh

2つ目のファイルはスクリプト自体です。ファイルを作成し、実行可能属性を付与してください:

/usr/local/bin/kernel-efi-copy.sh
#!/bin/sh
#
# Copy kernel and initramfs images to EFI directory
#

ESP_DIR="esp/EFI/arch"

for file in /boot/vmlinuz*
do
        cp -af "$file" "$ESP_DIR/$(basename "$file").efi"
        [ $? -ne 0 ] && exit 1
done

for file in /boot/initramfs*
do
        cp -af "$file" "$ESP_DIR/"
        [ $? -ne 0 ] && exit 1
done

[ -e /boot/intel-ucode.img ] && cp -af /boot/intel-ucode.img "$ESP_DIR/"
[ -e /boot/amd-ucode.img ] && cp -af /boot/amd-ucode.img "$ESP_DIR/"

exit 0

トラブルシューティング

ソフトウェア RAID1 上の ESP

ESP を RAID1 アレイに置くことも可能ですが、データが破損する危険性があり、また、ESP を作成する際に様々な注意をする必要があります。詳細は [6][7] を、解決策付きの詳細なガイドは UEFI booting and RAID1 を見てください。

鍵となる部分は、RAID メタデータをパーティションの最後に保持するために --metadata 1.0 を使うことです。さもないと、ファームウェアがアクセスできなくなります:

# mdadm --create --verbose --level=1 --metadata=1.0 --raid-devices=2 /dev/md/ESP /dev/sdaX /dev/sdbY

ファームウェアから EFI ディレクトリが見えない

FAT ファイルシステムにボリューム名(例: ファイルシステムラベル)をつける場合、EFI 以外の名前にしてください。(ボリューム名が EFI のディレクトリ名と一致するので)一部のファームウェアでバグを引き起こす可能性があります。その結果、ファームウェアは EFI ディレクトリが存在しないかのように振る舞います。

参照

翻訳ステータス: このページは en:EFI system partition の翻訳バージョンです。最後の翻訳日は 2022-09-18 です。もし英語版に 変更 があれば、翻訳の同期を手伝うことができます。