『ゼロからのOS自作入門』の写経を終えて
4月末から取り組んでいた『ゼロからのOS自作入門』(以下『みかん本』と書きます)の写経が本日終わりました。この本に取り組みながら本当に多くのことを学び、経験したと思います。記念に記録を残したくなったので、このブログ記事を書くことにしました。
1. 読み始めた理由
主な理由が3つありました:
1.1. OSが何をしているのか知りたい
自分は趣味でプログラミングをしているだけの人間ですが、アプリケーションを作っているうちに、道具であるプログラミング言語そのものにも興味を持ち始めました。そこで『Go言語でつくるインタプリタ』や『低レイヤを知りたい人のためのCコンパイラ作成入門』などを勉強していました(後者はまだ勉強途中)。
その過程で、「純粋に言語の世界があるだけでは、実用的なことはできないものなんだなあ」と感じました。何らかのランタイムシステムを通してOSの機能にアクセスできなければ、プログラムを実用的なアプリケーションにすることはできません。OSの偉大さを改めて知ったところで、そのOSについて自分がまったくの無知であることを痛感しました。自分がプログラミングにおいて普段やっていることの全体像をもう少し適切につかむために、OSの仕組みについていろいろ知りたいと思いました。
1.2. C/C++を使った開発を体験したい
かつて挫折したC/C++を再勉強しているところでもありました。幸いなことに、少し前にRustを学んでおり、その勉強の過程で得たポインタやメモリ管理などの知識を逆輸入1して、以前よりはC/C++が理解できるようになっていました。
しかし、より理解を深めるには勉強するだけではなくて実際に使うのが一番です。『みかん本』はC++をバリバリ使っている2ので、題材としてちょうど良いと考えました。
1.3. 自作OSにロマンを感じた
上記の理由は結局のところ背景に過ぎません。直接的な理由はやはりロマンです。
『みかん本』著者の内田公太さん(Twitter: @uchan_nos, 以下uchanさん)の自作OS「MikanOS」をTwitterで初めて見かけたとき、すごく衝撃を覚えました。マウスやキーボードを使ってGUIがグリグリ動くOSを個人で作るなんて、よほどの仕事だと感じました。しかもこのOSを題材にした本が出版されると知り、これはもう買うしかない、という気持ちになりました。
2. 何を得たのか
かれこれ4ヶ月取り組みました。基本的には公式リポジトリのタグを追いかけながらの写経になりました(『みかん本』にも大半のソースコードが掲載されていますが、一部省略されています)。初めは1ヶ月で終わらせる意気込みでやっていましたが、とても体力的に厳しかったので、途中からは安定的に続けられるサイクル(1週間に1日)に落ち着きました。また、Twitterで同じく写経に取り組んでいる人のツイートを見ながら「よーし、自分もやるかー」と気力を高めていました。
そのような自分なりの工夫や環境があった一方で、これだけの期間写経を続けることができたのは、常に『みかん本』から得られるさまざまな知識や体験があったからです。
2.1. 「OSという世界の地理感覚」が得られた
得られたものの中で特に大きかったのは「OSという世界の地理感覚」のようなものです。『みかん本』は、USBホストドライバを除くMikanOSのほぼ全てのソースコードを詳細に解説しています。自分が手を動かして写しているそのコードが何の意図をもって書かれているのか、常に確認しながら写経できるのです。最終的に、読者はMikanOSの全ソースコードについて、どこで何の機能が実装されているのか簡単に振り返られるようになります。
(簡単に、は言い過ぎですね。正直、解説されている内容は多岐に渡り過ぎていて、全容を完全に把握することができる人は一握りだと思います。自分の場合、大雑把な理解のみにとどまった箇所も多いです。ここで言いたかったのは、「自分が理解できる事柄に関して」それがどこで実装されているのかわかる、ということです。)
個人的には以下の点が面白かったです(もちろん、以下の点だけが面白かったということではなく、「特に印象に残ったところ」という意味です)。
- 割り込み処理
- メモリ管理
- 階層ページング
- デマンドページング
- プリエンプティブマルチタスク
- OSのセキュリティ機構
- リングプロテクション
- システムコール
普段使っているOSが裏側でこんなことをやっていたのか、と新鮮な驚きを感じながら進めることができました。それはときには予想以上にシンプルで、ときには予想以上に複雑だったりしました。もともと知っていたなけなしの幾つかのキーワードについて『みかん本』を読む前に漠然と抱いていたイメージが、読後にはまた違った形になっているのに気づくのが楽しいですね。
2.2. ソフトウェアの領域の限界を目撃できた
普段の低レイヤを意識することのないプログラミングでは、何か高度な機能を実装する時に頼るのは何らかのライブラリであったりします。OS開発でももちろんそういうシーンはあるのですが、本当に低レベルな部分で頼ることになるのは、レジスタやメモリの操作を通したハードウェアとの直接のやり取りです。「ああ、この先はソフトウェアの領域ではないんだな……」という感慨に浸れます。これは貴重な経験だと思います。
2.3. OS開発の過程を追体験できた
『みかん本』では「〇〇という機能が欲しいですね」→「そのために〇〇という概念や仕組みがあります」→「こう設計すれば行けそうです」→「作りましょう!」という流れで新機能が足されていきます。その追加のコードを追うのは、大変な時もありますが、「意外と少ない行数で実現できるんだな」と感じることもしばしばです。これはMikanOSが機能ごとにしっかりモジュール分割されていることの裏返しです。作者の中で知識が体系的に整理されていることの現れでもあると思います。この様子を見て学ぶべきことは多いと思います。
(本当は『みかん本』に書かれている内容はエッセンスのみを抽出したものであり、その裏で数多の試行錯誤やデバッグがあったであろうことは想像に難くありません。読者はそうした苦労を除いた「旨い汁」のみを味わっていることになります。初心者的には、挫折ポイントがある程度刈り取られているのは本当にありがたいです。)
2.4. MikanOS向けアプリのPRを提出できた
さらに自分の場合、今まで経験したことのなかったOSSへのプルリクを経験することができました。自作したMikanOS向けのアプリをたまたま見かけたuchanさんが、プルリクエストの提案をしてくださり、良い体験になると思ってチャレンジしました。真面目な開発をしたことがなかったので、初歩的なミスもしましたが、親切にいろいろチェックして頂き、無事マージされました。
https://t.co/3607FmSdbk
— SuitCase (@pickled_chair) June 23, 2021
縁あって、MikanOS向けに書いた自作アプリが公式リポジトリに取り込まれました。C++もプルリクエストも不慣れだったのですが、 @uchan_nos さんにいろいろサポートしていただきながら頑張れました。本当にありがとうございました!#ゼロからのOS自作入門
『みかん本』を読み始めた当初はこんなことまで起きるとは思ってもみなかったです。この一件も、この本を読んで本当に良かったと思わせてくれた出来事でした。本当にありがとうございました。
3. そのうち取り組みたい題材
当初の目的+αを達成した今、一旦自作OSからは離れることになると思います。理由は今年度後半とても忙しくなるからということと、他にも関心のある分野がいくつかあるから、ということがあります。
しかし、自作OSに関連したことを、またときどきフラッと取り組みたくなるだろうと感じています。MikanOSに関することとしては、今思いつくだけでも以下の題材があります。
3.1. MikanOS向けアプリの開発
ミニゲームとか小物アプリ、または何らかのユーティリティアプリを作れたら楽しいだろうな、と妄想しています。
3.2. USBホストドライバの実装
『みかん本』では解説されていなかった未踏の地です。これを完遂しないことには写経をコンプリートした気分にはなれなさそうです。著者のuchanさんによる同人誌『USB 3.0 ホストドライバ自作入門』があるので、機会があれば取り組んでみたいですね。
3.3. Rustによる再実装
Rustで再実装されている方が割と多い印象です。自分も当初はRustでやってみることを考えていましたが、絶対挫折すると思い直し断念しました(結果的にはそれで正解でした)。しかし個人的に注目言語であるRustでやってみたい気持ちはまだ残っていたりします。
(とはいえ、フリースタンディングなRustバイナリは作ったことがないので、まずはその作成方法に親しむ必要がありそうです。Writing an OS in Rust あたりを学ぶことを考えています。このサイトで扱うOSはUEFIではなくLegacy BIOSで起動するもののようです。なのでまた違った知識が得られるだろうと思います。)
3.4. OpeLa言語で遊ぶ
OpeLa (Operating and Language processing system) プロジェクトとは、OpeLa言語の開発から始めて、最終的にMikanOSをOpeLa言語で再実装し、さらにMikanOS上でOpeLa言語によるMikanOSの開発を可能にするという、uchanさんによる野心的なプロジェクトです。OpeLa言語がOS開発用言語としてどう発展していくのか興味深いですね。Go言語的な見た目でC言語でやるようなことを実現できる3ところがユニークです。遊んでみたい気持ちがあります。
3.5. オリジナルの自作OS
もちろん、期が熟せばオリジナルのOSを作ることも可能な気がします。『みかん本』はそう思わせてくれました。夢がありますね!
4. 結び
こんな感じで、書籍を読み終わっても色々な続きを夢想しています。またこの楽しい世界に浸れる未来を楽しみにしています。ときどきまた拾い読みしてイメージを作って置きたいですね。
ということで、写経は終わりましたが、自作OS関連の取り組みは「未完4」ということで、今回得たものを財産にしつつ、これからも何らかの形で発展させていければと思います。作者さんに改めて感謝を示しつつ、この拙文を締めたいと思います。ありがとうございました。
C/C++を特に工夫なく使うと、ポインタやメモリの操作を完全に安全に行うことは困難です。C++ではそれを解決するための方法としてスマートポインタや所有権の概念、ムーブセマンティクスなどが導入されました。そして後発の言語であるRustはより進んだメモリ安全性を実現するために、明示しなくてもこれらの仕組み+αを最初から採用するようになっています(このため、何でもない構文に多くの意味付けがなされており、学習コストが跳ね上がる一因となっているのですが……)。つまりRustはC++から影響を受けています。一方自分はポインタやメモリの操作が孕んでいる問題をRust→C++と逆向きに学んだので「逆輸入」と表現しました。 ↩︎
一方、公式FAQ には「それほど C++ の込み入った機能をばりばり使っているわけではありません」と書かれています。確かにMikanOSで使われているC++の機能は基本的なものだけかもしれません。しかし初心者的にはこれだけの分量のC++コードを書いたことがないだけに、MikanOSではC++が「バリバリ使われている」ように見えるのです。 ↩︎
現在OpeLa言語にはジェネリクスがあったりするのでC言語よりも高機能です。C言語を引き合いに出したのは、それが当初はUNIXのアプリケーション開発用言語として用いられ、やがてOSのカーネルを記述するようになった、という歴史的経緯を踏まえた上で、OpeLaの発展の仕方がそれと似ていると感じたためです(OpeLaは現時点でもMikanOS向けアプリケーションを記述できます)。 ↩︎
本を読んだ人は分かると思いますが、MikanOSのMikanには「未完」の意味が込められています。未来への意欲を感じさせるいい名前だと思います。 ↩︎