last update Jun 4, 1999
ひとつ上に戻ろう トップ・ページへ戻ろう

カーネルの設計

今の流行で普通に作ると

 取りあえず、目指すOSの仕様を書いてみる。新しいOSを作るとなると、必須の機能だ。 これくらいの機能を持ってないと作る意味がない。

 「マルチ」という言葉が多い。これだけ見ると「BeOSなんじゃないか」という気がするけど、 その通りだ。それだけBeOSは新しい、良くできたOSということだ。

マルチタスクの意味

 マルチタスクといっても、Windos 3.1もWindows NTもマルチタスクだ。 んが、この両者には決定的な違いがある。 Windows 3.1がイベントドリブン(event driven)でマルチタスクを実現していたのに対し、 Windows NTはタイムシェアリング(time shearing)で実現している(と思う)。 説明しよう。イベントドリブンとは、言葉の通り、イベントによって実行タスクが切り替わる、 というか、アプリケーション側でタスクをバトンリレーよろしくタスク実行権を受け渡す処理をしなければならない。 例を示そう。LHAなどの書庫解凍プログラムをイベントドリブン式のマルチタスクで実現しようとする場合、 プログラムの流れは以下のようになる。

[ 実行権受け取り ] - [ 書庫を20KB分解凍 ] - [ 実行権受け渡し ]

ここで重要なのは、書庫の20KB分解凍の「20KB」というのは、 そのアプリケーション作者の裁量に任されているということだ。 なので512KB分解凍してから実行権を他のタスクに回そうとか、 全部解凍し終わってから渡そう、というプログラムも作れる。その場合は、 解凍し終わるまで他のタスクが実行されない、つまり事実上シングルタスクのOSになってしまうのだ。 そういうことは悲しいと思う。また、アプリケーションのバグで無限ループかなんかにはまってしまうと、 実行権も無限に他のタスクに渡されなくなってしまい、デッドロック(dead lock)になってしまう。 Windows 3.1が不安定だった一つの理由だ。

 それに比べ、タイムシェアリングというのは、タスク実行権をOSが時間単位で強引に切り替えてしまう。 たとえば、1/100秒単位とかでだ。これを特に「プリエンティブなマルチタスク」と言ったりする。 Windows 3.1から95に代わるときは、この言葉がキーワードになった。この仕組みをとると、 アプリケーション側では特にマルチタスクのためのプログラミングをしなくてもよく、 アプリケーションにバグがあろうともOSは淡々と時間単位で実行権を切り替えていくので、 他のタスクに影響はない。

 つまり「マルチタスクのOS作るならプリエンティブなタイムシェアリングシステムよね」 とでも言っておけば、君の女子高生の彼女も納得するのだ。

リアルタイム性

 タイムシェアリングはマルチタスクの実現方法としては清く正しいのだけど、 問題がひとつある。実行プロセスを単位時間で切り替えるのは、 プロセッサの使用に無駄があるのだ。コンパイルしながらエディタでソースをいじるとしよう。 コンパイラはプロセッサの資源を100%要求するのに対し、エディタはキーボードを打つ人間がとろいので、 単位時間に割り当てられたプロセッサの資源を10%くらいしか使わない。 これはもったいない。ならば今まで均等に、コンパイラに(例えば)1/100秒、 エディタに1/100秒のプロセッサリソースを割り当てていたものを、 1/100秒と1/1000に不均等にしたほうが良い。これすなわち、 プロセスに実行権の優先順位をつけるということだ。

 ところで、何故これがリアルタイム性と関係してくるかだが、 今ひとつのデバイスに1/1000秒の精度を要求する観測機器がつながっているとして、 それをひとつのプロセスが監視している。しかし、タスク切り替えが1/100秒ならば、 遅延が最大10倍出てしまう。こりゃ大変だ。 なので観測機器に反応があった瞬間に、そのプロセスは実行権を欲しいわけで、 そのプロセスに優先度を高く設定しておけば、割り込みよろしく実行件を横取りできるわけだ。 つまり、決められた単位時間で動くのではなく、必要な時に動きたい=リアルタイムということだ。 そして、リアルタイムOSといえばOS-9やTRONなのだが、 これらは工業用組み込み機器のOSとして活躍している。 自動車のエンジンの点火制御などにはリアルタイム性が必要だからだ。

 さて、プロセスの優先順位が決められればそれだけでリアルタイムOSなのか、 というとそうでもない。割り込み遅延時間の保証やら、 保証されたスレッドの実行時間を獲得する方法だとか、よく解らないことがある。勉強しなければ。

