37

オペレーティング システムの物理/論理/仮想アドレスという用語について少し混乱しています (私は Linux-open SU​​SE を使用しています)。

これが私が理解していることです:

  1. 物理アドレス - プロセッサがシステム モードの場合、プロセッサが使用するアドレスは物理アドレスです。

  2. 論理アドレス - プロセッサがユーザー モードの場合、使用されるアドレスは論理アドレスです。いずれにせよ、これらはベースレジスタにオフセット値を追加することにより、何らかの物理アドレスにマップされます。ある意味で、一種のメモリ保護を提供します。

  3. 仮想アドレスと論理アドレス/アドレス空間は同じであるという議論に出くわしました。本当ですか?

どんな助けでも大歓迎です。

4

9 に答える 9

68

私の答えは、最新の Linux システムで実行されている Intel CPU に当てはまります。カーネル コードではなく、ユーザー レベルのプロセスについて話しているのです。それでも、他の可能性について考えるのに十分な洞察が得られると思います

住所の種類

質問3について:

仮想アドレスと論理アドレス/アドレス空間は同じであるという議論に出くわしました。本当ですか?

私の知る限り、少なくとも Intel プロセッサ上で実行されている最新の OS では、それらは同じです。

詳細を説明する前に、2 つの概念を定義してみましょう。

  • 物理アドレス: RAM チップ内で何かが物理的に配置されている場所のアドレス。
  • 論理/仮想アドレス: プログラムがアクセスするために使用するアドレス。通常、後でハードウェア チップによって物理アドレスに変換されます (ほとんどの場合、CPU でさえこの変換を認識していません)。

仮想/論理アドレス

仮想アドレスはまあ、仮想アドレスです.OSは、MMU(メモリ管理ユニット)と呼ばれるハードウェア回路とともに、プログラムがシステム内で単独で実行されていると誤解し、アドレス空間全体を持っています(32ビットシステムを持つということは、プログラムは、4 GB の RAM があると認識します (大まかに言えば)。

明らかに、一度に複数のプログラムを実行している場合 (GUI、Init プロセス、シェル、時計アプリ、カレンダーなど、常に実行しています)、これは機能しません。

何が起こるかというと、OS はプログラム メモリの大部分をハードディスクに置き、最も使用する部分は RAM に存在しますが、それはあなたとあなたのプログラムのアドレスを持っているという意味ではありません。知る。

例:プロセスには、仮想アドレス 0xff (想像上...) が与えられた (counter) という名前の変数と、仮想アドレス (0xaa) が与えられた (しばしばNotUsed) という名前の別の変数がある場合があります。

すべてのリンクが行われた後にコンパイルされたコードのアセンブリを読み取る場合、それらのアドレスを使用してそれらにアクセスすることになりますが、(しばしばNotUsed) 変数は実際には 0xaa の RAM にはなく、ハードディスクにあります。プロセスがそれを使用していないためです。

さらに、変数 (カウンター) は物理的に (0xff) にあるのではなく、RAM の別の場所にあります。CPU が 0xff にあるものを取得しようとすると、MMU と OS の一部がマッピングを行います。 RAMで実際に利用可能な場所からその変数を取得すると、CPUはそれが0xffにないことにさえ気づきません。

プログラムが (頻繁に使用されない) 変数を要求するとどうなるでしょうか? MMU+OS はこの「ミス」に気付き、CPU 用にハード ディスクから RAM にフェッチし、アドレス (0xaa) にあるかのように CPU に渡します。このフェッチは、RAM に存在していた一部のデータがハードディスクに送り返されることを意味します。

これがシステム内のすべてのプロセスで実行されていると想像してください。すべてのプロセスは 4GB の RAM を持っていると考えていますが、実際にそれを持っている人は誰もいませんが、プログラムの一部を RAM で物理的に利用できますが、プログラムの大部分はハードディスクに存在するため、すべてが機能します。HD に配置されるプログラム メモリのこの部分を、ファイル操作を通じてアクセスできるプログラム データと混同しないでください。

概要

仮想アドレス: プログラムで使用するアドレス (CPU がデータを取得するために使用するアドレス) は実際のものではなく、MMU を介して何らかの物理アドレスに変換されます。誰もが 1 つ持っており、そのサイズはシステムによって異なります (32 ビットを実行している Linux は 4GB のアドレス空間を持っています)。

物理アドレス: OS 上で実行している場合、到達することのないアドレス。仮想アドレスに関係なく、データが RAM に存在する場所です。他のプロセスにより多くのスペースを確保するために、データがハードディスクとの間で送受信される場合、これは変わります。

上で述べたことはすべて、概念全体の単純化されたバージョンですが、コンピュータ システムのメモリ管理部分と呼ばれるものです。

このシステムの結果

  • プロセスはお互いのメモリにアクセスできず、すべての人が個別の仮想アドレスを持ち、2 つのプロセスが同じ仮想アドレスにアクセスしようとしていることに気付く場合でも、すべてのプロセスが異なる領域への異なる変換を取得します。
  • このシステムはキャッシング システムとしてうまく機能します。通常、利用可能な 4 GB をすべて使用するわけではありません。他の人にそれを共有させ、彼らにも使用させてください。プロセスがさらに必要な場合、OS は HD からデータを取得し、他のプロセスのデータを置き換えますが、もちろん費用がかかります。
于 2013-04-06T13:21:51.653 に答える
10

物理アドレス - プロセッサがシステム モードの場合、プロセッサが使用するアドレスは物理アドレスです。

必ずしもそうではありません。それは特定のCPUに依存します。x86 CPU では、ページ変換を有効にすると、すべてのコードが物理アドレスまたは物理アドレスに簡単に変換できるアドレスで動作しなくなります (SMM、AFAIK を除きますが、ここでは重要ではありません)。

論理アドレス - プロセッサがユーザー モードの場合、使用されるアドレスは論理アドレスです。いずれにせよ、これらはベースレジスタにオフセット値を追加することにより、何らかの物理アドレスにマップされます。

論理アドレスは、必ずしもユーザー モードだけに適用されるわけではありません。x86 CPU では、カーネル モードにも存在します。

仮想アドレスと論理アドレス/アドレス空間は同じであるという議論に出くわしました。本当ですか?

それは特定のCPUに依存します。x86 CPU は、セグメントが明示的に使用されないように構成できます。これらは暗黙的に使用され、基数は常に 0 です (スレッド ローカル ストレージ セグメントを除く)。セグメント セレクターを論理アドレスから削除すると、32 ビット (または 64 ビット) のオフセットが残り、その値は 32 ビット (または 64 ビット) の仮想アドレスと一致します。この単純化されたセットアップでは、2 つが同じであるか、論理アドレスが存在しないと考えることができます。それは真実ではありませんが、ほとんどの実用的な目的では、近似値として十分です.

于 2013-04-06T13:10:27.280 に答える
6

Intel x86 CPUに基づく以下の回答を参照しています

論理アドレスと仮想アドレスの違い

プログラムが実行中の場合は常に、CPU は (16 ビット セグメント セレクターと 32 ビット オフセット) を含む命令の論理アドレスを生成します。基本的に、論理アドレス フィールドを使用して仮想 (線形アドレス) が生成されます。

セグメント セレクターは 16 ビット フィールドで、最初の 13 ビットはインデックス (セグメント記述子へのポインターであり、GDT に常駐します。後述)、1 ビット TI フィールド (TI = 1、LDT を参照、TI=0 GDT を参照)

ここで、セグメント セレクターまたはセグメント識別子は、コード セグメントまたはデータ セグメントまたはスタック セグメントなどを指します。Linux には、各セグメントの 8 バイト記述子を含む 1 つの GDT/LDT (グローバル/ローカル記述子テーブル) が含まれ、セグメント。

したがって、論理アドレスごとに、以下の手順を使用して仮想アドレスが計算されます。

1) セグメント セレクタの TI フィールドを調べて、どの記述子テーブルにセグメント記述子が格納されているかを判断します。このフィールドは、記述子が GDT (この場合、セグメンテーション ユニットは gdtr レジスタから GDT のベース リニア アドレスを取得する) またはアクティブな LDT (この場合、セグメンテーション ユニットはそのベース リニア アドレスを取得する) にあることを示します。 ldtr レジスタからの LDT)。

