この記事を作った動機

 CMOS リセット時に GRUB インストール時にデフォルトで作成される UEFI 設定が一緒に消えてしまう。結果として、はじめから Linux 環境を起動してほしいときに、意図した通りに起動しないことがあった。

 そこでしばらくは BIOS から直接 Linux 環境がインストールされた環境をわざわざ選択して起動したり、UEFI設定から直接エントリを作成して、Linux を起動するようにするなど、面倒くさい事を繰り返していた。

 今回は、それに対してefibootmgrというコマンドを使い、systemd によって一度起動したら自動でエントリがない場合に起動エントリを追加するようにした。その内容について記録を取りたい。

efibootmgr の使い方

インストール

yay -Sy efibootmgr
# sudo pacman -Sy efibootmgr

エントリを追加する例

 ブートローダである UEFI アプリケーションのパスを指定するとき注意が必要である。Linux 環境側から見て、/bootに EFI パティーションをマウントしていて、/boot/EFI/arch/grubx64.efi に対象のアプリファイルが配置されている場合の例について考える。この場合、efibootmgr で指定すべきパスは、/boot/EFI/arch/grubx64.efi ではなく /EFI/arch/grubx64.efi である。もしここで間違ったパスを指定していると、UEFI アプリケーションの起動に失敗し、UEFI の設定画面に飛ばされるなどの症状になる。

sudo efibootmgr -c -L ArchLinux -l /EFI/arch/grubx64.efi -d /dev/nvme0n1p1

fdisk で Linux 環境がインストールされたディスクを確認
sudo fdisk -l
# Disk /dev/nvme0n1: 476.94 GiB, 512110190592 bytes, 1000215216 sectors
# Disk model: SAMSUNG MZVKW512HMJP-000H1              
# Units: sectors of 1 * 512 = 512 bytes
# Sector size (logical/physical): 512 bytes / 512 bytes
# I/O size (minimum/optimal): 512 bytes / 512 bytes
# Disklabel type: gpt
# Disk identifier: 
# 
# Device             Start        End   Sectors  Size Type
# /dev/nvme0n1p1      2048    2097152   2095105 1023M EFI System
# /dev/nvme0n1p2   2099200  964689920 962590721  459G Linux filesystem
# /dev/nvme0n1p3 964691968 1000214527  35522560 16.9G Linux swap

エントリを削除する例

sudo efibootmgr -B -L ArchLinux

systemd スクリプト

 以下は、/etc/systemd/system/grubConfig.service として配置した systemd サービスの例である。いちいちエントリがあるか判定するのはめんどくさかった。そこで毎回 Linux 環境起動時に既にあるエントリはもし存在すれば重複防止のために消して、エントリを作るという挙動にした。

[Unit]
Description=Create UEFI entry by using efibootmgr command.

[Service]
Type=simple
User=root
ExecStart=/bin/bash -c "efibootmgr -B -L ArchLinux; efibootmgr -c -L ArchLinux -l /EFI/arch/grubx64.efi -d /dev/nvme0n1p1"
Restart=on-failure

[Install]
WantedBy=multi-user.target
sudo systemctl enable --now grubConfig

参考にしたサイトとか