MINIX Learning
MINIXの概要と、実践
榎本 優樹
目的
• ML == MINIX Learning
• 当初はMirBSD Learningでした ;-)
• MINIXの概観をつかみ、実際に使ってみる
MirBSD?
• NetBSDから派生したOpenBSDから派生したOS
• M から始まるBSDだと、真っ先にこれが浮かんだ
2部構成でいきます
• Tanenbaum 『オペレーティングシステム 設計と理論
およびMINIXによる実装』(第2版) のまとめ
• Virtual BoxでMINIXを使ったデモンストレーション
『オペレーティングシステム 設計
と理論およびMINIXによる実装』
• 全5章の構成
• オペレーティングシステム概論
• プロセス
• 入出力
• メモリ管理
• ファイルシステム
『オペレーティングシステム 設計
と理論およびMINIXによる実装』
• 全5章の構成
• オペレーティングシステム概論
• プロセス
• 入出力
• メモリ管理
• ファイルシステム
全部なんて
到底無理です
(90分x15週ならいける)
目次
• OSの機能について(1章)
• MINIXが起動し、シェルが立ち上がるまで(2章)
• MINIX上でのデバイスドライバについて(3章)
• MINIXのメモリ管理について(4章)
• ファイルについて(5章)
1. MINIXとは?
• UNIXのライセンス問題から、TanenbaumがUNIX
のソースコードを含まないOSを作ったのが始まり
• 教育用のため、読みやすさ > 機能
OSの役割とは?
• リソースを管理する
• プロセス, メモリ管理
• ユーザに複雑なものを見せない
• ファイル, システムコール
プロセス
• 実行中のプログラムのこと
• プロセスにはアドレス空間が関連付けられている
• 実行可能プログラム, データ, スタック
• プロセスの情報はプロセステーブルに保存される
アドレス空間
• テキストセグメント
• プログラムコード
• データセグメント
• 変数
• BRKシステムコールで拡
張される
• スタックセグメント
• 必要に応じて成長する
テキスト
データ
スタック
FFFF
0000
空き
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図1-11
マルチプログラミング
• プログラム間を高速で行き来すること
A
B
C
D
プロセス
時間
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図2-1(c)
ファイル
• OSは、デバイスを抽象化する => ファイル
• デバイスの操作を、ファイルの読み書きなどで
表すことができるようになる!
• ファイルの保存方法
• ディレクトリという考え方
• ツリー構造
システムコール
• カーネルレベルでの作業を、

