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

ゼロからオペレーティングシステムのカーネルを書く

概要

  • RISC-V向けに最小限のタイムシェアリングOSカーネルのPoCをZigで実装した事例紹介
  • 低レベルなシステムソフトウェアやドライバ、システムコールの基礎理解を目的とした内容
  • Unikernel構成・OpenSBIを利用したSBI層・スレッド仮想化の実装手法を解説
  • スタックとレジスタの保護、割り込みによるスレッド切り替えなどの実装詳細
  • 学生やシステムソフトウェア学習者に有用な、現代的RISC-Vアーキテクチャへの実践的アプローチ

RISC-V向け最小タイムシェアリングOSカーネルPoCの実装

  • GitHubリポジトリ で最終コードを公開、記事中でもコードを参照
  • ターゲット読者 はシステムソフトウェアやコンピュータアーキテクチャを学ぶ学生やエンジニア
  • モダンなRISC-Vアーキテクチャ とZig言語による実装実験
    • Zigはセットアップが容易で再現性が高い利点
  • 従来のC言語 ではなく Zig を採用し、クロスコンパイルや環境構築の手間を削減

推奨事前知識・参考文献

  • レジスタ・メモリアドレス・割り込み などの基本アーキテクチャ知識
  • 推奨参考文献
    • Bare metal programming on RISC-V
    • RISC-V boot process with SBI
    • RISC-V interrupts with a timer example
    • (オプション) Making a micro Linux distro

Unikernelアプローチ

  • Unikernel とは、アプリケーションコードとOSカーネルを一体化した単一バイナリ構成
    • ユーザコードを実行時に個別ロード不要
    • リンカやローダの複雑さを回避

SBI層と権限モード

  • RISC-Vの権限モード
    • M-mode: フルアクセスのベアメタル
    • S-mode: OSカーネルが動作
    • U-mode: アプリケーションコードが動作
  • OpenSBI を利用し、コンソール出力やタイマ制御を実現
    • SBI層を使うことで移植性向上

カーネルの目標

  • スレッドの静的定義 (実行前に固定、動的生成なし)
  • スレッドは無限ループ関数 として実装
  • ユーザモードスレッド がSモードカーネルにシステムコール可能
  • タイムスライス方式 でスレッド切り替え
  • シングルコア マシンを対象

スレッドと仮想化の基礎

  • スレッド とは、単一コアで複数ワークロードを同時に動かすための抽象
  • 協調型スケジューリング (YIELDを明示的に呼ぶ)と タイムシェアリング (割り込みで自動切り替え)の違い
  • 仮想化 :各スレッドが独自のコアを持つような錯覚を実現
    • 各スレッドは独自の アーキテクチャレジスタ (x0-x31, CSR等)と スタック を持つ

スタック・メモリ仮想化

  • スレッドごとに独立したスタック を割り当て
  • メモリは基本的に共有だが、スレッド/プロセス/コンテナ/VMのように仮想化レベルを選択可能
    • Linuxカーネルも“コンテナ”という明示的構造は持たず、chrootやcgroups等の仕組みを組み合わせて実現

スレッド仮想化の実装方針

  • レジスタの保護 :他スレッドからの不正アクセス防止
  • 独立スタック :関数呼び出し時の局所変数・戻りアドレス保持
  • プログラミングモデル はほぼ変更不要

割り込みコンテキストとタイムシェアリング

  • 割り込みハンドラ によりスレッド切り替えを実現
  • 割り込みハンドラのプロローグ/エピローグで レジスタ保存/復元 を実装
    • 例:RISC-V Sモードタイマ割り込みルーチン
  • 割り込みは“システム効果で呼ばれる関数”として捉え、 利用レジスタをスタックに退避 し、終了時に復元

この後の実装詳細(アセンブリスタートアップ、I/Oドライバ、S-modeハンドラ、ユーザ空間スレッドなど)は、GitHubリポジトリのコード参照を推奨。 本記事では RISC-Vの低レベルOSカーネル構築の基礎概念と設計方針 を重点的に解説。

Hackerたちの意見

こういうプロジェクトは本当にすごいと思う。Linuxって結局カーネルだけなんだよね。それでも、その作業があったからこそ、オープンソースのUnixが何十億台ものマシンにインストールされる道が開けたんだ。素晴らしいことだよね!

