一、什么是CMA

CMA,Contiguous Memory Allocator,是内存管理子系统中的一个模块,负责物理地址连续的内存分配。一般系统会在启动过程中,从整个memory中配置一段连续内存用于CMA,然后内核其他的模块可以通过CMA的接口API进行连续内存的分配。CMA的核心并不是设计精巧的算法来管理地址连续的内存块,实际上它的底层还是依赖内核伙伴系统这样的内存管理机制,或者说CMA是处于需要连续内存块的其他内核模块(例如DMA mapping framework)和内存管理模块之间的一个中间层模块,主要功能包括:

1、解析DTS或者命令行中的参数,确定CMA内存的区域,这样的区域我们定义为CMA area。

2、提供cma_alloc和cma_release两个接口函数用于分配和释放CMA pages

3、记录和跟踪CMA area中各个pages的状态

4、调用伙伴系统接口,进行真正的内存分配

二、使用CMA

示例一,https://stackoverflow.com/questions/35556593/how-to-work-with-reserved-cma-memory

To use dma_alloc_coherent() on reserved memory node, you need to declare that area as dma_coherent. You can do some thing like:In dt:cmadev_region: mycma {compatible = "compatible-name"no-map;reg = <0x02000000 0x00100000>;
};
In your driver: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);
Now on this cma_dev you can perform dma_alloc_coherent and get memory.

示例二,http://www.sohu.com/a/226744867_467784

/** kernel module helper for testing CMA** Licensed under GPLv2 or later.*/#include <linux/module.h>#include <linux/device.h>#include <linux/fs.h>#include <linux/miscdevice.h>#include <linux/dma-mapping.h>#define CMA_NUM 10static struct device *cma_dev;static dma_addr_t dma_phys[CMA_NUM];static void *dma_virt[CMA_NUM];/* any read request will free coherent memory, eg.* cat /dev/cma_test*/static ssize_tcma_test_read(struct file *file, char __user *buf, size_t count, loff_t *ppos){int i;for (i = 0; i < CMA_NUM; i++) {if (dma_virt[i]) {dma_free_coherent(cma_dev, (i + 1) * SZ_1M, dma_virt[i], dma_phys[i]);_dev_info(cma_dev, "free virt: %p phys: %pn", dma_virt[i], (void *)dma_phys[i]);dma_virt[i] = NULL;break;}}return 0;}/** any write request will alloc coherent memory, eg.* echo 0 > /dev/cma_test*/static ssize_tcma_test_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos){int i;int ret;for (i = 0; i < CMA_NUM; i++) {if (!dma_virt[i]) {dma_virt[i] = dma_alloc_coherent(cma_dev, (i + 1) * SZ_1M, &dma_phys[i], GFP_KERNEL);if (dma_virt[i]) {void *p;/* touch every page in the allocated memory */for (p = dma_virt[i]; p < dma_virt[i] + (i + 1) * SZ_1M; p += PAGE_SIZE)*(u32 *)p = 0;_dev_info(cma_dev, "alloc virt: %p phys: %pn", dma_virt[i], (void *)dma_phys[i]);} else {dev_err(cma_dev, "no mem in CMA arean");ret = -ENOMEM;}break;}}return count;}static const struct file_operations cma_test_fops = {.owner = THIS_MODULE,.read = cma_test_read,.write = cma_test_write,};static struct miscdevice cma_test_misc = {.name = "cma_test",.fops = &cma_test_fops,};static int __init cma_test_init(void){int ret = 0;ret = misc_register(&cma_test_misc);if (unlikely(ret)) {pr_err("failed to register cma test misc device!n");return ret;}cma_dev = cma_test_misc.this_device;cma_dev->coherent_dma_mask = ~0;_dev_info(cma_dev, "registered.n");return ret;}module_init(cma_test_init);static void __exit cma_test_exit(void){misc_deregister(&cma_test_misc);}module_exit(cma_test_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");MODULE_DEION("kernel module to help the test of CMA");MODULE_ALIAS("CMA test");申请内存:# echo 0 > /dev/cma_test释放内存:# cat /dev/cma_test

