web-dev-qa-db-ja.com

remap_pfn_rangeはどのようにカーネルメモリをユーザースペースに再マップしますか?

remap_pfn_range関数(ドライバーのmmap呼び出しで使用)を使用して、カーネルメモリをユーザースペースにマップできます。それはどのように行われますか?誰かが正確な手順を説明できますか?カーネルモードは特権モード(PM)ですが、ユーザースペースは非特権(NPM)です。 PM CPUはすべてのメモリにアクセスできますが、NPMでは一部のメモリが制限されています-CPUはアクセスできません。remap_pfn_rangeが呼び出されると、制限されていたメモリの範囲はどのようになりますか? PMユーザースペースにアクセスできるようになりましたか?

remap_pfn_rangeコードを見ると、pgprot_t structがあります。これは、保護マッピング関連の構造体です。保護マッピングとは何ですか?上記の質問に対する答えですか?

16
Kapil Gokhale

本当に簡単です。カーネルメモリには(通常)、「このページテーブルエントリはCPUがカーネルモードの場合にのみ有効です」というアーキテクチャ固有のビットを含むページテーブルエントリがあります。

Remap_pfn_rangeが行うことは、そのビットが設定されていない同じ物理メモリページへの異なる仮想アドレスを使用して、別のページテーブルエントリを作成することです。

通常、それは悪い考えです:-)

14
gby

メカニズムの中核はページテーブルMMUです。

関連画像1 http://windowsitpro.com/content/content/3686/figure_01.gif

またはこれ:

Related image

上の図は両方ともx86ハードウェアメモリMMUの特性であり、Linuxカーネルとは関係ありません。

以下に、VMAがプロセスのtask_structにリンクされる方法について説明します。

関連画像http://image9.360doc.com/DownloadImg/2010/05/0320/3083800_2.gif

Related image
(出典: slideplayer.com

そしてここで関数自体を調べます:

http://lxr.free-electrons.com/source/mm/memory.c#L1756

以下に示すように、物理メモリ内のデータには、カーネルのPTEを介してカーネルからアクセスできます。

Image result for page protection flags linux kernel
(ソース: tldp.org

ただし、remap_pfn_range()を呼び出した後、PTE(既存のカーネルメモリ用ですが、ユーザースペースでアクセスするために使用されます)が派生します(異なるページ保護フラグを使用)。プロセスのVMAメモリは、このPTEを使用して同じメモリにアクセスするように更新されるため、コピーによってメモリを浪費する必要性が最小限に抑えられます。ただし、カーネルとユーザースペースのPTEには異なる属性があります。これは、物理メモリへのアクセスを制御するために使用され、VMAはプロセスレベルで属性も指定します。

vma-> vm_flags | = VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;

7
Peter Teoh