[WSL][Ubuntu 20.04] edkIIで公式ドキュメントを読みながらUEFIアプリケーションのHello Worldを実行する
Ubuntu上で、UEFIアプリケーションの開発に入門してみました。
スタートガイドに沿ってHello Worldアプリをビルドし、UEFI Shell上で実行するところまでを説明します。
開発環境
Ubuntu 20.04 LTSをWSL上にインストールしています。
edkII(edk2)とは
UEFI BIOSのファームウェアやUEFI BIOS上で動くアプリケーションを開発するための開発キットです。
オープンソースとして下記にリポジトリが公開されています。
tianocore/edk2
edkIIのビルド方法
スタートガイドはこちらにあります。
ここにOSごとのセットアップ方法のページが列挙されているので、
LinuxのところからLinuxのページに進みます。
プロキシ設定が必要な場合はInternet proxiesの章を参考にプロキシの設定をしてください。
今回はUbuntu 20.04 LTS上で環境を整えるので、Ubuntu 20.04 LTSの章を参照しながらセットアップを進めていきます。
まず、aptを最新にしてください。
古いままですと、このあとのパッケージのインストールに失敗してしまう場合があります。
sudo apt update
次に、ドキュメントに記載の通りに必要なパッケージをインストールしていきます。
sudo apt install build-essential uuid-dev iasl git nasm python-is-python3
ここまで終わると、Continue with common instructionsの章にリンクが書いてあります。 ここからはUbuntuのバージョンによらず共通のセットアップになるようです。引き続きセットアップを進めていきます。
ソースコードを置くためのフォルダを作成し、その中でedk2のソースコードをクローンします。
mkdir ~/src
cd ~/src
git clone https://github.com/tianocore/edk2
別のリリースバージョンをクローンしたい場合はブランチを指定してクローンします。 今回はmainブランチからクローンしているので、下記は実行していません。
git clone https://github.com/tianocore/edk2.git vUDK2017
クローンして生成されたedk2ディレクトリに移動します。
cd ~/src/edk2
edk2リポジトリはいくつかサブモジュールを持っていますので、これらも取ってきます。
git submodule update --init
ビルドツールをコンパイルします。
make -C BaseTools
. edksetup.sh
これによりedk2の下に、/Conf/target.txt, Conf/tools_def.txt が作成されます。
BaseToolsをビルドします。
make -C edk2/BaseTools
export EDK_TOOLS_PATH=$HOME/src/edk2/BaseTools
. edksetup.sh BaseTools
次にConf/target.txtを書き換えます。
ドキュメントの通りに "ACTIVE_PLATFORM ="の箇所を探し、右辺を"MdeModulePkg/MdeModulePkg.dsc"に変更します。
ACTIVE_PLATFORM = MdeModulePkg/MdeModulePkg.dsc
同様に"TOOL_CHAIN_TAG = "の右辺を書き換えます。
Conf/tools_def.txtにSupported Tool Chainsという項目があり、ここにコンパイラ別のTOOL_CHAIN_TAGの書き方が書いてあります。
私の環境で"gcc --version"を実行したところ、GCC 9.4.0が入っていました。
Conf/tools_def.txtと照らし合わせると、gcc 5 以降のバージョンではGCC5を指定すれば問題なさそうでした。
TOOL_CHAIN_TAG = GCC5
"TARGET_ARCH = "の右辺にはX64を指定しました。
(IA32もビルドしてみたのですが、私の実行環境ではX64のアプリしか実行できないようでした。)
TARGET_ARCH = X64
これでビルドの準備が整いましたので、リポジトリにデフォルトで入っているUEFIアプリケーションをビルドしていきます。
build
最後に"Done"とビルド時間が表示されればビルド成功です。
- Done -
Build end time: 16:24:50, Jan.05 2023
Build total time: 00:00:44
実はここで一度ビルドに失敗してしまいました。
その時の対処法については後述します。
ビルド成果物は"Build/MdeModule/DEBUG_/"にできるとのことです。
今回の環境に沿い、"Build/MdeModule/DEBUG_GCC5/X64"以下にefi実行ファイルなどたくさんのファイルが生成されていることを確認できました。
HelloWorld.efiを実行
"Build/MdeModule/DEBUG_GCC5/X64"以下にはHelloWorld.efiが生成されていることが確認できます。
USBにコピーし、UEFI Shell上で実行してみます。
"UEFI Hello World!"と表示され、正常に動作していることを確認できました。
まとめ
今回はUEFIアプリのHello Worldを試してみました。
これからUEFIに入門される方のお役にたてば幸いです。
(おまけ)ビルドに失敗したときの対処法
先述した通り、今回の手順で一度ビルドに失敗しています。
ビルド時のログを見てみると、最後に下記のような行が表示されていました。
同じエラーが出ている方はご参考にしてください。
.../src/edk2/Build/MdeModule/DEBUG_GCC5/X64/MdePkg/Library/BaseLib/BaseLib/OUTPUT/X64/LongJump.iii:44: error: parser: instruction expected
.../src/edk2/Build/MdeModule/DEBUG_GCC5/X64/MdePkg/Library/BaseLib/BaseLib/OUTPUT/X64/LongJump.iii:49: error: parser: instruction expected
make: *** [GNUmakefile:790: .../src/edk2/Build/MdeModule/DEBUG_GCC5/X64/MdePkg/Library/BaseLib/BaseLib/OUTPUT/X64/LongJump.obj] Error 1
build.py...
: error 7000: Failed to execute command
make tbuild [.../src/edk2/Build/MdeModule/DEBUG_GCC5/X64/MdePkg/Library/BaseLib/BaseLib]
build.py...
: error F002: Failed to build module
.../src/edk2/MdePkg/Library/BaseLib/BaseLib.inf [X64, GCC5, DEBUG]
- Failed -
Build end time: 15:01:25, Jan.05 2023
Build total time: 00:00:07
エラーの原因を調べるためConf/tools_def.txtを見ながら環境の確認をしました。
すると、GCC toolchainを使うにはNASMが2.15.05以上でないといけないということがわかりました。
# Other Supported Tools
# =====================
# NASM -- http://www.nasm.us/
# - NASM 2.15.05 or later for use with the GCC toolchain family
# - NASM 2.15.05 or later for use with all other toolchain families
"nasm --version" でバージョンを調べてみると、NASM version 2.14.02 と表示されたので、これが原因かもしれないと思いました。
調べてみると同じエラーについて書かれた記事にたどり着き、やはりエラーの原因がnasmのバージョンが低いためであったことがわかりました。
記事の通りにnasmを2.15.05をインストールし、再度buildコマンドを実行したところ、ビルドに成功しました。