【问题标题】:Mapping Reserved High Memory to User Space via remap_pfn_range通过 remap_pfn_range 将保留的高端内存映射到用户空间
【发布时间】:2017-06-28 11:47:20
【问题描述】:

Arch=x86_64

我正在按照这个问题中概述的过程通过 DMA 解决方案, Direct Memory Access in Linux

我对@9​​87654322@ 的调用成功返回一个地址,pt。

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

当使用mmap 的用户空间应用程序执行并调用remap_pfn_range 时,机器崩溃。我假设映射已关闭,并且我正在强制系统使用已分配的内存(退出前的屏幕故障),但是我不清楚发生不匹配的位置。系统有 4 Gigs 的 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 提供大的连续缓冲区。在这个应用程序中,重新编译内核不是一个选项,所以我尝试使用模块 + 硬件来完成它。

【问题讨论】:

    标签: c linux memory-management linux-kernel


    【解决方案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 边界。这个假设准确吗?

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

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

    可能有多个内存条,非强制性内存将从物理地址空间的地址 0x0 开始。

    这可能对你有用Dynamic DMA mapping Guide

    【讨论】:

    • 谢谢,我会调查并报告。我很欣赏你的洞察力、简洁性和语气。
    猜你喜欢
    • 2012-02-05
    • 2019-05-28
    • 2012-09-29
    • 2017-01-12
    • 1970-01-01
    • 2016-03-10
    • 2011-09-16
    • 2014-06-10
    • 1970-01-01
    相关资源
    最近更新 更多