首页 > 解决方案 > 如何将 dma_alloc_attr() 与 DMA_ATTR_NO_KERNEL_MAPPING 一起使用?

问题描述

我想DMA_ATTR_NO_KERNEL_MAPPING用于内存分配。根据内核文档,我必须使用dma_mmap_attrs(),但它需要struct vm_area_struct作为其参数之一。我该如何使用它?

dma_addr_t phys;
void *virt;
void *tmp_virt;
struct vm_area_struct *vma;

pr_debug("pmap: cma: request to alloc %s for size 0x%08x\n",
         info->name, info->size);

if(strcmp(info->name,"video") == 0)
{
    pr_debug("video allocation.....\n");
    tmp_virt = dma_alloc_attrs(pmap_device, info->size, &phys, GFP_KERNEL,
                        DMA_ATTR_NO_KERNEL_MAPPING | DMA_ATTR_FORCE_CONTIGUOUS);

    virt = dma_mmap_attrs(pmap_device, vma, tmp_virt, &phys, info->size,
                        DMA_ATTR_NO_KERNEL_MAPPING | DMA_ATTR_FORCE_CONTIGUOUS);

}

我正在使用来自用户空间的 ioctl 调用请求内存分配,然后在系统重新启动时发生内核恐慌。

如何DMA_ATTR_NO_KERNEL_MAPPING使用 ioctl 进行用户空间分配?

在我的示例驱动程序代码中,我声明struct vm_area_struct *vma. 那是对的吗?

标签: cmemory-managementlinux-kernellinux-device-driverdma

解决方案


如果你在 dma_alloc_attr() 中使用了 DMA_ATTR_NO_KERNEL_MAPPING,这意味着你不想要分配区域的虚拟映射。DMA_ATTR_NO_KERNEL_MAPPING 仅用于再次映射到用户空间内存,没有直接 api 将其映射到内核空间内存。

如果用户空间想要虚拟映射它,下面是选项。

  1. 在驱动程序中使用 dma_mmap_attr() 你必须使用 .map = map_user_space_function() 然后在该函数中使用 dma_mmap_attr() ,它将映射到用户空间虚拟内存。
  2. 在驱动程序中使用 get_vm_area() 并使用 dma_mmap_attr(),其中使用了 get_vm_area() 返回的 vm_area。

推荐阅读