世界を動かす技術を、日本語で。

Show HN: Munal OS: WASMサンドボックスを備えたグラフィカルな実験用OS

概要

  • Munal OS はRust製の実験的なOSで、unikernel設計とWASMサンドボックスによるセキュリティモデルを特徴
  • 仮想アドレス空間や割り込みを持たず、単一EFIバイナリとして構築される
  • HD解像度のグラフィカルUI、VirtIOドライバ、カスタマイズ可能なUIツールキットを搭載
  • WASMアプリのサンドボックス実行と独自システムコールAPIを実装
  • QEMU上で動作し、ウェブブラウザやテキストエディタなど複数の組み込みアプリを提供

Munal OSの概要

  • Rust製 のフルスクラッチOS、ユニカーネル設計
  • WASMサンドボックス によるアプリケーション分離とセキュリティ
  • HD解像度対応のグラフィカルUI、マウス・キーボード入力対応
  • VirtIO 1.1 準拠のPCIドライバ実装
    • キーボード、マウス、ネットワーク、GPU用VirtIOドライバ
  • カスタマイズ可能なUIツールキット(Uitk) によるウィジェット・レイアウト・テキスト描画
  • 組み込みアプリ :ウェブブラウザ(DNS, HTTPS, 基本的なHTML対応)、テキストエディタ、Pythonターミナル

アーキテクチャと設計思想

  • シンプルなコードベース を追求した実験的設計
  • ブートローダ非依存、単一のEFIバイナリでカーネル・WASMエンジン・アプリを内包
  • 仮想アドレス空間・ページマッピング未実装
    • UEFIのIDマップ空間をそのまま利用
    • メモリ空間は単一、WASMサンドボックスでユーザー/カーネル分離を代用
  • 割り込み・マルチコア未対応、全てポーリングベースのドライバ
  • グローバルイベントループ による逐次処理
    • 各ループでネットワーク・入力・UI描画・WASMアプリ実行・フレームバッファ更新を順次処理
    • 各処理のCPU/フレーム時間計測が容易

ドライバとハードウェア対応

  • PS/2やVGA未対応、VirtIO専用設計
    • QEMUなど仮想環境でのみ動作
  • PCI経由のVirtIOドライバ
    • キーボード、マウス、ネットワーク、GPU用
  • 割り込み未使用、全てポーリング方式

アプリケーション実行モデル

  • wasmi WASMエンジン でWASMアプリをサンドボックス実行
    • カーネルとは独立したメモリ空間を確保
    • 独自の「システムコール」APIでOS機能にアクセス
      • 入力取得、TCPソケット操作、フレームバッファ描画など
    • WASI Preview1 の部分的サポート
      • 必要最小限のみ実装、WASI非互換
  • 協調的スケジューリング (Cooperative Scheduling)
    • 各アプリはイベントループ毎にCPU制御を明示的に返却
    • 長時間処理は明示的なyieldが必要
    • wasmiのfuel limitingで暴走アプリの強制終了も理論上可能(未実装)
  • アプリごとのログストリーム (UNIXのstdout類似)、監査ビューでリソース消費を可視化

UIツールキット(Uitk)

  • 即時モードUIツールキット
    • ボタン、プログレスバー、テキスト編集、スクロールキャンバス等の基本ウィジェット
    • 三角形ラスタライザで3Dデモやラジアルメニューも描画可能
  • グローバルスタイルシート による一括スタイリング、個別要素の上書きも可能
  • タイルキャッシュシステム
    • 変更IDで再描画判定、不要な再描画を回避
    • Rustのミュータビリティルールを活用した自動変更検知

ビルドと実行方法

  • Rust Nightly 2025-06-01、QEMU 10.0.0で動作確認済み
  • 必要コンポーネントの追加
    • rustup target add --toolchain nightly-2025-06-01-x86_64-unknown-linux-gnu wasm32-wasip1
    • rustup component add rust-src --toolchain nightly-2025-06-01-x86_64-unknown-linux-gnu
  • ビルド・実行スクリプト./run.sh
    • WASMアプリ→カーネル→QEMUの順でビルド・実行
    • QEMUコマンド名はqemu-system-x86_64を想定、環境に合わせて修正可能

