【UEFI OSを作る!?】UEFIアプリをより開発しやすくする

OS開発

前回はnanoを使ってコードを書いていましたが、もっと書きやすくするために、今回はVisual Studio Codeというエディタをインストールします

GitHubにソースコード等を公開しているので、完成形が欲しい方は持って行ってください。

GitHub - nova-27/osdev-blog: sample code of https://novablog.work/category/os%e9%96%8b%e7%99%ba/
sample code of - nova-27/osdev-blog

Visual Studio Code のインストール・設定

効率的にプログラムを作ったり、ケアレスミスをなくすために、エディタというものを使います。
別にメモ帳とか前回使ったnano、vimを愛しているならそれを使ってくれてもいいですけど、エラー祭りになっても知りません。

ということで、そのエディタの一つであるVisual Studio Code(以下VSCodeと表記)をインストールしましょう。

Visual Studio Code をインストールする

https://code.visualstudio.com/downloadからVSCodeをダウンロードします。

WSLを使って開発する人はWindows、実機や仮想PCでLinuxを使って開発する人は.debまたは.rpmを選びます。
Windowsで開発する人に注意してほしいのが、WSLを使って内部的にはLinuxを使いますが、Windows版をダウンロードしてください。

ダウンロードしたらインストールしてください。
「次へ」をクリックしていくだけなので特に難しくはありません。

Windows10のみ : VSCodeをWSLと連携する

まず拡張機能をインスト―ルします
VSCodeを開いてください

赤丸で囲ったアイコンをクリックして、「WSL」と検索します
「Remote – WSL」を選択して、右側の赤丸(筆者はインストール済みなので少し表示が違います)の中にある「インストール」をクリックしてインストールします

そしたらVSCodeを一旦閉じます。

WSLで以下のコマンドを実行します。

cd os-dev
code .

そうすると、VSCodeがWSLと連携した状態で起動します。

その他拡張機能をインストールする

直接Linuxを動かしている人は、

cd os-dev
code .

でVSCodeを開いてください。

「Remote – WSL」に続いて、「C/C++」もインストールします。
インストールの仕方はさっきと一緒です。

日本語表示するために、「Japanese Language Pack for Visual Studio」もインストールします。

ファイルを整理する

左にあるタブを見ると、このようなディレクトリ構造になっていると思います。

このままだと、どのコードがどこにあるかわからなくなるので、もうちょっと整理します。

筆者はPart1フォルダを作ってこのように整理してみました。

どんな整理の仕方でもいいですが、ややこしくなる人は筆者に合わせておくと無難です。

makefileを作る

makeというプログラムを使うと、プログラムのコンパイル等をを自動化してくれます。
まずそれをインストールしましょう。

sudo apt install make

次にコンパイルの仕方などを指定するmakefileを作成します。

このようにPart1フォルダ下に作成します(VSCodeで)。

makefileをVSCodeで開いて、↓のように編集します

CC = x86_64-w64-mingw32-gcc
CFLAGS = -Wall -Wextra -nostdinc -nostdlib
all: main.efi
run: main.efi
	mv $< root/EFI/BOOT/BOOTX64.EFI
	qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -drive format=raw,file=fat:rw:root
main.efi: main.c
	$(CC) $(CFLAGS)  -Wl,--subsystem,10 -e efi_main -o $@ $<

makefileは、以下のように書きます

[作りたいもの]: [必要なもの(複数指定可)]
	[コマンド]

例えば「main.efi: main.c」の部分だったら、「main.efiを作りたいから、main.cをちょうだい」という意味になります。
それを実行するときは「make main.efi」というコマンドを入力します。

CCにはコンパイラ、CFLAGSにはコンパイルするときの引数を入れておいて、$(CC)や$(CFLAGS)として使えるようにしています。

allはデフォルト(「make」とだけ入力したとき)に実行されます。
runはrunというファイルを作るわけではありませんが、「make run」というコマンドを実行したときにqemuを実行できるようにするための項目です。

$@は[作りたいもの]、$<は[必要なもの]の先頭を意味します。

makefileを使う

makefileを作成できたので、makefileを使ってみましょう!!

VSCodeの画面下に、このようなものがあると思います。
(無い場合はメニューから「ターミナル」→「新しいターミナル」を選択します)

これはWSL(実機でLinuxを動かしている人はLinux)と同じターミナルなので、ここに入力したコマンドは、WSLに送信されます。

