it-swarm-ja.com

x86でのスワッピング、ページング、セグメンテーション、および仮想メモリPMアーキテクチャ

これはよくある質問またはすでに尋ねられている質問のように思われるかもしれませんが、さまざまな本、オンラインチュートリアル、そしてここSUでさえ検索した後、これら4つの獣がx86プロテクトモードシステムでどのように連携するかについてはまだ戸惑っています。

これらのことについて話し合うときに使用できる正しい用語は何ですか?

私の知る限り、これら4つの概念はすべて完全に異なりますが、メモリ保護について話すときに関連します。これは私にとってそれが台無しになったところです!

最初にスワッピングから始めます。

スワッピング:

プロセスは、実行のために物理メモリ内にある必要があります。プロセスを一時的に物理メモリからバッキングストアにスワップしてから、メモリに戻して実行を継続することができます。

これは、複数のプロセスを同時に実行するマルチタスク環境に特に当てはまります。したがって、CPUスケジューラーを実装して、バッキングストアにスワップするプロセスを決定します。

ページング:別名単純ページング:

たとえば、プロセスが0〜16MBの範囲で使用/アクセスするすべてのアドレスを持っているとします。アドレスはプロセスによって生成されるため、これをプロセスの論理アドレス空間と呼ぶことができます。

この定義により、プロセスの論理アドレス空間は、プロセスが大きくなったり小さくなったりする可能性があるため、別のプロセスの論理アドレス空間とは異なる可能性があることに注意してください。

ここで、プロセスのこの論理アドレス空間をページと呼ばれる同じサイズのブロックに分割します。また、物理メモリをフレームと呼ばれる固定サイズのブロックに分割します。

Defによる。論理アドレス=ページ番号:そのページのオフセット

プロセスがCPUスケジューラによって実行されるように選択されると、そのページはバッキングストアから任意の使用可能なメモリフレームにロードされます。

このプロセスに属するページのすべては、制御がスケジューラからこのプロセスに転送される前に、メモリにロードされることに注意してください。このプロセスをバッキングストアにスワップする場合、そのページのすべてがバッキングストアに保存されます。

バッキングストアは、物理メモリフレームと同じサイズの固定サイズのブロックに分割されます。

これにより、バイトではなくページをスワップするため、スワッピングプロセスが容易になります。これにより、一部のバイトのスペースを見つける必要がないため、バッキングストアでの断片化が減少します。代わりに、ページにスペースが使用可能かどうかを確認します。

ページング手法では、ページをメモリに保持するため、物理メモリの断片化も減少します。

メインメモリには、プロセスを実行のためにメモリにロードするために、プロセスに属するページのすべて用のスペースが必要です。このプロセスの数ページだけのスペースがある場合は、他のプロセス(つまり、プロセスに属するすべてページ)をバッキングストアにスワップしてから、実行するプロセスのすべてのページのみをロードする必要があります。メモリ。

したがって、ページング手法は、単純なスワッピングよりも優れたパフォーマンスを提供します。

したがって、スワッピングにより、メモリを購入しすぎずに複数のプロセスを実行できます。代わりに、少量のメモリで作業できます(この量は、最大のプログラム/プロセスのページのすべてになる必要があります。 PCで実行する場合は、メモリにロードできます。つまり、プログラムを実行する前に、プログラムに必要なメモリの量を知っておく必要があります。)さらに、メインメモリよりもはるかに大容量の場合はコストが非常に低い追加のバッキングストア(通常はディスク)。

したがって、スワッピング+ページングにより、メモリを効率的に管理できるため、システム上で複数のプロセスを実行できます。

デマンドページング:

ただし、システムにインストールされている物理メモリは、プロセスの要件と同じである必要はありません。また、複数のプロセスを実行する必要があります。

解決策は、プロセスの一部のページのみをメモリにロードすることです。プロセスがメモリにないページのアドレスにアクセスすると、ページフォールトが生成され、OSがそのページをロードしますオンデマンドプロセスが実行を継続できるようにします。これにより、ページング+スワッピングの場合のように、プロセスのすべてのページをロードしてから制御を移す時間を節約できます。

