【问题标题】:Reserving memory for DMA usage为 DMA 使用保留内存
【发布时间】:2016-03-21 13:20:14
【问题描述】:

我正在尝试使用我在引导时将“mem”参数传递给 Linux 时保留的连续内存。

现在,我有了我之前保留的这个空间的物理地址,以及它的长度,我希望在我的驱动程序中利用这个保留的空间进行 DMA。

通常我会使用 dma_alloc_coherent() ,如果我使用 CMA 我也会使用它,但在这种情况下,它会有所不同。

现在,我读到将物理空间映射到内核虚拟空间的一种可接受的方法是使用ioremap

并且,为 DMA 目的“接管”连续空间的可接受方式是使用 dma_map_single(将其映射为总线地址)

我无法将两者结合起来。 ioremap 工作并返回一个虚拟地址。现在,我读到这不是普通的虚拟地址,我应该只使用访问方法来读取/写入这个内存。

问题是,当我尝试将此虚拟地址传递给 dma_map_single 时,它不会报告错误,但我怀疑这是错误的。

我做得对吗?我该怎么做才能让它正常工作?

10 倍

【问题讨论】:

  • 我懒得搜索了,但在这个网站上这个问题每年都会发生一次。
  • 谢谢。也许我不擅长搜索,但我确实搜索并发现了不同的变体,但与我的情况完全不同。

标签: c linux linux-kernel driver dma


【解决方案1】:

你做得对 您不需要分配内存,因为您已经在启动时设置了它,但是您需要使用 dam_map_single 来防止缓存问题,例如,如果您想从内存到设备进行 DMA,但 RAM 与 L2 不同步缓存(缓存有较新的版本)你会得到错误的数据所以你需要在DMA操作之前和之后映射和取消映射

【讨论】:

  • 谢谢。我不确定传递 dma_map_single 的 ioremap 地址是否正确。
  • @Liran 很抱歉破解了线程,但是使用 ioremap 创建的内存映射没有被缓存。那么它可以直接传递给 dma 的设备吗?
  • 如果你从一个 io 内存复制到另一个,没关系,但大多数时候你从 DDR 复制到设备(或相反)并且可以缓存 DDR
  • 如果我们在启动时保留 DDR,并且 DDR 内存被 ioremap 到内核虚拟地址空间。据我了解,此内存是非缓存的。如果底层平台不支持IOMMU,我认为我们可以将物理地址传递给设备并要求做DMA。我的理解错了吗?
  • 你是对的,但你仍然需要“告诉”CPU 你正在做一个 DMA 请求,这样它就不会接触到总线,直到它结束看到这里的一个例子discoversdk.com/knowledge-base/dma-example
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-05
  • 2021-06-05
  • 1970-01-01
  • 2014-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多