「EFI システムパーティション」の版間の差分
(→もう一つの例: 同期) |
|||
291行目: | 291行目: | ||
{{hc|/etc/mkinitcpio.d/linux.preset|2= |
{{hc|/etc/mkinitcpio.d/linux.preset|2= |
||
ESP_DIR="''esp''/EFI/arch" |
ESP_DIR="''esp''/EFI/arch" |
||
+ | #ALL_config="/etc/mkinitcpio.conf" |
||
− | cp -f "/boot/vmlinuz-linux$suffix" "$ESP_DIR/" |
||
− | ALL_config="/etc/mkinitcpio.conf" |
||
ALL_kver="$ESP_DIR/vmlinuz-linux$suffix" |
ALL_kver="$ESP_DIR/vmlinuz-linux$suffix" |
||
PRESETS=('default') |
PRESETS=('default') |
2023年7月6日 (木) 18:22時点における版
EFI System Partition (ESP とも呼ばれます) は UEFI ファームウェアによって起動される UEFI ブートローダ、アプリケーション、ドライバの格納場所として機能する 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]、Advanced Format ドライブとの互換性を確保するには[2]、ESP は少なくとも 300 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.10, section 13.3.1.1) を参照)。しかし、準拠したベンダーは任意で追加のファイルシステムをサポートできます。例えば、Apple Mac のファームウェアは HFS+ ファイルシステムをサポートします。
他のオペレーティングシステムとの潜在的な問題を回避するために、また UEFI 仕様では UEFI は「システムパーティションに FAT32、リームバブルメディアに FAT12 と FAT16 の使用を包含する」[5]とあるので、FAT32 を使用することが推奨されます。dosfstools の mkfs.fat(8) ユーティリティを使用してください:
# mkfs.fat -F 32 /dev/sdxY
WARNING: Not enough clusters for a 32 bit FAT!
というメッセージが表示され、大きい ESP を作成できない場合、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 システムパーティションのマウントに関しては、3つの典型的なシナリオがあります:
- ESP を
/boot
にマウントする:- システムのメンテナンスと管理が容易になります。
/boot
は、マイクロコードのパッケージが CPU のマイクロコード initramfs ファイルを配置し、mkinitcpio がカーネルと initramfs イメージを配置するデフォルトのパスだからです。 - 上記のファイルがほとんどのブートローダーからアクセスできることを保証できます。というのも、すべてのブートローダーが他のボリューム上のファイルにアクセスできるわけではないからです。
- この方法では、各ファイルに対してパーミッションや拡張属性を設定できません。FAT ファイルシステムはグローバルなパーミッションをマウント時に設定するからです。
- この方法では、ESP のサイズ要件が大きくなります。EFI 関連のファイルに加えて、通常
/boot
にインストールされるファイルが加わるからです。 - この方法では、デュアルブートの場合に OS 固有のブートファイルを他の OS からの潜在的に危険な操作に晒してしまいます。
- この方法では、/boot の暗号化が不可能です。EFI 関連のファイルはファームウェアからアクセス可能でなければならないからです。
- システムのメンテナンスと管理が容易になります。
- ESP を
/efi
にマウントする:- OS 関連のファイルと EFI 関連のファイルの懸念事項が分離されます。これらのファイルには他の OS のファイルが含まれている場合があり、放っておいたほうが良いでしょう。
/boot
にインストールされるファイルが ESP に入らないので、ESP のサイズ要件が大きくなってしまうことを防ぐことができます。EFI バイナリ (ブートローダ (とオプションでドライバ) や unified カーネルイメージ) のみが ESP に格納されることになるので、ストレージスペースを節約できます。/boot
内のファイルに Linux 固有のファイルシステムを設定することができ、FAT の制限に悩まされることはありません。- 必要に応じて ESP を別途マウントできます。例えば、ブートローダーをアップグレードするときにだけマウントするなどができます。
- 適切なセットアップでシステムの暗号化を行っている場合、
/boot
は保護される一方、いくつかの必要なファイルは暗号化されていない状態にできます。これは、他の場所に保存されているカーネルやファイルにアクセスできるファイルシステムドライバを持っている ブートローダーや unified カーネルイメージを使用する場合に便利です。
- 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 install the kernel, the initramfs... ESP_DIR="esp/EFI/arch" #ALL_config="/etc/mkinitcpio.conf" ALL_kver="${ESP_DIR}/vmlinuz-linux" [[ -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 # mv /boot/vmlinuz-linux esp/EFI/arch/ # mkinitcpio -p linux
もう一つの例
/etc/mkinitcpio.d/linux.preset
ESP_DIR="esp/EFI/arch" #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 を作成する際に様々な注意をする必要があります。詳細は [7] と [8] を、解決策付きの詳細なガイドは 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 ディレクトリが存在しないかのように振る舞います。