Linux DMA API 问题

标签 linux linux-kernel arm linux-device-driver dma

按照 https://www.kernel.org/doc/Documentation/DMA-API.txt 处的文字一些内联问题

Part Ia - Using large dma-coherent buffers
------------------------------------------

void *
dma_alloc_coherent(struct device *dev, size_t size,
                 dma_addr_t *dma_handle, gfp_t flag)

Consistent memory is memory for which a write by either the device or
the processor can immediately be read by the processor or device
without having to worry about caching effects.  (You may however need
to make sure to flush the processor's write buffers before telling
devices to read that memory.)

Q1。假设分配的区域是可缓存的是否安全?作为最后一行声明需要冲洗

Q1a。此 API 是否从被认为是 DMA 安全的低 16MB 分配内存。

dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
              enum dma_data_direction direction)

Maps a piece of processor virtual memory so it can be accessed by the
device and returns the physical handle of the memory.

The direction for both api's may be converted freely by casting.
However the dma_ API uses a strongly typed enumerator for its
direction:

DMA_NONE        no direction (used for debugging)
DMA_TO_DEVICE       data is going from the memory to the device
DMA_FROM_DEVICE     data is coming from the device to the memory
DMA_BIDIRECTIONAL   direction isn't known

Q2。 DMA_XXX 选项是否直接更改 VA=>PA 映射的页面属性。假设 DMA_TO_DEVICE 会将区域标记为不可缓存?

最佳答案

它说“无需担心缓存效果”。这意味着 dma_alloc_coherent() 返回不可缓存的内存,除非架构具有缓存一致的 DMA 硬件,因此缓存没有区别。然而,未缓存并不意味着写入不通过 CPU 写入缓冲区(即并非每个内存访问都会立即执行或以与它们在代码中出现的顺序相同的顺序执行)。当您告诉设备读取它时,要确保您写入内存的所有内容都真实存在,您至少必须执行 wmb()。有关详细信息,请参阅文档/memory-barriers.txt。

dma_alloc_coherent() 不从低 16 MB 返回内存,它返回由 dma_set_coherent_mask() 指定的可寻址区域内的设备可访问的内存。您必须在设备初始化过程中调用它。

可缓存性与 dma_map_*() 函数无关。他们确保给定的内存区域可以在他们返回的 DMA 地址处被设备访问。 DMA 完成后调用 dma_unmap_*()。对于 DMA_TO_DEVICE,顺序是“将数据写入内存,map(),启动 DMA,完成时取消映射()”,对于 DMA_FROM_DEVICE,顺序是“map(),启动 DMA,完成时取消映射(),从内存中读取数据”。

缓存没有区别,因为通常在映射时您不会写入或读取缓冲区。如果您真的必须这样做,则必须在读取缓冲区之前或写入缓冲区之后显式地dma_sync_*() 内存。

关于Linux DMA API 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23519794/

相关文章:

linux - 初始化 XGCValues 时出错

network-programming - 增加 SKB 的引用计数

linux-kernel - 如何在内核中分配不可缓存的物理内存?

c - 除了将 C 弦标记为宽弦之外,L 对 C 弦还有哪些特殊作用?

linux - 使用共享库时出现段错误

linux - shell脚本linux减去参数grep

c - 了解 C 运行时环境 (ARM) - 从哪里开始

c - STM32 NUCLEO F401RE无法写入GPIO BSRR中的某些位

linux - 您如何确定 bash ls 颜色的含义?

c - argv[0] 更改由 linux 内核阻止或记录