ユーザがしたいときに呼び出すもの
• いろいろある
• ファイル・ディレクトリ管理, シグナル…
システムコールの実行方法
主メモリ
ユーザプログラム(ユーザモード)
OS(カーネルモード)
トラップ
番号の決定
OSが作業する
戻る
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図1-16
MINIXの内部構造
プロセス管理
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図2-26
ディスク
タスク
Tty
タスク
クロック
タスク
システム
タスク
イーサネット
タスク …
…
…
メモリ
マネージャ
ファイル
システム
ネットワーク
サーバ
init
ユーザ
プロセス
ユーザ
プロセス
ユーザ
プロセス
レイヤ
4
3
2
1
ユーザプロセス
サーバプロセス
入出力タスク
MINIXの内部構造
プロセス管理
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図2-26
ディスク
タスク
Tty
タスク
クロック
タスク
システム
タスク
イーサネット
タスク …
…
…
メモリ
マネージャ
ファイル
システム
ネットワーク
サーバ
init
ユーザ
プロセス
ユーザ
プロセス
ユーザ
プロセス
レイヤ
4
3
2
1
ユーザプロセス
サーバプロセス
入出力タスク
リソース管理
カーネル
MINIXの内部構造
プロセス管理
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図2-26
ディスク
タスク
Tty
タスク
クロック
タスク
システム
タスク
イーサネット
タスク …
…
…
メモリ
マネージャ
ファイル
システム
ネットワーク
サーバ
init
ユーザ
プロセス
ユーザ
プロセス
ユーザ
プロセス
レイヤ
4
3
2
1
ユーザプロセス
サーバプロセス
入出力タスク
難しいものを隠す
MINIXの内部構造
プロセス管理
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図2-26
ディスク
タスク
Tty
タスク
クロック
タスク
システム
タスク
イーサネット
タスク …
…
…
メモリ
マネージャ
ファイル
システム
ネットワーク
サーバ
init
ユーザ
プロセス
ユーザ
プロセス
ユーザ
プロセス
レイヤ
4
3
2
1
ユーザプロセス
サーバプロセス
入出力タスク
割り込みを捉える
プロセス間通信
を処理する
MINIXの内部構造
プロセス管理
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図2-26
ディスク
タスク
Tty
タスク
クロック
タスク
システム
タスク
イーサネット
タスク …
…
…
メモリ
マネージャ
ファイル
システム
ネットワーク
サーバ
init
ユーザ
プロセス
ユーザ
プロセス
ユーザ
プロセス
レイヤ
4
3
2
1
ユーザプロセス
サーバプロセス
入出力タスク
デバイス
ドライバ
ともいう
入出力系のプロセス
MINIXの内部構造
プロセス管理
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図2-26
ディスク
タスク
Tty
タスク
クロック
タスク
システム
タスク
イーサネット
タスク …
…
…
メモリ
マネージャ
ファイル
システム
ネットワーク
サーバ
init
ユーザ
プロセス
ユーザ
プロセス
ユーザ
プロセス
レイヤ
4
3
2
1
ユーザプロセス
サーバプロセス
入出力タスク
FORK, BRK
MOUNT, READ
MINIXの内部構造
プロセス管理
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図2-26
ディスク
タスク
Tty
タスク
クロック
タスク
システム
タスク
イーサネット
タスク …
…
…
メモリ
マネージャ
ファイル
システム
ネットワーク
サーバ
init
ユーザ
プロセス
ユーザ
プロセス
ユーザ
プロセス
レイヤ
4
3
2
1
ユーザプロセス
サーバプロセス
入出力タスク
シェル, エディタ, コンパイラ
など
2. MINIXの起動について
ブートブロック
ブートプログラム
• ROMは、ブートディスク
の最初のセクタを読み、
そこにあるコードを実行
する
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図2-31(a)
ブートブロック
• 最初の512Bにはブー
トストラッププログラ
ムが格納されており、
bootをロードする
512 [B] 512 [B]
1 [KB]
ロードされる
セクタ
設定の保存に
使えるセクタ
• 第2セクタをbootというプログラムが見る
• bootはOS自体をロードする
• ファイルシステムの/minixファイルか、/minix/
以下の最新の イメージ
システムの初期化
• 16 [bit]か32 [bit]でMINIXをコンパイルすることが
できる
• mpx88.sかmpx386.sが使われる
#include <minix/config.h>
#if _WORD_SIZE == 2
#include “mpx88.s”
#else
#include “mpx386.s”
#endif
mpx386.s
• 32 bit CPU用の変数や関数の定義をする
• スタックフレームの設定や、

各種プロセッサレジスタの設定をする
• 用語いっぱいで難しいので、

Cプログラムのための準備をすると

考えて下さい
準備が終わったら……
• C言語の関数cstartを呼び出す
push edx
push ebx
push SS_SELECTOR
push MON_CS_SELECTOR
push DS_SELECTOR
push CS_SELECTOR
call _cstart
• cstartは32bitプロセッサで使われる
• OS内部のデータ構造を初期化する
今度はmain.cへ飛ぶ
• いろんな初期化をする
• プロセステーブルの初期化
• メモリに関する配列の初期化
• restart()を呼び出し、mainは終了する
restart()の処理
• mpx386.sの処理の一部
• 最初に実行されると、MINIXが実行される
• proc_ptrが指しているプロセスを実行する
proc[NR_TASKS+INIT_PROC_NR].p_pid = 1;
bill_ptr = proc_addr(IDLE);
lock_pick_proc();
/* ここでアセンブリコードを呼び出し、現在のプロセスの実行を開始する */
restart();
initをルートとして……
• initからgettyが呼び出される
• getty: 仮想端末を立ち上げる
• gettyからloginが呼び出される
• login: ユーザ名とパスの入力
• loginに成功すると、シェルが立ち上がる
• シェルの子プロセスとして、各プロ
グラムが実行される
init
getty
login
tcsh
ls
vimpwd
3. MINIX上でのデバイスドライバについて
プロセス管理
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図2-26
ディスク
タスク
Tty
タスク
クロック
タスク
システム
タスク
イーサネット
タスク …
…
…
メモリ
マネージャ
ファイル
システム
ネットワーク
サーバ
init
ユーザ
プロセス
ユーザ
プロセス
ユーザ
プロセス
レイヤ
4
3
2
1
ユーザプロセス
サーバプロセス
入出力タスク
特殊ファイル
• 入出力デバイスをファイルのように扱うためのもの
• ブロック型特殊ファイル
• ディスクなど、アドレス指定ができるもの
• キャラクタ型特殊ファイル
• 文字の流れを受信したり出力するもの
• プリンタ, モデムなど
デバイスドライバとは
• デバイスに関することを処理するプログラム
• デバイスに依存するコードは、

