したがって、LinuxまたはWindowsベースのx86システムは、カーネルモードにリング0のみを使用し、ユーザーモードにリング3を使用します。いずれにせよ、プロセッサが4つの異なるリングをすべて使用してしまうのに、なぜそれらを区別するのでしょうか。そして、これはAMD64アーキテクチャで変更されましたか?
主な理由は2つあります。
最初の理由は、x86 CPUは4つのメモリ保護リングを提供しますが、それによって提供される保護の粒度はセグメントごとのレベルにすぎないということです。つまり、各セグメントは、書き込み無効などの他の保護とともに、0から3までの特定のリング(「特権レベル」)に設定できます。しかし、利用できるセグメント記述子はそれほど多くありません。ほとんどのオペレーティングシステムは、より細かいメモリ保護を望んでいます。のように...個々のページ。
したがって、ページテーブルエントリ(PTE)に基づいて保護を入力します。すべてではないにしてもほとんどの最新のx86オペレーティングシステムは、多かれ少なかれセグメント化メカニズムを無視し(とにかく可能な限り)、PTEベースの保護に依存しています。これは、各PTEの下位12ビットであるフラグビットと、実行なしをサポートするCPUのビット63によって指定されます。各ページに1つのPTEがあり、通常は4Kです。
これらのフラグビットの1つは、「特権」ビットと呼ばれます。このビットは、ページにアクセスするためにプロセッサが「特権」レベルの1つである必要があるかどうかを制御します。 「特権」レベルはPL0、1、および2です。ただし、これは1ビットであるため、ページごとの保護レベルでは、メモリ保護に関する限り使用可能な「モード」の数は2つだけです。非特権モードからアクセスできるかどうか。したがって、2つのリングだけです。
各ページに4つの可能なリングを設定するには、各ページテーブルエントリに2つの保護ビットを設定して、4つの可能なリング番号の1つをエンコードする必要があります(セグメント記述子と同様)。彼らはしません。
2番目の理由はOSの移植性の目標です。 x86だけではありません。 Unixは、OSが複数のプロセッサアーキテクチャに比較的移植可能であり、それは良いことだと教えてくれました。また、一部のプロセッサは2つのリングのみをサポートします。アーキテクチャ内の複数のリングに依存しないことにより、OS実装者はOSの移植性を高めました。
番目の理由がありますこれはWindowsNT開発に固有のものです。 NTの設計者(MicrosoftがDEC Western Region Labsから採用したDavidCutlerと彼のチーム)は、VMSに関する豊富な経験を持っていました。実際、Cutlerと他の数人は、VMSの元の設計者の1人でした。また、VMSが設計された(およびその逆の)VAXプロセッサには4つのリングがあります。 VMSは4つのリングを使用します。 (実際、VAXにはPTEに4つの保護ビットがあり、「ユーザーモードからは読み取り専用ですが、リング2と内部からは書き込み可能」などの組み合わせが可能です。しかし私は逸脱します。)
ただし、VMSのリング1および2で実行されたコンポーネント(レコード管理サービスおよびCLI、それぞれ)は、NTの設計から除外されました。 VMSのリング2は、実際にはOSのセキュリティではなく、あるプログラムから次のプログラムへとユーザーのCLI環境を維持することであり、WindowsNTにはその概念がありませんでした。 CLIは通常のプロセスとして実行されます。 VMSのリング1に関しては、リング1のRMSコードはリング0をかなり頻繁に呼び出す必要があり、リング遷移はコストがかかります。リング0に移動する方がはるかに効率的であることがわかりました。そして、リング1コード内に多くのリング0遷移を持たせるのではなく、それで実行します(繰り返しますが、NTにはRMSとにかく)のようなものがあるわけではありません。)
しかし、なぜそこにあるのですか? OSがそれらを使用しなかったのにx86が4つのリングを実装した理由については、x86よりはるかに新しい設計のOSについて話しています。 x86の「システムプログラミング」機能の多くは、NTまたは真のUnix風カーネルが実装されるずっと前に設計されており、OSが何を使用するかを実際には知りませんでした。 (x86でページングを取得するまで(80386まで表示されませんでした)、真のUnix風またはVMSを実装できました -メモリ管理をゼロから再考することなく、カーネルのように。)
最新のx86OSは、セグメント化をほとんど無視するだけでなく(ベースアドレス0、サイズ4 GBのC、D、およびSセグメントを設定するだけです。FおよびGセグメントは、主要なOSデータ構造を指すために使用されることもあります)。 「タスク状態セグメント」のようなものはほとんど無視します。 TSSメカニズムは、スレッドコンテキストの切り替え用に明確に設計されていますが、副作用が多すぎることが判明したため、最新のx86OSは「手動で」それを実行します。たとえば、x86 NTがハードウェアタスクを変更するのは、二重障害例外などの真に例外的な条件の場合のみです。
X64では、これらの使われなくなった機能の多くが省略されていました。 (彼らの名誉のために、AMDは実際にOSカーネルチームと話し合い、x86から何が必要か、何が不要か不要か、何を追加したいかを尋ねました。)x64のセグメントは、可能性のあるものにのみ存在します。痕跡形式と呼ばれ、タスク状態の切り替えが存在しないなど。OSは引き続き2つのリングのみを使用します。