内存管理(三)--Linux CMA内存使用

2024-09-04 11:52
文章标签 linux 使用 内存 管理 cma

本文主要是介绍内存管理(三)--Linux CMA内存使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、预留一段内存常用方法
    • 1.1 设备树定义reserve memory
  • 二、内存节点常见属性
    • 2.1 no-map和reusable使用上的区别
  • 三、预留CMA的reserved memory方法
    • 3.1 共享cma(采用设备树)
    • 3.2 共享cma(采用bootargs)
    • 3.3 私有cma
  • 四、使用reserved memory


我们日常使用kmalloc最多只能动态申请到4M(2^order)内存,当我们需要大块连续内存时,就需要借助CMA申请大内存。
CMA内存分配器在系统中具有多种重要作用,包括分配连续大块内存、提高内存利用率、提供灵活性与可迁移性、优化性能以及简化内存管理等。这些作用共同使得CMA成为嵌入式系统和其他需要连续内存支持的应用场景中的重要技术之一。

前文讲了Linux几种内存预留方法,本文主要讲解Linux里预留CMA内存方法和使用。


一、预留一段内存常用方法

1.1 设备树定义reserve memory

如果需要保留一段内存,在reserved-memory 节点下定义新节点。

reserved-memory {#address-cells = <0x2>;#size-cells = <0x2>;...fb_reserved0: framebuffer{reg = <0x1 0x10000000 0x0 0x8000000>; //addr:0x110000000  128M... //指定这个内存的属性,如:no-map, reusable};....};      

如果要将这个内存私有指定设备里,由指定设备节点使用,通过memory-region字段进行引用(指定给节点fb1使用):

  fb1 {compatible = "xx,xxx";memory-region = <&fb_reserved0>;  //引用这段内存私有到这个设备interrupt-parent = <&gic>;interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;interrupt-names = "xx";...};

二、内存节点常见属性

预留内存可以指定常用的属性,常见有:
1. reusable:表示当前的内存区域除了被dma使用之外,还可以被内存管理(buddy)子系统reuse。
2. no-map:表示是否需要创建页表映射,对于通用的内存,必须要创建映射才可以使用,共享CMA是可以作为通用内存进行分配使用的,因此必须要创建页表映射。
3. linux,cma-default:如果要cma区域为共享区域,需要配置上linux,cma-default属性。 指定了 linux,cma-default 属性,内核在分配 cma 内存时会将这片内存当成默认的 cma 分配池使用,执行内存申请时如果没有指定对应的 cma 就使用默认 cma pool。
4. alignment:对齐参数,保留内存的起始地址需要向该参数对齐
5. alloc-ranges:指定可以用来申请动态保留内存的区间.
6. shared-dma-pool(compatible="shared-dma-pool")
有的时候设备驱动程序需要采用DMA的方式使用预留的内存,对于这种场景,可以dts中的节点属性设置为shared-dma-pool,从而生成为特定设备驱动程序预留的DMA内存池。这样,设备驱动程序仅需要以常规方式使用DMA API。

2.1 no-map和reusable使用上的区别

如上已经介绍了no-map和reusable的特点,显著区别在于这几点:

  1. 是否需要将这块内存进行系统管理,放入buddy中管理。
  2. no-map保留的内存区域已被内核排除,因此iomem信息(/proc/iomem)显示系统RAM小于主板中的内存量。
  3. no-map由于没有创建映射表,因此使用时需要通过ioremap/ioremap_nocache
    /memremap等方式将内存映射出使用。

三、预留CMA的reserved memory方法

cma内存可以理解为是借用了reserve memory节点,可以使用DMA通用映射框架的API对其内存进行申请和使用。
编译内核时需要开启以下配置宏使用cma:

(1)配置宏CONFIG_CMA,启用连续内存分配器。
(2)配置宏CONFIG_CMA_AREAS,指定CMA区域的最大数量,默认值是7。
(3)配置宏CONFIG_DMA_CMA,启用允许设备驱动分配内存的连续内存分配器

cma内存可以将reserve memory分为私有cma和共享cma区域。

3.1 共享cma(采用设备树)

共享cma,将从系统全局自动配置一个连续分配区域 ,所有设备驱动在需要cma内存的时可以从这里面申请,不需要的时候,将作为buddy给系统使用。
标准定义方法如下,定义节点为linux,cma节点定义属性为:shared-dma-pool,reusable,linux,cma-default

reserved-memory {  / / 需要预留内存放在这个reserved-memory节点内定义#address-cells = <0x2>;#size-cells = <0x2>;ranges;cma_reserved: linux,cma {compatible = "shared-dma-pool";reusable;//表示 cma 内存可被 buddy 系统使用size = <0x0 0x80000000>; // 2GBalignment = <0x0 0x2000>; // 8KBlinux,cma-default; //作为cma默认内存池};....
};

3.2 共享cma(采用bootargs)

共享cma也通过内核参数“cma”配置全局CMA区域的大小。
使用内核参数“cma=nn[MG]@[start[MG][-end[MG]]]”设置全局CMA区域的大小和物理地址范围。

3.3 私有cma

reserved memory除了共享cma以外定义方式,其他认为是私有cma。个人认为,为方便区分,cma内存通常指共享池的cma,其他方式的就都称为reserved内存。
如上3.1 案例就是私有cma预留方式,通常配合各种属性对这个内存进行定义。


四、使用reserved memory

当内存compatible为shared-dma-pool。这时候设备驱动程序可以采用DMA的方式去使用预留的内存

  1. 设置设备寻址能力mask: dma_set_coherent_mask/dma_set_mask(一致/非一致性) 。这个会影响cma申请地址大小:2^mask。
  2. 通过of_reserved_mem_device_init来将从设备树memory-region获取内存地址私有化到设备里。
  3. 驱动通过接口dma_alloc_coherentdma_alloc_noncoherent(一致/非一致性)用来分配内存,接口dma_free_coherent和dma_free_noncoherent用来释放内存。

其他类型的内存需要通过如:ioremap/ioremap_nocache/memremap等,映射出内存地址使用。

这篇关于内存管理(三)--Linux CMA内存使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1135953

相关文章

SpringBoot中使用Flux实现流式返回的方法小结

《SpringBoot中使用Flux实现流式返回的方法小结》文章介绍流式返回(StreamingResponse)在SpringBoot中通过Flux实现,优势包括提升用户体验、降低内存消耗、支持长连... 目录背景流式返回的核心概念与优势1. 提升用户体验2. 降低内存消耗3. 支持长连接与实时通信在Sp

基于Linux的ffmpeg python的关键帧抽取

《基于Linux的ffmpegpython的关键帧抽取》本文主要介绍了基于Linux的ffmpegpython的关键帧抽取,实现以按帧或时间间隔抽取关键帧,文中通过示例代码介绍的非常详细,对大家的学... 目录1.FFmpeg的环境配置1) 创建一个虚拟环境envjavascript2) ffmpeg-py

