如何通过DMA将数据从RAM传输到RAM?

我想写一个内核模块,可以通过DMA从RAM传输数据到RAM。 有一些文章讨论这个,但我真的不明白。 有人说可能有人说这不是。

如果我理解了ldd3,那么RAM到RAM的拷贝是不可能的,但是驱动程序/dma/dmaengine.c提供了一个标志DMA_MEMCPY用于“DMA传输types”,所以应该有一个办法。

这是否正确,我可以使用dma引擎将数据从一个ram地址传输到另一个吗?

如果是硬件相关的,我怎样才能确定我的系统是否支持dma memcpy?

正如您正确指出的那样,应该使用DMA_MEMCPY来执行RAM到RAM的复制。 它在Documentation / dmaengine / provider.txt中有描述。 这里只是一个相关的摘录,请看整个文件的更多细节:

支持的事务类型

接下来您需要设置您的设备(和驱动程序)支持的事务类型。

我们的dma_device结构有一个名为cap_mask的字段,用于保存支持的各种事务类型,并且需要使用dma_cap_set函数修改此掩码,各种标志取决于您支持的事务类型作为参数。

所有这些功能都在include/linux/dmaengine.h中的dma_transaction_type枚举中定义

目前,可用的类型是:

  • DMA_MEMCPY
    • 该设备能够将内存复制到内存中

只是要总结一下:

  • 这取决于你的DMA控制器。 有些可以做RAM到RAM的事务,有些则不行。

  • 例如,对于基于OMAP的SoC,DMA控制器在omap_dma_probe()函数中执行以下操作( drivers/dma/omap-dma.c文件):

     dma_cap_set(DMA_MEMCPY, od->ddev.cap_mask); 
  • 这样,您可以稍后在驱动程序中检查它(如果您的DMA控制器能够执行RAM到RAM的事务)。 在dmatest_add_channel()函数中看看它是如何在drivers/dma/dmatest.cdmatest_add_channel()

     if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) { 

如果您需要有关如何使用DMA API执行RAM到RAM事务的示例,请参阅drivers / dma / dmatest.c 。