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