本連載の目標
次回起動時にブートするOSを変更し、コンピュータを再起動させるUEFIソフト「BootNextChanger」を作成する。
謝辞
大神祐真様のフルスクラッチで作る!UEFIベアメタルプログラミングが、大変参考になりました。ありがとうございます。
UEFIについて
Unified Extensible Firmware Interfaceの略で、OSとファームウェアの間を結ぶインターフェースです。UEFIは、仕様が「UEFI Specificatrion」として公開されていることが大きい特徴の1つです。2025年1月3日時点での仕様書の最新版は、UEFI Specification 2.11です。
UEFIによるOSの起動
UEFIは、ブートマネージャーを備えています。ブートマネージャーは、UEFI仕様書に則って作成されたアプリケーション(.efi形式の場合がほとんど)を起動することができます。例えばWindowsの場合は、起動時に「bootmgfw.efi」を呼び出します。
UEFIでは、NVRAM(不揮発性メモリ)に保存する変数(UEFI実行ファイルへのポインタなど)も規定しており、ブートマネージャーはNVRAM上に保存された変数からUEFIアプリケーションをロードし、実行します。
UEFIと、それに付随したブートマネージャーを使うと、OSを介さずにファームウェアを使って計算機を動作させる、ベアメタルプログラミングが可能です。
さらなる詳細は、UEFIの仕様書をご確認ください。
作成するUEFIソフトの詳細
ファイル形式、呼び出し方法
C言語のソースコードでアプリケーションの内容を記述し、mingwでPE32+にクロスコンパイルすることでUEFIで実行可能な形式にします。
実行可能となったEFIファイルは、rEFIndブートマネージャーで呼び出します。
動作
BootNextChangerは、呼び出されると、まずはグローバル変数「BootNext」を書き換えます。次に、コンピュータを再起動させます。
使用例
ブートエントリが次のように設定されていたとします。
$ efibootmgr -u
BootCurrent: 0001
Timeout: 0 seconds
BootOrder: 0001,0000
Boot0000* Windows Boot Manager HD(1,xxxxxxxx)/\EFI\Microsoft\Boot\bootmgfw.efi????
Boot0001* UEFI OS HD(1,xxxxxxxx)/\EFI\refind\refind_x64.EFI
BootNextChangerは、BootNextを0000に書き換えるよう設定しておきます。
このとき、UEFIのブートマネージャーは、最初にrEFIndを起動します。(rEFIndの起動の際にエラーメッセージが吐かれたら、Windows Boot Managerを起動します。)
ここで、rEFIndでBootNextChangerを起動すると、BootNextChangerは、OSの起動していないベアメタルの上で動作します。BootNextChangerはBootNextを0000に書き換え、自動的に再起動したあとにBoot0000に登録されたブートオプション(今回の場合は、Windows)が起動します。さらに、BootNextは次回起動時のみに効くため、さらに再起動をすると今度はrEFIndが起動します。
ブートローダーから直接Windowsブートマネージャーを呼び出すと動作が不自然になることが多いですが、今回の方法を使えば、Windowsによって設定されたブートエントリそのものを起動できるため、動作がとても自然です。
おわりに
私はベアメタルプログラミング初心者なので、間違っているところなどあればご指摘いただけますと幸いです。
今後ともよろしくお願いします。
参考