カーネルの論理アドレスと仮想アドレスを正確に区別することはできません。 Linuxデバイスドライバーブックには、すべての論理アドレスがカーネル仮想アドレスであり、仮想アドレスには線形マッピングがないと記載されています。しかし、それが論理的であると言うとき、そして仮想的であると言うとき、そしてどのような状況でこれら2つを使用するのか、論理的に賢明ですか?
Linuxカーネルは、カーネルに属する仮想アドレス空間のほとんどをマッピングして、物理メモリの最初の部分のオフセットを使用して1:1マッピングを実行します。 (32ビットx86の1Gbよりもわずかに少ないですが、他のプロセッサまたは構成では異なる場合があります)。たとえば、x86アドレス0xc00000001のカーネルコードは、物理アドレス0x1にマップされます。
これは論理マッピングと呼ばれ、カーネルがマシンのほとんどの物理メモリにアクセスできるようにする1:1マッピング(オフセットあり)です。
しかし、これだけでは十分ではありません。32ビットマシンに1Gbを超える物理メモリがある場合、単純にするために連続していない物理メモリブロックを参照したい場合、マップされたメモリをマップしたい場合がありますIO RAMではない領域。
このため、カーネルは、仮想アドレス空間の上部に領域を保持し、そこで「ランダムな」ページ間マッピングを実行します。そこでのマッピングは、論理マッピング領域の1:1パターンに従っていません。これは、仮想マッピングと呼ばれるものです。
多くのプラットフォーム(x86が例)では、論理マッピングと仮想マッピングの両方が同じハードウェアメカニズム(仮想メモリを制御するTLB)を使用して行われることを追加することが重要です。多くの場合、「論理マッピング」は実際にはプロセッサの仮想メモリ機能を使用して行われるため、これは少し混乱する可能性があります。したがって、違いは、マッピングが行われるパターンです。論理の場合は1:1、仮想の場合はランダムです。
基本的に3種類のアドレス指定があります。
現在、Linuxでは、カーネルメモリ(アドレス空間内)が3 GB(3GBから4GB)を超えています。つまり、0xc000000です。カーネルが使用するアドレスは物理アドレスではありません。仮想アドレスをマップするには、PAGE_OFFSETを使用します。ページの翻訳が含まれないように注意する必要があります。つまり、これらのアドレスは本質的に連続しています。ただし、これには制限があります。つまり、x86では896MBです。どのページングを超えて翻訳に使用されます。 vmallocを使用すると、割り当てられたメモリにアクセスするためにこれらのアドレスが返されます。
要するに、誰かがユーザースペースのコンテキストで仮想メモリを参照する場合、それはページングを介して行われます。カーネル仮想メモリが言及されている場合、それはPAGE_OFFSETedまたはvmallocedアドレスのいずれかです。
(リファレンス-Linuxカーネルの理解-2.6ベース)
シャッシュ
カーネル論理アドレスは、通常のCPUメモリアクセス関数を介してカーネルコードにアクセスできるマッピングです。 32ビットシステムでは、それよりも多くの物理メモリが使用されている場合でも、4GBのカーネル論理アドレス空間しか存在しません。物理メモリに裏打ちされた論理アドレス空間は、kmalloc
で割り当てることができます。
仮想アドレスには、必ずしも対応する論理アドレスがあるとは限りません。 vmalloc
を使用して物理メモリを割り当て、対応する論理アドレスがない仮想アドレスを取得できます(たとえば、PAEを備えた32ビットシステムの場合)。次に、kmap
を使用して、その仮想アドレスに論理アドレスを割り当てることができます。
簡単に言えば、仮想アドレスには「高メモリ」が含まれます。これは、RAMサイズがカーネルのアドレス範囲(通常は)より大きい場合、物理アドレスの1:1マッピングを行いません。 、X86の1G/3Gの場合、RAMは3Gですが、カーネルのアドレス指定範囲は1G)であり、kmap()およびvmalloc()からアドレスが返されます。ロジックアドレスは常にカーネルによってメモリマッピングされるため(1:1マッピング)、特定のページのページテーブルエントリを設定するためにset_pteのようにカーネルAPIを明示的に呼び出す必要はありません。
そのため、仮想アドレスを常に論理アドレスにすることはできません。