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

ゼロからオペレーティングシステムを作る方法

概要

os-tutorial は古く、設計や技術面で課題があるプロジェクト。 OS開発の基礎を短時間で学びたい人向けの実践的なチュートリアル。 理論よりも実践重視で、各レッスンは5~15分で完了可能。 順番に進めることで、OSの基礎から応用まで段階的に学習可能。 貢献やフォークも歓迎されているが、公式メンテナンスは停止中。

os-tutorialの概要

  • os-tutorial は古く、現在は メンテナンスされていない プロジェクト
    • 技術的・設計的な課題点が README に明記
  • OS開発を ゼロから始める ためのチュートリアル
    • 既存カーネルの読解ではなく、 自作のブートセクタ から開始
  • OSDev wiki や他のドキュメントに触発された構成
    • 理論よりも 実装重視 のアプローチ

特徴

  • 低レベルプログラミング に興味がある人向け
    • Linuxカーネル全体を読む時間がない人に最適
  • 理論説明は最小限、必要な理論は自分で調査
    • 理論の過剰な説明は学習の妨げになるという思想
  • 各レッスンは 5~15分で完了 できる設計
    • 小さなステップで着実に進行

チュートリアルの進め方

  • 最初のフォルダから順番に 進めることを推奨
    • 前のレッスンのコードに依存するため、順序を守る必要
  • 各READMEの 最初の行 で前提知識を確認
  • 2行目 で各レッスンの目標を把握
  • README全体 を読んだ後、コード例を参照
    • コードは 詳細なコメント付き
  • (任意) コードを自分で書いてみる、または 改変・実験 して理解を深める

進行中・今後の内容

  • 完了済み
    • 独自ブート・32bitモード移行・アセンブリからCへの移行
    • 割り込み処理・画面出力・キーボード入力
    • 小規模なlibcの実装
  • 今後の目標
    • メモリ管理
    • ファイルシステムの作成
    • シンプルなシェル実装
    • ユーザーモード対応
    • (余力があれば) テキストエディタ・プロセス管理・スケジューリング
    • (さらに挑戦的な内容) BASICインタプリタ・GUI・ネットワーク対応

コントリビューションと今後

  • 個人の学習プロジェクト として公開
    • 長期間更新されていないが、今後再開の可能性もあり
  • バグ報告・プルリクエスト に感謝
    • 対応には時間がかかる可能性あり
  • フォークや派生プロジェクト は歓迎
    • メインとなるフォークがあればREADMEからリンク予定

参考資料

  • the little book about OS development
  • JamesM's kernel development tutorials
  • OSDev wiki

Hackerたちの意見

著者はこれを古いと切り捨ててるけど、これは見た中で最もわかりやすい例の一つだね。少なくとも00と01を読むのは。

こちらも見てみてね: https://wiki.osdev.org/Getting_Started

readmeから: > 大学は大変だから、ほとんどのことを覚えてないんだ。高ストレス環境が知識の定着にどれだけ逆効果かって面白いよね。

関連する話題なんだけど、すごく古いLinuxバージョン、例えばLinux 0.92/0.12を現代のツールチェーンでビルドする試みをした人いる?元のビルドプロセスはgcc 1.4.0とか、現代のシステムでは使えないasみたいなプログラムが必要なんだよね。目標は、現代のgccを使ってLinux 0.12をビルドして、QEMUで動かすか、できれば本物の80386マシンで動かすことなんだ。私の知る限り、現代のgccはこのアーキテクチャをまだサポートしてるから、概念的には可能だと思う。ただ、ソースコードにはかなりの変更が必要になるかもね。アイデアは、現代のシステムで簡単にビルドできる非常に古いLinuxを手に入れて、現代のCサポートを使って徐々に自分のものを追加していくことなんだ。そうすれば、古いツールチェーンに縛られずに済むから。追記: Linux 0.12/0.92を選んだ理由は、1) なんとなく完成度が高い(ネットワークなしだと思うけど)けど、複雑すぎない(locは20K以下だと思う)、2) おもちゃのOSじゃなくて、実際のハードウェア(80386マシン)で動くこと、3) それに関する素晴らしい本があるから: https://download.oldlinux.org/CLK-5.0-WithCover.pdf

YouTubeの"NCommander"は、必要なことを把握したり質問するのに良い出発点になるかも。非常に面白い/クレイジーなアーキオロジーのビルドがあって、1993年の不完全なツールチェーンを使ってWinXP SFUからLinuxをブートストラップするみたいなやつだよね(?)。8)

https://github.com/mariuz/linux-0.01は、いくつかのアイデアを提供してくれるかもしれないよ。

アセンブラのasはまだ使えるよ。

英語版: https://download.oldlinux.org/ECLK-5.0-WithCover.pdf

それと… > こんにちは!これは古い放置されたプロジェクトで、技術的にもデザイン的にも問題があるよ。これを楽しんでみてね。でも、OSデザインについて学びたいなら、もっと現代的で信頼できる情報源を探してみて。

それと、もう少し詳しくコメントしたことがあるよ。90年代にOSをゼロから作る方法を理解するのは大事なんだ。OSが何をするのか、どのハードウェアで動かすのか全く分からない状態でね。実際に使えるOSを作りたいなら、欠けているものがたくさんあって、それが後で大変なことになるよ。こういうことをするのは楽しいけど、これが現代のOSやハードウェアの動き方だと勘違いしない方がいい。