↓のコマンドを実行します

cd Part1
make main.efi

このコマンドでPart1フォルダへ移動し、「main.efi: main.c」の項目のコマンドを実行されます。

こんな感じのが出たらOKです。

もう一度「make main.efi」コマンドを実行します。
すると、このように表示されます

これは既にmain.efiが最新の状態なので、makeプログラムがコンパイルする必要が無いと判断して、中断してくれたからです。
この機能のおかげで、コードが増えてきたとき全てコンパイルしなおす必要がなくなり、時間短縮になります。

次に「make run」コマンドを実行してください。

make run

このようにqemuを起動してくれます。

ちなみにですが、「make run」の実行には「main.efi」が必要とmakefileで記述しましたが、「make main.efi」でmain.efiを作成しないで「make run」だけを実行してもエラー無くqemuが起動します。

これもmakeの賢い機能の一つで、makefile内に[必要なもの]の作り方が書かれていたら、[必要なもの]が無くても自動で作成してくれます。

このように今後はmakeコマンドを使ってコンパイル等をしていきます。

実機で動かしてみる

勿論ですが、このプログラムはPC実機で動かせます。
というか、動かなかったらOSじゃないです(汗

ということで、実際に動かしてみましょう。
UEFI対応のOSを作っているため、実行にはUEFI対応のPCが必要です。
UEFI対応かどうかはWindowsの場合、Win+Rで「msinfo」と入力しエンター、「BIOS モード」の欄を見ればわかります。
最近のPCはUEFIに対応している可能性が高いです。

USBメモリを使うので、USBメモリを用意してください。
容量は小さくても大丈夫なはずです。

USBを初期化

変なデータが入っていると挙動がおかしくなるかもしれないので、すべて削除します。
USB内にあるファイルはすべてバックアップしておいてください

パーティションを「FAT32」としてフォーマットします。

Linuxの人はGParted等を使ってフォーマットするとかんたんです。

Windows10のみ : USBメモリをWSLに認識してもらう

USBメモリ内のデータとリンクさせるフォルダを作成します。

sudo mkdir /mnt/usb

USBメモリとフォルダをリンクさせます
(G:はWindows上で認識されているUSBメモリのドライブレターを指定してください A:など)

 sudo mount -t drvfs G: /mnt/usb

これで/mnt/usbフォルダがUSBメモリ内のデータとリンクされました。

/mnt/usb内のデータをいじくれば、USBメモリのデータも弄られます。

このmountコマンドは実機でOSをプログラムを動かす際、WSLを閉じるごとに実行してください。

ファイルをコピーする

UEFIではBIOSと違って第一パーティション(FAT32)にある特定のディレクトリにあるefiファイルから開始します。
なので、特定のディレクトリにefiファイルをコピーします。

毎回入力するのも面倒なので、makefileにファイルをコピーするコマンドを書いてしまいましょう!
下の項目をmakefileの最後に追加してください。

install: main.efi
	mv $< root/EFI/BOOT/BOOTX64.EFI
	cp -r root/* /mnt/usb/

Linuxの人は以下のように書いて下さい。
ドライブ名はUSBメモリを指しさときに自動でマウントされるので、プロパティを表示すればわかると思います。

install: main.efi
	mv $< root/EFI/BOOT/BOOTX64.EFI
	cp -r root/* /media/[ドライブ名]

そしたら「make install」コマンドを実行してください。
するとUSBメモリにEFIフォルダがコピーされます。

USBメモリから起動する

では、実際に起動してみましょう!!

UEFI(BIOS)の設定を開いて、USBメモリの起動優先順位を一番高くします。
設定方法はメーカーによって違うのでググってください。

また、SecureBootをオフにしてください。
悪意のあるブートローダーなどを排除するための仕組みなのですが、今回作ったBOOTX64.EFIは署名をしていないので、安全であることを証明できず、起動に失敗します。
筆者はこのせいで数時間無駄にしました…

起動すると、こんな感じに表示されるはずです。
(※環境によっては文字の位置が違う可能性があります)

もし普通にWindows等が起動したら、どこかの設定が間違っています。

まとめ

今回はVSCodeのインスト―ル、実機で動かす方法を学びました。
次回は今回できなかったコードの解説をしていきたいと思います。

コメント

タイトルとURLをコピーしました