プロセスの一部のみをメモリに保持し、ディスクなどのバッキングストアに置くこの手法は、デマンドページングと呼ばれます。

したがって、デマンドページング=ページング+スワッピング+プロセスの一部のページ(すべてではない)のみをメモリに保持します。


これは、私が知っているページングとスワッピングに関するものです。上記のどこかで私が間違っていると私を訂正してください。

今私の質問は次のとおりです:

  1. x86プロテクトモードのコンテキストで、仮想メモリと仮想アドレス空間(別名線形アドレス空間)の用語がデマンドページングにどの程度正確に関連しているか。

  2. 「プロセスの仮想メモリ」は正しい用語ですか、それとも仮想メモリはマルチタスクシステムで現在実行されているすべてプロセスに対して定義されていますか?

  3. 私は正しいですか:プロセスで使用可能な仮想メモリ==プロセスの仮想アドレス空間(別名線形アドレス空間)の最高のアドレス+ 1?

  4. これはセグメンテーションについてです。x86プロテクトモードでは、各プロセスが4GBの仮想アドレス空間(VAS)を持つことができると言われています。つまり、セグメンテーションはx86アーキテクチャに存在するため、このVASを分割に2つ以上のセグメント。 x86フラットモデルではプロセスのVASにセグメントを作成しますが、それらはすべて正確にオーバーラップしているため、事実上セグメンテーションは無効になっています-セグメントはありません。しかし、あるプロセスのVASの仮想アドレスに、いくつかのcpu命令が存在する場合、(このVASで)メモリを割り当てるとき、または変数や配列を作成するときに、これらの命令を上書きする可能性があります。これが発生しないようにするにはどうすればよいですか。フラットモードではすべてのセグメントがオーバーラップするため、記述子の保護ビットは領域の白黒を区別しません。これらのビットは、コードの読み取りやデータの実行を防ぐことしかできず、セレクターを介してセグメントにアクセスすることしかできません。

  5. または、各セグメントが独自のVASとして扱われるようなものですか。ただし、その場合、フラットモードでのプロセスで使用可能な合計仮想メモリ(または合計VAS)は、「プロセスに属するセグメントの数x単一セグメントの仮想メモリ」になります。 x86保護モードの場合、これは6 x 4GB = 24GBのVASに変換されます。 CS、DS、ES、GS、FS、SSレジスタが指す6つのセグメントを想定しています。これは正しいです ?

  6. 単純なページング(デマンドページングではない)をサポートしているが仮想メモリはサポートしていない環境では、フラットメモリモデルのさまざまなセグメントの保護をどのように保証しますか?ここでは、シングルタスクシステムとマルチタスクシステムの2つのケースがあります。

更新:2012-07-29

だから私がそれを正しく理解していれば:

仮想メモリは概念であり、実装x86アーキテクチャ上でによってデマンドページング技術+いくつかの保護ビット(具体的にはUビットとWビット)を使用します。

IOW、プロセスのVASはページに分割であり、デマンドページングで使用されます。

仮想メモリメカニズムには、基本的に2つの用途がマルチタスク環境であります。

  1. プログラムのサイズは、使用可能な物理メモリの量を超える場合があります。オペレーティングシステムは、プログラムのこれらの部分を現在メインメモリで使用し、残りをディスクに保持します。これは、各ページのページテーブルエントリに「現在のビット」と「アクセスされたビット」が関連付けられたデマンドページングによって実装されます。

  2. 各プロセスに独自の仮想アドレス空間を与えることでメモリ保護を提供するため、1つのプロセスは他のプロセスのVASにアクセスできません。これは、いくつかの保護ビット各ページに関連付けられているを持つことによって実装されます。具体的には、ページテーブルエントリの「ユーザー/スーパーバイザビット-Uビット」、読み取り/書き込みビットWビット 'がページアクセス保護に使用されます。

