自作OS系個人サークル「へにゃぺんて」で作ったものと、そのとき考えていたこと (前編)

はじめに

初めての方ははじめまして、大神祐真と申します。「へにゃぺんて」という個人サークルで「自作OS」を軸に趣味で独自な創作を行い、それを同人誌・同人作品という形で発表を続けています。また、その開発手法自体についても興味があり、近年は「プログラミング言語によらない開発」をテーマにマシン語や「バイナリ生物学」(後述します)という独自の手法で開発してみたり、対象とするハードウェアについてもPCに限らず自分の好きなレトロゲームハードを対象にしてみる、といった事を行っています。発表の場としては、主に「オープンソースカンファレンス」や「技術書典」や「コミックマーケット」といったイベントです。加えて今年は「セキュリティ・ネクストキャンプ2022」というイベントで「バイナリ生物学入門」という講義をさせていただけたり、この様な場所で記事執筆のご依頼をいただける等、ありがたいことにへにゃぺんての活動を発表させていただく場が増えてきました。

記事執筆にあたり、どの活動について書こうかと考えましたが、せっかくの機会なので主なものを一通り紹介いたします! 低レイヤーで独自で(変な)ものばかりですが、へにゃぺんてのこれまでの主な活動をまとめましたので、お楽しみいただければ幸いです。

以降の活動紹介では、同人誌・同人作品の公開・頒布場所や、過去のLT・セミナー発表やデモ動画等へのリンクを多く載せるようにしています。同人誌・同人作品は、電子版は無料ですので、もし興味があればご覧いただけると嬉しいです! なお、以降では過去に製作した自作OS等を紹介しますが、特にPCやVM向けの自作OSに関しては今や環境によってはうまく動かないかもしれません。それらについては、過去の発表やデモ等で動作させている様子の動画のリンクを載せていますので、もし興味がありましたらそちらをご覧ください。

自作OS「OS5」

OS5の実行時のスクリーンショット

初めてOSとして形になったものが「OS5」というOSでした。これは自身の勉強のために主に2015年〜2017年辺りで製作していたOSです。かねてよりOSが好きで、当時は仕事でOSのブートローダーやカーネル周りの開発をしていました。そんな中で得られたOSに関する理解を実際に作ってみる事で確認したい、そして何よりも「自分のOS」を作ってみたいという思いで製作したものです。

スペックとしては、ごく限られたコマンドしか使えないシェルの様なものが動くCUIのみのOSです。冒頭の画像はOS5の実行時のスクリーンショットです。対象のハードウェアは、レガシーBIOS + x86(32ビット)のPCという枯れすぎた様な環境で、QEMU上での動作を想定していました。

OS5が動く様子は、以下のデモ動画をご覧ください。QEMU上で動くということで、x86(32ビット)のQEMU(qemu-system-i386)を入れたRaspberry Pi 3上で動作させてみたものです。

OSの作りとしては、ブートローダー・カーネル・ユーザーランド(アプリケーション群)という一般的なOSの作りをしています。ユーザーランドのアプリケーション群は、ファイルシステム内に実行ファイルとして存在していて、OSを起動すると、カーネルに「一番最初に起動するアプリ」として設定されたアプリが立ち上げられるようになっていました(Linuxのinitプロセスのようなものです)。一番作り込んでいたのがカーネルで、タスク管理としてプリエンプティブなスケジューラ、メモリ管理としてヒープアロケータ、そして前述の通りファイルシステムや、カーネルとアプリをバイナリレベルで分離するためにカーネル側にシステムコールを備えていたり、キーボード入力や画面出力を扱うために一部ですがデバイスドライバ等が実装されていました。OS5の構造は以下の図の通りです。

OS5の構造

作る際に重視していた事は、「アウトプットに集中する」事と「自分のOSを作る」事です。作ってみることで自分の理解を確認する意味で行っていたので、何かを見ながら作るとかではなく、基本的に自分の頭の中にあるものをアウトプットすることに集中していました。そして何より「自分のOS」を作ってみたいという思いがありましたので、ファイルシステムや実行ファイル形式等も全て独自に考えて設計・実装を行っていました。ただそれ故に、このOSは他のどのOSとも互換性が無く、例えば「Bashが動く」という事もできないのですが、何もかもを独自にすることが楽しかったのでそのようにしていました。そして独自にするが故に製作スタイルとしてもいかなるライブラリも使わない「フルスクラッチ」というスタイルになりました。プログラミング言語としてはC言語を使っていましたが、インクルードしたりリンクしたりするものは全て自分が書いたもののみというスタイルです。

