初心者がフルスクラッチ自作OSに挑戦し始めた話

この記事は自作OS Advent calendar2021 15日目の記事として書かれています。 Covid-19関連で在宅期間が増えたのを良い機会だと思い自作OSを始めた超初心者で、昨年ははりぼてOSの写経を行いました。その約1年後にみかん本が発売されたのが個人的にはとてもいいタイミングで、今度は少しでもオリジナリティを持って取り組もうと考えており、みかん本の流れを参考にしてフルスクラッチでOSを自作し始めました。「UEFI is 何?」みたいな状況から始めたので調べ物の時間が非常に長くなったこともあり、実装できたものはそこまで多くはなりませんでしたが、今年開発を進めてきた中で躓いたことなどを振り返りたいと思います。

UEFI Specificationを読む

まずは画面をクリアしてメッセージを表示するだけのプログラムを書いてUEFIアプリケーションの書き方を学ぼうとしていました。そこで早速UEFIAPIを叩く際の構造体の作成に躓きます。仕様書をちゃんと読めていなかっただけなのですが、ClearScreenとOutputString以外の使っていない関数の分をバッファで確保するのを忘れていました。ただ、これをクリアしたことでUEFI Specificationの読み方やどこに何が書いてあるのかなどが分かってきました。

エラーメッセージを出力する

次に、前述のメッセージの出力に失敗している時に何もエラーメッセージが出ないことを不便に感じて、せめてstatusの値からどのエラーが発生しているのかを出力するサブルーチンを書きました(メッセージが表示すらできない状態では意味のないサブルーチンなので、メッセージ出力でウンウン唸っているときは結局仕様書をよく読む以外に解決策はなかったわけですが...)。とはいえこれがあることでこの後UEFIAPIを叩く上で助けにはなりました。

謎の関数が無いぞと怒られた

その次はメモリマップの取得やカーネルファイルを読み込む部分を作っているときに躓きます。これは今も根本的に解決できているわけではないのですが、コンパイル時に以下のメッセージが出ました。コンパイラはclangを使いました。

clang -target x86_64-pc-win32-coff \
      -fno-stack-protector -fshort-wchar \
      -nostdlibinc\
      -mno-red-zone -Wall\
      -c main.c
lld-link -subsystem:efi_application -nodefaultlib -dll\
         -entry:EfiMain -out:main.efi main.o
lld-link: error: undefined symbol: __chkstk
>>> referenced by main.o:(EfiMain)

名前的にローカル変数のサイズをチェックしてくる関数であることは察しがつきましたが、調べていくとwindows向けのバイナリを吐くときにコンパイラが挿入してくる関数で、ローカル変数のサイズが4kを超える時(64bitの場合は8kを超える時)に呼ばれるようです。グローバル変数にして回避できる部分は回避しましたが、カーネルファイルを読み出すときに使用するEFI_FILE_PROTOCOL内のGetInfo関数を使用する際はこの関数を呼び出すだけでアウトでした。コンパイラのことなのでgccでもコンパイルして試してみましたが、この場合は「undefined reference to `___chkstk_ms'」と怒られました。

この関数に与えている引数の容量的には4kバイトも無いと思うのですが...。結局、これを無効化する術もないとの記述を見てしまいました。問題が生じる場面もありそうですし、そのうちまともな対処が強制されるかなと思って一旦は以下のようなダミー関数をつくって放っていました。

void __chkstk(){}

が、ふと「EDK IIではどうしているんだろう?」と思って「edkII chkstk(検索)」で一番上に出てきたリポジトリ

github.com

を見てみました。ダミー関数ですね。コメントにも「Hack function for passing GCC build」とあります。そういうことなら遠慮なくダミー関数を作らせてもらいます。

こうしてカーネルファイルを読んで何もしないカーネルを起動するところまでを書いたのが今年の進捗でした。今年は時間が取れなかったので、来年はもっと個人開発の時間を取りたいです。自作OS自体は個人的サグラダファミリアになりそうなので焦らず楽しみたいですね。

おわりに

みかん本は、今取り組んでいる場所よりも先の方まで読むと「早くこういうの実装していきたいな」とモチベアップになるのでことあるごとに読んでいます。時折挟まれるコラムも興味深いですし、冒頭にも書きましたが私ははりぼてOSを写経したばかりで「今度はUEFI使った方法とか、開発環境も一般に出回っているやつで構築してやってみたいな」という思いがあったため、ドンピシャのタイミングでした。ありがたい限りです。

あまり何も書けていない気もしますがこれで終わりになります。ご覧いただきありがとうございました。