【ゼロからのOS自作入門】MikanOSをRustに移植する 3章

前回

https://ymzkmtfm.hatenablog.com/entry/2021/03/28/165022

続きです。

https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%81%AEOS%E8%87%AA%E4%BD%9C%E5%85%A5%E9%96%80-%E5%86%85%E7%94%B0-%E5%85%AC%E5%A4%AA/dp/4839975868/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%81%AE&qid=1619090804&sr=8-1

↑の3章をrustに移植しました。 あとサボりすぎて1章進めるうちに1ヵ月経ってました。

成果物

github.com

本物と違う所

kernelにbase addrを設定していない

rust はリンカに ld.lld が指定できるので確実に設定可能です。
ただ設定の仕方がよくわからなかったので諦めました。
(リロケーションや静的リンクに関しては設定できました。)
結果としてバイナリがちょっと複雑になって単純にロードしても動きませんでした。
仕方ないので簡易的な(というよりも中身スカスカの嘘実装な)ELFローダを書いて対処しました。
もっといい方法があれば教えてください。

エラー処理

エラーがあったらメモリにマップされている VGA に出力します。
正常に動いてから作ったので動作未検証です。
(コードは↓から拝借しました)

github.com

なんで VGA なんだよと疑問に思う方もいらっしゃるかもしれません。
rust と uefi-rs の力でエラーがあったら大体しっかり panic() を呼んでくれます。
エラー処理はこの panic() に書いとけばまぁなんとかなるのですが色々あって UEFI の各種機能を呼ぶのは面倒くさいんです。
めんどくさくなった私の結論としてはもう出力してくれるメモリに直接書き込むことにしました。
それでちょうどいいのが VGAだったので今回の実装になっています。

躓いたところ

依存しているライブラリの拡張機能の使い方

Cargo.toml に feature=["exts", "alloc"] と書きましょう。

format! マクロと vec

extern crate alloc しましょう。
ただアロケータが何者でどこからどこまでやってるのかはよくわかってません。
しかもアロケータに関する諸々を実装する必要がありちょっとどうしたらいいか悩みました。
ただ uefi-rs はそこらへんも色々提供してくれてるみたいです。ありがたや。
マクロも自分で実装できるのかもしれませんが私にはよくわかりませんでした。

entry_pointの呼び出し方

最初は「rust で関数生ポインタとか操作できるのかな?」と思っていましたができました。
以下の二つは大変参考になりました。

github.com (180行目)

gitlab.redox-os.org (enter関数内73行目)

感想

・移植するときは使用しているツールも含めて移植可能か検討しておく方がいいかも
・Rust はコンパイラに従ってなんとなく型を直すだけで割と動くので面白い
・安全かどうかわからない unsafe を使いまくると Rust でもしっかりバグる(安全な unsafe は割と大丈夫)
コンパイル通るだけで感動する
・画面塗りつぶすだけで感動する