三、doc

*** Reserved memory regions ***Reserved memory is specified as a node under the /reserved-memory node.
The operating system shall exclude reserved memory from normal usage
one can create child nodes describing particular reserved (excluded from
normal use) memory regions. Such memory regions are usually designed for
the special usage by various device drivers.Parameters for each memory region can be encoded into the device tree
with the following nodes:/reserved-memory node
---------------------
#address-cells, #size-cells (required) - standard definition- Should use the same values as the root node
ranges (required) - standard definition- Should be empty/reserved-memory/ child nodes
-----------------------------
Each child of the reserved-memory node specifies one or more regions of
reserved memory. Each child node may either use a 'reg' property to
specify a specific range of reserved memory, or a 'size' property with
optional constraints to request a dynamically allocated block of memory.Following the generic-names recommended practice, node names should
reflect the purpose of the node (ie. "framebuffer" or "dma-pool"). Unit
address (@<address>) should be appended to the name if the node is a
static allocation.Properties:
Requires either a) or b) below.
a) static allocationreg (required) - standard definition
b) dynamic allocationsize (required) - length based on parent's #size-cells- Size in bytes of memory to reserve.alignment (optional) - length based on parent's #size-cells- Address boundary for alignment of allocation.alloc-ranges (optional) - prop-encoded-array (address, length pairs).- Specifies regions of memory that areacceptable to allocate from.If both reg and size are present, then the reg property takes precedence
and size is ignored.Additional properties:
compatible (optional) - standard definition- may contain the following strings:- shared-dma-pool: This indicates a region of memory meant to beused as a shared pool of DMA buffers for a set of devices. It canbe used by an operating system to instanciate the necessary poolmanagement subsystem if necessary.- vendor specific string in the form <vendor>,[<device>-]<usage>
no-map (optional) - empty property- Indicates the operating system must not create a virtual mappingof the region as part of its standard mapping of system memory,nor permit speculative access to it under any circumstances otherthan under the control of the device driver using the region.
reusable (optional) - empty property- The operating system can use the memory in this region with thelimitation that the device driver(s) owning the region need to beable to reclaim it back. Typically that means that the operatingsystem can use that region to store volatile or cached data thatcan be otherwise regenerated or migrated elsewhere.Linux implementation note:
- If a "linux,cma-default" property is present, then Linux will use theregion for the default pool of the contiguous memory allocator.- If a "linux,dma-default" property is present, then Linux will use theregion for the default pool of the consistent DMA allocator.Device node references to reserved memory
-----------------------------------------
Regions in the /reserved-memory node may be referenced by other device
nodes by adding a memory-region property to the device node.memory-region (optional) - phandle, specifier pairs to children of /reserved-memoryExample
-------
This example defines 3 contiguous regions are defined for Linux kernel:
one default of all device drivers (named linux,cma@72000000 and 64MiB in size),
one dedicated to the framebuffer device (named framebuffer@78000000, 8MiB), and
one for multimedia processing (named multimedia-memory@77000000, 64MiB)./ {#address-cells = <1>;#size-cells = <1>;memory {reg = <0x40000000 0x40000000>;};reserved-memory {#address-cells = <1>;#size-cells = <1>;ranges;/* global autoconfigured region for contiguous allocations */linux,cma {compatible = "shared-dma-pool";reusable;size = <0x4000000>;alignment = <0x2000>;linux,cma-default;};display_reserved: framebuffer@78000000 {reg = <0x78000000 0x800000>;};multimedia_reserved: multimedia@77000000 {compatible = "acme,multimedia-memory";reg = <0x77000000 0x4000000>;};};/* ... */fb0: video@12300000 {memory-region = <&display_reserved>;/* ... */};scaler: scaler@12500000 {memory-region = <&multimedia_reserved>;/* ... */};codec: codec@12600000 {memory-region = <&multimedia_reserved>;/* ... */};
};

