カーネル モジュールは Linux 固有のものでしょうか、それとも一般的なメカニズムでしょうか?

カーネル モジュールは Linux 固有のものでしょうか、それとも一般的なメカニズムでしょうか?

Tanenbaum のオペレーティング システムに関する本で、保護リングがあり、リング 0 はカーネルに属すると読みました。一般的には、「カーネル モジュールはリング 0 の I/O とメモリ管理を処理する」と言えるのでしょうか、それとも「カーネル モジュール」は Linux に固有のものであり、たとえば OpenBSD や MULTICS には適用されないのでしょうか。

答え1

Andrew Tanenbaum が提示したアイデアは、通常、Linux (または従来のモノリシック Unix カーネル) に直接適用できません。質問に対する答えは、あなたが示唆しているよりもはるかに簡単です。Linux カーネル モジュールは、カーネル イメージにリンクされるのではなく、コンパイルされて別のファイルにリンクされたカーネル コードです。この別のカーネル オブジェクト ファイル (.ko) は、実行時に必要に応じてカーネル アドレス空間にロードできます。カーネル モジュールとしてコンパイルできるドライバーは、実質的にすべて、カーネル イメージに静的にリンクすることもできます。コードがロードされると、機能に違いはありません。

モジュール コードはカーネル コードであり、他のすべてのカーネル コードと同じ権限で実行されます。カーネル モジュールは、原理的には任意のカーネル コードを置き換えることができますが、これを適切に実行するには、カーネル自体がモジュールがフックできるメカニズムを提供する必要があります。

用語に関する補足: 保護リングは、Multics オペレーティング システムで導入された概念です。「リング 0」から「リング 3」は、Intel プロセッサに固有の用語です。他のプロセッサ アーキテクチャでは、ユーザー/スーパーバイザ モードなど、別の用語が使用されています。Intel プロセッサは 4 つの異なる権限レベルを提供していますが、ほとんどのオペレーティング システムでは、他のプロセッサのユーザー/スーパーバイザ モードを反映して、ユーザー レベル コード用のリング 3 とカーネル コード用のリング 0 の 2 つのレベルのみを使用しています (例外は、3 つの権限レベルを使用した OS/2 です)。

特権レベルの概念は、ハードウェア レベルの仮想化テクノロジの出現により、最近拡張されました。たとえば、ARM アーキテクチャでは、ユーザー、スーパーバイザー、ハイパーバイザーの 3 つの特権レベルが定義されています。冗談で言えば、Intel ベースのマシンでは最終的に 4 つのリングが使用されると言われています。ユーザー レベル コードにはリング 3、(仮想マシン) カーネル コードにはリング 0、ハイパーバイザー コードにはリング -1、SMM モードにはリング -2 です。

答え2

カーネルの概念は、すべてのオペレーティング システムに適用されるわけではありません。カーネルの概念は広く普及していますが、特定のシステムにカーネルをどのように適用するかについては議論の余地があります。

プログラムが互いに分離されているマルチプログラミング システムの場合、カーネルの正確な定義があります。カーネルは、すべてにアクセスできるシステムの一部です。カーネルは分離されていない部分です。カーネルの役割は、少なくとも分離メカニズムを提供することですが、それ以上のこともできます。Linux を含む従来の Unix カーネル アーキテクチャでは、カーネルにはハードウェア ドライバー、ネットワーク プロトコル、ファイル システム ドライバーなども含まれています。

ほとんどのシステムでは、実行中のプログラム間の分離はハードウェア機能 (プロセッサの特権モード、メモリ管理ユニット) に依存しています。カーネルは、プロセッサの最高特権モードで実行されるシステムの一部であり、システム全体の特権を制御できるモードです。x86 プロセッサでは、このモードは「リング 0」と呼ばれます。「リング 0」は x86 用語であり、一般的な概念ではないことに注意してください。一般的な概念は「カーネル モード」または「特権モード」または「スーパーバイザ モード」と呼ばれます。

「カーネル モジュールはリング 0 の I/O とメモリ管理を処理する」という記述は意味をなしません。カーネルは全体として、メモリ管理 (どのプロセスがどのメモリを所有し、どのアドレスでアクセスするかを決定するレベル) と I/O (周辺機器との間でデータをコピーするレベル) を処理します。カーネルは全体として、プロセッサのカーネル モード (x86 プロセッサのリング 0) で実行されます。

カーネル モジュールは、ブート後にロードされるカーネルの一部です。モジュールとブート時コードの唯一の違いは、ロード方法にあります。カーネル モジュール内のコードは、ブート時にロードされるカーネル コードと同じ権限レベルで実行され、同じ機能を実行できます (モジュールとしてロードできるコードは、ブート時イメージに含めることもできます)。Solaris、*BSD、Linux など、多くの最新の Unix システムにはカーネル モジュールがあります。

関連情報