独自に設計・実装する際、「シンプルにする」事を意識しており、OSとしては「ごく簡単なシェル上でカーネルのテスト程度のいくつかのコマンドが動く」くらいを想定して、ブートローダー・カーネル・ユーザーランドの全てにおいて、「それくらい」を実現するにあたって過剰な実装は行わないように、ひたすらシンプルに・簡単にという方針で設計・実装を行っていました。そのため、ブートローダー・カーネル・ユーザーランド全て含めても3000行程度というコンパクトなOSとなりました。

OS5については、製作中は勉強会での発表や同人誌にするといった事は考えていなかったのですが、ある程度できあがったくらいの時期に低レイヤーな事も発表できる勉強会がある事を知り、そこで発表させていただきました。自分の趣味について発表すること自体初めてだったのですが、ありがたく好評をいただくことができ、自身の活動を積極的に発表していこうと考えるきっかけになりました。そして、「技術書典」というイベントがある事を知り、同人誌の作り方から教えていただけた事で、人生初の「同人誌即売会でのサークル出展」を果たすことができました。同人誌のタイトルは「Ohgami's Commentary on OS5」で、OS自体がコンパクトということで、「OS5の全コードとコメンタリー」という本になりました。

表紙・裏表紙説明
Ohgami's Commentary on OS5
PDF版(技術書典様)・物理版(とらのあな様)
初出イベント:技術書典2

概要:
OS5の全ソースコード+コメンタリー本!

なお、「OS5」という名前は、私が5番目に作ったOSという所から来ています。それまでの4つはモチベーションが続かずにやめてしまったものたちです。OS5とそれまでの4つの違いは「フルスクラッチで作る」所で、自分にはそのような開発スタイルが楽しんで続けられるのだと気づかせてくれたのがOS5でした。また、OS5は、始めた当初は「自分の勉強」や「自分の楽しみ」といった目的のみでしたが、最終的には現在にもつながる「イベント発表」や「同人誌作り」のきっかけを与えてくれたOSでした。

自作OS(っぽいもの)「poiOS」とブートローダー「poiboot」

poiOSの実行画面の写真

「x86(64ビット)の自分のPCを自力で制御したい」という思いがありました。そこで、「OS5の次」を考えていた2017年頃に「まずはブートローダーから」という事で、現代のPCに搭載されているBIOSはUEFI仕様に則ったチップが搭載されているため、UEFI仕様の勉強を始めました。勉強の際は、UEFIの仕様を読む事はもちろん、確認のための実験プログラムをいくつか作成しました。この実験プログラムに関しても「UEFIのライブラリや開発環境は使わず、UEFIの仕様に従ってUEFIのチップに実装されている機能を自力で呼び出す」というフルスクラッチでの開発を行っていました。そしてUEFIの仕様を勉強し自力で叩く中で、UEFIの高機能さに驚き、「これならUEFIの機能を呼び出すだけでOSっぽいものが作れるのでは?」という考えで製作したものが「poiOS」です。

poiOSは、UEFIの機能を呼び出す形で、UEFIで使用するパーティション上のファイル操作が行えます。操作はOS5と同じ様な簡単なCUIの他、GUI(っぽい)モードも備えています。冒頭の画像はGUIモードが動作している様子です。アルファベット3文字が書かれている白い四角の一つ一つがファイルあるいはディレクトリです。これはUEFIのテキスト出力機能と矩形描画機能を使って描画しているのですが、矩形を描画する際の座標計算の簡単さから、poiOSで扱うファイル/ディレクトリ名は全て3文字という(とんでもなく割り切った)事にしています。「hhh」というファイルの下の方に白いドットが3つ程固まったものがありますが、これがマウスカーソルです。一応、ファイルをクリックするとテキストファイル/画像ファイルを閲覧したりできます。他にも、テキストファイルの編集や新規作成にも対応しています。また、立ち位置としてはブートローダーなので、右下のペンギン(タックス君)の画像をクリックすると、Linux+BusyBox環境をブートできたりします。poiOSの構造は以下の図の通りです。

poiOSの構造

poiOSが動く様子は、以下の発表動画やデモ動画をご覧ください。

poiOSを単純なブートローダーとしたものが「poiboot」です。これが次に製作するOSのブートローダーとなりました。