クレジット・参考資料

  • Philipp Oppermann’s Rust OS tutorial、OSDev Wiki、Wasmi、smoltcp、Rustls、RustPythonなどのOSS
  • フォント・アイコン・壁紙の出典明記

Munal OSの今後と課題

  • 実機対応未実装
    • BIOS/UEFIのPS/2/VGA/GOPやGPU・USBドライバの追加が必要
  • WASMアプリの多言語対応可能
    • Rust以外の言語でもWASMコンパイル対応で実行可能
  • WASI完全互換ではない
    • アプリごとの独自API設計、移植性に制限
  • マルチコア・割り込み・仮想記憶未対応
    • 今後の拡張余地

公式リポジトリhttps://github.com/Askannz/munal-os デモ動画https://streamable.com/5xqjcf 技術詳細 :README参照

Hackerたちの意見

すごいね。これがOSの未来になるのかな。READMEを読むのがめっちゃ面白い。なんでwasmiを使ったの?wasmtimeじゃなくて。実際にこのOSをVMの中で使ってみようかな。自分のリアクティブGUIライブラリをMunalに移植したい気持ちもある。

ありがとう!wasmtimeを使おうとしたけど、no_stdモードでコンパイルするのがめんどくさすぎて、wasmiにしたよ。

これがOSの未来になるのかな。SPECTREとMELTDOWNが登場するね。

これがOSの未来になるのかな。アプリの隔離を仮想化で行うことについて話しているなら、Qubes OSでその未来をかなり前から体験しているよ。そこでの隔離は非常に信頼性が高い。

もちろん、ループの各ステップはCPUを任意の時間保持することができず、長時間のタスクのためには明示的にyieldしなければならないというデメリットがあります。もっと大きなデメリットは、アプリをたくさん開くほど、各アプリが遅くなることだと思います。10個以上開いたことはないけど、30タブ開いたことはあるから、それぞれが別のプロセスだったら、30倍遅くなるんじゃない?全体のコンピュータが十分に速ければそれでいいけど、動画レンダラーみたいな重いプロセスは明らかに遅くなるよね。1秒から30秒に伸びるだけでも。とはいえ、これは全体のOSを動かすための本当に賢いショートカットだと思う。大したもんだし、ワクワクするね!

みんなが時間通りに仕事を終えれば、全然遅くならないはずだよ。実行して、完了して、次のフレームを待つ。もしリソースが制約されてて、その待ち時間が0以下に縮まるなら、確かに全体が遅くなるけど、もっと公平で複雑なスケジューリングシステムよりは少し不格好になるかもね。でも、各プログラムは次のフレームの準備ができたら明示的に譲歩するみたいだから、もしプログラムがあまりやることがなければ、その「時間のシェア」はフリーの不動産みたいなもんだね。

ループの各反復はネットワークと入力ドライバーをポーリングし、デスクトップインターフェースを描画し、各アクティブなWASMアプリケーションの1ステップを実行し、GPUフレームバッファをフラッシュします。これは本当に興味深いね。Wasmiを使ってどう実装したのか気になる。コードはここにあるみたいだよ:https://github.com/Askannz/munal-os/blob/2d3d361f67888cb2fe8... 新しいバージョンのWasmi(v0.45+)では、燃料が切れたときにyieldできるように、再開可能な関数呼び出し機能が拡張されたみたいだよ:https://docs.rs/wasmi/latest/wasmi/struct.TypedFunc.html#met... すでにWasmiの燃料メーターを使っているなら、Wasmアプリをステップで実行するためのより効率的で失敗しにくいアプローチかもしれないね。やり方の例はWasmiのWastランナーにあるよ:https://github.com/wasmi-labs/wasmi/blob/019806547aae542d148...

