ゼロからのOS自作入門で引っかかる人がいるかもしれないこと

こんにちは~
ゼロからのOS自作入門、通称みかん本?を読んでいるひとしか
このブログを見ていないとは思いますが。
私はまだ矩形描くあたりまでしか進んでません。頑張ります。

 

本が出るもーちょっと前から、UEFI起動の自作OSを作っています。MikanOSはまさにその参考となり、みかん本は私を導くマニュアルです。0から1(pdfから実装)は嫌いですが1から2(実装や誰かがまとめてくれたマニュアルから自分でアレンジしたりする)は得意目なのです。
はい。自分語りが過ぎました。そんなもののために来ているわけではないはずですので。

そんなこんなで見つけた、タイトルの"引っかかりそうな問題"を解説していきます。
その問題は、カーネル呼び出し時に引数をちゃんと受け取れない、というバグです。写経していては起きません。ここ大事です。

あくまでg++で実装してみた!みたいな人に起きる可能性のあるバグです。

 

注:ぶっちゃけMikanOSのコードを流用しているからと人の目につきやすいタイトルにしてます。必要な情報がなかった場合、本当にごめんなさい。

 

解決法を答えてしまうと、-mabi=sysvというオプションをつけようってことです。

 

はい。これだけです。これだけのためにgdgdとごめんなさい。どうしてもうまくまとまらなかったのです。

さて、理由を説明します。長いので、結論を知りたかった方は上を見て実行してください。


typedef void EntryPointType(UINT64, UINT64);

EntryPointType* entry_point = (EntryPointType*)entry_addr;

entry_point(gop->Mode->FrameBufferBase, gop->Mode->FrameBufferSize);

ここの部分でカーネルを呼び出して、

extern "C" void KernelMain(uint64_t frame_buffer_base,uint64_t frame_buffer_size) {

ここで引数を受け取っているのは理解している前提です。
なぜ?ってなった人は本を読み返しましょう。
しかし、qemuのinfoで確認すると、引数がおかしくなっていることがあります。具体的にわかる例としてはframe_buffer_baseを使っているのに描画ができていないなどでしょうか。

 

MikanOSでは、EDKII(UEFIで起動するブートローダーを作るのに使うもの)もカーネルもclangを使っています。(EDKIIのほうはConf/target.txtにCLANGって書いてあります。)
私の環境では、両方ともgccですが、片方でしか上のオプション(-mabi)を使っていませんでした。その結果、ABIがそれぞれで違い、うまく与えられたデータを扱えなかったわけです。
例えると、数字を求められているのに文字列を渡されたようなもの(?)です。
ABIのわかりやすい解説は、みかん本の101ページにあります)
みかん本ではSystem V AMD64 ABIを使っているので、そのABIに対応させているのが上のオプションです。


はい。全然うまく伝わっていない気がしますが、私の説明力の限界でした。脳内OCしてこれです。
こんなひどい文章ですが、最後まで読んでくださった方、ありがとうございます。

(このブログ1400文字以上あるんだなぁって)