remap_pfn_range如何将内核内存重新映射到用户空间?

时间:2012-01-09 12:15:48

标签: linux-kernel linux-device-driver kernel-module virtual-address-space

remap_pfn_range函数(用于驱动程序中的mmap调用)可用于将内核内存映射到用户空间。怎么做?谁能解释一下精确的步骤?内核模式是特权模式(PM),而用户空间是非特权(NPM)。在PM中,CPU可以访问所有内存,而在NPM中,某些内存受到限制 - CPU无法访问。调用remap_pfn_range时,用户空间现在可以访问仅限于PM的内存范围吗?

查看remap_pfn_range代码,pgprot_t struct。这是与保护映射相关的结构。什么是保护映射?这是上述问题的答案吗?

2 个答案:

答案 0 :(得分:13)

这很简单,内核内存(通常)只有一个页表条目,其架构特定位表示:“此页表条目仅在CPU处于内核模式时有效”。

remap_pfn_range的作用是创建另一个页表项,其中不同的虚拟地址指向没有该位设置的同一物理内存页。

通常,这是一个坏主意: - )

答案 1 :(得分:5)

该机制的核心是页表MMU:

Related image1 http://windowsitpro.com/content/content/3686/figure_01.gif

或者这个:

Related image

上面两张图都是x86硬件内存MMU的特性,与Linux内核无关。

下面描述了VMA如何链接到流程的task_struct:

Related image http://image9.360doc.com/DownloadImg/2010/05/0320/3083800_2.gif

Related image http://images.slideplayer.com/16/5079265/slides/slide_24.jpg

在这里查看函数本身:

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

内核可以通过内核的PTE访问物理内存中的数据,如下所示:

Image result for page protection flags linux kernel http://www.tldp.org/LDP/tlk/mm/page-tables.gif

但是在调用remap_pfn_range()之后,派生出PTE(用于现有内核内存但在用户空间中用于访问它)(具有不同的页面保护标志)。进程的VMA内存将更新为使用此PTE访问相同的内存 - 从而最大限度地减少了通过复制浪费内存的需要。但内核和用户空间PTE具有不同的属性 - 用于控制对物理内存的访问,VMA还将在进程级别指定属性:

  

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