借り初めのひみつきち

仮ブログです。

my new gear...

前回の日記でお察しかと思いますが、さいきん Rust + UEFI で OS がどのくらい作れるのか検証していました。

TL; DR

結論から言うとマルチスレッドが動く程度までは動いて、今後も継続して開発していこうと思います。💪(๑╹ω╹💪๑ )

Rust で OS

Rust 特有の苦労した点はスレッドの所有権周りで、よくわからないタイミングでスレッドが解放されてしまうバグに若干悩まされました。 最終的にはスレッドプールがスレッドを所有し、スケジューラーは一時的に借用する形で落ち着きました。

とはいえ、おかしなコードを書こうとするとだいたい叱ってくれるので Rust は優しいかな、と思います。

じんせいはロックフリー

Rust 固有の問題ではないところでとてもハマっていて、ロックフリーのキューを作るのに苦労しました。 当初は以前 C で作ってなんとなく動いていたものを移植したのですが、考慮漏れでデータ破壊が起きることが発覚し、 その後リストで実装し直したものも安定してるとは言えない状態です。

SMP のスケジューラのキューは複数のプロセッサから同時に読み書きされるためロックフリーで実現するのはかなり要求仕様が厳しく、 ロックフリーキューを何度か作り直して結局安定させることができませんでした。

しかし、実は同じコア内ではデータ競合が決して起こらないので、ロックしてしまえば簡単に実装できます。当面はロックするバージョンを使おうと思います。

Rust で UEFI + ACPI

uefi-rs はとりあえず Rust で UEFI プログラミングするには便利ですが、中にはちゃんと対応してない API もあります。 今のところ致命的な問題にはぶつかっていないですが、 MP protocol が non-blocking mode で使えないのがちょっと気になりました。 そもそも MP protocol のちゃんとした仕様が手に入らず SMP の初期化に使っていいのかどうかも怪しかったので、 SMP の初期化には以前書いた IPI を使ってリアルモードから起動する方法をベースに作ることにしました。

同じところで提供されている ACPI ライブラリの対応は深刻で、 FADT の内容がパース後のオブジェクトからほとんど参照できず、テーブルの自由な検索などもできず、したがって BGRT を表示するような使い方もできず、 AML パーサーは qemu でいくつかのメソッド呼び出しは成功したものの実機ではエラーでうまくパースできないという状況で、ちょっと実用に耐えないかなと思います。 いまどきの PC の OS では ACPI が必須で、とりあえず簡単に動かすためにこのライブラリを使いましたが、今後別のライブラリの導入を検討したり自作する必要がありそうです。

まとめ

そんな感じでいろいろ勉強しながら、マルチタスクでキーボードやマウスの入力ができる程度の完成度になりました。

f:id:neriring16:20200616225253p:plain

単体のプロジェクトとして名前も決まってないし当面は練習や勉強がメインになるのでレポジトリの宣伝はしません。 もう少し形になってきたら、以前作りかけた例の OS の後継としてリリースすることになりそうな気がします。