python使用库爬取m3u8文件的示例

《python使用库爬取m3u8文件的示例》本文主要介绍了python使用库爬取m3u8文件的示例,可以使用requests、m3u8、ffmpeg等库,实现获取、解析、下载视频片段并合并等步骤,具有... 目录一、准备工作二、获取m3u8文件内容三、解析m3u8文件四、下载视频片段五、合并视频片段六、错误

gitlab安装及邮箱配置和常用使用方式

《gitlab安装及邮箱配置和常用使用方式》:本文主要介绍gitlab安装及邮箱配置和常用使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装GitLab2.配置GitLab邮件服务3.GitLab的账号注册邮箱验证及其分组4.gitlab分支和标签的

SpringBoot3应用中集成和使用Spring Retry的实践记录

《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项

nginx启动命令和默认配置文件的使用

《nginx启动命令和默认配置文件的使用》:本文主要介绍nginx启动命令和默认配置文件的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录常见命令nginx.conf配置文件location匹配规则图片服务器总结常见命令# 默认配置文件启动./nginx

在Windows上使用qemu安装ubuntu24.04服务器的详细指南

《在Windows上使用qemu安装ubuntu24.04服务器的详细指南》本文介绍了在Windows上使用QEMU安装Ubuntu24.04的全流程:安装QEMU、准备ISO镜像、创建虚拟磁盘、配置... 目录1. 安装QEMU环境2. 准备Ubuntu 24.04镜像3. 启动QEMU安装Ubuntu4

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

Python常用命令提示符使用方法详解

《Python常用命令提示符使用方法详解》在学习python的过程中,我们需要用到命令提示符(CMD)进行环境的配置,:本文主要介绍Python常用命令提示符使用方法的相关资料,文中通过代码介绍的... 目录一、python环境基础命令【Windows】1、检查Python是否安装2、 查看Python的安