我想为支持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)不可能为连续分配设置预定义的物理地址。当然,我可以使用内核cmdline:
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的内存。但不幸的是,我对这个解决方案有问题。也许我的cmdline有错误?下一次尝试是设备树实现。
cmadev_region: mycma {
/*no-map;*/ /*DMA coherent memory*/
/*reusable;*/
reg = <0x02000000 0x00100000>;
};和phandle在某些节点中:
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 via (因为我只知道一个外部API函数dma_alloc_coherent) dma_alloc_coherent()而不是IO-MAP ioremap()。但是如何调用
start_cma_virt = dma_alloc_coherent(dev->cmadev,(size_t)size_cma,&start_cma_dma,GFP_KERNEL);
是否将内存从设备树(注册表= <0x02000000 0x00100000>;)关联到开发->cmadev?在使用cmdline的情况下,很明显它具有设备名称和地址区域。在自动调用of_parse_phandle()之后,是否应该为您的特殊驱动程序(解析DT)预留内存。下一次调用dma_alloc_coherent将从cmadev_region中分配内存中的dma区域: mycma?
发布于 2019-03-12 17:54:46
要在保留内存节点上使用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->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并获取内存。
https://stackoverflow.com/questions/35556593
复制相似问题