「EFI ブートスタブ」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(同期)
8行目: 8行目:
 
{{Related|Unified Extensible Firmware Interface}}
 
{{Related|Unified Extensible Firmware Interface}}
 
{{Related articles end}}
 
{{Related articles end}}
  +
Linux カーネル ({{Pkg|linux}}>=3.3) は {{ic|EFISTUB (EFI BOOT STUB)}} ブートをサポートしています。カーネルコンフィグで {{ic|CONFIG_EFI_STUB=y}} を設定することで有効にすることができ、Arch Linux のカーネルではデフォルトで有効にされています (詳しくは [https://www.kernel.org/doc/Documentation/efi-stub.txt EFI Boot Stub] を参照してください)。
{{Warning|1=カーネルバージョンとマザーボードのモデルによっては EFISTUB の起動が失敗するというバグが報告されています。詳しくは [https://bugs.archlinux.org/task/33745] や [https://bbs.archlinux.org/viewtopic.php?id=156670] を見て下さい。}}
 
   
  +
EFISTUB カーネルだけでは他のカーネルを起動することはできません。よってブートメニューエントリごとに EFISTUB カーネル + Initramfs のペアが必要です。このため、複数のカーネルを使う場合は、[[ブートローダー]]を使うことが推奨されています。
Linux カーネル ({{Pkg|linux}}>=3.3) は {{ic|EFISTUB (EFI BOOT STUB)}} ブートをサポートしています。カーネル設定で {{ic|CONFIG_EFI_STUB=y}} を設定することで有効にすることができ、Arch Linux のカーネルではデフォルトで有効にされています (詳しくは [https://www.kernel.org/doc/Documentation/efi-stub.txt EFI Boot Stub] を参照してください)。
 
 
EFISTUB カーネルだけでは他のカーネルを起動することはできません。よってブートメニューエントリごとに EFISTUB カーネル + Initramfs のペアが必要です。このため、複数のカーネルを使う場合は、UEFI Boot Manager を使うことが推奨されています。
 
   
 
== EFISTUB の設定 ==
 
== EFISTUB の設定 ==
   
  +
[[EFI システムパーティション]]を作成したら、システムパーティションをマウントする方法を選択してください。一番簡単なのは {{ic|/boot}} にマウントするか {{ic|/boot}} に[[EFI システムパーティション#バインドマウントを使う|バインドマウント]]することです。pacman が直接 EFI ファームウェアによって読み込まれるカーネルを更新してくれます。その場合、[[#EFISTUB の起動]]に進んでください。
# [[Unified Extensible Firmware Interface#EFI System Partition|EFI System Partition]] を作成してください。
 
  +
# {{ic|/boot}} (推奨) かどこか他の好きなところに (他のディストロやツールは大抵 {{ic|/boot/efi}} を使っています) EFI System Partition をマウントしてください。以後このマウントポイントは {{ic|$esp}} として示します。
 
  +
{{Note|[[rEFInd]] などのファイルシステムドライバーを備えているブートマネージャを使用する場合、カーネルや initramfs を ESP 以外に保存できます。}}
  +
  +
=== 他の ESP マウントポイント ===
   
  +
EFI システムパーティションを {{ic|/boot}} にマウントしない場合、ブートファイルをコピーする必要があります (以下 EFI システムパーティションの場所を {{ic|''esp''}} とします):
=== カーネルと initramfs を ESP にコピーする ===
 
   
  +
# mkdir -p ''esp''/EFI/arch
EFISYS のマウントポイントとして {{ic|/boot}} を使って''いない''場合 ({{ic|/boot/efi}} など)、ブートファイルを EFISYS にコピーする必要があります (EFISYS の場所は {{ic|$esp}} として示します):
 
  +
# cp /boot/vmlinuz-linux ''esp''/EFI/arch/vmlinuz-linux
  +
# cp /boot/initramfs-linux.img ''esp''/EFI/arch/initramfs-linux.img
  +
# cp /boot/initramfs-linux-fallback.img ''esp''/EFI/arch/initramfs-linux-fallback.img
   
  +
{{Note|Intel 製の CPU を使用する場合、[[マイクロコード]]をブートエントリの場所にコピーする必要があります。}}
# mkdir $esp/EFI/arch
 
# cp /boot/vmlinuz-linux $esp/EFI/arch/vmlinuz-linux
 
# cp /boot/initramfs-linux.img $esp/EFI/arch/initramfs-linux.img
 
# cp /boot/initramfs-linux-fallback.img $esp/EFI/arch/initramfs-linux-fallback.img
 
   
カーネルアップデートされる度EFISTUB カーネルを更新する必要があります。また、以下の方法のどれか一つを使うこと EFISTUB カーネルを自動で更新することができます。
+
さらに、カーネルアップデートがあったときESP のファイルを更新する必要があります。更新しないとシステムが起動できなくなってしまいす。以下のセクション自動でコピーする方法を説明しています。
   
==== systemd ====
+
==== systemd を使う ====
   
[[systemd]] にはイベントトリガータスク機能があります。これで、パス上の変更を検知する能力を使って、{{ic|boot}} にる EFISTUB カーネルと initramfs ファイルが更新されたときにそれらを同期させることが可能です。
+
[[Systemd]] には特定のイベントが起こったときにタスクを実行する機能があります。{{ic|/boot}} が更新されたときに特定のパスおけ変更を検知して EFISTUB カーネルと initramfs ファイルを同期してくだい:
   
{{Warning|mkinitcpio がカーネルスタブと initramfs を作成するのには時間がかかるので、以下の systemd サービスが新しいカーネルスタブと initramfs の代わりに古いものをコピーしてしまう可能性があります。このエラーの可能性を減らすために、(mkinitcpio によって最後に作成される) initramfs-linux-fallback.img が更新されたか確認する efistub のコピーサービスをバインドすると良いでしょう。}}
 
 
{{hc|/etc/systemd/system/efistub-update.path|<nowiki>
 
{{hc|/etc/systemd/system/efistub-update.path|<nowiki>
 
[Unit]
 
[Unit]
44行目: 44行目:
 
[Install]
 
[Install]
 
WantedBy=multi-user.target
 
WantedBy=multi-user.target
  +
WantedBy=system-update.target
 
</nowiki>}}
 
</nowiki>}}
   
  +
{{Note|上記のユニットは {{ic|initramfs-linux-fallback.img}} の変更を監視します。このファイルは mkinitcpio によって最後に作成されるファイルであり、ビルドが完了する前に他のファイルをコピーしてしまう競合状態を避けることができます。}}
{{hc|/etc/systemd/system/efistub-update.service|<nowiki>
 
  +
  +
{{hc|1=/etc/systemd/system/efistub-update.service|2=
 
[Unit]
 
[Unit]
 
Description=Copy EFISTUB Kernel to UEFISYS Partition
 
Description=Copy EFISTUB Kernel to UEFISYS Partition
52行目: 55行目:
 
[Service]
 
[Service]
 
Type=oneshot
 
Type=oneshot
ExecStart=/usr/bin/cp -f /boot/vmlinuz-linux $esp/EFI/arch/vmlinuz-linux
+
ExecStart=/usr/bin/cp -f /boot/vmlinuz-linux ''esp''/EFI/arch/vmlinuz-linux
ExecStart=/usr/bin/cp -f /boot/initramfs-linux.img $esp/EFI/arch/initramfs-linux.img
+
ExecStart=/usr/bin/cp -f /boot/initramfs-linux.img ''esp''/EFI/arch/initramfs-linux.img
ExecStart=/usr/bin/cp -f /boot/initramfs-linux-fallback.img $esp/EFI/arch/initramfs-linux-fallback.img
+
ExecStart=/usr/bin/cp -f /boot/initramfs-linux-fallback.img ''esp''/EFI/arch/initramfs-linux-fallback.img
  +
}}
</nowiki>}}
 
  +
{{Tip|(自分の鍵を使って) [[セキュアブート]]する場合、({{Pkg|sbsigntools}} を使って) イメージに署名するようにサービスを設定することができます:
  +
{{bc|1=ExecStart=/usr/bin/sbsign --key ''/path/to/db.key'' --cert ''/path/to/db.crt'' --output ''esp''/EFI/arch/vmlinuz-linux ''esp''/EFI/arch/vmlinuz_linux}}
  +
}}
   
次のコマンドでサービスを有効してください:
+
ユニット作成したら {{ic|efistub-update.path}} を[[起動]]・[[有効化]]してください
# systemctl enable efistub-update.path
 
   
  +
==== incron を使う ====
再起動するか、次のコマンドを実行して systemd にパスの監視を開始するように伝える必要があります:
 
# systemctl start efistub-update.path
 
   
  +
{{Pkg|incron}} を使うことでカーネルの更新時に EFISTUB カーネルを同期させるスクリプトを実行できます。
==== Incron を使う ====
 
   
  +
{{hc|/usr/local/bin/efistub-update.sh|
{{Pkg|incron}} を使って更新後に EFISTUB カーネルを同期するスクリプトを実行することができます。
 
 
{{Tip|下のスクリプトを {{ic|/usr/local/bin/efistub-update.sh}} として保存してください}}
 
{{bc|<nowiki>
 
 
#!/usr/bin/env bash
 
#!/usr/bin/env bash
/usr/bin/cp -f /boot/vmlinuz-linux $esp/EFI/arch/vmlinuz-linux
+
/usr/bin/cp -f /boot/vmlinuz-linux ''esp''/EFI/arch/vmlinuz-linux
/usr/bin/cp -f /boot/initramfs-linux.img $esp/EFI/arch/initramfs-linux.img
+
/usr/bin/cp -f /boot/initramfs-linux.img ''esp''/EFI/arch/initramfs-linux.img
/usr/bin/cp -f /boot/initramfs-linux-fallback.img $esp/EFI/arch/initramfs-linux-fallback.img</nowiki>}}
+
/usr/bin/cp -f /boot/initramfs-linux-fallback.img ''esp''/EFI/arch/initramfs-linux-fallback.img}}
   
  +
{{Note|最初のパラメータの {{ic|/boot/initramfs-linux-fallback.img}} は監視するファイルです。2番目のパラメータの {{ic|IN_CLOSE_WRITE}} は監視する操作です。3番目のパラメータの {{ic|/usr/local/bin/efistub-update.sh}} は実行するスクリプトです。}}
{{Tip|下のスクリプトを {{ic|/etc/incron.d/efistub-update.conf}} として保存してください}}
 
{{Note|最初のパラメータ {{ic|/boot/initramfs-linux-fallback.img}} は監視するファイルです。2番目のパラメータ {{ic|IN_CLOSE_WRITE}} は監視するイベントです。3番目のパラメータ {{ic|/usr/local/bin/efistub-update.sh}} は起動するスクリプトです。}}
 
{{bc|<nowiki>
 
/boot/initramfs-linux-fallback.img IN_CLOSE_WRITE /usr/local/bin/efistub-update.sh
 
</nowiki>}}
 
   
  +
{{hc|/etc/incron.d/efistub-update.conf|<nowiki>
{{Tip|この方法を使うには、incron が有効になっている必要があります。有効になっていない場合は次を実行してください
 
  +
/boot/initramfs-linux-fallback.img IN_CLOSE_WRITE /usr/local/bin/efistub-update.sh</nowiki>}}
{{bc|<nowiki>
 
# systemctl enable incrond.service
 
</nowiki>}}}}
 
   
  +
この方法を使う場合、{{ic|incrond}} のサービスを有効にしてください:
==== Mkinitcpio フックを使う ====
 
   
  +
# systemctl enable incrond.service
Mkinitcpio はフックを生成することができシステムレベルデーモンを機能させる必要はありません。ファイルをコピーする前にバックグラウンドプロセスを生成して {{ic|vm-linuz}}, {{ic|initramfs-linux.img}}, {{ic|initramfs-linux-fallback.img}} の生成を待ちます。
 
   
  +
==== mkinitcpio フックを使う ====
{{Tip|下のスクリプトを {{ic|/usr/lib/initcpio/install/efistub-update}} として保存してください}}
 
{{bc|<nowiki>
 
#!/usr/bin/env bash
 
   
  +
Mkinitcpio はフックを生成することができ、システムレベルのデーモンを必要としません。バックグラウンドプロセスが生成され {{ic|vm-linuz}}, {{ic|initramfs-linux.img}}, {{ic|initramfs-linux-fallback.img}} が生成されてからファイルをコピーします。
  +
  +
{{ic|/etc/mkinitcpio.conf}} のフックのリストに {{ic|efistub-update}} を追加してください。
  +
  +
{{hc|/usr/lib/initcpio/install/efistub-update|<nowiki>
  +
#!/usr/bin/env bash
 
build() {
 
build() {
 
/root/watch.sh &
 
/root/watch.sh &
101行目: 100行目:
 
This hook waits for mkinitcpio to finish and copies the finished ramdisk and kernel to the ESP
 
This hook waits for mkinitcpio to finish and copies the finished ramdisk and kernel to the ESP
 
HELPEOF
 
HELPEOF
  +
}</nowiki>}}
}
 
</nowiki>}}
 
   
  +
{{hc|/root/watch.sh|<nowiki>
{{Tip|下のスクリプトを {{ic|/root/watch.sh}} として保存し実行可能にしてください}}
 
{{bc|<nowiki>
 
 
#!/usr/bin/env bash
 
#!/usr/bin/env bash
   
111行目: 108行目:
 
sleep 1
 
sleep 1
 
done
 
done
  +
</nowiki>
  +
/usr/bin/cp -f /boot/vmlinuz-linux ''esp''/EFI/arch/vmlinuz-linux
  +
/usr/bin/cp -f /boot/initramfs-linux.img ''esp''/EFI/arch/initramfs-linux.img
  +
/usr/bin/cp -f /boot/initramfs-linux-fallback.img ''esp''/EFI/arch/initramfs-linux-fallback.img
   
  +
echo "Synced kernel with ESP"}}
/usr/bin/cp -f /boot/vmlinuz-linux $esp/EFI/arch/vmlinuz-linux
 
/usr/bin/cp -f /boot/initramfs-linux.img $esp/EFI/arch/initramfs-linux.img
 
/usr/bin/cp -f /boot/initramfs-linux-fallback.img $esp/EFI/arch/initramfs-linux-fallback.img
 
   
  +
==== mkinitcpio フックを使う (別の方法) ====
echo "Synced kernel with ESP"
 
</nowiki>}}
 
   
  +
上記の方法と別に、コピー操作を減らす方法があります。逆転の発想で initramfs を {{ic|/boot}} ではなく EFI パーティションに直接保存します。そして mkinitcpio フックを使ってカーネルなどのファイルを ESP にコピーします。
{{Tip|{{ic|efistub-update}} を {{ic|/etc/mkinitcpio.conf}} 内の hook のリストに加えて下さい}}
 
   
  +
{{ic|/etc/mkinitcpio.d/linux.preset}} ファイルを編集してください:
==== バインドマウントを使う ====
 
   
  +
{{hc|/etc/mkinitcpio.d/linux.preset|<nowiki>
ESP を {{ic|/boot}} にマウントする代わりに、バインドマウントを使うことで ESP のディレクトリを {{ic|/boot}} にマウントすることができます ({{ic|mount(8)}} を参照)。これによって ESP を自由に扱えるようにしつつ pacman が直接カーネルを更新できるようにすることができます。ファイルをコピーする他の方法よりもずっとシンプルな方法になります。
 
  +
# mkinitcpio preset file for the 'linux' package
   
  +
# Directory to copy the kernel, the initramfs...
{{Note|1=バインドマウントを利用するには FAT32 に対応するカーネルとブートローダーが必要です。通常の Arch のインストールでは問題になりませんが、他のディストリビューションでは問題になることがあります (つまり {{ic|/boot}} にシンボリックリンクを必要とするディストリビューション)。フォーラムの[https://bbs.archlinux.org/viewtopic.php?pid=1331867#p1331867 この投稿]を見て下さい。}}
 
  +
ESP_DIR="/boot/efi/EFI/arch"
   
  +
ALL_config="/etc/mkinitcpio.conf"
[[#カーネルと initramfs を ESP にコピーする|上]]に書かれているように、ESP のディレクトリに全てのブートファイルをコピーしますが、ESP は {{ic|/boot}} の外にマウントします (例: {{ic|/esp}})。そしてディレクトリをバインドマウントします:
 
  +
ALL_kver="/boot/vmlinuz-linux"
   
  +
PRESETS=('default' 'fallback')
# mount --bind /esp/EFI/arch/ /boot
 
   
  +
#default_config="/etc/mkinitcpio.conf"
ファイルが {{ic|/boot}} に現れるようにしたい場合、[[fstab|fstab]] を編集して永続化させます:
 
  +
default_image="${ESP_DIR}/initramfs-linux.img"
  +
default_options="-A esp-update-linux"
   
  +
#fallback_config="/etc/mkinitcpio.conf"
{{hc|/etc/fstab|<nowiki>
 
  +
fallback_image="${ESP_DIR}/initramfs-linux-fallback.img"
/esp/EFI/arch /boot none defaults,bind 0 0
 
  +
fallback_options="-S autodetect"
 
</nowiki>}}
 
</nowiki>}}
   
  +
そして {{ic|/usr/lib/initcpio/install/esp-update-linux}} ファイルを作成して実行可能属性を付与してください:
{{Warning|この方法を使って起動するには {{ic|1=root=''system_root''}} [[カーネルパラメータ#パラメータ一覧|カーネルパラメータ]]を使う必要があります。}}
 
   
  +
{{hc|/usr/lib/initcpio/install/esp-update-linux|<nowiki>
== EFISTUB の起動 ==
 
  +
# Directory to copy the kernel, the initramfs...
  +
ESP_DIR="/boot/efi/EFI/arch"
   
  +
build() {
{{Warning|Linux Kernel EFISTUB initramfs のパスは EFI System Partition のルートからの相対パスでなければなりません。例えば、initramfs が {{ic|$esp/EFI/arch/initramfs-linux.img}} にあったとしたら、適切な UEFI 行は {{ic|1=initrd=/EFI/arch/initramfs-linux.img}} か {{ic|1=initrd=\EFI\arch\initramfs-linux.img}} になります。}}
 
  +
cp /boot/vmlinuz-linux "${ESP_DIR}/vmlinuz-linux.efi"
  +
# If ucode is used uncomment this line
  +
#cp /boot/intel-ucode.img "${ESP_DIR}/"
  +
}
   
  +
help() {
以下の方法のどれか一つを使うことで EFISTUB カーネルを起動することができます:
 
  +
cat <<HELPEOF
  +
This hook copies the kernel to the ESP partition
  +
HELPEOF
  +
}
  +
</nowiki>}}
   
  +
テストするには以下のコマンドを実行:
=== gummiboot を使う ===
 
   
  +
# rm /boot/initramfs-linux-fallback.img
[[Gummiboot|Gummiboot]] は EFISTUB カーネルのナイスなメニューを提供する UEFI Boot Manager です。EFISTUB ブートの推奨ブートマネージャです。詳細は [[Gummiboot|gummiboot]] を見て下さい。
 
  +
# rm /boot/initramfs-linux.img
  +
# mkinitcpio -p linux
   
=== rEFInd を使う ===
+
== EFISTUB の起動 ==
   
  +
{{Warning|Linux カーネル EFISTUB の initramfs のパスは EFI システムパーティションのルートディレクトリからの相対パスになります。例えば、initramfs が {{ic|$esp/EFI/arch/initramfs-linux.img}} に存在する場合、UEFI で設定するのは {{ic|1=initrd=/EFI/arch/initramfs-linux.img}} または {{ic|1=initrd=\EFI\arch\initramfs-linux.img}} になります。以下の例では必要なファイル全てが {{ic|$esp/}} にあることを前提としています。}}
[[rEFInd|rEFInd]] は (Intel Mac で使われている) rEFIt Boot Manager の Rod Smith (GPT-fdisk の作者) によるフォークです。rEFInd は Mac 以外の UEFI ブートについて rEFIt の多くの問題を修正してあり EFISTUB カーネルをサポートしています。詳しくは [[rEFInd|rEFInd]] を見て下さい。
 
  +
  +
=== ブートマネージャを使う ===
  +
  +
UEFI ブートマネージャには UEFI ブートを簡単にすることができるオプションが存在します (特に複数のカーネルやオペレーティングシステムをインストールしている場合)。詳しくは[[ブートローダー]]を見てください。
   
 
=== UEFI Shell を使う ===
 
=== UEFI Shell を使う ===
   
通常の UEFI アプリケーションように UEFI Shell から EFISTUB カーネルを起動することが可能です。の場合カーネルパラメータは通常のパラメータとして起動する EFISTUB カーネルファイルに渡します。
+
通常の UEFI アプリケーションと同じように UEFI Shell から EFISTUB カーネルを起動できます。の場合通常のパラメータとして起動する EFISTUB カーネルファイルにカーネルパラメータを渡してください:
   
 
> fs0:
 
> fs0:
  +
> /vmlinuz-linux root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 rw initrd=/initramfs-linux.img
> cd \EFI\arch
 
> vmlinuz-arch.efi root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 rootfstype=ext4 add_efi_memmap initrd=EFI/arch/initramfs-arch.img
 
   
また、ブパラメータを記述したシンプルな {{ic|archlinux.nsh}} ファイを書いて UEFI System Partition に置き、それを実行することできます:
+
毎回カネルパラメータを全て指定したくない場合、UEFI ステムパーティショ {{ic|archlinux.nsh}} などのシェスクリプトの実行コマンドを保存することできます。以下のコマンドで起動できるようになります:
   
 
> fs0:
 
> fs0:
 
> archlinux
 
> archlinux
   
  +
=== UEFI を直接使う ===
スクリプト例:
 
{{hc|$ESP/archlinux.nsh|2=
 
echo -on
 
\EFI\arch\vmlinuz-arch.efi root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 rootfstype=ext4 add_efi_memmap initrd=/EFI/arch/initramfs-arch.img
 
}}
 
   
  +
UEFI は [[GRUB]] などの中間的なブートローダーを排除できるように設計されています。使用しているマザーボードの UEFI 実装に問題がなければ、カーネルパラメータを UEFI ブートエントリの中に埋め込んでマザーボードから Arch を直接起動できます。{{Pkg|efibootmgr}} や UEFI Shell v2 を使ってマザーボードのブートエントリを編集できます。
この方法では名前をメモしておいたり20-30文字も入力せずとも UUID を指定することができます。
 
   
  +
==== efibootmgr ====
=== ブートマネージャを使わずに直接起動する ===
 
   
  +
以下のようなコマンドを実行してください:
{{Warning|1=カーネルと efibootmgr の組み合わせによっては手動で調整しないと動かないことがあります [https://bugs.archlinux.org/task/34641]。ブートエントリを削除することはできますが作成することは出来なくなります。}}
 
   
  +
# efibootmgr -d ''/dev/sdX'' -p ''Y'' -c -L "Arch Linux" -l /vmlinuz-linux -u "root=''/dev/sdBZ'' rw initrd=/initramfs-linux.img"
{{Note|UEFI ファームウェアによってはブートエントリの uefi アプリケーションにコマンドラインパラメータを埋め込むことができません。}}
 
   
  +
{{ic|''/dev/sdX''}} と {{ic|''Y''}} は ESP が存在するディスクとパーティションに置き換えてください。{{ic|1=root=}} パラメータを変更することで Linux のルートパーティションを指定できます (ディスクの UUID を使うこともできます)。{{ic|-u}} 引数をダブルクオーテーションで囲っているのは[[カーネルパラメータ]]を指定するためであり、[[サスペンドとハイバネート#必要なカーネルパラメータ|ハイバネート]]や[[マイクロコード]]を使う場合はパラメータを追加する必要があります。
UEFI ブートエントリに直接カーネルパラメータを埋め込むことが可能です。つまりあなたの UEFI ブートオーダー・GUI を使って GRUB など他のブートローダーを使わずに直接 Arch Linux を起動することができます (下のコマンドの {{ic|X}} と {{ic|Y}} は EFI System Partition があるディスクとパーティションに置き換えてください、{{ic|1=root=}} パラメータは root にあわせて変更してください)。
 
   
  +
以下のコマンドを実行することで作成したエントリが問題ないか確認できます:
# mount -t efivarfs efivarfs /sys/firmware/efi/efivars # 既にマウントされている場合は無視して下さい
 
# efibootmgr -d /dev/sd'''X''' -p '''Y''' -c -L "Arch Linux" -l /EFI/arch/vmlinuz-linux -u "root='''/dev/sda2''' rw initrd=/EFI/arch/initramfs-linux.img"
 
 
作成されたエントリが問題ないか確認するために次のコマンドを実行すると良いでしょう:
 
   
 
# efibootmgr -v
 
# efibootmgr -v
   
  +
{{Warning|特定のカーネルと {{ic|efibootmgr}} のバージョンの組み合わせでは新しいブートエントリを作成できません。NVRAM に空き容量が存在しないことが原因です。EFI のダンプファイルを削除してみてください:
ブートの順番を設定するには、次を実行します:
 
  +
  +
# rm /sys/firmware/efi/efivars/dump-*
  +
  +
もしくは、{{ic|efi_no_storage_paranoia}} カーネルパラメータを使って起動してください。キャッシュに前のバージョンが存在する場合、efibootmgr のバージョンを 0.11.0 にダウングレードしてみてください。このバージョンでは Linux のバージョン 4.0.6 が動作します。詳しくは {{Bug|34641}} を参照。}}
  +
  +
ブートの順序を設定するには、次のコマンドを実行:
   
 
# efibootmgr -o XXXX,XXXX
 
# efibootmgr -o XXXX,XXXX
   
XXXX は `efibootmgr` コマンドによって出力されそれぞれのエントリの番号に置き換えてください。
+
XXXX は `efibootmgr` コマンド出力で確認できるエントリの数字に置き換えてください。
  +
  +
{{Tip|ブートエントリを作成するコマンドをシェルスクリプトに保存することで、(カーネルパラメータを変更するときなど) 編集が簡単になります。}}
  +
  +
efibootmgr については [[UEFI#efibootmgr]] を見てください。https://bbs.archlinux.org/viewtopic.php?pid=1090040#p1090040 も参照。
  +
  +
==== UEFI Shell ====
  +
UEFI の実装によっては efibootmgr を使用して NVRAM を編集できないことがあります。efibootmgr でエントリを作成できない場合、UEFI Shell v2 の [[UEFI#bcfg|bcfg]] コマンドを使用する方法があります。
  +
  +
カーネルのエントリを追加するには、以下を実行:
  +
  +
Shell> bcfg boot add '''N''' fs'''V''':\vmlinuz-linux "Arch Linux"
  +
  +
{{ic|N}} はエントリの優先度 (0 が一番優先されます) に、{{ic|V}} は EFI パーティションのボリューム番号に置き換えてください。ボリューム番号がわからない場合、map コマンドを使うことでファイルシステムが確認できるので、ls コマンドで中身を確認してください:
  +
  +
Shell> map
  +
Shell> ls fs0:
  +
  +
最低限必要なカーネルオプションだけを追加する場合:
   
  +
Shell> bcfg boot -opt '''N''' "root='''/dev/sdX#''' rw initrd=\initramfs-linux.img"
{{Tip|シェルスクリプトでブートエントリを作成するコマンドをどこかに保存しておけば、修正 (例えばカーネルパラメータの変更) が楽になります。}}
 
   
  +
{{ic|N}} は優先度に {{ic|/dev/sdX#}} はルートパーティションに置き換えてください。
efibootmgr の詳細は [[Unified Extensible Firmware Interface#efibootmgr|UEFI#efibootmgr]] で説明しています。フォーラムの投稿 https://bbs.archlinux.org/viewtopic.php?pid=1090040#p1090040 。
 

2016年11月12日 (土) 17:46時点における版

関連記事

Linux カーネル (linux>=3.3) は EFISTUB (EFI BOOT STUB) ブートをサポートしています。カーネルコンフィグで CONFIG_EFI_STUB=y を設定することで有効にすることができ、Arch Linux のカーネルではデフォルトで有効にされています (詳しくは EFI Boot Stub を参照してください)。

EFISTUB カーネルだけでは他のカーネルを起動することはできません。よってブートメニューエントリごとに EFISTUB カーネル + Initramfs のペアが必要です。このため、複数のカーネルを使う場合は、ブートローダーを使うことが推奨されています。

EFISTUB の設定

EFI システムパーティションを作成したら、システムパーティションをマウントする方法を選択してください。一番簡単なのは /boot にマウントするか /bootバインドマウントすることです。pacman が直接 EFI ファームウェアによって読み込まれるカーネルを更新してくれます。その場合、#EFISTUB の起動に進んでください。

ノート: rEFInd などのファイルシステムドライバーを備えているブートマネージャを使用する場合、カーネルや initramfs を ESP 以外に保存できます。

他の ESP マウントポイント

EFI システムパーティションを /boot にマウントしない場合、ブートファイルをコピーする必要があります (以下 EFI システムパーティションの場所を esp とします):

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

さらに、カーネルのアップデートがあったときに ESP のファイルを更新する必要があります。更新しないとシステムが起動できなくなってしまいます。以下のセクションでは自動でコピーする方法を説明しています。

systemd を使う

Systemd には特定のイベントが起こったときにタスクを実行する機能があります。/boot が更新されたときに特定のパスにおける変更を検知して EFISTUB カーネルと initramfs ファイルを同期してください:

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

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

[Install]
WantedBy=multi-user.target
WantedBy=system-update.target
ノート: 上記のユニットは initramfs-linux-fallback.img の変更を監視します。このファイルは mkinitcpio によって最後に作成されるファイルであり、ビルドが完了する前に他のファイルをコピーしてしまう競合状態を避けることができます。
/etc/systemd/system/efistub-update.service
[Unit]
Description=Copy EFISTUB Kernel to UEFISYS Partition

[Service]
Type=oneshot
ExecStart=/usr/bin/cp -f /boot/vmlinuz-linux esp/EFI/arch/vmlinuz-linux
ExecStart=/usr/bin/cp -f /boot/initramfs-linux.img esp/EFI/arch/initramfs-linux.img
ExecStart=/usr/bin/cp -f /boot/initramfs-linux-fallback.img esp/EFI/arch/initramfs-linux-fallback.img
ヒント: (自分の鍵を使って) セキュアブートする場合、(sbsigntools を使って) イメージに署名するようにサービスを設定することができます:
ExecStart=/usr/bin/sbsign --key /path/to/db.key --cert /path/to/db.crt --output esp/EFI/arch/vmlinuz-linux esp/EFI/arch/vmlinuz_linux

ユニットを作成したら efistub-update.path起動有効化してください。

incron を使う

incron を使うことでカーネルの更新時に EFISTUB カーネルを同期させるスクリプトを実行できます。

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

この方法を使う場合、incrond のサービスを有効にしてください:

# systemctl enable incrond.service

mkinitcpio フックを使う

Mkinitcpio はフックを生成することができ、システムレベルのデーモンを必要としません。バックグラウンドプロセスが生成され vm-linuz, initramfs-linux.img, initramfs-linux-fallback.img が生成されてからファイルをコピーします。

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

/usr/lib/initcpio/install/efistub-update
#!/usr/bin/env bash
build() {
	/root/watch.sh &
}

help() {
	cat <<HELPEOF
This hook waits for mkinitcpio to finish and copies the finished ramdisk and kernel to the ESP
HELPEOF
}
/root/watch.sh
#!/usr/bin/env bash

while [[ -d "/proc/$PPID" ]]; do
	sleep 1
done

/usr/bin/cp -f /boot/vmlinuz-linux esp/EFI/arch/vmlinuz-linux
/usr/bin/cp -f /boot/initramfs-linux.img esp/EFI/arch/initramfs-linux.img
/usr/bin/cp -f /boot/initramfs-linux-fallback.img esp/EFI/arch/initramfs-linux-fallback.img

echo "Synced kernel with ESP"

mkinitcpio フックを使う (別の方法)

上記の方法と別に、コピー操作を減らす方法があります。逆転の発想で initramfs を /boot ではなく EFI パーティションに直接保存します。そして mkinitcpio フックを使ってカーネルなどのファイルを ESP にコピーします。

/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="/boot/efi/EFI/arch"

ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"

PRESETS=('default' 'fallback')

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

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

そして /usr/lib/initcpio/install/esp-update-linux ファイルを作成して実行可能属性を付与してください:

/usr/lib/initcpio/install/esp-update-linux
# Directory to copy the kernel, the initramfs...
ESP_DIR="/boot/efi/EFI/arch"

build() {
	cp /boot/vmlinuz-linux "${ESP_DIR}/vmlinuz-linux.efi"
	# If ucode is used uncomment this line
	#cp /boot/intel-ucode.img "${ESP_DIR}/"
}

help() {
	cat <<HELPEOF
This hook copies the kernel to the ESP partition
HELPEOF
}

テストするには以下のコマンドを実行:

# rm /boot/initramfs-linux-fallback.img
# rm /boot/initramfs-linux.img
# mkinitcpio -p linux

EFISTUB の起動

警告: Linux カーネル EFISTUB の initramfs のパスは EFI システムパーティションのルートディレクトリからの相対パスになります。例えば、initramfs が $esp/EFI/arch/initramfs-linux.img に存在する場合、UEFI で設定するのは initrd=/EFI/arch/initramfs-linux.img または initrd=\EFI\arch\initramfs-linux.img になります。以下の例では必要なファイル全てが $esp/ にあることを前提としています。

ブートマネージャを使う

UEFI ブートマネージャには UEFI ブートを簡単にすることができるオプションが存在します (特に複数のカーネルやオペレーティングシステムをインストールしている場合)。詳しくはブートローダーを見てください。

UEFI Shell を使う

通常の UEFI アプリケーションと同じように UEFI Shell から EFISTUB カーネルを起動できます。その場合、通常のパラメータとして起動する EFISTUB カーネルファイルにカーネルパラメータを渡してください:

> fs0:
> /vmlinuz-linux root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 rw initrd=/initramfs-linux.img

毎回カーネルパラメータを全て指定したくない場合、UEFI システムパーティションに archlinux.nsh などのシェルスクリプトの実行コマンドを保存することができます。以下のコマンドで起動できるようになります:

> fs0:
> archlinux

UEFI を直接使う

UEFI は GRUB などの中間的なブートローダーを排除できるように設計されています。使用しているマザーボードの UEFI 実装に問題がなければ、カーネルパラメータを UEFI ブートエントリの中に埋め込んでマザーボードから Arch を直接起動できます。efibootmgr や UEFI Shell v2 を使ってマザーボードのブートエントリを編集できます。

efibootmgr

以下のようなコマンドを実行してください:

# efibootmgr -d /dev/sdX -p Y -c -L "Arch Linux" -l /vmlinuz-linux -u "root=/dev/sdBZ rw initrd=/initramfs-linux.img"

/dev/sdXY は ESP が存在するディスクとパーティションに置き換えてください。root= パラメータを変更することで Linux のルートパーティションを指定できます (ディスクの UUID を使うこともできます)。-u 引数をダブルクオーテーションで囲っているのはカーネルパラメータを指定するためであり、ハイバネートマイクロコードを使う場合はパラメータを追加する必要があります。

以下のコマンドを実行することで作成したエントリが問題ないか確認できます:

# efibootmgr -v
警告: 特定のカーネルと efibootmgr のバージョンの組み合わせでは新しいブートエントリを作成できません。NVRAM に空き容量が存在しないことが原因です。EFI のダンプファイルを削除してみてください:
# rm /sys/firmware/efi/efivars/dump-*
もしくは、efi_no_storage_paranoia カーネルパラメータを使って起動してください。キャッシュに前のバージョンが存在する場合、efibootmgr のバージョンを 0.11.0 にダウングレードしてみてください。このバージョンでは Linux のバージョン 4.0.6 が動作します。詳しくは FS#34641 を参照。

ブートの順序を設定するには、次のコマンドを実行:

# efibootmgr -o XXXX,XXXX

XXXX は `efibootmgr` コマンドの出力で確認できるエントリの数字に置き換えてください。

ヒント: ブートエントリを作成するコマンドをシェルスクリプトに保存することで、(カーネルパラメータを変更するときなど) 編集が簡単になります。

efibootmgr については UEFI#efibootmgr を見てください。https://bbs.archlinux.org/viewtopic.php?pid=1090040#p1090040 も参照。

UEFI Shell

UEFI の実装によっては efibootmgr を使用して NVRAM を編集できないことがあります。efibootmgr でエントリを作成できない場合、UEFI Shell v2 の bcfg コマンドを使用する方法があります。

カーネルのエントリを追加するには、以下を実行:

Shell> bcfg boot add N fsV:\vmlinuz-linux "Arch Linux"

N はエントリの優先度 (0 が一番優先されます) に、V は EFI パーティションのボリューム番号に置き換えてください。ボリューム番号がわからない場合、map コマンドを使うことでファイルシステムが確認できるので、ls コマンドで中身を確認してください:

Shell> map
Shell> ls fs0:

最低限必要なカーネルオプションだけを追加する場合:

Shell> bcfg boot -opt N "root=/dev/sdX# rw initrd=\initramfs-linux.img"

N は優先度に /dev/sdX# はルートパーティションに置き換えてください。