01-01.UEFIとEDKⅡによるHelloWorld

 この項では、UEFIでのブートを実現するEDKⅡというツールの説明をするとともに、HelloWorldします。
 はじめににも述べたように、今、ノート型の開発マシン(ubuntuがセットアップされている)があります。ネットもつながっています。
 この項で行うのはEDKⅡのドキュメントに記述されていることをなぞる感じです。英語のサイトなので日本語訳くらいに考えていただければと思います。
 UEFIというのは、これまでのBiosによるパソコンの起動の仕組みを根本から変えるものです。DVDやUSBなど、ブートしたいメディアに1つの規格を設け、その規格に合っていればそのメディアの中のプログラムを実行してくれる、というのがUEFIです。
 ただ、UEFIがやってくれるのは、指定されたプログラムをメモリにロードして実行するだけです。そのあとはプログラムする必要があります。UEFIが起動するアプリをUEFIアプリなんて書かれている場合もあります。拡張子は.efiです。
 パソコンのブート時の状態は、PCATマシンであればbiosが実行できるだけの状態です。C言語でプログラムすることができますが、たぶん、多くの人が考えているC言語とは勝手が違います。なんせ、標準ライブラリが使えない状態です。
 C言語の標準ライブラリはOSが用意するライブラリです。Linuxしかり、Windowsしかり。しかしUEFIが起草するプログラムにはそれがついてないのです。
 しかし、それではいくら何でも不便だろう、ということでCの標準ライブラリではないですが、ある程度パソコンを操れるライブラリを用意しているツールがあります。UEFIアプリのSDKともいえるツールです。
 ネットを探すといろいろ出てくるのですが、有名どころは
EDKⅡ
gnu-efi
 などです。ここではEDKⅡを使ったUEFIアプリの制作をやってみたいと思います。

開発ツールのインストール

 まず、コンパイラとか様々な開発ツールをセットアップする必要があります。
 端末を開いて
$ sudo apt install build-essential uuid-dev iasl git gcc-5 nasm python3-distutils
 と実行しますと、開発環境がインストールされます。あとからもう少し開発ツールをインストールしますが、今んとこは、ここまでにしておきます。

EDKⅡのダウンロード

 EDKⅡのダウンロードは、以下のように行います。
$ mkdir ~/src
$ cd ~/src
$ git clone https://github.com/tianocore/edk2
 ここでは、ホームディレクトリにsrcというディレクトリを作成し、その中にedk2をダウンロードします。上記のコマンドで
/home/アカウント名/src/edk2/
 にEDKⅡがダウンロードされます。
 断るまでもないかもしれませんが、上記は
~/src/edk2/
 の意味です。コマンドで
cd ~
 で自分のホームディレクトリに行けますので、~ホームという意味です。

EDKⅡのコンパイル

 続いてEDKⅡの基本的なライブラリをコンパイルします。
$ make -C edk2/BaseTools
 今のカレントディレクトリは
~/src
 ですから、そこから上記のコマンドを打ち込みます。すると、EDKⅡの基本的なライブラリがコンパイルされます。(結構時間がかかります)

EDKⅡのパスの設定

 コンパイルが終わりましたら、
$ cd ~/src/edk2
$ export EDK_TOOLS_PATH=$HOME/src/edk2/BaseTools
$ . edksetup.sh BaseTools
 と打ち込みます。これでEDKⅡの各パッケージをビルドできる環境になります。またカレントディレクトリは~/src/edk2になります。

MdeModulePkgパッケージのビルド

 EDKⅡパッケージという単位でプログラムをビルドします。パッケージを選択するには
Conf/target.txt
 というファイルを、テキストエディタ(gedit)で開き、その中の以下のブロックを修正します。
ACTIVE_PLATFORM       = MdeModulePkg/MdeModulePkg.dsc
TOOL_CHAIN_TAG        = GCC5
TARGET                = RELEASE
TARGET_ARCH           = X64
 それぞれ、赤くなってるように書き換えます。
 書き換えたら、カレントディレクトリは~/src/edk2になっている状態で
$ build
 と打ち込みます。MdeModulePkgパッケージがビルドされます。
 問題なければDoneというメッセージが表示されます

HelloWorldアプリの実行準備

 これで、MdeModulePkgパッケージに含まれるHelloWorldアプリが出来上がったわけですが、これを実行する場合にはもう少し作業が必要です。
 UEFIアプリは基本的に、パソコンが起動したときに実行されるプログラムです。USBやCD-ROMにコピーしてパソコンを再起動する形で動作させるのが目標ですが、現時点では、そのための設定やらが大変です。
 そのため、qemuというエミュレータを使います。  qemuをインストールするには以下のコマンドを打ちます。一緒にOVMFというUEFIのファームウェアもインストールします。
$ sudo apt install qemu ovmf
 UEFI+EDKⅡについては、いろんな方々がブログや記事なども書いているのですが、その中ではOVMFEDKⅡのパッケージにあるものをビルドして使うように記述されているのですが、今回の開発環境では、思うようにビルドできません。ですのでUbuntuのパッケージにあるOVMFを使用することにします。
 上記のインストールが終わったら、以下のようにブートディスクイメージを作成します。
$ cd ~/src
$ mkdir -p image/EFI/BOOT
$ cp edk2/Build/MdeModule/RELEASE_GCC5/X64/HelloWorld.efi image/EFI/BOOT/BOOTX64.efi
 このimageディレクトリ配下がブートイメージになります。
 上記のコマンドでHelloWorld.efiという名前のUEFIアプリが、ブートイメージのEFI/BOOT/BOOTX64.efiという名前で保存されます。

HelloWorldアプリの実行

 さあ、あとは、エミュレーターを起動して、アプリを実行します。
$ qemu-system-x86_64 \
-bios OVMF.fd \
-drive if=ide,file=fat:image,index=0,media=disk
 上記の \ はubuntuだと、バックスラッシュになります。
 しばらくしてネットからのブートがタイムアウトになるとShellが起動します。
 Mapping tableの項目を見てくださいFS0:という項目が見つかると思います。Shellから
Shell>FS0:
 と記述してEnterを押します。その際 : は打ちにくいと思います。認識が英語のキーボードになっているためで : shift + ; を打ちましょう ; はセミコロンの場所です。すると
FS0:\>
 とでます。ここでlsと打つとEFIが見えると思います。ここで
FS0:\> cd EFI/BOOT
FS0:\EFI\BOOT> ls
 とすると、BOOTX64.efiが見えると思います。これこそHelloWorldアプリです。
FS0:\EFI\BOOT> BOOTX64.efi
 と打ち込んでみましょう。
UEFI Hello World!
 と表示されると思います。これがUEFIHelloWorldです。