仮想メモリは、両方シングルタスクシステムとマルチタスクシステムで役立ちます。シングルタスクシステムの場合、のみUse#1が関係します。

ページアクセス保護には2つの側面があります:特権レベルの保護および書き込み保護。これらは、それぞれUビット(prviledge用)とWビット(書き込み用)によって実装されます。これらのビットは、そのページのページテーブルエントリに存在します。

メモリ保護には2つの側面があります:プログラムを相互にアクセスから保護し、プログラムをそれ自体を上書きするから保護します(そのプロセス/プログラムのVASでセグメントが重複する場合)。

前者問題はVASまたは仮想メモリの概念によって解決されますが、後者はどうですか

ページアクセス保護スキームしない私が知る限り、後者を防ぎます。 IOW、仮想メモリ技術は、プロセスのVASでセグメントが重複する場合に、プログラムがそれ自体を上書きするのを防ぎません。

しかし、セグメントレベルの保護でさえメモリ保護の後者の(それ自体を上書きする)問題を防ぐことはできないように私には思えます。

x86 cpu常にセグメントレベルの保護を評価します前にページレベルの保護チェックを実行します-フラットモデルかマルチセグメントモデルかに関係なく-x86cpuでセグメンテーションを無効にする方法がないため。

フラットモデルのシナリオを考えてみましょう。

CS:offによって参照される仮想アドレスについて考えてみます。 'off'の値が両方の場合でまったく同じである場合、DS:offはCS:offによって参照される同じ仮想アドレスも参照します。これはSS:offにも当てはまります。

これは、this仮想/線形アドレスが存在するページが、セグメンテーションについて知らないため、ページングユニットによって単なるページとして表示されることも意味します。

フラットモードのプログラムのすべてのセグメントが同じ特権レベル、たとえばring0に属していると仮定します。

CS:off = DS:off = SS:offでデータを書き込んだり実行したりするとどうなるでしょうか。

このアドレスは、プロセスのVASにマップされたOSコードに属していないと仮定します。簡単にするためにOSは脇に置いておいてください。ハードウェアレベルの保護について話しています!

最初にセグメントレベルの保護が渡され、次にこのページ(CS:offまたはDS:offまたはSS:offを含むページ)にアクセスしている間、すべてのセグメントが同じ特権に属しているため、特権レベルのチェックが渡されます。 、しかしこのページのWビットはどうですか。書き込みを許可するには、これを1に設定する必要があります。そうしないと、データセグメントが自分のページで書き込みを実行できなくなります。つまり、このページも書き込み可能であることを意味します。

これは、この仮想(線形)アドレスでデータの読み取り/書き込み/実行ができることを意味します:CS:off = DS:off = SS:off。?

X86ハードウェアがこの問題を保護する方法を理解していませんセグメントが重複している場合

4
jacks

確かに、たくさんの用語が飛び交い、混乱する言葉遣いがありましたが、私は答えるために最善を尽くします。私が知る限り、あなたの理解の大部分は正しいと言えますが、いくつかのポイントがあります。

ページングと仮想メモリがハードウェアコンテキストからどのように機能するかを理解することが重要です。プロセスはメモリの配置方法に依存しない必要があり、オペレーティングシステムはシステム上のすべてのプロセスをベビーシッターするためにソフトウェアを使用する必要がないため、ページングは​​ハードウェアサポートなしでは実用的ではありません。そこで登場するのがメモリ管理ユニット(MMU)です。このユニットは基本的にオペレーティングシステムによってプログラムされ、仮想アドレス空間にページを配置し、オペレーティングシステムによって自由に制御できます。オペレーティングシステムは、どのページが実際に物理RAMにあり、どのページがまだロードされていないか、またはスワップアウトされているかをユニットに通知できます。

