Linuxでは、セグメントのベースがすべて0であるため、論理アドレスは線形アドレスと一致します(「Linuxカーネルについて」を参照)。異なるプロセスの論理アドレスは同じである可能性があると思います。したがって、異なるプロセスの線形アドレスは同じであり、各プロセスビュー4GBとして、各プロセスには独自の線形アドレス空間(ローカルアドレス空間)があります。しかし、他のいくつかの記事では、すべてのプロセスで共有される大きな線形アドレス空間があり、セグメントメカニズムを使用して、さまざまなプロセスを線形アドレス空間のさまざまな部分にマッピングすると述べています。より広いアドレスビットを持つグローバル線形アドレス空間のように聞こえます。私はどこが間違っていますか?または、それらは異なるアーキテクチャで使用されていますか?
2 に答える
各Linuxプロセスには独自のアドレス空間があります; それは仮想メモリです。プロセスが異なればアドレス空間も異なります(ただし、プロセス内のすべてのスレッドは同じアドレス空間を共有します)。
1234
Linuxでのプロセスのマップは、プロセスを読ん/proc/1234/maps
だり、プロセスの内部から取得したりできます。/proc/self/maps
次のコマンドを試してください
cat /proc/$$/maps
cat /proc/self/maps
そしてそれらの出力について考えます。最初のコマンドは、シェルのメモリマップを表示します。2つ目は、実行中のプロセスのメモリマップを示していますcat
アドレス空間は、プログラムの起動時にexecve(2)で設定され、 mmap(2)および関連するシステムコールで変更されます。
アプリケーションは、syscallを介してのみカーネルと対話します。カーネルには「異なる」アドレス空間がありますが、これは気にする必要はありません(カーネル内でコーディングしている場合を除く)。
AdvancedUnixProgrammingやAdvancedLinuxProgrammingのような良い本も読んでください。
システムコールに関するこの説明も参照してください。
セグメント化されたアドレス指定はi386に固有であり、廃止されていることに注意してください。ほとんどのシステムはそれを使用しなくなりました。x86-64の64ビットモードでは完全に消えました。すべてのLinuxシステムはフラットメモリモデルを使用します
すべての参考文献を注意深くお読みください。
Intelは3種類のアドレスをサポートしています:
論理アドレス-(セグメント単位)--->線形アドレス---(ページング単位)--->物理アドレス
ご存知のように、すべてのカーネルおよびユーザーコードは、データまたはテキスト思考仮想アドレス(CPUの論理アドレス)にアクセスします。次のグラフのように、アドレスは線形アドレスに変換されます。
Linuxの実装は線形アドレス指定の概念をサポートしておらず、セグメントは権限制御のためにのみ提供されているためです。Linuxカーネルは、各セグメントのオフセット値をゼロに構成します。そのため、カーネルで線形アドレスを確認することはできず、カーネルはページングユニットで仮想アドレスを直接使用します。
線形アドレスを取得した後、MMUページングユニットはCR3レジスタを参照して、物理アドレスを生成するためのページングテーブルのベースを取得します。
cpuキャッシュと同様に、ページングユニットにはCPUコアごとにTLBキャッシュがあり、メモリで実行されるアドレス変換を高速化します。