HighmemとLowmemの違いに興味があります。
- なぜそのような違いがありますか?
- このようにして、私たちは何を得ますか?
- それぞれの特徴は何ですか?
答え1
32ビットアーキテクチャでは、RAMアドレス指定のためのアドレス空間の範囲は次のとおりです。
0x00000000 - 0xffffffff
または4'294'967'295
(4GB)。
Linuxカーネルは3/1(おそらく2/2または1/3 1)をユーザースペース(高メモリ)とカーネルスペース(低メモリ)に分割します。
ユーザースペースの範囲:
0x00000000 - 0xbfffffff
新しく作成された各ユーザープロセスには、この領域内のアドレス(範囲)が提供されます。ユーザープロセスは通常信頼できないため、カーネル空間にアクセスすることは禁止されています。また、これは緊急ではないと見なされ、通常、カーネルはこれらのプロセスのメモリ割り当てを延期しようとします。
カーネル空間範囲:
0xc0000000 - 0xffffffff
これはカーネルプロセスがアドレス(範囲)を取得する場所です。カーネルはこの1GBアドレスに直接アクセスできます(もちろん、フル1GBではなく高度なメモリアクセス用に128MBが予約されています)。
カーネル空間で生成されたプロセスは信頼性が高く緊急であり、エラーがないと仮定すると、メモリ要求はすぐに処理されます。
必要に応じて、各カーネルプロセスはユーザースペースの範囲にアクセスすることもできます。これを達成するために、カーネルはユーザー空間(高メモリ)のアドレスをカーネル空間(低メモリ)にマッピングし、上記の128 MBはそのために特別に予約されています。
1分割が3/1、2/2、または1/3であるかどうかはオプションで制御されます。カーネルにどのオプションが選択されているかを確認CONFIG_VMSPLIT_...
できます。/boot/config*
答え2
最初の参考資料はLinuxデバイスドライバ(オンラインまたは本の形で利用可能)、特に。第15章このトピックに関するセクションがあります。
理想的な世界では、各システムコンポーネントがアクセスする必要があるすべてのメモリをマッピングできます。これは、Linuxおよびほとんどのオペレーティングシステムのプロセスに当てはまります。 32ビットプロセスは、2^32バイトよりわずかに小さい仮想メモリ(実際には通常のLinux 32ビットアーキテクチャでは約3GB)にのみアクセスできます。これは、システムコールを実行するプロセスのメモリ全体と、物理メモリ全体と他のメモリマップされたハードウェアデバイスをマッピングできる必要があるカーネルの場合に困難です。
したがって、32ビットカーネルが4 GB以上のメモリをマッピングする必要がある場合は、高いメモリをサポートするようにコンパイルする必要があります。大容量メモリは、カーネルアドレス空間に永続的にマップされないメモリです。 (低メモリの場合はその逆です。常にマッピングされるので、ポインタを逆参照するだけでカーネルからアクセスできます。)
カーネルコードから高いメモリにアクセスするときは、kmap
まず呼び出してページデータ構造()からポインタを取得する必要がありますstruct page
。kmap
呼び出しは、ページが高いメモリにあるか低いメモリにあるかに関係なく動作します。kmap_atomic
制約を追加しますが、よりきめ細かいロックを使用するため、マルチプロセッサシステムではより効率的です。取得したポインタkmap
はリソースです。アドレス空間を占有します。完了したらkunmap
(またはkunmap_atomic
)を呼び出してリソースを解放する必要があります。これにより、ポインタが無効になり、再度呼び出されるまでページの内容にアクセスできなくなりますkmap
。
答え3
これはLinuxカーネルに関連しています。 Unixカーネルがこれをどのように処理するのかわかりません。
大容量メモリは、ユーザ空間プログラムがアドレスを指定できるメモリセグメントです。メモリ不足に触れることができません。
低メモリは、Linuxカーネルが直接解決できるメモリセグメントです。カーネルが高いメモリにアクセスする必要がある場合は、まずそれを独自のアドレス空間にマップする必要があります。
クリップの位置を制御できるパッチが最近リリースされました。欠点は、カーネルが使用する前にマッピングする必要のないメモリを増やすことができるように、ユーザー空間からアドレス指定可能なメモリをインポートすることです。
追加リソース:
答え4
Linuxカーネルのメモリスペースに関する説明を探している人は、以下を参照してください。2つの矛盾する定義高/低メモリ分割(残念ながら標準がないため、状況に合わせて解釈する必要があります):
「上位メモリ」はカーネル空間の和として定義される。仮想メモリ。カーネルのみがアクセスできる領域で、.以上のすべての仮想アドレスを含みます
PAGE_OFFSET
。したがって、「低メモリ」は、各ユーザプロセスによってアクセス可能なユーザ空間メモリに対応する残りのアドレス領域を指します。例: デフォルト値が 32 ビット x86 の場合、
PAGE_OFFSET
これは上位メモリーがランダムなアドレスADDR
(ADDR ≥ 0xC0000000 = PAGE_OFFSET
たとえば、より高い 1 GB) であることを意味します。これがLinux 32ビットプロセスが通常3 GBに制限される理由です。
PAGE_OFFSET
直接設定できず、設定可能なオプションVMSPLIT_x
(源泉)。要約すると、32ビットアーキテクチャでは、仮想メモリはデフォルトで下位3GB(ユーザースペース)と上位1GB(カーネルスペース)に分けられます。
64ビットの場合は設定
PAGE_OFFSET
できず、カーネルのロード中に実行時に検出されるアーキテクチャの詳細によって異なります。x86_64から4レベルのページング(標準)と
PAGE_OFFSET
5レベルのページング(0xffff888000000000
0xff11000000000000
源泉)。 ARM64の場合、これは通常真です0x8000000000000000
。ただし、KASLRが有効な場合、この値は意図的に予測できません。
「高度なメモリ」は、次のように定義されます。物理残りのカーネル仮想メモリと連続的にマッピングできないメモリ。カーネルの仮想アドレス空間の一部は、単一の連続ブロックとしていわゆる物理的な「低メモリ」にマッピングすることができます。これが何を意味するのかを完全に理解するには、Linux仮想メモリ空間のより深い理解が必要です。合格をお勧めしますこのスライド。
スライドから:
この「高/低メモリ」区分は、インストールされている物理RAMのサイズが比較的大きい(約1 GB以上)32ビットアーキテクチャにのみ適用されます。そうでない場合、つまり物理アドレス空間が小さい場合(<1GB)、仮想メモリ空間が大きい場合(64ビット)、カーネル仮想メモリ空間から物理空間全体にアクセスできます。この場合、全ての物理メモリは「メモリ不足」とみなされる。
高度なメモリがまったく存在しない場合は、より良いでしょう。物理空間全体をカーネルから直接アクセスできるため、メモリ管理がより簡単で効率的です。これは、DMA(通常は物理的に連続したメモリが必要です)を処理するときに特に重要です。
また見てください@gillesの答え