分散アプリを作るたびに、同時処理が増えると、結局OSの仕事をたくさん再発明してることに気づいたんだ。スケジューリングや、いろんなキャッシュ技術、キャッシュに事前に追加するためのヒューリスティックを再構築してる。もっとカーネルデザインについて学ぶべきだな。OSデザインからもっとコンセプトを持ってくれば、分散システムエンジニアとしてももっと良くなれると思う。

…もう少し進むと、OSやアプリが分散データベースみたいに見えてくる。OSにラティスタイプを含めるのはいいケースだと思う。つまり、最初から。OSにはAPIがあることを忘れないでね。つまり、DSLや言語があって、Micropythonがいい例だよ: https://www.neilconway.org/docs/socc2012_bloom_lattices.pdf

OSを作るのは楽しいよ。でも、ドライバーやハードウェアサポートが本当に厄介なんだ。感謝されない苦労で、これがないとどこにも行けない。

何年かにわたっていくつかのベアメタルやホビーOSプロジェクトを作ってきたけど、このチュートリアルシリーズの道はお勧めしないな。OSを書くつもりなら、最初にブートローダーを書くべきじゃない。この記事は基本的にレガシーBIOSファームウェアの上にあるステージ1ブートローダーについて説明してる。OSの概念を理解したいなら、歴史的なx86の細かいことを学ぶのは障害にしかならないよ。むしろ、高水準言語(C、C++、Rust、Zigなど)で書かれたブート可能なELF(マルチブート)やPE(UEFI)イメージをできるだけ早く作るべきだ。QEMUで簡単にブートできるし(ブートセクターイメージと比べて)、実際のデバッガ(gdb)やシステムモニター、他の貴重なツールも使えるようになる。これがプロジェクトの進行速度に大きく影響して、面白いところに早く到達できるから。ベアメタル/OSプロジェクトは書くのが難しいけど、デバッグはもっと難しいから、できるだけ助けを得る必要があるよ。

実用的な観点から見ると、君の言う通りだと思う。16ビットx86コードのデバッグは悪夢だし、どのデバッガもちゃんとサポートしてない。実用性を置いておいて、美的な面に焦点を当てると…普通、こういうホビーの車輪再実装プロジェクトでは、他人のコードを最小限に抑えて、できるだけベアメタルに近い形でやる方が楽しいと思う。でも、私の知る限り、最近のレガシーBIOSブートはUEFIの下で動いているエミュレートされた互換モードに過ぎない。ブートローダーがすでにハードウェアを設定してくれて、その後いくつかの設定を解除して再設定できるようにしている。80年代のPCの役割を演じているだけなんだ。これが深く不満だと思う。UEFIは実質的にベアメタルAPIだよ。(完全にブロブレスで、自分のファームウェアを書くつもりじゃない限り。)

それに関しておすすめのリソースってありますか?HNでそのアプローチを取った記事を見たことがある気がするけど、もうずいぶん前のことだし。小さなOSを作るのに挑戦したいと思ってたんだよね。もしRustがそれを完全にできるなら、試してみようかな。Rustを使ういい口実になるし。

もう一歩進めて、既存のマイクロカーネルから始めるのもいいと思うよ。確かに、自分の「OS」ってわけじゃないけど、マイクロカーネルは本当に小さいから、あんまり気にならないよ。

その通り。ブートローダーを書いたり、32ビットの保護モードに切り替えるコードを書いたりすると、あまり意味がわからないエソテリックな魔法をたくさん見ることになるよね。それを覚えておくのは難しいし。だから、最初はosdevのコードを使って、実際に何が起こっているのかを後でじっくり学ぶのが一番だと思う。

レッスン#3が参照している重要な外部ドキュメントは、今はリンク切れになってる。アーカイブはこちら - ページ14が指摘されてるところだよ: https://web.archive.org/web/20241112015613if_/https://www.cs... でも、メモリオフセットの理由についてのもっと簡潔な説明はこちら: https://stackoverflow.com/a/51996005

自分でゼロからOS(vmwOS)を作って、授業も教えてる者として、x86ベースのOSプロジェクトは結局、40年前のPC/x86レトロコンピューティングの練習になっちゃうって意見には同意するよ。数年前は、ラズベリーパイ用のOSを書く道を勧めてたけど、最近はパイがちょっとおかしくなってるからね。Pi-1B+用のシンプルなOSを書くのは比較的できるけど(簡単だし、そこそこドキュメントもあるし、最大の欠点はキーボードにUSBが必要なこと)。みんながPi4を使いたがるようになってからは大変だった(2023年のCPU不足の時に手に入ったのはそれだけだったから)。ドキュメントが貧弱で、割り込みを扱うのがほぼ不可能になったし、64ビットコアの仮想メモリやキャッシュの設定(少なくとも数年前)は全然ドキュメントが整ってなかった。

もし64ビットARMのSMPにまだ興味があるなら、Pi Zero 2 Wで仮想メモリやキャッシュ、周辺機器に関しては少し成功してるよ。