32 ビット アーキテクチャでは、RAM をアドレス指定するためのアドレス空間の範囲は次のとおりです。
0x00000000 - 0xffffffff
または 4'294'967'295
(4GB).
Linux カーネルは、その 3/1 (2/2 または 1/3 の場合もあります) をユーザー空間 (高メモリ) とカーネル空間 (低メモリ) にそれぞれ分割します。
ユーザー空間の範囲:
0x00000000 - 0xbfffffff
新しく生成されたすべてのユーザー プロセスは、この領域内のアドレス (範囲) を取得します。ユーザー プロセスは一般に信頼されていないため、カーネル空間へのアクセスは禁止されています。さらに、それらは緊急ではないと見なされ、原則として、カーネルはそれらのプロセスへのメモリの割り当てを延期しようとします。
カーネル空間の範囲:
0xc0000000 - 0xffffffff
カーネル プロセスは、ここでアドレス (範囲) を取得します。カーネルは、この 1 GB のアドレスに直接アクセスできます (完全な 1 GB ではなく、128 MB が高メモリ アクセス用に予約されています)。
カーネル空間で生成されたプロセスは、信頼され、緊急であり、エラーがないと想定され、メモリ要求は即座に処理されます。
すべてのカーネル プロセスは、必要に応じてユーザー空間の範囲にアクセスすることもできます。これを実現するために、カーネルはアドレスをユーザー空間 (高メモリ) からカーネル空間 (低メモリ) にマップします。上記の 128 MB は特にこのために予約されています。
分割が 3/1、2/2、または 1/3 のいずれであるかは、CONFIG_VMSPLIT_...
によって制御されます。 オプション;おそらく /boot/config*
の下で確認できます カーネルにどのオプションが選択されたかを確認します。
最初に参照するのは Linux Device Drivers (オンラインと書籍の両方で入手可能) で、特にこのトピックに関するセクションがある第 15 章です。
理想的な世界では、すべてのシステム コンポーネントが、アクセスする必要のあるすべてのメモリをマップできます。これは、Linux およびほとんどのオペレーティング システムのプロセスに当てはまります。32 ビット プロセスは、2^32 バイト弱の仮想メモリにしかアクセスできません (実際、典型的な Linux 32 ビット アーキテクチャでは約 3GB です)。カーネルにとっては、システム コールを実行しているプロセスのメモリ全体、物理メモリ全体、およびその他のメモリ マップされたハードウェア デバイスをマップできる必要があるため、困難になります。
したがって、32 ビット カーネルが 4GB を超えるメモリをマップする必要がある場合は、高メモリ サポートでコンパイルする必要があります。ハイ メモリとは、カーネルのアドレス空間に永続的にマップされていないメモリです。 (低メモリはその逆です。常にマップされているため、ポインタを逆参照するだけでカーネル内でアクセスできます。)
カーネル コードからハイ メモリにアクセスする場合は、kmap
を呼び出す必要があります。 まず、ページのデータ構造からポインタを取得します (struct page
)。 kmap
を呼び出す ページが高メモリまたは低メモリのどちらにあるかに関係なく機能します。 kmap_atomic
もあります これには制約が追加されていますが、より粒度の細かいロックを使用するため、マルチプロセッサ マシンでより効率的です。 kmap
で取得したポインタ はリソースです。アドレス空間を使い果たします。終了したら、kunmap
を呼び出す必要があります。 (または kunmap_atomic
) そのリソースを解放します。その後、ポインターは無効になり、 kmap
を呼び出すまでページのコンテンツにアクセスできなくなります
これは Linux カーネルに関連しています。 Unix カーネルがこれをどのように処理するかはわかりません。
ハイ メモリは、ユーザー空間プログラムがアドレス指定できるメモリのセグメントです。メモリ不足に触れることはできません。
ロー メモリは、Linux カーネルが直接アドレス指定できるメモリのセグメントです。カーネルがハイ メモリにアクセスする必要がある場合は、まずそれを独自のアドレス空間にマップする必要があります。
最近導入されたパッチがあり、セグメントの場所を制御できます。トレードオフは、使用前にマップする必要のないより多くのメモリをカーネルが持つことができるように、アドレス可能なメモリをユーザー空間から取り除くことができるということです。
追加リソース:
- http://tldp.org/HOWTO/KernelAnalysis-HOWTO-7.html
- http://linux-mm.org/HighMemory