OPじゃないけど、これがどう役立つのかよくわからない。例えば、彼がこの関数を使って関数からコルーチンを作り始めて、もし関数がメモリ不足で失敗したら、モジュールにもっとメモリを与えてコルーチンを再開できるってこと?それなら、自然に起こることと何が違うの?wasmにはtry/catchがないの?それに、モジュールは失敗した後に手動でバックアップしてmallocを再試行する必要があるんじゃない?全然わからない。

Wasmiを作ってくれてありがとう! :) > 新しいバージョンのWasmi(v0.45+)では、燃料が切れたときにyieldできるように再開可能な関数呼び出し機能が拡張されたみたいだね。 それ、めっちゃ面白い!その機能が実装される前にWasmiのドキュメントで探してたのを覚えてる。もしその機能があったら、WASMアプリのデザインを違うものにしてたかも。

wasmコンポーネントが現実になった後、こういう試みがどんな感じになるのか楽しみだな。ユニカーネルデザインには大きなリスペクトを持ってるし、これは素晴らしい機能が詰まってる。だけど…なんでこんなに重要に感じるのか自分でもわからないけど、wasmが一つの大きなプリコンパイルアプリだけに役立つのではなく、もっと役立ってほしい。今、wasi preview3に向けていろんな作業が進んでいて、同期と非同期のコードが共存できるようにしてる。これが実現すれば、wasmはついにすべての必要な要素を揃えて、あらゆるもののランタイムになれる気がする(ホストオブジェクトのブリッジももっと注目されるといいんだけど、rust web-sysみたいなjsベースのブリッジを超える意図があるのかは不明)。wasmランタイムがもっとダイナミックなサブ環境をホストするために使われることに興味が集まるといいな。一つの素晴らしいプロセスだけでなく、たくさんのプロセスをホストするために。wasmコンポーネントの約束は、標準でポータブル、軽量で、きちんとサンドボックス化されていて、クロスランゲージで構成可能なモジュールを提供すること(下の素晴らしいトークに基づいて)で、もうすぐそこにあるように思えるけど、ユニカーネルのようなアプリケーションで広く使われている現状は、wasmが拡張していくべき分野だと思う。仕様としてではなく(仕様はあるみたい!)、実際に実行可能なものとして、wasmコンポーネントが何に役立つのかを見たい。単なる配布形式ではなく、ランタイムの能力として。コンポーネントとは何か(そしてなぜ) https://youtu.be/y3x4-nQeXxc

SDL3を使ったRustアプリを始めたんだけど、埋め込みV8でスクリプトが書けるようにしてるんだ。でも、wasmtimeやwasmiを埋め込んで、どんな言語でもスクリプトが書けるようにしたくて、アプリにいくつかのwasmコンパイラを組み込んで、ファイルを渡すだけで後は自動でやってくれるようにしたいなと思ってる。主にwasmtimeとwasmiの速度が他の選択肢と比べて優れてるからなんだけど。だけど、一番の懸念は、実際の便利さが増してないことなんだ。結局、全体のコード環境を整えなきゃいけないから、スクリプトを書く意味が薄れてしまう。とはいえ、すごくいいアイデアだから、やらないのはもったいないし、やるかもしれないな。

すごい!これ、独自のウェブブラウザまであるんだ!デモ動画でHacker Newsが動いてるのが見れるよ。

/愚痴モードオン Xerox PARC以来、数年ごとにバイトコードユーザースペースへの新たな試みが出てくるけど、今のところIBM i、ChromeOS、Androidだけが生き残ってるね。主にオーナーたちが「自分のやり方か、さもなくば去れ」って態度を持ってるおかげで、管理者もチームを支えるのに時間がかかっても構わないって感じ。/愚痴モードオフ とにかく、このプロジェクトに幸運を祈るよ、かっこいいね。