poiOS・poibootに関しては、「UEFIを直接叩く方法を解説する」という形で「フルスクラッチで作る!UEFIベアメタルプログラミング」という同人誌をパート1(無印)・パート2の2冊出しました。「パート1(無印)」は、フルスクラッチでのUEFIの叩き方からUEFIのファイルシステム上のファイルを閲覧・編集したりできるOSっぽいものをステップ・バイ・ステップで作っていく本になっていて、「パート2」は、パート1で紹介しなかったUEFIのその他の機能を試したり、Linuxカーネル+BusyBox環境をブートしてみるといった本になっています。この辺りから技術書典やコミックマーケットの度に同人誌を出す流れができ、コミックマーケットは出展しなかった回もありましたが、技術書典は2で初出展してからこれまで全てサークル出展させていただきました。ただ、こうなってくるとOS5の時とは違い、OS開発と並行して同人誌を出すタイミングが来る事になるので、「執筆を始めるタイミングまでで実装した内容について、ステップ・バイ・ステップで解説する本」をOS開発が進むにつれてパートに分けて刊行するというスタイルができました。

表紙・裏表紙説明
フルスクラッチで作る!UEFIベアメタルプログラミング
PDF版(技術書典様)
初出イベント:コミックマーケット92

概要:
ライブラリやツールチェイン等を使わず、エディタとコンパイラだけの「フルスクラッチ」でUEFIファームウェアを叩く「ベアメタルプログラミング」を紹介し、OSっぽいもの(poiOS)を作る本
〃 パート2
PDF版(技術書典様)
初出イベント:技術書典3

概要:
パート1(無印)で紹介しきれなかったUEFIの機能を紹介するTIPS本です。Linux+BusyBox環境のブートも行います。

自作OS「ゆあOS」

ゆあOSの実行画面の写真

ブートローダーを作ったので、2018年頃に、そこからブートされる側であるカーネルとユーザーランドの自作を始めました。この時期の開発は正に技術書典とコミックマーケットの両イベントでの同人誌刊行と共にあったようなものです。それは以下の通りで、年に2回ずつあったそれぞれのイベントで新刊としてOSの機能を一つずつ実装していく本を刊行していました。

表紙・裏表紙説明
フルスクラッチで作る!x86_64自作OS
PDF版(技術書典様)・物理版(とらのあな様)
初出イベント:技術書典4

概要:
poibootでブートされる側を作り始める本
この本ではシングルタスクOSとして画像ビューアアプリが動く程度のものを作成します
〃 パート2 ACPIでHPET取得してスケジューラを作る本
PDF版(技術書典様)・物理版(とらのあな様)
初出イベント:コミックマーケット94

概要:
タイトル通り、スケジューラを実装してマルチタスク対応します
〃 パート3 システムコールの薄い本
PDF版(技術書典様)・物理版(とらのあな様)
初出イベント:コミックマーケット95

概要:
システムコールを実装する事でカーネルとアプリをバイナリレベルで分離します
〃 パート4 ぼくらのイーサネットフレーム!
PDF版(技術書典様)・物理版(とらのあな様)
初出イベント:技術書典6

概要:
NICドライバを実装しイーサネットフレームを扱えるようにする本
〃 パート5 てっとりばやくマルチコア
PDF版(技術書典様)・物理版(とらのあな様)
初出イベント:コミックマーケット96

概要:
ハードウェア依存の機能を使用しますが、てっとりばやくマルチコア対応する本です

タイトルの「フルスクラッチで作る!」は、ブートローダーを作成した「フルスクラッチで作る!UEFIベアメタルプログラミング」シリーズから引き継いでおり、この「x86_64自作OS」シリーズでもそれぞれの本の中では、その本でのゴールまでをステップ・バイ・ステップで作り上げていく構成にしています。このようにした理由は、「読者の方の分かりやすさ」ということもありますが、ある程度意味のある内容の同人誌をOSを作りながら刊行していくにあたって、私にはこれ以外やれそうな方法がなかった、という事もあります。

なお、当初このOSには名前がありませんでした。それは、特に名付ける必要が生じなかったためです。各同人誌では、同人誌内で作っているOSの事は「このOS」とか呼べば良く、ソースコードを置くGitHubリポジトリについても、各同人誌のサンプルコードとして公開しているため、「<同人誌タイトルの英訳>_samples」といったリポジトリ名にしていた事から、OS名を付ける必要がしばらくは生じませんでした。ただ、ある時、そろそろマスターとなるリポジトリを用意しようと考え、OSに名前を付けることにしました。そこで、「このシリーズで作り上げるOSは、できあがったらそれは読者の方々一人ひとりのOSである」という考えから「あなたの(Your、ゆあ)OS」という意味に加え、「英語由来なのに名前にひらがなが入ってたら面白いな」という考えで「ゆあOS」となりました。(ただ、リポジトリ名はアルファベットの方が都合が良いので「yuaos」となっています。)

