如何在内核中执行单个 dma 事务?

How to do a single dma transaction in kernel?

我阅读了有关 dma 的自述文件 API,但仍然不明白应该如何使用它。 据说 dma_alloc_coherent 负责分配缓冲区,它是否也负责交易? (我在 ivtvfb.c 驱动程序中看到 fb_write 中 dma_alloc_coherent 的使用就好像它实际负责事务一样)

  1. 但是如何触发DMA交易开始呢?
  2. 完成后有回调吗?

What is a DMA transfer?

DMA 是一种硬件机制,它允许外围组件将它们的 I/O 数据直接传入和传出主内存,而无需涉及系统处理器。使用这种机制可以大大提高进出设备的吞吐量,因为从主要 CPU.

中消除了大量计算开销

...the use of dma_alloc_coherent() is done as if it actually responsible for the transaction.

相反,dma_alloc_coherent() 只是创建一个 dma 控制器可接受的缓冲区,即在主内存中保留一个区域(通常是连续的),可以在 CPU 和 DMA 之间共享控制器。

例如执行 DMA 写入,CPU 可以填充此缓冲区并指示 DMA 控制器将其写入设备,一旦完成, 调用回调函数(通知CPU上的SW运行)。

与此同时,当 DMA 控制器正在处理向外部设备的数据传输时,CPU 可以继续执行其他不依赖于同时传输的数据的无关任务并行。

类似地,要执行 DMA 读取,CPU 只需将通过调用 dma_allocate_coherent() 获得的缓冲区传递给 DMA 控制器并指示它执行读取。随后,DMA 控制器读取外部设备并开始填充提供的缓冲区,并在缓冲区填充后调用回调函数(半填充在一定的时间间隔后 如配置的那样 。)

延伸阅读:
Chapter 15 of LDD3 - "mmap and DMA".
Article on DMA APIs in the Linux kernel


通常这取决于 DMA 控制器。 即 DMA 控制器驱动程序提供的 API。

dma-engine is a standard framework in the Linux kernel used by several DMA providers.

相关:What is DMA mapping and DMA engine in context of linux kernel?


dma-engine的情况下:

Is there a callback when it is finished?

在从dmaengine_prep_slave_sg()

获得的描述符中填充回调指针

How to trigger the dma transaction to start?

使用dma_async_issue_pending()并传递初始化的描述符。


有关详细信息,请参阅 dma-engine client documentation