オペレーティングシステムとそれらが実行されるハードウェアがどのように機能し、相互作用するかについて詳しく知ると、奇妙なことや「リソース」の活用不足が発生しているように見えることに驚くかもしれません。何故ですか?今日のスーパーユーザーのQ&A投稿には、好奇心旺盛な読者の質問に対する回答があります。
今日の質疑応答セッションは、コミュニティ主導のQ&AWebサイトのグループであるStackExchangeの下位区分であるSuperUserの好意で行われます。
写真提供: Lemsipmatt(Flickr) 。
質問
スーパーユーザーリーダーのAdHominemは、x86CPUが4つのリングのうち2つしか使用しない理由を知りたがっています。
LinuxおよびWindowsベースのx86システムは リング0 カーネルモードおよび リング3 ユーザーモード用。いずれにせよ、プロセッサが4つの異なるリングを使用するだけなのに、なぜそれらを区別するのでしょうか。これはAMD64アーキテクチャで変更されましたか?
x86 CPUが4つのリングのうち2つしか使用しないのはなぜですか?
答え
スーパーユーザーの寄稿者であるJamieHanrahanが答えを持っています。
主な理由は2つあります。
1つ目は、x86 CPUは4つのメモリ保護リングを提供しますが、それによって提供される保護の粒度はセグメントごとのレベルにすぎないということです。つまり、各セグメントは、書き込み無効などの他の保護とともに、特定のリング(特権レベル)に設定できます。しかし、利用できるセグメント記述子はそれほど多くありません。ほとんどのオペレーティングシステムは、個々のページのように、はるかに細かいメモリ保護を望んでいます。
したがって、ページテーブルベースの保護を入力します。すべてではないにしても、ほとんどの最新のx86オペレーティングシステムは、セグメント化メカニズムを多かれ少なかれ無視し(とにかく可能な限り)、ページテーブルエントリの下位ビットから利用可能な保護に依存しています。これらの1つは、「特権」ビットと呼ばれます。このビットは、ページにアクセスするためにプロセッサが「特権」レベルの1つである必要があるかどうかを制御します。 「特権」レベルは PL 0、1、および2 。ただし、これは1ビットであるため、ページごとの保護レベルでは、メモリ保護に関する限り使用可能な「モード」の数は2つだけです。非特権モードからページにアクセスできるかどうかです。したがって、2つのリングだけです。各ページに4つの可能なリングを設定するには、各ページテーブルエントリに2つの保護ビットを設定して、4つの可能なリング番号の1つをエンコードする必要があります(セグメント記述子と同様)。ただし、そうではありません。
もう1つの理由は、オペレーティングシステムの移植性に対する要望です。 x86だけではありません。 Unixは、オペレーティングシステムが複数のプロセッサアーキテクチャに比較的移植可能であり、それは良いことだと教えてくれました。また、一部のプロセッサは2つのリングのみをサポートします。アーキテクチャ内の複数のリングに依存しないことにより、オペレーティングシステムの実装者はオペレーティングシステムの移植性を高めました。
WindowsNT開発に固有の3番目の理由があります。 NTの設計者(MicrosoftがDEC Western Region Labsから採用したDavidCutlerと彼のチーム)は、VMSに関する豊富な経験を持っていました。実際、Cutlerと他の数人は、VMSの元の設計者の1人でした。また、VMSが設計されたVAXプロセッサには4つのリングがあります(VMSは4つのリングを使用します)。
しかし、VMSで実行されたコンポーネント リング1と2 (それぞれレコード管理サービスとCLI)はNTの設計から除外されました。 リング2 VMSでは、実際にはオペレーティングシステムのセキュリティではなく、あるプログラムから次のプログラムまでユーザーのCLI環境を維持することを目的としており、Windowsにはその概念がありませんでした。 CLIは通常のプロセスとして実行されます。 VMSについては リング1 、のRMSコード リング1 に電話しなければならなかった リング0 かなり頻繁に、リング遷移は高価です。ただ行くだけではるかに効率的であることが判明しました リング0 たくさん持っているのではなく、それで終わります リング0 内の遷移 リング1 コード(繰り返しますが、NTにはRMSのようなものがあります)。
オペレーティングシステムが4つのリングを使用していないのに、x86が4つのリングを実装した理由については、x86よりもはるかに新しい設計のオペレーティングシステムについて話しています。 x86のシステムプログラミング機能の多くは、NTまたは真のUnix風カーネルが実装されるずっと前に設計されており、オペレーティングシステムが何を使用するかを実際には知りませんでした。真のUnix風またはVMSのようなカーネルを実装できるようになったのは、x86でページングを取得するまででした。
最新のx86オペレーティングシステムは、セグメント化をほとんど無視するだけでなく(ベースアドレスが0、サイズが4 GBのC、D、およびSセグメントを設定するだけです。FおよびGセグメントは、主要なオペレーティングシステムのデータ構造を指すために使用されることがあります。 )、「タスク状態セグメント」などもほとんど無視します。 TSSメカニズムは、スレッドコンテキストの切り替え用に明確に設計されていますが、副作用が多すぎることが判明したため、最新のx86オペレーティングシステムは「手動で」それを実行します。 x86 NTがハードウェアタスクを変更するのは、二重障害の例外など、いくつかの本当に例外的な条件の場合のみです。
x64アーキテクチャに関しては、これらの使われなくなった機能の多くが省略されていました。彼らの名誉のために、AMDは実際にオペレーティングシステムのカーネルチームと話し合い、x86から何が必要か、何が不要か、何が不要か、何を追加したいかを尋ねました。 x64のセグメントは、痕跡形式と呼ばれるものでのみ存在し、タスク状態の切り替えは存在しません。オペレーティングシステムは引き続き2つのリングのみを使用します。
説明に追加するものがありますか?コメントで音を立ててください。他の技術に精通したStackExchangeユーザーからの回答をもっと読みたいですか? ここで完全なディスカッションスレッドをチェックしてください 。