OSの全体像

OSを作り始める前に、どんな機能を作るのか、どのようなソースコードの構成になるのかをざっくりと把握しておきましょう。

本書で実装する機能

本書で作るOSは、大きく分けて次の機能を持ちます。

  • マルチタスク: プロセスの切り替えを行い、複数のプログラムが同時に動作している (ように見せかける) 機能
  • 例外ハンドラ: 実行時エラーなどのCPUがOSの介入を必要とするイベントを処理する機能
  • ページング: 各プロセスごとの独立したメモリ空間を実現
  • システムコール: アプリケーションからOSの機能を呼び出す機能
  • デバイスドライバ: ディスクの読み書きなど、ハードウェアを操作する機能
  • ファイルシステム: ディスク上のファイルを管理する機能
  • コマンドラインシェル: 利用者がコマンドを入力してOSの機能を呼び出せる機能

本書で実装しない機能

逆に何が欠けているのかというと、主に次のような主要機能が省かれています。

  • 割り込み処理: 「デバイスに新しいデータがないか定期的にチェックする」方式 (ポーリング) で実装されています。
  • タイマー処理: プリエンプティブマルチタスクは実装されません。各プロセスが自発的にCPUを譲る、協調的マルチタスクで実装されています。
  • プロセス間通信: プロセス間でデータをやり取りする機能は実装されません。
  • マルチプロセッサ対応: シングルプロセッサのみ対応です。

もちろん、これらの機能は後から実装可能です。本書の実装を済ませた後に、HinaOSなどを参考にしながら実装してみると良いでしょう。

ソースコードの構成

ゼロからゆっくり作っていきますが、最終的には次のようなファイル構成になります。

├── disk/     - ファイルシステムの中身
├── common.c  - カーネル・ユーザー共通ライブラリ: printf関数やmemset関数など
├── common.h  - カーネル・ユーザー共通ライブラリ: 各種構造体・定数などの定義
├── kernel.c  - カーネル: プロセス管理、システムコール、デバイスドライバ、ファイルシステム
├── kernel.h  - カーネル: 各種構造体・定数などの定義
├── kernel.ld - カーネル: リンカスクリプト (メモリレイアウトの定義)
├── shell.c   - コマンドラインシェル
├── user.c    - ユーザー用ライブラリ: システムコールの呼び出し関数など
├── user.h    - ユーザー用ライブラリ: 各種構造体・定数などの定義
├── user.ld   - ユーザー: リンカスクリプト (メモリレイアウトの定義)
└── run.sh    - ビルドスクリプト

本書中では「ユーザーランド」を略して「ユーザー」と表記していることがあります。ざっくり「アプリケーション側」という意味で捉えると分かりやすいでしょう。