osdev-jpでは、OS開発に有用な情報を収集し公開しています

View My GitHub Profile

OS 開発を始める人たちへ

このページでは、 OS 開発をやってみたいけれど、何をどうすれば良いかわからない!という人たちのために、OS に関する一般論を説明していこうと思います。

OSってなんだろう

OS の定義はなかなか難しいのですが、基本的には、ハードウェアを抽象化し、そのインターフェースをユーザーやアプリケーションプログラムに提供するのが OS の仕事です。たとえばネットワークデバイスであれば、 I という会社の製品であっても、 R という会社の製品であっても、同じように(例えば Transmit と Receive 関数みたいな形で)扱えるようになっているのは、OS のお陰なのです。 OS が存在しない世界では、アプリケーションは星の数程もある各デバイス向けのコードを書かなければならず、アプリケーションを作るのが相当大変になってしまう事でしょう。

抽象化のわかりやすい例が、 UNIX のファイル抽象です。 UNIX では、本来ファイルでないもの、例えばデバイスをファイルとしてファイルシステムにマップする事で、read 、write システムコールによってファイルと同じように扱う事ができるようになっています。仮にデバイスがファイルとして扱えない場合、デバイス専用のインターフェースを用意しなければならない所が、ファイル抽象によって同じインターフェースで扱えて便利、というわけですね。

ハードウェアの抽象化という原則を発展させる過程で、仮想化という機能も OS が果たす重要な仕事になってきました。例えばマルチタスク、つまり CPU の個数以上のプロセスを動かす事、について考えてみましょう。本来プログラムは一つの CPU 上で動くものなので、プログラムの数が CPU の個数を超える事はできないわけです。それを OS が裏でこっそり CPU を切り替える事によって、プログラムからすれば一つの CPU を独占しているように見えるにも関わらず、実際には CPU の数以上のプロセスが立ち上がる、という仕組みになっています。難しい言葉で書くと、 OS による計算資源の仮想化、となるのですが、要するに OS が仮想的に各プロセス毎に一つの CPU を用意してあげているわけです。

仮想化のもう一つわかりやすい例はページングでしょう。ページングが有効になっている 32bit OS であれば、個々のプロセスはそのプロセス固有の 4GB のメモリ空間の上で動作します。この際、実際に基盤に刺さっているメモリサイズは関係ありません。実際のメモリサイズや、他のプロセスのメモリ空間を気にする事なく、 4GB メモリ空間を好きに扱えるのは、ページングによるメモリの仮想化のお陰なのです。

仮想化はセキュリティとも繋がりがあります。例えば、ある悪意のあるプロセスが他のプロセスの資源を奪いたいと思っても、 OS が資源空間をプロセス毎に適切に切り分けていれば、そんな事はできません。具体的に書くならば、あるプロセスが他のプロセスのメモリを覗き見ようとしても、プロセスから見えるメモリ空間は OS が仮想化によって作り出したものなので、覗き見る事はできないのです。

このように考えると、OS を作る事の本質や意義は、ハードウェアをいかに効率的に扱うかや、ソフトウェアがいかに容易に、或いは安心してハードウェアを使えるようなインターフェースを設計するか、という所に落ち着くのではないでしょうか。もちろんそれ以外の目的(単に OS を作ってみたいとか)で作るのも各人の自由ですが、このような考え方をする事で、OS とは何か、そしてそれを自分で作るとはどういう事か、なんとなく見えてくるかもしれません。

OS 開発の概要

殆どの人は、OS を作ってみたい!でも何から始めたらいいかわからない!となると思うので、OS 開発の全体像(これはあくまでも一例に過ぎませんが)を書いてみます。

システムブート

OS をゼロから作ってみたいと思う人は、おそらくコンピュータの立ち上げの部分から全部自力でやりたいと思っている事でしょう。これ自体は難しい事はありません。

x86 環境で説明すれば、BIOS や UEFI からブートして、CPU の初期化、メモリの初期化( GDT ,ページング)、割り込みの設定( IDT )、をすれば必要最低限の初期化は終わります。簡単ですね。

メモリ管理

メモリには仮想メモリと物理メモリという二種類のメモリがありますが、それぞれのメモリを管理(確保されている領域の管理)する必要があります。

プロセス管理

プロセスの立ち上げ、コンテキストスイッチ、プロセス間通信等をサポートすると、OS の上で自由にプログラムを動かす事ができるようになります。

ドライバ

ディスクドライバ、画面ドライバ、ネットワークインターフェースカードドライバ等を各デバイス毎に用意しましょう。使いたいデバイスのドライバだけを用意すれば良いので、ありとあらゆるデバイスに対応する必要はありません。

また場合によっては、より上位のドライバ(プロトコル・スタックなど)を実装する必要があるかもしれません。

ファイルシステム

FAT や、ext4 等のファイルシステムに加えて、ファイル抽象の OS を作る場合は、デバイスマッピングの仕方等を考える必要があります。