マイクロカーネル

 マイクロカーネルを語るには、モノシリックカーネルを語るが早い。 モノシリックとは「一枚岩」という意味で、OS機能が一つのプログラムで提供されることを表す。 伝統的なUNIXがモノシリックカーネルだ。

 モノシリックカーネルでは、そのOSがネットワークをサポートしていればネットワーク機能をOS内部に持ち、 さらにはネットワークカードのデバイスドライバまで持っている。 こんなふうに扱う機能やそのためのドライバをカーネル内部に持っているもんだから、 機能が増えればカーネルがでかくなるし、それが嫌でいらない機能をはずしたり、 システムの設定を変更したいときには「カーネルのリコンパイル」という作業をしなければ成らない。 おそろしい。それに第一、バグが見つけにくい。

 これを解決するために(と言うか必然的に)、マイクロカーネルが出てくるわけだ。 マイクロカーネルは文字通り小さいカーネルで、カーネルはOSの必要最低機能しか持たない。 プロセス管理、メモリ管理等だ。その他の機能はタスクとして走らせ、カーネルとはメッセージ通信でやり取りする。 美しい、設計としては美しい。また、アーキテクチャが違うコンピュータにOSを移植するときにも、 変更点が少なくすみ容易になる(らしい)。またSMP(後で説明)にも対応させやすい(らしい)。

 良いことばかりでなく欠点は、カーネルとはメッセージ通信でやり取りするため、 そのオーバーヘッドで遅くなると言うことだ。Windows NT 3.51のグラフィックは遅いと苦情が出たので、 その機能を4.0ではユーザーモードからカーネルモードへ移している。 んが、逆にいえばAGPなど作って速度を要求するのはグラフィックデバイスくらいなもので、 次に早そうなUltra Wide SCSIでも80MB/secと、PCIバスの132MB/secより遅い (デュアルチャンネルなら160MB/sec出るけどそれは理論値だし、 それに追いつけないのはPCIの性能限界の問題だ。ん!?じゃあ160MB/secって値に意味ないじゃん。 RAID組んでもそんな転送速度持ってるHDシステムは組めないだろうし) のでグラフィック機能はカーネルの内部に置き、 その他の機能はユーザーモードでタスクとして走らせるのが適当だろう。 「遅くなってでもマイクロカーネルを死守し、グラフィックインターフェイスもユーザーモードで走らせるんじゃあ!」 というのも、やっぱり美しい、と思う、けど。

マルチランゲージ

 マルチランゲージと言うけれど、要は日本語が使えれば良いわけで、 それはUNICODEかUTF-8(二つの区別がいまいちわからん。 UTF-8はUNICODEのスーパーセットなのか?)が使えれば済むことで、 そうすると自然に中国語にも韓国語にもロシア語にもドイツ語にも対応するアルネ。

マイクロカーネル 続き

 先にマイクロカーネルは最小限カーネルとして必要な機能だけをカーネル内に置き、 外に出せるものは出してしまっていると述べた。ここでMachの例を出そう。

 Mach(発音は「まーく」だか「まーち」だか「まっは」だか知らん。 個人的には「まっは」と読んでいるけどこれはドイツ語読みで、 アメリカじゃ「まっく」だとややこしいんで「まーく」らしい。 開発元はアメリカの大学なんで、アメリカ読みが本とは正しいんだろう。 Linuxといい発音記号をつけとくべきだ) はカーネギーメロン大学で研究開発されて、 Windows NTやら(OS/2もかな)NeXT STEPやら、 次期MacOSのXのベースカーネルにもなっている最新鋭のマイクロカーネルだ。

ここも見てみよう
Mach
Mach 4
Realtime Mach

 それで実は、MachはもともとBSDをマイクロカーネル化したものなので、 4.4 BSDとPOSIXに準拠している。んが、正確にはしていない。この言葉の意味はと言えば、 4.4 BSDとPOSIXのシステムコール(最近はAPIか)をカーネルレベルではなくユーザータスクレベルで実装している。 つまりpersonality serverなるプロセスがカーネルの上で走っているのだ。 このことを知ったとき、あたしは驚いた。 そしてすぐに「Human68kサーバ」という言葉が頭に浮かんだのだけれども、まあそれは先の話だ。 ちなみにそのPOSIXサーバはLitesとかいうフリーのがあったはず。それを組み合わせれば、 FreeBSDとかのカーネルをMachに入れ替えられたりする。