Home > System Tutorial > LINUX > body text

In-depth discussion of Linux driver technology (3) _The implementation principles and related technologies of DMA programming

WBOY
Release: 2024-02-13 14:03:03
forward
1232 people have browsed it

In the process of writing Linux drivers, DMA programming is a very important technology. It can achieve high-speed data transmission and improve system performance and response speed. In this article, we will delve into the implementation principles and related technologies of Linux driver technology (3) _DMA programming.

深入探讨Linux驱动技术(三) _DMA编程的实现原理和相关技术

DMA, Direct Memory Access, is a technology that allows peripherals to directly access memory data without CPU involvement. When the peripherals complete reading and writing the memory, DMAC notifies the CPU through interrupts. This technology is multi-purpose It is suitable for peripheral control that has high requirements on data volume and data transmission speed, such as display devices, etc.

DMA and Cache consistency

We know that in order to improve system operating efficiency, modern CPUs adopt a multi-level cache structure, which includes the use of multi-level Cache technology to cache data in memory to alleviate the problem of CPU and memory speed differences. Under this premise, it is obvious that if the data in the DMA memory has been cached by the Cache, and the peripheral modifies the data, this will cause a mismatch between the Cache data and the memory data, that is, DMA and Cache Consistency issue. In order to solve this problem, the simplest way is to disable the Cache function of DMA memory. Obviously, this will lead to a decrease in performance

Virtual address VS physical address VS bus address

In a computer with an MMU, the CPU sees the virtual address, which is converted into a physical address after being sent to the MMU. The virtual address is then converted into ## through the corresponding circuit. #Bus address is the address seen by the peripheral. Therefore, the address seen by the DMA peripheral is actually the bus address. The Linux kernel provides corresponding APIs to achieve conversion between three types of addresses:

//虚拟->物理
virt_to_phys()
//物理->虚拟
ioremap()

//虚拟->总线
virt_to_bus()
//总线->虚拟
bus_to_virt()
Copy after login

DMA address mask

DMA peripherals may not be able to perform DMA operations on all memory addresses. In this case, a DMA address mask should be used

int dma_set_mask(struct device *dev,u64 mask);
Copy after login

For example, for a DMA peripheral that can only access a 24-bit address, use

dma_set_mask(dev,0xffffff)

Programming process

The following is the process of using DMA memory in the kernel program:

Consistent DMA

If you use a DMA buffer in the driver, you can use the API provided by the kernel that already takes consistency into account:

/**
 * request_dma - 申请DMA通道
 * On certain platforms, we have to allocate an interrupt as well...
 */
int request_dma(unsigned int chan, const char *device_id);


/**
 * dma_alloc_coherent - allocate consistent memory for DMA
 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
 * @size: required memory size
 * @handle: bus-specific DMA address *
 * Allocate some memory for a device for performing DMA.  This function
 * allocates pages, and will return the CPU-viewed address, and sets @handle
 * to be the device-viewed address.
 */
void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag)

//申请PCI设备的DMA缓冲区
void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)


//释放DMA缓冲区
void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle )

//释放PCI设备的DMA缓冲区
void pci_free_consistent()

/**
 * free_dma - 释放DMA通道
 * On certain platforms, we have to free interrupt as well...
 */
void free_dma(unsigned int chan); 
Copy after login

Streaming DMA

If you use the application layer buffer to create a DMA application instead of the buffer in the driver, you may only use functions such as kmalloc to apply, then you need to use a streaming DMA buffer. In addition, you must also solve the problem of Cache consistency. question.

/**
 * request_dma - 申请DMA通道
 * On certain platforms, we have to allocate an interrupt as well...
 */
int request_dma(unsigned int chan, const char *device_id);

//映射流式DMA
dma_addr_t dma_map_single(struct device *dev,void *buf, size_t size, enum dma_datadirection direction);

//驱动获得DMA拥有权,通常驱动不该这么做
void dma_sync_single_for_cpu(struct device *dev,dma_addr_t dma_handle_t bus_addr,size_t size, enum dma_data_direction direction);

//将DMA拥有权还给设备
void dma_sync_single_for_device(struct device *dev,dma_addr_t dma_handle_t bus_addr,size_t size, enum dma_data_direction direction);

//去映射流式DMA
dma_addr_t dma_unmap_single(struct device *dev,void *buf, size_t size, enum dma_datadirection direction);

/**
 * free_dma - 释放DMA通道
 * On certain platforms, we have to free interrupt as well...
 */
void free_dma(unsigned int chan); 
Copy after login

In short, DMA programming is an integral part of the Linux driver writing process. It can achieve high-speed data transmission and improve system performance and response speed. I hope this article can help readers better understand Linux driver technology (3) _The implementation principles and related technologies of DMA programming.

The above is the detailed content of In-depth discussion of Linux driver technology (3) _The implementation principles and related technologies of DMA programming. For more information, please follow other related articles on the PHP Chinese website!

source:lxlinux.net
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template