2.3. カーネル サービス

カーネルレベルコードとユーザレベルコードの間の境界は、 基盤となるハードウェアで提供されるハードウェアレベルの保護機能によって 分離されています。 カーネルは、ユーザプロセスにとってアクセスしにくい切り離された アドレス空間で作動します。特権のある操作 -- たとえば I/O の開始や中央処理装置 (CPU) の停止 -- は、カーネルだけが利用可能です。 アプリケーションはシステムコールを用いてカーネルに サービスを要求します。システムコールは二次記憶装置にデータを 書き込むような複雑な作業や、現在の日時を返すような単純な作業を カーネルに実行させるために使用されます。 アプリケーションからは、 すべてのシステムコールが同期的に実行するように見えます。 つまりアプリケーションは、カーネルがシステムコールに関連した 動作をしているときには停止しています。 カーネルはシステムコール操作の一部を、 システムコールが戻った後に完了することもあります。 たとえば write システムコールは、 プロセスが待っている間に書き込むデータをユーザプロセスからカーネルバッファにコピーしますが、 通常、そのカーネルバッファがディスクに書き込まれる前にシステムコールから戻ります。

通常、システムコールは CPU の実行モードおよび現在のアドレス空間マッピングを変更する ハードウェアトラップとして実装されています。 ユーザによって与えられたシステムコール中のパラメータは、 使用される前にカーネルによって検証されます。 そのようなチェックはシステムの完全性を保証します。 カーネルへ渡されたパラメータはすべてカーネルのアドレス空間にコピーされます。 これは、システムコールの副作用により検証されたパラメータが 変更されないことを保証するためです。 システムコールの戻り値は、カーネルによってハードウェアレジスタ中に返されるか、 あるいはユーザが指定したメモリアドレスにコピーされる値で返されます。 カーネルへ渡されたパラメータのように 結果を戻すためにアプリケーションによって指定されたアドレスは、 それらが確実にアプリケーションのアドレス空間の一部である、 ということが検証されなければなりません。 システムコールを処理する間にカーネルがエラーに遭遇した場合、カーネルは ユーザにエラーコードを返します。 C プログラミング言語においては、このエラーコードが大域変数 errnoに格納されます。また、システムコールを 実行した関数は -1 の値を返します。

ユーザアプリケーションとカーネルは、互いに独立して動作します。 4.4BSD は I/O コントロールブロックや、 オペレーティングシステムに関連するその他のデータ構造体を アプリケーションのアドレス空間に格納しません。 ユーザレベルのアプリケーションはそれぞれ、 実行のための独立したアドレス空間を提供されます。 カーネルは、たとえば別のプロセスが走っている間そのプロセスを停止させ、 関係するプロセスに見えないようにするというような、 状態変更のほとんどを実現しています。