dma_alloc_contiguous 是一个用于在 Linux 内核中分配连续 DMA 物理内存的接口。它主要用于设备驱动程序,以确保为设备分配的内存是物理上连续的,从而满足某些硬件对内存地址的要求。
下面是 dma_alloc_contiguous 的使用示例,适用于 Linux 驱动开发。
示例代码
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
struct my_device {
    void *virt_addr;       // 虚拟地址
    dma_addr_t phys_addr;  // 物理地址
    size_t size;           // 分配大小
};
static struct my_device *my_dev;
static int __init my_driver_init(void) {
    // 分配设备结构体
    my_dev = kmalloc(sizeof(struct my_device), GFP_KERNEL);
    if (!my_dev) {
        pr_err("Failed to allocate memory for device structure\n");
        return -ENOMEM;
    }
    // 设置要分配的DMA缓冲区大小(例如:1MB)
    my_dev->size = 1024 * 1024;
    // 分配连续DMA内存
    my_dev->virt_addr = dma_alloc_coherent(NULL, my_dev->size,
                                            &my_dev->phys_addr,
                                            GFP_KERNEL);
    
    if (!my_dev->virt_addr) {
        pr_err("Failed to allocate DMA coherent memory\n");
        kfree(my_dev);
        return -ENOMEM;
    }
    pr_info("Allocated %zu bytes of DMA memory at virtual address: %p, physical address: %pad\n",
            my_dev->size, my_dev->virt_addr, &my_dev->phys_addr);
    return 0;
}
static void __exit my_driver_exit(void) {
    if (my_dev && my_dev->virt_addr) {
        // 释放DMA内存
        dma_free_coherent(NULL, my_dev->size,
                          my_dev->virt_addr,
                          my_dev->phys_addr);
        
        pr_info("Freed DMA memory\n");
    }
    
    kfree(my_dev);
}
module_init(my_driver_init);
module_exit(my_driver_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A simple example of using dma_alloc_coherent");
MODULE_AUTHOR("Your Name");
代码说明
包含必要的头文件:包括了所需的库,例如
module.h和dma-mapping.h。定义设备结构体:包含虚拟地址、物理地址和分配大小等信息。
初始化函数 (
my_driver_init):- 首先分配设备结构体。
 - 然后设置要分配的DMA缓冲区大小。
 - 使用 
dma_alloc_coherent()函数申请连续的DMA内存,并获取其虚拟地址和物理地址。如果失败,则清理并返回错误。 
退出函数 (
my_driver_exit):- 在模块卸载时,释放已分配的DMA内存和设备结构体。
 
模块宏:使用
module_init()和module_exit()宏来指定模块的入口和出口点。
注意事项
- 确保在你的系统上编译这个模块时,相关驱动框架已经正确安装。
 - 上述代码中的 
NULL参数传递给dma_alloc_coherent()表示没有特定于设备上下文。在实际情况中,应该传入与硬件相关的信息,例如相应的设备结构指针。 - 请根据具体需求调整缓冲区大小和其它参数。这只是一个基本示例,用于展示如何调用这个接口。
内容由零声教学AI助手提供,问题来源于学员提问 


        
        
        
        
        
        
        
        
        
        
                
                
                
                
                
                