remap_pfn_range
関数(ドライバーのmmap
呼び出しで使用)を使用して、カーネルメモリをユーザースペースにマップできます。それはどのように行われますか?誰かが正確な手順を説明できますか?カーネルモードは特権モード(PM)ですが、ユーザースペースは非特権(NPM)です。 PM CPUはすべてのメモリにアクセスできますが、NPMでは一部のメモリが制限されています-CPUはアクセスできません。remap_pfn_range
が呼び出されると、制限されていたメモリの範囲はどのようになりますか? PMユーザースペースにアクセスできるようになりましたか?
remap_pfn_range
コードを見ると、pgprot_t struct
があります。これは、保護マッピング関連の構造体です。保護マッピングとは何ですか?上記の質問に対する答えですか?
本当に簡単です。カーネルメモリには(通常)、「このページテーブルエントリはCPUがカーネルモードの場合にのみ有効です」というアーキテクチャ固有のビットを含むページテーブルエントリがあります。
Remap_pfn_rangeが行うことは、そのビットが設定されていない同じ物理メモリページへの異なる仮想アドレスを使用して、別のページテーブルエントリを作成することです。
通常、それは悪い考えです:-)
メカニズムの中核はページテーブルMMUです。
関連画像1 http://windowsitpro.com/content/content/3686/figure_01.gif
またはこれ:
上の図は両方ともx86ハードウェアメモリMMUの特性であり、Linuxカーネルとは関係ありません。
以下に、VMAがプロセスのtask_structにリンクされる方法について説明します。
関連画像http://image9.360doc.com/DownloadImg/2010/05/0320/3083800_2.gif
(出典: slideplayer.com )
そしてここで関数自体を調べます:
http://lxr.free-electrons.com/source/mm/memory.c#L1756
以下に示すように、物理メモリ内のデータには、カーネルのPTEを介してカーネルからアクセスできます。
(ソース: tldp.org )
ただし、remap_pfn_range()を呼び出した後、PTE(既存のカーネルメモリ用ですが、ユーザースペースでアクセスするために使用されます)が派生します(異なるページ保護フラグを使用)。プロセスのVMAメモリは、このPTEを使用して同じメモリにアクセスするように更新されるため、コピーによってメモリを浪費する必要性が最小限に抑えられます。ただし、カーネルとユーザースペースのPTEには異なる属性があります。これは、物理メモリへのアクセスを制御するために使用され、VMAはプロセスレベルで属性も指定します。
vma-> vm_flags | = VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;