ゆあOSもC言語で開発しているため、カーネルとユーザーランドにはOS5から流用できる部分も多かったですが、下手にOS5を持ち出すと同人誌にする時に説明が難しくなるのと、また作り直す方が楽しかったので作り直すことにしました。ただ、作り直しはしましたが、結果的に、ハードウェアを制御する部分以外はOS5と大体同じ様な作りになっていたと思います。それは、ゆあOSを作っていたときのモチベーションとして、ブートローダーを作り始めた時から持っていた「自分のPCを自力で制御したい」という思いがあったためです。ハードウェアを直接制御する方法を調査して実装し自分で動かせるようになる事が楽しく、それをどうカーネルとして抽象化するかといった所にはあまり力を入れておらず、OS5の時と同じ様な実装で済ませていた覚えがあります。特にNICドライバの実装は楽しく、同人誌では最終的にイーサネットフレームで対向側のPC(Linux)と通信確認をするという所までなのですが、その後にプロトコル・スタックを最低限実装し、HTTP/0.9の通信を行ったりしていました。カーネル周りを中心にゆあOSの構造を図示すると以下の通りです。

ゆあOSの構造

ただ、ユーザーランドは別で、「せっかくの『自作OS』なのに、よくあるシェルみたいなものが起動するのでは面白くない」という思いから、ファイルシステム上のファイルを選択して表示したり実行したりするUIとして「アドベンチャーゲーム風UI」を作ってみたりしていました。それが冒頭の写真です。このような事をするようになったきっかけは、オープンソースカンファレンス(OSC)等のイベントでLTをするようになった事です。ゆあOSは画像ビューアでスライドショーができることから、この時期からイベントでの発表はゆあOSで行っていました。LT等でそれがウケたのが嬉しく、「もっと面白いことをやってみよう」という気持ちでした。ただ、それをきっかけに「自分のOSを作りたい」という思いから追求するようになった「独自性」が、一般的なOSの作りにまで及ぶようになりました。「せっかく趣味で自作OSをするなら、もっと何もかも独自なOSを作ってみたい」と考え、その様な「何もかも独自なOS」はどんな形が面白いだろうと追求する中で、ゆあOSの開発は止まりました。

ゆあOSが動く様子は、以下のデモ動画をご覧ください。

振り返ってみると、ゆあOSはOS5とは真逆なOSでした。OS5は、主にカーネルとして一般的な機能を取り揃える事に力を入れていて、ハードを制御するデバイスドライバとユーザーランドはそのカーネルを実験するのに最低限のものしか作っていませんでした。対してゆあOSは、主にハードの持つ色々な機能を自分で制御するデバイスドライバ実装や独自な見せ方をするユーザーランドのUIに力を入れていて、カーネルはデバイスドライバとユーザーランドをつなぐのに最低限必要な機能を持っている程度のものでした。また、作り方としても、OS5はOSの開発中はイベント発表や同人誌作りをしていなかったのでOSを作ることだけに集中してゆっくりじっくりと作っていました。対してゆあOSは、OS製作が「次の同人誌のネタ作り」の意味もあるのであまりじっくり作り込むことはせず「とにかく動けばOK」という感じで勢いで作っていた感じでした。どちらも楽しく、良い思い出です。

「遺伝的MBR」

上記の表では「技術書典5」では「フルスクラッチで作る!x86_64自作OS」の刊行がありませんでした。実は技術書典5では「自作OS自動化のPoCとしての遺伝的MBR」という別の本を出していました。

表紙・裏表紙説明
自作OS自動化のPoCとしての遺伝的MBR
PDF版(技術書典様)・物理版(とらのあな様)
初出イベント:技術書典5

概要:
遺伝的アルゴリズムでMBRを生成する実験環境を設計・実装し、試してみる本

レガシーBIOSの話に戻ってしまうのですが、レガシーBIOSではPCの電源を入れると起動ディスクとして指定されたディスクの先頭512バイト(マスターブートレコード、MBR)をメモリへロードし、それを実行していました。そのため、レガシーBIOSの頃のブートローダー自作は、まずこのMBRの部分のプログラムを作ることになります。この本は、「512バイトのMBRくらいなら遺伝的アルゴリズムで生成できるのではないか」というアイディアを実際に実験する環境として、KVMを利用した実験環境を設計・実装し、試してみる、という内容です。本の中では交叉の仕方を工夫したりして、「BIOSの機能を呼び出して'A'という文字を出力するMBR」や「'A'に限らず何らかのASCII文字を出力するMBR」等の生成を試しています。

ゆあOS開発の最中に出したこの本のアイディア自体はこれ以上の発展は無く終わるのですが、実行バイナリの生成に関して「プログラミング言語によらない方法として何か面白いやり方は無いか」という事をこれ以降は考えるようになりました。

つづきは後編で

これ以降にどのようなものを作ってきたかは後編の記事でご紹介します。引き続きお楽しみください!