各物理メモリページはどれか一つだけのプロセスが所持しています。Reseaでは共有メモリを実装できません。意地でもメッセージパッシングします。システムコールReseaはメッセージパッシングしか出来ない美しいシステムコール体系をもっています。notification);notificationの送信。Unixのシグナルみたいなやつ。ドキュメントを読んでください。実装(カーネル)「Rustで書かれたカーネル」という謳い文句にはとても惹かれるものがあります。当初はカーネルをRustで書いていましたが途中で辞めました。いうのも,Rustはマイクロカーネルを書くのには向いていない気がするのです。操作の塊であり,普通にRustで書いても単に複雑になるだけ。抽象化によって処理が隠れてしまう。いう処理を行うのか明示的にしたい。RAIIをしたくない。メモリ割り当ての失敗もpanicせずエラーとして伝搬したい。抽象化がないと辛いと感じるほど,マイクロカーネルは大きくないし複雑でもない。ここで強調しておきたいのはRustという言語に問題があるという話ではなく,使い方の問題であるということです。「いつも」の使い方では上手くいかないということです。いうわけで,ユーザランドは全てRustですがカーネルはC言語で書くことにしました。C言語は機能も標準ライブラリも今どきの言語に比べて貧弱ですが,マイクロカーネルのようなベアメタルで動く小さなプログラムを書くには今もなお(多分いつまでも)最適な言語です。結局,カーネルは5回くらい書き直しました。得られた知見はみんなこの論文にまとまってありました。先人はやはり偉大ですね。実装(ユーザランド)メモリ管理サーバ,TCP/IP,FAT32ファイルシステム,IDE(ハードディスク)ドライバ,e1000(ネットワークカード)ドライバ,キーボードドライバ,シェルを実装しました。それぞれ独立したユーザプロセスとして動きます。ユーザランドはRustで実装することで,C言語でよくある厄介なバグに悩まされることがなくなりました。適当に書いてもしっかり動いてくれます。カーネルはよく逆アセンブリを読みながら厄介なバグを直していましたが,Rustで書いたユーザランドは全くその必要がありませんでした。書いている人間は同じなのに言語が違うだけでここまで変わるというのはすごいです。Cに比べフットプリントやビルド時間が増加するデメリットはありますが,その代償を払う価値は十分あると感じました。さくらのクラウドで元気に動いている様子(再掲)ようやく目標の「作ったOSのHTTPサーバをIaaSで動かす」です。今回はさくらのクラウドを使いました。virtio-netではなくe1000を選べるという非常に魅力的な機能と,課金体系と設定が分かりやすくポンコツTCP/IP実装が暴走してもクラウド破産しにくいという面から選びました。KVMのはずなのでそのまま動くだろうと楽観視していましたが,現実は厳しいものでした。飛び交うARPパケットでメモリを使い果たしたり(実装が悪い),何も表示せずカーネルパニックを起こしていたりと,手元の環境では再現しないバグに立ち向かう日々を送る羽目になりました。おかげで勘デバッグ能力が上がりました。それはそうと,さくらのクラウドで一つ不思議な挙動がありました。DISCOVERを返信してもらえないのです。後ほど再送すると返信してもらえます。ぽんこつe1000デバイスドライバが原因なのか起動が速すぎるのが原因なのか分かりませんが,後者だったら面白いですね。運が良ければReseaがWebページを返してくれます。fastpathマイクロカーネルのメッセージパッシングには「よくあるケース」があります。クライアントプロセスは,リクエストをサーバプロセスに「送信」してレスポンスを「受信」するという送受信(call)操作がメインです。メッセージの内容にページやチャネルはあまり使われず,大抵は普通のデータ(整数型一つとか)だけ入っています。宛先チャネルでは大抵スレッドが既に受信状態で待っています。fastpath)を加えることで,性能向上を図るというのがマイクロカーネルで見られます。面白そうなのでReseaにも実装してみました。IPCを測ってみました。空のメッセージを送って空のメッセージを受け取るまでの処理にかかるCPUサイクル数を測るものです。みたいなもので,システム全体の性能は全く別の話です。3.4GHzReseaの結果は上の表の通りになりました。fastpathだとまあまあ早くなるみたいですが,seL4の方が速いですね。Fuchsia(Zircon)には勝っているようなので第2世代マイクロカーネルを名乗れる性能はあるのではないでしょうか。fastpathの実装はここにあります。しているのでお気に入りです。シンプルに実装できているのにベンチマークに負けているのは納得いかないですが,たぶんReseaの方はキャッシュメモリを上手く使えていないのでしょう。CPUエミュレータです。QEMUやVirtualBoxみたいなやつです。遅いので普段はQEMUを使いますが,例外処理やコンテキストスイッチといったカーネルのコアの実装をする時には手放せないエミュレータです。いう何もしない命令をブレークポイントとして認識してくれるので,デバッグしたい部分にこの命令を置いて,そこからステップ実行しながら処理を追っていく...​ということをよくやりました。Wiresharkで見るメッセージパッシングWiresharkはTCP/IPのパケットキャプチャを読むやつとして有名ですが,BluetoothやUSBといったものまで扱える汎用プロトコルアナライザーです。何にでも対応が可能です。そこで,Reseaのメッセージパッシング用プラグインを書いて使っていました。当初は頑張ってカーネルログを読んでいましたが,Wiresharkのおかげでましになりました。色分けされているだけでも分かりやすさが段違いですね。.stack_sizesカーネル開発の中で一番苦しんだバグが「カーネルスタックを使い切りスタックの先にあるスレッド構造体を部分的に破壊し,全く別のところでありえない動作を引き起こす」というバグでした。「何もしてないのに壊れた」状態でした。スタックは程よく余裕のあるサイズを割り当てたり,使い切ったらページフォルトが起きるようにしたりするものでしょうが,Reseaカーネルでは実装をできるだけシンプルにするためにケチって1ページ分(4KiB)しか割り当てないのです。)したりすることでスタックを使い切るバグに気づけるようになりました。Sanitizers基本的にカーネルは何でもできるので,おかしい動作をしてもそのまま実行されてしまいます。Cで書くとなおさら色んなバグが隠れてしまいます。そこで,未定義動作やdouble-freeのようなメモリ関連のバグを実行時に検出してくれるSanitizerというコンパイラの機能を使っていました。何度も気づきにくいバグを教えてくれました。まとめ初めてHTTPサーバがさくらのクラウドで動いた時には筆舌に尽くしがたい感動がありました。作ったOSがインターネットの一員になったのです。行数は空行やコメント行を含めて,カーネルが約5000行(コア部分は3000行),そしてユーザランドが約4500行になりました。Unix互換性を提供しないことで,MINIXよりシンプルかつコンパクトで読みやすい物ができたと思っています。自作キーボード」をやってみたいですね。