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

How to transfer data via DMA from RAM to RAM?

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

如果我对 ldd3 的理解是正确的,RAM 到 RAM 的复制是不可能的 linux 的 DMA API,但是 driver/dma/dmaengine.c为"DMA Transfer Type"提供了一个标志DMA_MEMCPY,所以应该有办法。

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

如果它依赖于硬件,我如何确定我的系统是否支持 dma memcpy?

正如您正确指出的那样,DMA_MEMCPY 应该用于执行 RAM 到 RAM 的复制。 Documentation/dmaengine/provider.txt 中对其进行了描述。这里只是相关的摘录,更多详细信息请查看整个文件:

Supported transaction types

The next thing you need is to set which transaction types your device (and driver) supports.

Our dma_device structure has a field called cap_mask that holds the various types of transaction supported, and you need to modify this mask using the dma_cap_set function, with various flags depending on transaction types you support as an argument.

All those capabilities are defined in the dma_transaction_type enum, in include/linux/dmaengine.h

Currently, the types available are:

  • DMA_MEMCPY
    • The device is able to do memory to memory copies

总结一下:

  • 这取决于您的 DMA 控制器。有些能够进行 RAM 到 RAM 事务,有些则不能。

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

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

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

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