C言語でUEFIアプリを書いてQUEMで実行してみよう
イントロダクション
自作OS入門の門を叩きました。 続きをやっていきます。
C言語によるUEFIアプリケーションの起動
実行環境を整えていきます。 幸いにもAngibleで環境構築ができるように設定ファイルが用意されています。 ありがたい。
調べてみるとRedHat社がつくっているようで、YAML形式で記載された定義ファイルを実行できます。
git clone https://github.com/uchan-nos/mikanos-build.git osbook
sudo apt install ansible
cd osbook/devenv
ansible-playbook -K -i ansible_inventory ansible_provision.yml
しばらくすると導入が完了します。 インストールに成功すればEDKⅡが入っているはずなので確認します。
iasl -v
ls ~/edk2
edk2は2章以降で使うようです。
ソースコード
Remote-WSLというプラグインをVScodeに入れておきます。 WSL上からVSCode起動します。
vscode
左下に緑色でWSL接続されている状態なら成功です。 Fileから開発したいフォルダを開いて、hello.cを書きます。
uchan-nos/mikanos-build のday01にある、hello.cを写経します。
typedef unsigned short CHAR16;
typedef unsigned long long EFI_STATUS;
typedef void *EFI_HANDLE;
struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
typedef EFI_STATUS (*EFI_TEXT_STRING)(
struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
CHAR16 *String);
typedef struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
void *dummy;
EFI_TEXT_STRING OutputString;
} EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
typedef struct {
char dummy[52];
EFI_HANDLE ConsoleOutHandle;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
} EFI_SYSTEM_TABLE;
EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
EFI_SYSTEM_TABLE *SystemTable) {
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Hello, world!\n");
while (1);
return 0;
}
続いてコンパイルしていきます。
clang -target x86_64-pc-win32-coff -mno-red-zone -fno-stack-protector -fshort-wchar -Wall -c hello.c
lld-link /subsystem:EFI_APPLICATION /entry:EfiMain /out:hello.efi hello.o
WSL環境下なのかわからないが、subsystemの指定方法が大文字出ないと上手くいかなかったので大文字で実行します。
参考 https://learn.microsoft.com/ja-jp/cpp/build/reference/subsystem-specify-subsystem?view=msvc-170
コンパイルしてリンカ張れたらOKです。
実行結果
QEMUの実行コマンドを支援するスクリプトが用意されているのでこちらを実行しましょう。
$HOME/osbook/devenv/run_qemu.sh hello.efi
挨拶文を書き換えて本当に動いているかも確認します。
おっさんな、小学生みたいなことして喜ぶからな困っちゃうよな。
まとめ
これにてC言語をコンパイルしてリンカ動かしてQUEM上で動作させることができました。 ELFファイルって聞くと長寿で耳の長い種族が出てきますが、Executable and Linkable Formatの略称です。実行ファイル形式の一つです。
このペースで良いのか疑問ですが、毎日少しずつですが進めていきたいですね。
以上