EFI システムパーティション
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
という名前のディレクトリがあるかどうかをチェックします。
既存の EFI システムパーティションが見つかった場合は、#パーティションのマウントに進んでください。見つからなかった場合はパーティションを作成する必要があります。#パーティションの作成に進んでください。
パーティションの作成
以下のセクションでは EFI System Partition (ESP) を作成する方法を説明しています。
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 でパーティションされたディスク
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 を使用することが推奨されます。dosfstools の mkfs.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 によってサポートされています。
代替のマウントポイント
#典型的なマウントポイント のシンプルな方法を使わない場合、ブートファイルを 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 上のファイルを最新に保つ必要があります。これに失敗するとシステムが起動不能になる可能性があります。以下のセクションでは、これを自動化する方法をいくつか説明しています。
バインドマウントを使う
ESP を /boot
にマウントする代わりに、バインドマウントを使うことで ESP のディレクトリを /boot
にマウントすることができます (mount(8)
を参照)。これによって ESP を自由に扱えるようにしつつ pacman が直接カーネルを更新できるようにすることができます。ファイルをコピーする他の方法よりもずっとシンプルな方法になります。
#代替のマウントポイントに書かれているように、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
を有効化・起動してください。
ファイルシステムイベントを使う
ファイルシステムイベントは、カーネルのアップデート後に 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/
/etc/incron.d/efistub-update.conf
/boot/initramfs-linux-fallback.img IN_CLOSE_WRITE /usr/local/bin/efistub-update
この方法を使うには、incrond.service
を有効化してください。
mkinitcpio フックを使う
Mkinitcpio はシステムレベルのデーモンを必要としないフックを生成できます。コピーする前に vmlinuz
、initramfs-linux.img
、initramfs-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 ディレクトリが存在しないかのように振る舞います。