What is DMA mapping and DMA engine in context of linux kernel? When DMA mapping API and DMA engine API can be used in Linux Device Driver? Any real Linux Device Driver example as a reference would be great.
DMA mapping is a conversion from virtual addressed memory to a memory which is DMA-able on physical addresses (actually bus addresses).
DMA stands for direct memory access and refers to the ability of devices or other entities in a computing system to modify main memory contents without going through the CPU.
The DMA engine is a generic kernel framework for developing a DMA controller driver. The main goal of DMA is offloading the CPU when it comes to copy memory. One delegates a transaction (I/O data transfers) to the DMA engine by the use of channels.
So that Linux can use the dynamic DMA mapping, it needs some help from the drivers, namely it has to take into account that DMA addresses should be mapped only for the time they are actually used and unmapped after the DMA transfer. The following API will work of course even on platforms where no such hardware exists.
What is DMA mapping and DMA engine in context of linux kernel?
The kernel normally uses virtual address. Functions like kmalloc()
, vmalloc()
normally return virtual address. It can be stored in void*
. Virtual memory system converts these addresses to physical addresses. These physical addresses are not actually useful to drivers. Drivers must use ioremap()
to map the space and produce a virtual address.
CPU CPU Bus
Virtual Physical Address
Address Address Space
Space Space
+-------+ +------+ +------+
| | |MMIO | Offset | |
| | Virtual |Space | applied | |
C +-------+ --------> B +------+ ----------> +------+ A
| | mapping | | by host | |
+-----+ | | | | bridge | | +--------+
| | | | +------+ | | | |
| CPU | | | | RAM | | | | Device |
| | | | | | | | | |
+-----+ +-------+ +------+ +------+ +--------+
| | Virtual |Buffer| Mapping | |
X +-------+ --------> Y +------+ <---------- +------+ Z
| | mapping | RAM | by IOMMU
| | | |
| | | |
+-------+ +------+
If device supports DMA , the driver sets up buffer using kmalloc
or similar interface which returns virtual address (X). The virtual
memory system maps X to a physical address (Y) in system RAM. The driver
can use virtual address X to access the buffer, but the device itself
cannot because DMA doesn't go through the CPU virtual memory system. In some system only Device can directly do DMA to physical address.
In some system IOMMU hardware is used to translate DMA address to physical address.Look at the figure above It translate Z to Y.
When DMA mapping API can be used in Linux Device Driver?
Reason to use DMA mapping API is driver can return virtual address X to interface like dma_map_single()
, which sets up any required IOMMU
mapping and returns the DMA address Z.The driver then tells the device to
do DMA to Z, and the IOMMU maps it to the buffer at address Y in system
RAM.
Reference is taken from this link.
Any real Linux Device Driver example as a reference would be great.
A simple PCI DMA example
Inside linux kernel you can look to drivers/dma for various real drivers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With