では、プログラムがこのメモリ管理のものを台無しにしないようにするにはどうすればよいでしょうか。私たちが保護と呼ぶもの。プロセスがオペレーティングシステムや他のプロセスと干渉しないように、プロセスをサンドボックス化しておくことができます。これらの用語がすべて一緒に使われる理由についての混乱は、それらが実際に相互に関連しているという事実から生じています。コードが持つ特権は、ページテーブルによって指定されます。ページテーブルは、MMU仮想空間のレイアウト方法を示し、MMUページがA)存在するかどうかB)読み取り/書き込み可能C)コードの実行を許可するかどうかも示しますD)そのページのコードが実行できる特権レベル(リング)。

スケジューラがプロセスをスケジュールするとき、ページテーブルは再作成されず、新しいメモリを配置する必要はありません。オペレーティングシステムは、MMUに別のページテーブルを使用するように指示するだけです。これはO(1)プロセス、つまり、プロセスのサイズや使用するメモリの量に依存しません。プロセス全体が一度にメモリにスワップインおよびスワップアウトされることはめったになく、通常は一度にページのみであるため、「スワッピング」という用語は「ページスワッピング」として明確にされることがよくあります。

さて、そのような背景で、私はあなたの質問のそれぞれに答えようとします:

  1. 線形アドレス空間とは、0から2 ^ 32までの範囲にアクセスできることを意味します。 16ビットプロセッサの時代に必要だったような凝ったセグメンテーションの必要はありません。仮想メモリとは、プロセスの線形アドレス空間がメインメモリではなくオペレーティングシステムによって定義されることを意味します。つまり、オペレーティングシステムはこのアドレス空間にページを任意に配置し、それ自体を高レベルに配置し、プロセスをたとえば、下位レベル。さらに、プロセッサは、この仮想アドレス空間のどの部分にどの特権でアクセスできるかを指定できます。オペレーティングシステム(カーネル)はすべての仮想アドレス空間にロードされるため、プロセスはシステムコールを実行でき、プリエンプトされたときに移動できる場所があります。ただし、OSによって「特権コードのみ」としてマークされているため、この領域の読み取りまたは書き込みはできません。プロセッサのシステムコールメカニズム(つまり、ソフトウェア割り込み)を介してのみアクセスできます。デマンドページングとは、プロセスがこの仮想アドレス空間の特定の部分(おそらくファイルまたはそれ自体の一部)を含むことを期待していることを意味しますが、実際には存在せず、OSはページテーブルの領域を「存在しない」とマークしています。 。プロセスが最終的にこの領域にアクセスすると、存在しないため、CPUはOSによってトラップされた障害をスローします。その後、OSはそのページをロードし、中断したところからプロセスを再開するのに十分スマートです。その結果、プロセスは問題を認識せず、要求されたときにのみロードされ、メモリを節約します。

  2. 仮想メモリは、ページテーブルとその保護を指定するこのメカニズム全体の名前であり、ページはディスクなどの別のメディア上にある可能性があるため、ページングします。仮想メモリは、おそらくセグメンテーションを除いて、おそらくあなたのタイトルの総称です。特定のプロセスを参照するときは、「プロセスの仮想アドレス空間」のようなものを個人的に使用します。これは、特定のプロセスの仮想メモリレイアウトを明確に参照しているためです。

  3. いいえ。前述したように、OSは実メモリをプロセスの仮想アドレス空間内の任意の場所に任意にマップできます。これは、たとえば、プロセスコードがアドレス0x0にあるが、ヒープ(成長)が0xFFFFFFFで始まり、アドレス空間の反対側でクリアされる状況が発生する可能性があることを意味します。デバイスドライバがハードウェア用の特定のアドレス領域を必要とするため、実際にはマッピングされる場所に制約がある場合がありますが、仮想メモリを理解するために、制限はありません。

  4. セグメンテーションは、単なるアドレス指定スキームです。 286では、保護を実装するためのメカニズムとしても使用されていましたが、柔軟性が低すぎることが判明したため、32ビットプロセッサでは、保護は常にページングで行われます(ただし、私が理解しているように、286保護スキームはページング時に保持されます)無効になっています)。保護はページングメカニズムによって定義されるため、セグメンテーションはフラットメモリモードよりもデータを上書きするリスクを多かれ少なかれ引き起こしません。ほとんどの実行可能ファイル形式では、コードセグメントはデータセグメントから明確に分離されています。コードが変更されることはないと予想できるため、オペレーティングシステムは通常、コードセグメントのページを読み取り専用としてマークします。したがって、コードに書き込もうとすると障害が発生し、プログラムが終了します。最新のオペレーティングシステムでは、すべての変数と配列がスタックまたはヒープを介して割り当てられている場合、これは発生しません。ただし、プログラムがこれ以外のことを突っ込み始めた場合、コードを上書きする前にクラッシュします。より大きなリスク(および以前は大きな問題であったリスク)は、スタックがバッファオーバーランで上書きされることです。一部の人はこれを利用してコードをスタックに置き、それを不正に実行させる可能性があります。修正として、ページテーブルの「NoeXecute」(NX)ビットに新しいビットが配置されました。これにより、ページが実行されるのを防ぎます。

  5. これはまったく真実ではありません。セグメントは、アドレス空間の元の2 ^ 32バイトの領域(セグメント)へのポインタとして機能するだけです。この背後にある考え方は、元々、ポインタを小さく保つというものでした。これは、セグメントポインタと、そのセグメント内にアドレス空間全体よりも小さいポインタを含めることができるためです。たとえば、286(16ビットプロセッサ)では、ポインタを16ビットに保つことは理にかなっていますが、286は2 ^ 24バイトのメモリをアドレス指定できるため、これには問題がありました。ソリューション?セグメンテーションを使用します。セグメントは2 ^ 16バイトの大きさで、アドレス空間の任意の場所を指すことができます。次に、コードが動作する必要がある場合、そのセグメント内でのみ16ビットポインターを使用します。これはより速く、より効率的でした。 32ビットプロセッサが登場したとき、このメカニズムはもはや必要ではありませんでしたが、以前のコードで非常に多く使用され、プログラマーがそれらに慣れていたため、セグメンテーションを維持しました。新しい64ビットプロセッサは、セグメンテーションをまったく使用しません。

  6. ここでの混乱は、仮想メモリがこれらのさまざまなメカニズムの多くの用語であるという事実です。あるプロセスを別のプロセスのアドレス空間から保護するためのマルチタスクには、仮想メモリが必要です。ページング、ひいてはプリエンプティブマルチタスクは、仮想メモリ機能でのみ可能です。ただし、これらの機能の多くは効果的に無効にすることができます。おそらくあなたはアドレス変換を望まないのですか?次に、すべてのページをそれ自体にマップします。おそらく、メモリ保護は必要ないが、アドレス変換は必要ですか?次に、すべてのページにすべての権限を付与します。 DOSやその他のシングルプロセッサシステムでは、「プロテクトモード」を参照すると混乱が生じます。通常、これは16ビットのリアルモードではなく32ビットモードを指します。そのため、名前にもかかわらず、必ずしも保護が使用されることを意味するわけではなく、そのモードでのみ有効にできます。この「保護モード」で実行されるが、仮想メモリも保護も使用しない単一プロセスシステムはおそらく多くあります。オリジナルのXboxはその良い例です。これらの機能をすべて無効にすると、パフォーマンスがわずかに向上する可能性があります。ただし、DOSでは、これらの機能の多くを使用する方が有利な場合があります。最も注目すべきはページスワッピングです。DOSが普及していた初期の頃はRAMを入手するのが困難であったため、RAMに保存されたメカニズムは歓迎されよく使用されていました。保護は、プログラムが醜い方法でクラッシュするのを防ぎ、より良いデバッグを可能にし、悪いハードウェアアクセスによるデータの破損を防ぐことができるため、単一プロセスシステムでもその利点がありました。

これがあなたの質問に答えることを願っています。

3
Dougvj