内存管理 – 如何使用保留的CMA内存?
我想为支持DMA的设备分配一些物理上连续的保留内存(在预定义的物理地址中).
我认为CMA有三种选择: 1.通过内核配置文件保留内存. 2.通过内核cmdline保留内存. 3.通过设备树内存节点保留内存. 在第一种情况下:可以保留区域的大小和数量. CONFIG_DMA_CMA=y CONFIG_CMA_AREAS=7 CONFIG_CMA_SIZE_MBYTES=8 所以我可以使用: start_cma_virt = dma_alloc_coherent(dev->cmadev,(size_t)size_cma,&start_cma_dma,GFP_KERNEL); 在我的驱动程序中分配连续的内存.我可以使用它最多7次,最多可以分配8M.但不幸的是 dma_contiguous_reserve(min(arm_dma_limit,arm_lowmem_limit)); 来自arch / arm / mm / init.c: void __init arm_memblock_init(struct meminfo *mi,const struct machine_desc *mdesc) 不可能为连续分配设置预定义的物理地址. mem=cma=cmadevlabel=8M@32M cma_map=mydevname=cmadevlabel //struct device *dev = cmadev->dev; /*dev->name is mydevname*/ 之后,dma_alloc_coherent()应将物理内存区域中的内存从32M 8M(0x2000000 0x800000)分配到0x27FFFFF. cmadev_region: mycma { /*no-map;*/ /*DMA coherent memory*/ /*reusable;*/ reg = <0x02000000 0x00100000>; }; 并在某个节点中发布: memory-region = <&cmadev_region>; 正如我在内核中常见的那样,它应该被用作: of_find_node_by_name(); //find needed node of_parse_phandle(); //resolve a phandle property to a device_node pointer of_get_address(); //get DT __be32 physical addresses of_translate_address(); //DT represent local (bus,device) addresses so translate it to CPU physical addresses request_mem_region(); //reserve IOMAP memory (cat /proc/iomem) ioremap(); //alloc entry in page table for reserved memory and return kernel logical addresses. 但我想使用DMA通过(因为我只知道一个外部API函数dma_alloc_coherent)dma_alloc_coherent()而不是IO-MAP ioremap().但是如何打电话 start_cma_virt = dma_alloc_coherent(dev-> cmadev,& start_cma_dma,GFP_KERNEL); 将内存从设备树(reg =< 0x02000000 0x00100000>;)关联到dev-> cmadev?对于cmdline,很明显它有设备名称和地址区域. 解决方法
要在保留的内存节点上使用dma_alloc_coherent(),需要将该区域声明为dma_coherent.你可以做一些事情:
在dt中: cmadev_region: mycma { compatible = "compatible-name" no-map; reg = <0x02000000 0x00100000>; }; 在你的司机: struct device *cma_dev; static int rmem_dma_device_init(struct reserved_mem *rmem,struct device *dev) { int ret; if (!mem) { ret = dma_declare_coherent_memory(cma_dev,rmem->base,rmem->size,DMA_MEMORY_EXCLUSIVE); if (ret) { pr_err("Error"); return ret; } } return 0; } static void rmem_dma_device_release(struct reserved_mem *rmem,struct device *dev) { if (dev) dev->dma_mem = NULL; } static const struct reserved_mem_ops rmem_dma_ops = { .device_init = rmem_dma_device_init,.device_release = rmem_dma_device_release,}; int __init cma_setup(struct reserved_mem *rmem) { rmem->ops = &rmem_dma_ops; return 0; } RESERVEDMEM_OF_DECLARE(some-name,"compatible-name",cma_setup); 现在在这个cma_dev上你可以执行dma_alloc_coherent并获取内存. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |