remap_pfn_range
函数(用于驱动程序中的mmap
调用)可用于将内核内存映射到用户空间。怎么做?谁能解释一下精确的步骤?内核模式是特权模式(PM),而用户空间是非特权(NPM)。在PM中,CPU可以访问所有内存,而在NPM中,某些内存受到限制 - CPU无法访问。调用remap_pfn_range
时,用户空间现在可以访问仅限于PM的内存范围吗?
查看remap_pfn_range
代码,pgprot_t struct
。这是与保护映射相关的结构。什么是保护映射?这是上述问题的答案吗?
答案 0 :(得分:13)
这很简单,内核内存(通常)只有一个页表条目,其架构特定位表示:“此页表条目仅在CPU处于内核模式时有效”。
remap_pfn_range的作用是创建另一个页表项,其中不同的虚拟地址指向没有该位设置的同一物理内存页。
通常,这是一个坏主意: - )
答案 1 :(得分:5)
该机制的核心是页表MMU:
Related image1 http://windowsitpro.com/content/content/3686/figure_01.gif
或者这个:
上面两张图都是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;