Linuxプログラミングインターフェースプロセスの仮想アドレス空間のレイアウトを表示します。グラフのすべての領域が線分ですか?
~からLinuxカーネルについて学ぶ、
MMUの分割単位がセグメントとセグメント内のオフセットを仮想メモリアドレスにマッピングし、ページング単位が仮想メモリアドレスを物理メモリアドレスにマッピングするのは正しいですか?
メモリ管理装置(MMU)は、分割装置というハードウェア回路を介して論理アドレスを線形アドレスに変換し、続いてページング装置という第2のハードウェア回路が線形アドレスを物理アドレスに変換する(図2−1参照)。
それでは、Linuxはなぜ分割を使用せず、ページングのみを使用しますか?
プログラマがアプリケーションをサブルーチンやグローバルおよびローカルデータ領域などの論理的に関連するエンティティに分割することを奨励するために、80x86マイクロプロセッサに分割機能が含まれています。しかし、 Linuxは非常に限られた方法で分割を使用します。実際には、分割とページングはどちらもプロセスの物理アドレス空間を分離するために使用できるため、多少冗長です。分割は各プロセスに異なる線形アドレス空間を割り当てることができ、ページングは同じ線形アドレス空間を異なる物理アドレス空間にマッピングできます。アドレス空間。 Linuxは、次の理由で分割よりもページングを好みます。
•すべてのプロセスが同じセグメントレジスタ値を使用する場合(つまり、同じ線形アドレスセットを共有する場合)、メモリ管理がより簡単になります。
• Linux の設計目標の 1 つは、さまざまなアーキテクチャに移植することです。具体的には、RISCアーキテクチャは分割を限定的にサポートしています。
Linux 2.6 バージョンは、80x86 アーキテクチャで必要な場合にのみ分割を使用します。
答え1
x86-64アーキテクチャは、ロングモード(64ビットモード)では分割を使用しません。
セグメントレジスタの4つ(CS、SS、DS、ES)は0に強制され、2 ^ 64に制限されます。
https://en.wikipedia.org/wiki/X86_memory_segmentation#Later_developments
オペレーティングシステムで利用可能な「線形アドレス」の範囲を制限することはできません。したがって、メモリ保護のために分割を使用することはできず、ページングに完全に依存する必要があります。
x86 CPUの詳細を心配しないでください。従来の32ビットモードで実行されている場合にのみ適用されます。 Linuxの32ビットモードはあまり使用されていません。 「長年にわたって良性の放置に苦しんだ」と考えることもできます。バラよりFedoraの32ビットx86をサポート[LWN.net、2017]。
(32ビットLinuxでも分割を使用しない場合がありますが、私の言葉を信じる必要はありません。ただ無視しても構いません。 :-)。
答え2
グラフのすべての領域が線分ですか?
いいえ。
分割システム(x86の32ビット保護モード)は、別々のコード、データ、およびスタックセグメントをサポートするように設計されていますが、実際にはすべてのセグメントが同じメモリ領域に設定されています。つまり、0から始まり、メモリの終わり(*)で終わります。これは論理アドレスと線形アドレスを等しくする。
これは「フラット」メモリモデルと呼ばれ、内部に別々のセグメントとポインタを持つモデルよりも簡単です。特に、分割モデルでは、オフセットポインタに加えてセグメントセレクタを含める必要があるため、より長いポインタが必要です。 (16ビットセグメントセレクタ+ 32ビットオフセット、合計48ビットポインタ、32ビットフラットポインタのみ。)
64ビットロングモードは、フラットメモリモデルを除いて実際に分割をサポートしません。
286から16ビット保護モードでプログラムするには、アドレス空間は24ビットですが、ポインタは16ビットにすぎず、より多くのセグメントが必要です。
(* 32ビットLinuxがカーネル/ユーザースペースの分離をどのように処理するか覚えていないことに注意してください。パーティションを使用すると、カーネルスペースを含めないようにユーザースペースセグメントの制限を設定してこれを可能にします。ページングはページごとの保護を提供するので、これを許可します。
それでは、Linuxはなぜ分割を使用せず、ページングのみを使用しますか?
x86にはまだこれらのセグメントがあるため、無効にすることはできません。それらはできるだけ少なく使用されます。 32ビット保護モードでは、フラットモデルにセグメントを設定する必要があり、64ビットモードでもまだ存在します。
答え3
x86 にはセグメントがあるため、使用しないでください。ただし、cs
(コードセグメント)とds
(データセグメント)のベースアドレスは両方とも0に設定されているため、セグメントは実際には使用されません.例外は、一般的に使用されていないセグメントレジスタの1つが指すスレッドローカルデータです。ただし、これは主にこの操作のために汎用レジスタの1つを予約しないためです。
Linuxがx86で分割を使用しないと言うのは不可能だからです。その部分を強調しましたね。Linuxは非常に限られた方法で分割を使用します。。 2番目の部分はLinux は、80x86 アーキテクチャで必要な場合にのみ分割を使用します。
すでにその理由に言及しています。ページ付けがより簡単で移植性に優れています。
答え4
Linux x86/32は、すべてのセグメントを同じ線形アドレスと制限に初期化するため、分割を使用しません。 x86アーキテクチャでは、プログラムにセグメントが必要です。コードはコードセグメントでのみ実行でき、スタックはスタックセグメントにのみ配置でき、データはデータセグメントの1つでのみ操作できます。 Linuxは、すべてのセグメントを同じ論理アドレスが有効になるように、すべてのセグメントを同じ方法で設定します(本に記載されていない例外を除く)、このメカニズムをバイパスします。これは、事実上セグメントが全くないという意味です。