我想编写一个内核模块,可以通过 DMA 在 RAM 之间传输数据。有一些帖子讨论了这个问题,但我不太明白。有人说有可能,有人说不可能。
如果我对 ldd3 的理解正确,那么使用 linux 的 DMA API 不可能实现 RAM 到 RAM 的复制,但是 driver/dma/dmaengine.c 为“DMA 传输类型”提供了一个标志 DMA_MEMCPY,因此应该有一个方式。
这是正确的吗?我可以使用 DMA 引擎将数据从一个 RAM 地址传输到另一个吗?
如果与硬件相关,我如何确定我的系统是否支持 dma memcpy?
正如您正确指出的那样,应该使用
DMA_MEMCPY
来执行 RAM 到 RAM 的复制。它在Documentation/dmaengine/provider.txt中进行了描述。这里只是相关摘录,请查看整个文件以了解更多详细信息:
支持的交易类型
接下来您需要设置您的设备的交易类型 (和驱动程序)支持。
我们的
结构有一个名为dma_device
的字段,它保存 支持多种交易类型,需要修改此 使用cap_mask
函数进行掩码,具有各种标志,具体取决于 您支持的交易类型作为参数。dma_cap_set
所有这些功能都在
枚举中定义, 在dma_transaction_type
include/linux/dmaengine.h
目前可用的类型有:
DMA_MEMCPY
- 设备能够进行内存到内存的复制
总结一下:
这取决于您的 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。