LINUX CMA 初探相关推荐

  1. linux cma机制探究

    Linux cma机制探究 cma的作用    cma,全称(contiguous memory allocation),在内存初始化时预留一块连续内存,可以在内存碎片化严重时通过调用dma_allo ...

  2. linux CMA总结

    [前言] 有时候对一个词记忆特别深刻的时候,那一定是你被这个词伤害过,我就是被CMA伤害过... 那是一个冬天,高通的面试官问我,知道什么是CMA吗,我心头翻涌出无数浪花,脑子也和进了水一样,CMA, ...

  3. Linux cma内存的使用

    CMA的全称叫做contiguous memory allocator,它是为了便于进行连续物理内存申请的一块区域,一般我们把这块区域定义为reserved-memory. 早期的Linux内核中没有 ...

  4. linux CMA 布局

    CMA 布局策略 转自:https://biscuitos.github.io/blog/CMA-layout/#C019 CMA 20 Dec 2019 Email: BuddyZhang1 bud ...

  5. linux CMA使用机制分析--基于SigmaStar SSD202

    前一篇文档提到CMA相关的内容Linux虚拟内存映射分析以及CMA测试 - 以SSD202为例,其主要使用标准内核CMA API进行,并直接经由CMA进行管理,通过进一步查探,SSD202内核有独立的 ...

  6. linux cma内存,【原创】(十六)Linux内存管理之CMA,

    [原创](十六)Linux内存管理之CMA, 背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. ...

  7. linux CMA 内存分配器(Contiguous Memory Allocator)

    目录 1 什么是CMA 2 CMA配置 2.1 cmdline 配置 2.2 设备树配置节点 2.3 其他CMA区创建 3 CMA 初始化 cma_init_reserved_mem() 4 CMA区 ...

  8. Linux 文件系统初探

    文章目录 文件系统 Linux文件系统标准结构 所有分区的含义 Linux分区 文件系统 Windows Linux 分盘,每个驱动器有自己的根目录,形成的是多个树并列的结构. 只有一个根目录 / , ...

  9. Linux内核初探3

    1.内核的任务 内核:充当底层的驱动程序,应用程序只与内核有联系,内核是应用程序的所知道的层次结构中最底层的,也是资源管理程序,也是一种库,提供了一组面向系统的命令. 2.实现策略 微内核(中央内核) ...

最新文章

  1. iOS私有Api检测
  2. Redis之跳跃表(面试重点容易考)
  3. python扇贝单词书_Python脚本 扇贝单词书爬取
  4. axure 鼠标变成手,Axure教程|鼠标移入移出自动显示与隐藏三级菜单
  5. ConcurrentProgramming:volatile/构造方法溢出/禁止重排序
  6. jquery attr
  7. pyqt5 登录窗口调用主窗口
  8. Objective-C 高性能的循环
  9. 一行数据中三列值的比较
  10. 第七节、文件系统与磁盘分区
  11. 武汉理工大学华夏学院计算机类,2015年武汉理工大学华夏学院招生专业代码
  12. 运用PS做图片快捷键
  13. 逻辑回归(logistics regression)
  14. debug——程序停止正常工作
  15. Android的SharedPreferences和SQLite
  16. iOS锁屏显示歌曲信息
  17. lsdyna如何设置set中的node_list_如何理解vue的双向绑定
  18. 【Git】常用命令详解(循序渐进,逐步分析)
  19. 以《天天炫斗》的兴衰看动作类手游运营策略
  20. NestJS、Vite 和 esbuild 入门

热门文章

  1. 【操作系统经典问题】睡眠理发师问题
  2. 15 Rest高级客户端实践(一):文档索引
  3. 期货中的“心静”和“身静”
  4. 70+分级调色lut预设 Psychedelia LUTs Pack无水印
  5. 教你如何申请软件著作权(超级详细)--小白教学
  6. 《动手学深度学习》第三十三天---AdaGrad算法,RMSProp算法,AdaDelta算法,Adam算法
  7. The located assembly’s manifest definition does not match the assembly reference
  8. 【Java】网络编程——多线程下载文件
  9. 小米为其他手机适配rom_如何刷入其他系统•简(小米手机)
  10. 嵌入式培训经验分享——C语言小项目(五子棋)