ChromeOSはただのブラウザのOSだから、たまたまV8を使ってるだけだよ。Androidは何を使っても成功してたと思う、C++でもね。どちらも成功したのは、技術じゃなくて安さのおかげだね。

君はWebAssemblyに関するスレッドによく登場するね。毎回、バイトコードVMが以前から存在していることを指摘してるのを見かけるけど、それが会話に面白い要素を加えることはないんだよね。敵意を持って言ってるわけじゃないけど、HNのWebAssemblyスレッドを開くたびに君の予測可能で低努力なコメントを見つけるのがイライラしてきた。正直、君のユーザー名を見るたびにコメントを折りたたむようになっちゃったよ。コンセプトの各反復は、以前の試みから学んだ教訓に基づいて異なるアプローチやトレードオフをもたらすんだ。これがエンジニアリングや業界のやり方なんだよね。リスペクトがないわけじゃないし、君は経験から話してるんだろうと思う。基本的なパターン認識よりも、細かいところについて君の考えを聞きたいな。

協調スケジューリングを除けば、Spectreがセキュリティモデルを壊してると思うし、仮想メモリなしで効率的に動くとは思えない。memory.growはどう実装するの?10 kB増やしたいときに、別のアプリが邪魔してたら、アプリ全体のメモリをmemmoveしなきゃいけないの?それって可能なの?それでも、すごく印象的なプロジェクトだね!

詳しく教えてもらえる?

クライアントOSだなんて信じられない!このデザインはサーバーサイドで即座に使えると思う。カーネルを小さくして、実行しているもの以外のライブラリやアプリケーションを排除することで、セキュリティ境界をかなり減らせるからね。例えば、キー/バリューストアはこうやって動かすのにぴったりだと思う。このIOモデルで decentなネットワークパフォーマンスを達成するのは可能なの?ほとんどのプログラムでWASMをホスティングするときに必要なコピーを減らすために、メモリで何かトリックを使える?

ちょっと聞きたいんだけど、「The Birth and Death of Javascript」っていうPycon 2014のトークに影響を受けたことある? https://www.destroyallsoftware.com/talks/the-birth-and-death... そのトークでは、オペレーティングシステムがasm.js(wasmの前身)サンドボックスを仮想メモリ保護の代わりに使う未来の仮定について話してるんだ。あれはすごくクールなアイデアだと思ってたし、君のデザインにも大事な部分みたいだね。

これがMidori、2008年から2015年まで活動していたマイクロソフトの研究用オペレーティングシステムに影響を受けた可能性が高いね。 https://www.siberoloji.com/understanding-microsoft-midori-th...

これは本当にインスピレーションを与えてくれるし、クールだね。頭の中にこういう概念がたくさん浮かんでるけど、必要な能力や実行力が足りなかったんだ。きっと他の人もそうだと思う。誰かがそれを実行しているのを見るのはすごくクールだね。こういう孤立したアプリケーションを持つオペレーティングシステムが、何らかの証明を提供できるのか気になるな。ユーザーに敵対的でない方法でそれを実現するのは可能なのかな?私が夢見るユースケースはオンライン競技ゲームなんだ。大多数のユーザーが公平なコミュニティのためにソフトウェアの自由を犠牲にする状況だよね。コンソールは他のユーザーが公平に参加していることを保証するためのロックダウンされた方法だったけど、チーターが進化するにつれてそれはどんどん少なくなってきてる。これを解決するには、ソフトウェアやハードウェアへのアクセスをロックダウンする必要があると思う。ゲーム理論の観点からは、他のアプローチが見えないんだ。「カーネルレベルのアンチチート」っていうのが出てくるけど、誰に聞くかによってはルートキットとも呼ばれるよね。だから、こういうレベルでの仮想化が、ソフトウェアの自由やユーザーのプライバシー、セキュリティを保ちながら解決策の一部になれるのか、ちょっと気になるな。