スタールマンがCコンパイラやUnixユーティリティを1984年に書き始めたことも、オープンソースのUnixが何十億台ものマシンにインストールされる道を開いたと言えるよね。

最初のLinuxリリースメールでトーバルズが「ただの趣味で、gnuのように大きくてプロフェッショナルにはならない」って言ってたことを思い出すと、さらに面白くて笑えるよね。https://groups.google.com/g/comp.os.minix/c/dlNtH7RRrGA/m/Sw...

この手のプロジェクトは本当にすごいと思うけど、そこまでとは思わないな。最小限のマルチタスクカーネルを書く方法なんて、何十年も前に確立されてるし。カーネルを書いて、いくつかのことができるようにするのは、ちょっと頭を使って根気があればできることだよね。RISC-Vでやるのはx86に比べてちょっと難しくなるけど、ハードウェアの初期化に関する情報は結構簡単に手に入るし(例えば: https://wiki.osdev.org/RISC-V_Meaty_Skeleton_with_QEMU_virt_... このプロジェクトがそれを使ったかは知らないけど)。著者も同意してると思うよ、だって「これは大学のオペレーティングシステムの授業でやった演習のやり直しです」って書いてるし。これは作業だし、いい仕事かもしれないけど、ソフトウェア工学の学位を持ってる人なら誰でもできると思う。確かにOSにはバグがあるだろうし、粗い部分もあるだろうけど、プロセス同士をMMUで遮断してマルチプロセスできるものを作るのは、もうそんなに難しくないよ。

ZigはOS開発に向いてるよね。RISC-Vも同じく。俺は最初にx86で同じことをやり始めたんだけど、必要なレガシーのボイラープレートにすぐイライラしちゃった。RISC-Vにはそれがないから、すぐに立ち上げられるんだ。これが俺のダメなZigだよ: https://github.com/Fingel/aeros-v

x86で最初に。必要なレガシーのボイラープレートにすぐイライラしちゃった。俺の意見では、合理的なブートローダーを使えば、そんなにボイラープレートは必要ないよ。マルチブートローダーはリアルモードで起動するけど、ほとんどの人はプロテクトモードにいたいから、テーブルを設定してジャンプする必要がある。でも、それほど多くのボイラープレートじゃないよ。レガシーの割り込みコントローラーを無効にすると、もう少し手間がかかるけど(多分それをしたいだろうし)、普通のPCで動かせる可能性があるならそれだけの価値はあると思うよ(コンソールインターフェースについての注意点もあるけど…俺の趣味のOSはBIOSブートが必要で、サポートがあまり良くないVGAのことを使ってる…シリアルコンソールは簡単だけど、たくさんのコンピュータにはシリアルポートがないしね)。

これに挑戦してみたいな。RISC-Vカーネルを動かすのに何を使ってるの?Qemuだけ?それとも実際のハードウェアをおすすめできる?

自然に、これは基本的にObject PascalやModula-2の安全性を再考して、それをCの構文に詰め直してる感じだね。C自体は特別なものではなかったけど、UNIXのライセンスのおかげで広く使われてたからね。

低コストのRISCハードウェアってどうやって手に入れるの?

AliexpressにMilk-V Duo Sっていう10ドルのボードがあるんだ。たまにおすすめに出てくる。面白そうだよ。https://aliexpress.com/w/wholesale-Milk%2525252dV-Duo-S.html 説明から直接引用すると: > Milk-V Duo Sは、512MBのRAMと拡張されたIO機能を持つSG2000マスターを搭載したDuoのアップグレードモデルです。 > Onboard WI-FI6/BT5(モデルMilk-V-Duo-S-512M-Basic/Milk-V-Duo-S-512M-eMMCにはこの機能はありません) > USB 2.0 HOSTポート > 100 Mbpsのイーサネットポート(PoEサポートあり) > デュアルMIPI CSIとISP > デバイスはスイッチを使ってRISC-VとARMのブートを切り替えることもサポートしています。

今では数十種類のボードがあると思うけど、俺が面白いと思って支援したのはこれだよ: https://www.kickstarter.com/projects/starfive/visionfive-2-l... 自分は初版のVisionFive2を持ってないけど、いい話を聞いたし、エコシステムも成長してるみたい。まだ粗い部分もあるけど、早く出荷されるといいな(商標)。今、俺が個人プロジェクト用に持ってるのはPolarFire SoC Discovery Kit。これはFPGAが埋め込まれたクアッドコアのRISC-Vシステムだよ。ちょっと高いし、誰にでも向いてるわけじゃないけど(130ドル、面白いことに、開発ボードの方がチップ自体より安い)。https://www.microchip.com/en-us/development-tool/MPFS-DISCO-... それに、マイクロチップのドキュメントやツールチェーンは本当に古臭くて使いづらいけど、慣れればそんなに悪くないし、実際にベアメタルのRISC-Vコードを動かすのは簡単だよ。Linuxやベアメタル用の簡単な例もあるし。

まずはx86やAppleでエミュレーターを動かしてみたら?実際のハードウェアより速いと思うし、カーネルの開発も絶対早く進むよ。https://www.qemu.org/docs/master/system/target-riscv.html

これにはRISC-Vが搭載されてるよ。https://www.raspberrypi.com/products/raspberry-pi-pico-2/

現在のIPアドレスへのアクセスは、2024年12月18日の判決に基づき、バルセロナの商業裁判所第6部によってブロックされています。この判決は、プロフェッショナルサッカーリーグとTelefónica Audiovisual Digital, S.L.U.が提起した通常手続きの一環です。 > https://www.laliga.com/noticias/nota-informativa-en-relacion... なんでこんなことに…httpを使うのとこれは別の話だよね…

...え?スペインのサッカー団体が国全体のインターネットアクセスを制限できるの?

スペインでCloudflare(他にもかもしれないけど)が間違ってブロックされてるって聞いたよ。サッカーのストリーミングサイトに関連してるかららしいけど。みんなこの問題をどうやって回避してるんだろう、VPNかな?間違ってブロックされたIPの中には、仕事で必要なものもあるだろうし。

著者が別に投稿したもの: https://news.ycombinator.com/item?id=45236479 彼らのコメントをここにコピーするね: 小さなOSカーネルを書いて、ユーザースレッドを管理する古典的な演習をやり直しました。私の目標は、特にRISC-V + OpenSBIで実験することでした。さらに、Zigを少し探求したかったので、伝統的なCの代わりにその言語を使いましたが、CやRustで同じ実験をするのは簡単だと思います。確かにまだ粗い部分が多いですが、これは実験的なもので、OSカーネル開発やコンピュータアーキテクチャを学ぶためのステップ0を踏む人たちへの入門です。それでも、週末に遊ぶには楽しい実験的なものだと思います!完全なウォークスルーとGitHubのリンクは、投稿されたリンクで確認できます!

同じような作業を「パッケージ化」された体験でやりたい人には、「1000行のコードで作るオペレーティングシステム」(https://operating-system-in-1000-lines.vercel.app/en/)があるよ。昔Zigでやったことがあって(CのコードスニペットをZigに翻訳する感じ)、楽しかったよ。コードとVODはここにあるよ: https://github.com/kristoff-it/kristos/

いつも楽しくて面白いことだよね。自分の暗号技術に挑戦してみるのもいいよ。「自分で暗号を作るな」ってアドバイスは、テストされてないものをデプロイするなって意味だから、そこは注意が必要だよ。大きなミスをしやすい分野だからね。いつでも実験して探求することを楽しんでほしい。もっとオペレーティングシステムが必要だし、選択肢も増やしたいよ。

いいね!RISC-V ISAがこんなにアクセスしやすいのが大好きだよ。ドキュメントも素晴らしいし、例もたくさんあるし、エミュレーターもいっぱいある。非圧縮の機械コードもかなり読みやすいしね。娘のために本を書いてるんだけど、Forthとタイムシェアリングで小さなOSも作ってるんだ。https://punkx.org/projekt0/book/part1/os.html x86ではできなかったと思うし、ForthとRISC-Vアセンブリを学びながら進めてるのがすごく楽しいよ。正直、もしおもちゃのOSをゼロから作りたいなら、今が一番いいタイミングだと思う(1980年を除いてね)。安いRISC-VのRP2350を手に入れて、ドキュメントの関連部分をClaudeにアップロードすれば、詰まったときに助けてくれるよ。

自分の国の価格をチェックしたら、これがこんなに安いなんて驚いたよ。90%の確率で、ちょっと遊ぶために買っちゃうと思う。