肥大化したブートローダーに別れを告げる
GRUB (Grand Unified Bootloader) は、Linux界の古くからの頼れる存在です。汎用性が高く、レガシーBIOSをサポートし、ほぼすべてのOSを起動できます。しかし、UEFIを搭載したモダンなマシンを使用している場合、GRUBはまるで仕上げ釘を打つのに大型ハンマーを使っているような過剰さを感じさせます。単純な grub.cfg を生成するためだけに1,000行もの巨大なスクリプトに依存しており、再起動のたびに不要なオーバーヘッドが発生します。
数年前、カーネルアップデート後に起動しなくなったサーバーのデバッグに2時間を費やしたことがあります。原因は、自分が書いたわけでもないスクリプト内のわずかな構文エラーでした。その不満から、より軽量で透明性の高いものを探すようになりました。UEFI時代に特化したブートプロセスを求めるなら、systemd-bootがその答えです。
なぜモダンなハードウェアにGRUBは過剰なのか
GRUBの複雑さは、その歴史の副産物です。古いハードウェアと最新のソフトウェアの橋渡しをするために設計されたため、ファイルシステム、ビデオモード、さらにはネットワークプロトコルのための独自のドライバーまで含まれています。電源ボタンを押すと、GRUBは実際のOSを見つけてロードするためだけに、本質的には「ミニOS」を起動しているのです。
UEFIシステムでは、これは冗長です。マザーボードのファームウェアは、すでにパーティションの読み取りやファイルのロード方法を知っています。GRUBを使い続けることは、中間業者のなかに別の中間業者を置くようなものです。このセットアップは、いくつかの悩みの種を引き起こします。
- 時間の浪費: GRUBは初期化のためだけに、ブートシーケンスに2〜5秒を追加することがあります。
- 脆弱性: 設定ファイルは
os-proberなどのスクリプトによって生成されるため、手動での編集は困難を極めます。 - 学習コスト: 設定ロジックが抽象化の層に埋もれているため、新人管理者がブートパラメータをカスタマイズするのに苦労することがよくあります。
ソリューションの比較:GRUB vs. systemd-boot
ブートマネージャーを選択する場合、一般的に3つの道があります。GRUBは依然として「安全な」デフォルトですが、重量級です。rEFIndはmacOSとLinuxのマルチブートシステムなどに美しいグラフィカルインターフェースを提供しますが、専用のワークステーションには過剰な場合が多いです。
systemd-boot(旧称 gummiboot)は異なるアプローチを取ります。OSになろうとはせず、UEFIファームウェアにどのカーネルを実行すべきかを伝えるシンプルな論理ゲートとして機能します。GRUBのコアは数メガバイトに及ぶことがありますが、systemd-bootのEFIバイナリは通常500KB未満です。人間が数秒で読み取り、修正できるプレーンテキストの設定ファイルを使用します。
「Less is More(少ないほど豊か)」なアプローチ
本番環境のUbuntu 22.04サーバーをsystemd-bootに移行したところ、すぐに違いが現れました。GRUBの検出フェーズを排除することで、ファームウェアからカーネルへの移行がほぼ瞬時になりました。標準的なNVMeドライブでは、「ファームウェアからログイン画面まで」の時間が約3秒短縮されました。
切り替える前に、システムがUEFIモードであることを確認してください。このプロセスはレガシーBIOSマシンでは動作しません。確認するには次のコマンドを実行します。
[ -d /sys/firmware/efi ] && echo "UEFIモード" || echo "レガシーモード"
出力で「UEFIモード」と確認できれば、準備は完了です。
ステップ1:EFIパーティションの準備
systemd-bootでは、カーネルとinitramfsファイルがEFIシステムパーティション(ESP)上にある必要があります。ほとんどのディストリビューションはESPを /boot/efi にマウントしますが、systemd-bootはESPが /boot に直接マウントされている場合に最もよく機能します。
lsblk で現在の設定を確認してください。EFIパーティションが100MBしかない場合は、少なくとも500MBにリサイズすることをお勧めします。これにより、アップデート中に容量不足になることなく、複数のカーネルバージョンと関連イメージを保存できる十分なスペースが確保されます。
ステップ2:systemd-bootの初期化
モダンなディストリビューションを使用している場合、systemd-bootはおそらく systemd パッケージの一部としてすでにディスク内に存在します。新しくダウンロードする必要はなく、有効化するだけです。次のコマンドを実行して、EFIパーティションにマネージャーをインストールします。
sudo bootctl install
このコマンドは必要なバイナリをコピーし、マザーボードのNVRAMに新しいエントリを作成します。bootctl status を実行して、ブートエントリの状態を確認できます。
ステップ3:ローダーの設定
次に、ブートローダーの動作を定義する必要があります。メインの設定ファイルを開きます。
sudo nano /boot/loader/loader.conf
以下の設定を貼り付けます。
default linux.conf
timeout 3
console-mode max
editor no
editor を ‘no’ に設定することは、重要なセキュリティステップです。これにより、権限のないユーザーがブートメニューから直接カーネルパラメータを変更する(ルートシェルでの起動など)のを防ぐことができます。
ステップ4:ブートエントリの作成
GRUBの単一で巨大な設定ファイルとは異なり、systemd-bootはエントリごとに個別のファイルを使用します。これらは /boot/loader/entries/ に配置されます。メインOS用のファイルを作成します。
sudo nano /boot/loader/entries/linux.conf
/boot ディレクトリに実際に存在するファイル名と一致することを確認しながら、以下の行を追加します。
title Linuxデスクトップ
linux /vmlinuz-linux
initrd /initramfs-linux.img
options root=PARTUUID=xxxx-xxxx-xxxx rw
PARTUUID を確認するには、blkid -s PARTUUID -o value /dev/sdXn を実行します(デバイスパスをルートパーティションのものに置き換えてください)。PARTUUIDを使用することは、/dev/sda2 のようなデバイス名よりもはるかに信頼性が高いです。デバイス名は新しいUSBドライブを接続すると変わる可能性があるためです。
ステップ5:カーネルアップデートの管理
よくある質問は「カーネルがアップデートされたらどうなるのか?」というものです。Arch Linuxではファイル名が固定されているため、これらの設定に触れる必要はありません。DebianやUbuntuでは、アップデートのファイル名にバージョン番号が含まれることがよくあります。
これを自動化するために、systemdに含まれているスクリプト kernel-install を使用できます。これは、新しいバージョンがインストールされるたびに、カーネルを自動的にESPに移動し、エントリファイルを生成します。よりシンプルな手動アプローチとしては、最新のカーネルを vmlinuz-linux のような汎用名にシンボリックリンクする小さなスクリプトを作成することもできます。
ステップ6:不要なものの削除
systemd-bootを使用して正常に再起動できたら、GRUBを安全に削除できます。これにより、使用しなくなったブートローダーの更新にシステムリソースを浪費するのを防げます。UbuntuやDebianの場合は、以下を実行します。
sudo apt purge grub-common grub-pc-bin grub-efi-amd64
sudo apt autoremove
プロのヒント: 古いブートローダーを削除する前に、必ずLive USBを手元に置いておきましょう。systemd-bootは非常に安定していますが、リカバリツールを用意しておくことは、準備万端な管理者の証です。
結果:透明性の高いブートプロセス
systemd-bootへの切り替えは、単に起動時間を数秒短縮するだけのことではありません。透明性を手に入れるためのものです。GRUBの複雑さを取り除くことで、ブートプロセスを謎の「ブラックボックス」から、インフラストラクチャの管理可能な一部へと変えることができます。クリーンなエントリディレクトリ、単一の設定ファイル、そしてモダンなハードウェアのパワーを尊重するシステムが手に入ります。