全てデバドラ内に記述される
• 例)マウス, USBメモリ
• ソフトウェアからの抽象的な要求を受け入れ、

具体的な処理をするのが仕事
UNIXでのデバイスドライバの呼び出し
• UNIXでは、すべてのプロセス
がユーザ空間とカーネル空間
を持っている
• システムコールが発行される
と、切り替わる
• UNIXのデバドラは、プロセス
のカーネル空間部によって呼
び出される手続き
プロセス
ユーザ
空間部
ファイル
システム
デバイス
ドライバ
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図3-14(b)
ユーザ空間
カーネル空間
MINIXでのデバイスドライバ
• プロセスがファイルシステムの
プロセスにメッセージを送る
• ファイルシステムがデバイスド
ライバへメッセージを送る
ユーザ
プロセス
ファイル
システム
デバイス
ドライバ
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図3-14(a)
ユーザ空間
カーネル空間
システムが起動すると……
• 各ドライバが開始され、メッセージを待つ
• メッセージを受け取ると、作業を開始し、返信する
• 各デバイスドライバのメインプログラムは同じ構造
PUBLIC void driver_task(dp)
struct driver *dp;
{
int r, caller, proc_nr;
message mess;
…(中略)…
while(TRUE) {
receive(ANY, &mess);
caller = mess.m_source;
proc_nr = mess.PROC_NR;
…(中略)…
switch(mess.m_type) {
case DEV_OPEN: r = (*dp->dr_open)(dp, &mess); break;
case DEV_CLOSE: r = (*dp->dr_close)(dp, &mess); break;
…(中略)…
default: r = EINVAL; break;
}
…(中略)…
mess.m_type = TASK_REPLAY;
mess.REP_PROC_NR = proc_nr;
mess.REP_STATUS;
send(caller, &mess);
}
}
struct driver {
_PROTOTYPE( char *(*dr_name), (void) );
_PROTOTYPE( int (*dr_open), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_close), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_ioctl), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( struct device *(*dr_prepare), (int device) );
_PROTOTYPE( int (*dr_schedule),
(int proc_nr, struct iorequest_s) *request );
_PROTOTYPE( int (*dr_finish), (void));
_PROTOTYPE( void (*dr_cleanup), (void) );
_PROTOTYPE( void (*dr_geometry), (struct partition *entry) );
};
4. MINIXのメモリ管理について
• OSでメモリを管理する部分
• メモリマネージャ
• メモリのどの部分が使用中かを記録する
• プロセスにメモリを割り当てたり、解放する
メモリ管理の方法
• スワッピング
• 各プロセスをメモリに読み込み、

しばらくしたらディスクに返す
• 仮想メモリ
• プログラムの一部が

メインメモリにあるとき、

そのプログラムを実行できる。
スワッピングのイメージ
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図4-3
OS
時間
A
OS
A
B
OS
A
B
C
OS
B
C
OS
B
C
D
仮想メモリとは?
• メモリに入りきらないくらい大きいプログラムを

どう実行したらいいのか?
• プログラムを分割して、一部をメインメモリに、
残りをディスク上に保存すればいい
• 必要に応じて、プログラムの一部をディスクと
メモリでスワップする
ページング
• プログラムが指すメモリのアドレス
• 実は仮想のアドレスを指している
• メモリ管理マネージャが、仮想アドレスを

実際の物理アドレスに対応づける
• この技法をページングという
物理メモリ
アドレス
仮想アドレス空間
2
1
6
0
4
3
X
X
X
5
X
7
X
X
X
X
0K-4K
4K-8K
8K-12K
12K-16K
16K-20K
20K-24K
24K-28K
28K-32K
0K-4K
4K-8K
8K-12K
12K-16K
16K-20K
20K-24K
24K-28K
28K-32K
32K-36K
36K-40K
40K-44K
44K-48K
48K-52K
52K-56K
56K-60K
60K-64K
仮想ページ
ページフレーム
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図4-8
MINIXのメモリ管理
• スワッピングもページングも使わない
• プロセス数が少ないことを想定しているから
• IBMのCPUが仮想メモリのサポートしてないから
• 移植性を高めるため
• ユーザ空間内で実行され、

