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

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

2025年9月15日原文(popovicu.com)

概要

  • 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

Hacker Newsで議論の続きを見る