上記は、物理メモリが512MBしかない状況を説明しています。これまで私が読んだのは、ZONE_NORMALが示すようにカーネル仮想アドレス空間にマップされるということです。本質的に私は512MBの物理メモリを持ち、そのうち496MBはカーネル仮想空間にマッピングされたZONE_NORMALです。この理解に基づいて、私の質問は次のとおりです。
- ZONE_NORMALには次のものが含まれていますか?ただカーネル空間ページ?
- ZONE_NORMALがカーネルページのみで構成されマッピングされている場合完全カーネル空間仮想アドレス範囲では、ユーザ空間ページはどこにありますか?ユーザースペースページ用の物理メモリスペースがないようです。
私が提示した例に示すように、物理メモリが4 GB未満の場合は完全に混乱しています。
誰もがこれについて明らかにすることができれば非常に感謝します。
答え1
32ビットアーキテクチャでは、物理アドレスを参照するための線形アドレス(物理空間ではない)0xffffffff
(4'294'967'295
または4GB)があります。
物理ストレージ(バスに接続された物理RAMスティック)が512 MBしかない場合でも、カーネルはまだ4'294'967'295
(4 GB)リニアアドレスを使用して物理アドレスを計算します。
Linuxカーネルはこの4GB(アドレス)をユーザー空間(高メモリ)とカーネル空間(低メモリ)で3/1に分割するため、カーネル空間には使用1'073'741'823
できる線形アドレス(1GB)があります。
この1GBの線形アドレスはカーネルからのみアクセス可能で、より細かくなります。
Area_DMA:16MB未満のメモリページフレームを含みます。これは、RAMの最初の16 MBのみをアドレス指定できる古いISAバスに使用されました。
面積_通常:16 MB以上および896 MB未満のメモリページフレームを含み、カーネルが直接マッピング/アクセスできるアドレス。
ZONE_HIGHMEM:896MB以上のメモリページフレームを含みます。この境界の上のページフレームは通常カーネル空間にマップされないため、カーネルから直接アクセスできません。ユーザー空間のページフレームは、ここに一時的または永続的にマッピングできます。
さまざまな地域で占める物理物理RAMスペースの量は、実行中のプロセスの種類と数によって異なります。
free -ml
コンソールに入力すると、低メモリと高メモリの使用量の両方を表示できます。
total used free shared buffers cached
Mem: 3022 2116 905 0 105 1342
Low: 839 196 642
High: 2182 1919 263
-/+ buffers/cache: 667 2354
Swap: 2859 93 2766
答え2
同じ物理ページを複数の仮想アドレスにマッピングできます。
ZONE_NORMALは、マッピングできるページで構成されています。渡すコア。ほとんどのメモリはカーネルに属していませんが、カーネルは特定の時点ですべてのメモリをマップする必要があります(すべて同時にではありません)。たとえば、カーネルがwrite
システムコールを処理するときに、ユーザー提供のバッファからデータをコピーする必要があります。つまり、バッファをカーネルの仮想アドレス空間にマップする必要があります。
図は、高いメモリを持たない(比較的)簡単なケースを示しています。 (高度なARMデバイスを使用している場合は、今この大容量メモリについて学習しています。)これにより、カーネルはすべてのプロセスメモリとすべての物理メモリを同時にマッピングできます。
以下は、カーネルコードで見られる仮想メモリの再分割の例です(正確な数値が可能かどうかはわかりませんが、基本的なアイデアは正確でなければなりません)。つまり、カーネルコードで使用されるポインタの意味を説明します。
0x00000000..0x00000fff
:割り当てられていません。この範囲内のポインタは無効です。0x00001000..0xbfffffff
:プロセスメモリ。これは、検討中のカーネルコードがシステムコールを処理するプロセスの仮想アドレス空間へのポインタです。その範囲内のページは、割り当てられていないか、RAMに割り当てられてスワップされるか(物理アドレスがある場合)、割り当てとスワップアウトされます(物理アドレスがない場合)。それはスワップにあります。 )に位置があります。0xc0000000..0xdfffffff
:物理メモリ。この範囲のポインタは物理アドレス p-0xc0000000 を示します。このポインタの解釈は実際にはMMUに依存しません。0xe0000000..0xffefffff
:割り当てられていません。この範囲内のポインタは無効です。0xff000000..0xffffffff
:カーネルメモリ。これはカーネルコードまたはデータへのポインタです。この範囲のページには、MMUで見つかった接続された物理アドレスがあります。
私が見つけたLinuxデバイスドライバLinuxカーネルの内部構造の良い紹介です。最終的に次に切り替えたいと思うかもしれません。源泉。