このシリーズについて
このシリーズは私がSecHack365(2023年度学習駆動コースの坂井ゼミです)を通して制作した「ぼくがつくったさいきょうのおーえす(Shizuku)」についてただただ語るだけのシリーズです。もし興味があればGitHubを覗いてくれると嬉しいです。SecHack365成果発表会もあるので興味がありましたら3/2アキバスクエアに来てくれると嬉しいです。
おーえすのロゴ(SecHack365成果発表会での目印)
ぼくがつくったおーえす(Shizukuと言います)のロゴです。このマークがポスターに10cmくらいの大きさで貼ってあることでしょう(タイトルにデカデカとぼくがつくったさいきょうのおーえすと書いてはあるのですがQiitaのアイコンがないので念のため...)
構成
- ぼくがつくったきっかけ
- さいきょうとは何か
- OSとは何か
---↑この記事はここまで--- - つくったおーえす
- オブジェクトとオブジェクトシステム
ぼくがつくったきっかけ
僕は既存のOSに対して欠点や不満を大量に抱えています(だから自作OSをやっています)
この不満には色々ありますが最大の不満は「OS内部構造や設計思想を一つの概念で言い表せない」ということです。たとえば有名なUNIX哲学の一つに「全てはファイルである」というものがあります。素晴らしいことに最近のLinuxではアプリケーションから全てはファイルであるかのように見えてるのではないのかなと思います。しかし、Linuxカーネル用のドライバ開発など、カーネルからはでは、必ずしも全てはファイルとして見えているとは限りません(LinuxではI2Cデバイスドライバを開発する際、i2c_register_driver関数などの関数を呼び出す必要があります。間違ってたらごめんなさい。追記:(この記事を書きながらなぜこのような仕組みになっているのか考えていたら)Linuxカーネルモジュールは読み込まれる時に動的リンクがどうせ行われるみたいだから速度優先で不要と判断されたのかorz)。このことから、僕はLinuxが複雑でそう簡単に理解や開発を行えるカーネルではないと思っています。そこで僕はカーネル空間やユーザー空間も内部の構造をたった一つの概念で言い表すことができるカーネルを作ることを決意しました。
さいきょうとは
- 簡単に使いこなせる
- 簡単に動作がわかる
- 簡単に開発ができる
ことだと思います(盛大にタイトル詐欺してます。わかりやすさがさいきょうということで許してくださいなんでもしますから)。これを外から見ても中から見ても満たすためにはまずOSとは何か、OSに求められるものはなんなのかを整理することから始めました。
OSとは何か
大きく分けてOSの役割は4つあります
- デバイス操作
- デバイスの抽象化
- プログラム間の通信
- リソース管理
詳しく説明していきます
デバイス操作
これはデバイスドライバというカーネルになんらかの方法で組み込まれたプログラムが行います。デバイスドライバの性質は次のようなものがあります。
- 一つのデバイスドライバと、一つのデバイスは対応しています(複数のデバイスドライバが一つのデバイスを操作することはありません。逆に同じ種類のデバイスでプログラムの使い回しが可能な場合など複数のデバイスを一つのドライバで操作することはあります)
- デバイスドライバにはデバイスを操作する権限をカーネルから与えられます(これはマイクロカーネルやLinuxなど拡張可能なカーネルの場合です。もちろんカーネルに直接リンクで組み込まれたものもあって、それは完全にカーネルの一部なので当たり前にデバイスを操作できます)
- デバイスドライバはデバイスの動作に専念すべきです(全てがそうかどうかはわからないのでここではすべきとしています)
デバイスの抽象化
デバイスの抽象化とはアプリケーションが大雑把にディスプレイとかスピーカーとかMetalとかVulkanとかOpenGLとかDirectXとかとかとかとにかく抽象的なデバイスへの操作を、具体的なデバイス(例えばRTX3080とか)への操作へと変換することです。最近は抽象的デバイスを操作すると、複数の具体的デバイス(複数のGPUやスピーカーが搭載されている状況)から、特定の具体的デバイスだけを操作させる仕組みも担っています。複数のスピーカーからOSの機能で特定のスピーカーを選ぶ(あるいはスピーカーを変える)とそのままそこから音が出るという仕組みも、抽象化の仕組みの中に備わっています。
プログラム間の通信
Linuxではプロセス間通信と呼ばれているものです。Linuxではプロセス間通信の手段はいくつかあります(興味があれば共有メモリとかパイプとかで調べると幸せになれます)
プロセス間通信を行う目的として、マルチスレッドプログラミングや、サーバークライアントモデルを実現することが挙げられます。Linuxではプロセス間通信の手段として共有メモリ、シグナル、ソケット等があります。
カーネルは上のような仕組みを提供すると同時に、通信しているプログラムを確かめる(送信元の特定と送信先の保証)仕組みと、通信の秘匿性を保証する仕組み(これが外部のコンピューターと通信するなど秘匿性を担保できない場合、代わりに暗号化機構を使用して秘匿性の担保)を提供する必要があります。
リソース管理
一口にリソース管理と言ってもリソースの中には計算能力や記憶力、デバイスまで含まれる場合もあって複雑ですがここではそれを占有するプログラムは一つであるべきものとします。例えばデバイスを占有するのは一つのデバイスドライバであるべきです(そしてアプリは抽象デバイスおよびデバイスドライバ経由で操作するべきです)。これに加えてCPUの処理時間の一部やメモリ空間の一部を一つのプログラムが占有できるように管理してあげることがOSに求められています。管理とはリソースをそのプログラムが占有する権限を持っているか確認して、そのリソースが他のプログラムによってすでに占有されていないか確認するなどを行うことです。LinuxではこれはVFSやプロセス管理(CPU時間はnice値によって割り当てられるそうですアンマクワシクシランケド)が担います。
続く
ぼくがつくったさいきょうのおーえす(Shizuku)の紹介はSecHack365成果発表会で行おうと思います(終わったらQiitaにも解説記事を投稿します)のでもし僕はどうやってこれらを実現したかに興味を持っていただけたらぜひ来てください!!!