2) セグメント セレクタのインデックス フィールドからセグメント記述子のアドレスを計算します。インデックス フィールドは 8 (セグメント ディスクリプタのサイズ) で乗算され、その結果が gdtr または ldtr レジスタの内容に追加されます。

3) 論理アドレスのオフセットをセグメント記述子のベース フィールドに追加し、線形 (仮想) アドレスを取得します。

現在、仮想アドレスから物理アドレスを変換するのは、ページング ユニットの仕事です。

参照 : Linux カーネルの理解、第 2 章メモリ アドレス指定

于 2014-04-12T09:05:42.040 に答える
5

通常、発行されるすべてのアドレス (x86 アーキテクチャの場合) は、セグメント テーブルを介して線形アドレスに変換される論理アドレスです。リニア アドレスに変換された後、ページ テーブルを介して物理アドレスに変換されます。
同じことを詳しく説明している素晴らしい記事:
http://duartes.org/gustavo/blog/post/memory-translation-and-segmentation/

于 2014-07-01T09:50:44.890 に答える
1

物理アドレスは、メモリ ユニットによって認識されるアドレス、つまりメモリ アドレス レジスタにロードされるアドレスです。論理アドレスは、CPU によって生成されるアドレスです。ユーザー プログラムは、実際の物理アドレスを見ることはできません。メモリ マッピング ユニットは、論理アドレスを物理アドレスに変換します。ユーザー プロセスによって生成された論理アドレスは、使用する前に物理メモリにマップする必要があります。

于 2014-02-02T14:17:52.250 に答える
0

ユーザーモードまたはユーザースペースでは、プログラムから見えるすべてのアドレスは仮想アドレスです。カーネル モードでは、カーネルによって認識されるアドレスは依然として仮想ですが、物理 + pageoffset に等しいため、論理アドレスと呼ばれます。物理アドレスは、RAM によって認識されるものです。仮想メモリを使用すると、プログラム内のすべてのアドレスがページ テーブルを通過します。

于 2013-04-06T13:23:50.017 に答える