カーネル
そして、それらプログラムにロックと入出力サービスを提供する。つまり、カーネルはあらゆる場面に介在しているわけではなかった。
その後、計算モデルが変化し、UNIXの何でもファイルで表す手法が常に適用可能な方法ではなくなってきた。端末はファイルで表せるが(どちらも文字列を読み書きできる)、GUIはそのように扱うことはできない。コンピュータネットワークは別の問題を提起した。ネットワーク経由の通信はファイルアクセスに対応させることができるが、低レベルのパケット指向アーキテクチャはファイルというよりも離散的なデータの塊として扱う必要がある。コンピュータの機能が拡大するにつれ、UNIXのコードは増大していった。それはまた、UNIXカーネルのモジュール性が非常にスケーラブルなためでもあった。初期のカーネルのソースは10万行ほどだったが、Linuxカーネルなどでは1300万行にもなっている。
現代のUnix系OSは、モノリシックカーネルにモジュールローディング機能を加えたものとなっている。たとえば、Linuxカーネルを採用した各種Linuxディストリビューションや、BSDの子孫である FreeBSD、DragonFly BSD、OpenBSD、NetBSD、macOS などがある。
これにはアドレス空間の切り替えを必要とするため、オブジェクト間で複雑なやりとりが必要なシステムでは性能が低下するが、現代のOSはアクセス頻度が低いオブジェクトや性能を要求されないオブジェクトについてはこの方式を採用している。保護機構をより高い階層でシミュレートする方式も可能だが(たとえば、直接サポートされていないハードウェアについてのページテーブルを操作してケイパビリティをシミュレートするなど)、性能上の問題がある。言語ベースの保護を選択するシステムでは、ハードウェアサポートがなくても問題にならない。
カーネル設計における重要な点として、セキュリティの機構と方針を実装する抽象化レベルの選択がある。カーネルのセキュリティ機構は、高度なセキュリティをサポートする上で重要である。
1つの方式として、ファームウェアとカーネルでフォールトトレラント性をサポートする方式があり、その上に悪意ある動作に対するセキュリティ方針を構築し(必要に応じて暗号機構を追加する)、一部の責任をコンパイラに委任する。コンパイラやアプリケーションレベルへのセキュリティ方針の責任委譲の方式を一般に「言語ベースのセキュリティ」と呼ぶ。
現代の主流のOSの多くは重要なセキュリティ機構が欠如しているため、アプリケーションの抽象化レベルでの適切なセキュリティ方針実装ができないことがある。一般にカーネルサポートがどうであれ、アプリケーションで任意のセキュリティ方針を実装可能だとされているが、間違いである。
UNIXの設計段階で、全ての高レベルのデバイスをファイルとして抽象化することが決定された。なぜならUNIX設計者は情報処理の目的をデータの変換であると考えていたからである。
たとえば、プリンターもファイルとして抽象化され、データをそのファイルにコピーすると印字が行われる。他のシステムでは同様の機能を提供するにあたって、デバイスを低レベルに抽象化する傾向があった。デバイスもファイルも何らかの低レベルの概念の実体化である。システムをファイルのレベルで仮想化したことにより、ユーザは既存のファイル管理機能と概念で全てを扱うことができるようになり、操作が大幅に簡略化された。同じパラダイムを拡張して、UNIXはファイルを複数の小さなプログラムで操作するパイプの概念を可能とした。最終的な結果は同じであっても、このような小さなプログラム群を使うことで柔軟性が劇的に向上しただけでなく、開発も利用も容易になった。
UNIXでは、オペレーティングシステムは2つの部分で構成される。さまざまな操作を実行するユーティリティプログラム群とカーネルである。プログラミングの観点から見ると両者の違いは小さい。カーネルは特権モードで動作するプログラムであり、プログラムローダーとしての役割とシステムの残りの部分を構成するユーティリティプログラム群を監督する役割を持つ。
意味のある作業を実行するには、ユーザプログラムはカーネルの提供する全サービスにアクセスできなければならない。これはカーネルによって実装が異なるが、多くは標準CライブラリやAPIが提供され、そこから対応するカーネル機能が呼び出される。
カーネル機能を呼び出す方法は主にCPUがどのような機能を提供しているかに依存する。カーネル空間とユーザー空間が分離されている場合、ユーザープロセスが直接カーネルを呼び出すことはできない。たとえば以下のような技法を採用する。
例外処理や割り込みを明示的に発生する命令(トラップ命令、ソフトウェア割り込み)を使用。多くのハードウェアで実装されている技法である。
コールゲートを使用。x86で採用されている。
特別なシステムコール命令を使用。最近のx86で実装された。
メモリ上のキューを使用。仮想空間の所定の位置にユーザープロセスが要求を投入できるキューを用意し、カーネルがそこから定期的に要求を読み取って実行する。即時性が要求されない場合で、プロセスから複数の要求を行う場合に便利である。