Linux   发布时间:2022-03-31  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了内存管理 – 如何使用保留的CMA内存?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

我想为支持DMA的设备分配一些物理上连续的保留内存(在预定义的物理地址中). 我认为CMA有三种选择: 1.通过内核配置文件保留内存. 2.通过内核cmdline保留内存. 3.通过设备树内存节点保留内存. 在第一种情况下:可以保留区域的大小和数量. CONFIG_DMA_CMA=y CONFIG_CMA_AREAS=7 CONFIG_CMA_SIZE_MBYTES=8 @R_482_9447@使用: star
我想为支持DMA的设备分配一些物理上连续的保留内存(在预定义的物理地址中).
我认为CMA有三种选择:
1.通过内核配置文件保留内存. 2.通过内核cmdline保留内存. 3.通过设备树内存节点保留内存.
在第一种情况下:可以保留区域的大小和数量.

CONfig_DMA_CMA=y
CONfig_CMA_AREAS=7
CONfig_CMA_SIZE_MBYTES=8

@R_482_9447@使用:

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:

@H_283_24@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>;      
};

在某个节点中发布:

@H_283_24@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 
@R_618_10613@est_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,很明显它有设备名称和地址区域.
自动调用of_parse_phandle()之后的预留内存应该为您的特殊驱动程序(解析DT)预订.接下来调用dma_alloc_coherent将从cmadev_region:mycma中分配内存中的dma区域?

解决方法

要在保留的内存节点上使用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并获取内存.

大佬总结

以上是大佬教程为你收集整理的内存管理 – 如何使用保留的CMA内存?全部内容,希望文章能够帮你解决内存管理 – 如何使用保留的CMA内存?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。