通过remap_pfn_range将保留的高内存映射到用户空间

时间:2017-02-10 07:49:45

标签: c linux memory-management linux-kernel

拱= x86_64的

按照此问题中列出的流程,我正在使用DMA解决方案, Direct Memory Access in Linux

我对ioremap的呼叫成功返回地址,pt。

在致remap_pfn_range的电话中,我使用virt_to_phys(pt) >> PAGE_SHIFT来指定ioremap电话生成的区域的pfn。

当执行使用mmap的用户空间应用程序并调用remap_pfn_range时,计算机崩溃。我假设映射已关闭,我正在强制系统使用已分配的内存(退出前屏幕毛刺),但我不清楚错配发生的位置。系统有4 Gigs of Ram,我使用内核启动选项mem=2048M保留了2Gigs。

我使用BUFFER_SIZE=1024u*1024u*1024uBUFFER_OFFSET=2u*1024u*1024u*1024u

将这些放入pt=ioremap(BUFFER_SIZE,BUFFER_OFFSET)我相信pt应该等于位于2GB边界直到3GB边界的物理内存的虚拟地址。这个假设准确吗?

当我执行我的内核模块时,但是我将remap_pfn_range更改为使用vma->vm_pgoff>>PAGE_SHIFT作为目标pfn,代码执行时没有错误,我可以读取和写入内存。但是,这并没有使用我想要的保留物理内存。

由于使用vma->vm_pgoff>>PAGE_SHIFT时一切正常,我相信我的罪魁祸首是在ioremapremap_pfn_range之间

感谢您的任何建议!

使用此内核模块背后的动机是需要为PCI设备提供大量连续的DMA缓冲区。在这个应用程序中,重新编译内核不是一个选项,所以我试图用模块+硬件完成它。

1 个答案:

答案 0 :(得分:1)

  

我对ioremap的调用成功返回地址,pt。

     

在我使用remap_pfn_range的调用中,virt_to_phys(pt)>> PAGE_SHIFT,   指定ioremap调用生成的区域的pfn。

这是非法的,因为ioremap会在vmalloc区域中保留虚拟区域。 virt_to_phys()仅适用于线性映射的内存部分。

  

将这些放入pt = ioremap(BUFFER_SIZE,BUFFER_OFFSET)我相信pt   应该等于虚拟地址到位于的物理内存   2GB边界直到3GB边界。这个假设准确吗?

这不完全正确,例如在我的机器上  cat / proc / iomem

...
00001000-0009ebff : System RAM
...
00100000-1fffffff : System RAM
...

可能有几个存储体,非强制存储器将从物理地址空间的地址0x0开始。

这可能对您Dynamic DMA mapping Guide

有用