17

私はオペレーティング システムの設計と概念に関するコースを受講しており、現在は Linux カーネルを徹底的に研究しようとしています。どうしても捨てられない質問があります。最新のオペレーティング システムでは、各プロセスに独自の仮想アドレス空間 (VAS) があります (たとえば、32 ビット システムでは 0 から 2^32-1 まで)。これには多くの利点があります。しかし、実装では、いくつかの点で混乱しています。例を挙げて説明しましょう。

2 つのプロセス p1、p2 があるとします。p1 と p2 には独自の VAS があります。アドレス0x023f4a54が異なる物理アドレス (PA) にマップされていますが、どうすればよいでしょうか? この翻訳はどのように行われますか。つまり、変換メカニズムは知っていますが、異なるプロセスのアドレス空間になると、同じアドレスが異なる物理アドレスにマップされることを理解できません。

0x023f4a54 in p1's VAS => PA 0x12321321
0x023f4a54 in p2's VAS => PA 0x23af2341 # (random addresses)
4

6 に答える 6

26

仮想メモリを提供する CPU では、CPU が参照するメモリ アドレスの物理メモリ アドレスへのマッピングを設定できます。通常、これは MMU と呼ばれるハードウェア ユニットによって行われます。

OS カーネルは、通常は個々のアドレスではなく、ページ単位 (4096 バイトが一般的) でその MMU をプログラムできます。これは、たとえば仮想アドレス 0x1000-0x2000 を物理アドレス 0x20000-0x21000 に変換するように MMU をプログラムできることを意味します。

OS は、プロセスごとにこれらのマッピングの 1 つのセットを保持し、プロセスの実行をスケジュールする前に、そのマッピングを MMU にロードしてから、制御をプロセスに戻します。これにより、プロセスごとに異なるマッピングが可能になり、それらのマッピングが同じ仮想アドレスを別の物理アドレスにマッピングすることを妨げるものは何もありません。

プログラムに関する限り、これはすべて透過的であり、CPU で命令を実行するだけであり、CPU が仮想メモリ モード (ページ モード) に設定されているため、すべてのメモリ アクセスは MMU によって変換されてから、メモリへの物理バス。

実際の実装の詳細は複雑ですが、より多くの洞察を提供する参考文献を次に示します。

于 2010-08-08T19:08:57.143 に答える
6

あなたの質問は、仮想アドレスとアドレスを識別方法として使用することを混同しているため、理解するための最初のステップは概念を分離することです。

実際の例は、C ランタイム ライブラリ関数sprintf()です。適切に宣言されて呼び出されると、必要なすべてのサブ関数とともに、共有オブジェクト モジュールとしてプログラムに組み込まれます。ライブラリは使用可能な空きアドレスにロードされるため、のアドレスはsprintfプログラムごとに異なります。単純なhello worldプログラムの場合、sprintf はアドレス 0x101000 にロードされる可能性があります。税金を計算する複雑なプログラムの場合、0x763f8000 にロードされる可能性があります (メイン プログラムに含まれる厄介なロジックはすべて、参照するライブラリの前に配置されるため)。システムの観点から見ると、共有ライブラリは 1 か所だけでメモリにロードされますが、各プロセスがそのメモリを参照するアドレス ウィンドウ (アドレスの範囲) は、その実行可能ファイルに固有のものです。

もちろん、共有ライブラリ マッピングなど、さまざまなプログラム セクションがメモリにロードされるアドレスをランダム化するSecurity Enhanced Linux (SELinux)の機能によって、これはさらに複雑になります。

--- 明確化 --- 誰かが正しく指摘しているように、各プロセスの仮想アドレス マッピングは、ファイル記述子、ソケット接続、プロセスの親と子などのセットとは異なり、各プロセスに固有です。つまり、p1 がマップされる可能性があります。アドレス 0x1000 を物理 0x710000 にマップし、p2 はアドレス 0x1000 をページ フォールトにマップし、p3 は物理 0x9f32a000 の共有ライブラリにマップします。仮想アドレス マッピングは、オペレーティング システムによって慎重に監視されます。これはおそらく、スワッピングやページングなどの機能を提供するためだけでなく、共有コードやデータ、プロセス間共有データなどの機能も提供するためです。

于 2010-08-08T19:05:24.663 に答える
5

ページングを扱う 2 つの重要なデータ構造があります。ページ テーブルと TLB です。OS は、プロセスごとに異なるページ テーブルを維持します。TLB は、ページ テーブルの単なるキャッシュです。

さて、さまざまな CPU は、まあ、さまざまです。x86 は、使用中のページ テーブルを指す CR3 と呼ばれる特別なレジスタを使用して、ページ テーブルに直接アクセスします。MIPS プロセッサはページ テーブルについて何も知らないため、OS は TLB を直接操作する必要があります。

一部の CPU (例: MIPS) は TLB に識別子を保持して異なるプロセスを分離するため、OS はコンテキスト スイッチを実行するときに制御レジスタを変更するだけで済みます (識別子を再利用する必要がない場合)。他の CPU では、すべてのコンテキスト スイッチで完全な TLB フラッシュが必要です。したがって、基本的に、OS はいくつかの制御レジスタを変更する必要があり、場合によっては TLB をクリア (TLB フラッシュを実行) して、さまざまなプロセスからの仮想アドレスを必要な物理アドレスにマップできるようにする必要があります。

于 2010-08-08T20:04:09.633 に答える
2

すべての回答に感謝します。私が知らない実際のポイントは、異なるプロセスの同じ仮想アドレスが互いの物理通信相手とどのように衝突しないかということです。以下のリンクで答えを見つけました。各プロセスには独自のページテーブルがあります。

http://tldp.org/LDP/tlk/mm/memory.html

于 2010-08-09T14:10:18.477 に答える
1

このマッピング (仮想アドレスから物理アドレスへ) は、​​OS と MMU によって処理されます (@nos の回答を参照)。この抽象化のポイントは、 p10x023f4a54が実際にアクセスしているときにアクセスしていると「考える」こと0x12321321です。

機械語レベルでプログラムがどのように機能するかについてクラスに戻ると、p1 は、0x023f4a54読み込まれるたびに変数/関数/何かが同じ場所にあることを期待します (例: )。物理アドレスから仮想アドレスへの OS マッピングは、この抽象化を提供します。実際には、常に同じ物理アドレスにロードされるとは限りませんが、同じ仮想アドレスにある限り、プログラムは気にしません。

于 2010-08-08T19:11:50.640 に答える