メッセージを使ってカーネルと通信する
少プロセス想定の理由
• MINIXは個人のパソコン向けのものだから
• ユーザが何人もアクセスするような大型な

システムで動かすわけじゃないし……
IBMのプロセッサ
• 80386, 80486, Pentiumでは、

仮想メモリのサポートが行われているが……
• それ以前のIBM CPUにも対応させたい
• 色々なマシンとの互換性を保ちたい
移植性を高める
• 原始的な実装のほうが移植しやすい
• ハードウェアへ依存する部分を減らしたい
MINIXのメモリ管理
• メモリが割り当てられるケース
• プロセスがFORKを行うとき、

子プロセスに必要な分のメモリ量を割り当てる
• プロセスがEXECシステムコールによって

そのメモリイメージを変更したとき、

古いイメージを解放して新しく割り当てられる
MINIXのメモリのイメージ
MINIX
A
B
MINIX
A
B
Aの子プロセス
MINIX
A
B
C
[出典] A.S.Tanenbaum 『オペレーティング 設計と理論およびMINIXによる実装』図4-32
上位
メモリ限界
5. MINIXのファイルシステムについて
• そもそもファイルシステムとは?
• ファイルはOSが管理する
• OSの、ファイルを扱う部分のこと
• ファイルシステム(一部)
• そもそもファイルとは?
• ディスクへの書き込みの種類
ファイル がうれしい理由
• 多くの情報を保存したい
• プロセスが終了しても、

使っていた情報を失いたくない
• ==> ファイルという単位で情報を保存すればよい
ファイルの種類
• 通常ファイル: バイト列で構成される
• ASCII, バイナリ
• ディレクトリ:ファイルシステムの構造を保持するもの
• キャラクタ型特殊ファイル: 

          シリアル入出力デバイスのモデル化に使用
• ブロック型特殊ファイル:ディスクのモデル化に使用
ASCIIファイルの構成
• ただのバイト列
• OSは、バイト列のみを扱う
• 何を書いても、どう名付けてもいい
• これについて、OSは口出ししない
1 byte
どうファイルを記録するか?
• == どうディスクに書き込むか?
• ベタッと全部
• ディスクのアドレスを使う
• iノードに関連づける
ベタッと全部
• 1Kのブロックを持つデバ
イス上では、4KBのファ
イルには4連続のブロック
が与えられる
• 簡単・読み込みが早い
• ファイルの最大サイズが分
からないとダメ
ディスクのアドレスを使う
• ディスクブロックの
連結リストとしてファ
イルを保存する
• どこに書き込んでも
いい
• ポインタのために数
バイト必要
4 5 9
2 14
物理
ブロック
ファイル
ブロック
0
ファイル
ブロック
1
ファイル
ブロック
2
ファイル
ブロック
3
ファイル
ブロック
4
ちなみに……
• このポインタをメモリに置く
のがMS-DOS式
• こうすると、

ブロック全体をデータに

割り当てることができる
• メモリの中に

テーブルを置く
0
1
2 14
3
4 5
5 9
6
7
8
9 2
10
11
12
13
14 0
15
start
物理
ブロック
iノード
• ディスクアドレスはiノード自体に保存される
• ファイルを、iノードというテーブルに関連づける
• ファイルごとにiノードの番号が割り振られる
iノードと多重間接
属性
iノード 1KB
1KB
1KB
1KB
1KB
1KB
1KB
1KB
1KB
1KB
1KB
1KB
1KB
1KB
単一間接
ブロック
二重間接
ブロック
MINIXの
iノード構造
モード(ファイルタイプとrwxビット)
リンク数(このファイルのディレクトリエントリ)
uid(ファイル所有者のID)
gid(所有者のグループ)
ファイルサイズ
ファイルサイズ(ファイルのバイト数)
アクセス時刻
更新時刻
状態更新時刻
ゾーン0
ゾーン1
ゾーン2
ゾーン3
ゾーン4
ゾーン5
ゾーン6
単一間接ゾーン
二重間接ゾーン
未使用(三重間接ゾーンに使う予定)
単一間接ゾーンは256個の
ブロックを指せるので、
二重間接ゾーンだと
256 x 256 = 65536 [KB]
= 64 [MB]
までアクセスできる
まとめ
• いや、まとめようが……
• MINIXは安いマシンで動かすことを前提としたOS
• それがOSの実装に顕著に表れている
• メモリ管理, iノードのファイルの制限……
実際に使ってみましょう

Minix Learning