一、概述

如图所示,在海思平台上将内存分为两个部分:os内存和mmz内存。os内存指:由linux操作系统管理的内存;mmz内存:由mmz驱动模块进行管理供媒体业务单独使用的内存,在驱动加载时可以指定该模块管理内存的大小:

insmod hi_osal.ko mmz=anonymous,0,0x4fa00000,6Manony=1 || report_error

二、数据结构

1、mmz区域描述符

struct hil_media_memory_zone {

   char name[HIL_MMZ_NAME_LEN+1]; //mmz区域名字:anonymous

       

   unsigned long gfp;   //区域标识:0

 

   unsigned long phys_start; //mmz区域起始物理地址:0x4fa00000

   unsigned long nbytes; //mmz区域大小:6M

       

   struct list_head list; //mmz链表

 

   unsigned char *bitmap; //位图

   struct list_head mmb_list; //mmz区域的mmb链表,存放所有申请到的物理内存

   

   unsigned int alloc_type;

   unsigned long block_align;

   

   void (*destructor)(const void *);

};

2、mmb内存描述符

hil_media_memory_block描述了从mmz区域申请一块内存,同一个mmz区域内的所有mmb通过链表连接。

struct hil_media_memory_block {

   #ifndef MMZ_V2_SUPPORT

   unsigned int id;

   #endif

   char name[HIL_MMB_NAME_LEN+1]; //该mmb模块使用者名字

   struct hil_media_memory_zone *zone; //指向mmb所属的mmz区域

   struct list_head list; //mmb链表

        

   unsigned long phys_addr; //申请到的mmb起始物理地址

   void *kvirt;  //对应内核虚拟地址,从代码看未用

   unsigned long length; //申请的mmb大小

   

   unsigned long flags; //标识

   

   unsigned int order;

 

   int phy_ref; //引用计数

   int map_ref; //引用计数

};

3、mmz_userdev_info

该结构体保存打开该设备文件的进程信息,存放在file结构体的private_data成员里。

struct mmz_userdev_info {

   pid_t pid;         //打开设备文件的进程pid

   pid_t mmap_pid;

   struct semaphore sem; //信号量

   struct list_head list; //指向mmb_info链表

};

4、mmb_info

该结构体描述应用申请到mmb后的相关信息,同进程的mmb_info通过链表形式管理。

struct mmb_info {

   unsigned long phys_addr;    //申请到的物理内存,同mmb.phys.addr

   unsigned long align;        /* ifyou need your phys-memory have special align size */

   unsigned long size;     //申请的物理内存大小

   unsigned int order;

   

    void *mapped;       //指向mmap后的虚拟地址空间

       

   union {

       struct {

           unsigned long prot  :8; /*PROT_READ or PROT_WRITE */

           unsigned long flags :12;/* MAP_SHARED or MAP_PRIVATE */

   

#ifdef __KERNEL__

           unsigned long reserved :8; /* reserved, do not use */

           unsigned long delayed_free :1;

           unsigned long map_cached :1;

#endif

       };

       unsigned long w32_stuf;

   };

   

   char mmb_name[HIL_MMB_NAME_LEN+1];

   char mmz_name[HIL_MMZ_NAME_LEN+1];

   unsigned long gfp;      /*reserved, do set to 0 */

   

#ifdef __KERNEL__

   int map_ref;

   int mmb_ref;

       

   struct list_head list;    //mmb_info链表

   hil_mmb_t *mmb;     //指向申请到的mmb

#endif

};

三、关系图

1、mmz和mmb关系

下图展示了mmz驱动管理mmz和mmb的关系。mmz驱动模块支持多个mmz区域,只要在加载mmz.ko时通过参数传递即可,一般情况下只有一个mmz区域。多个mmz区域之间通过链表的形式组织在一起,链表头为mmz_list;而每个mmz区域通过mmb_list维护mmb链表,管理该区域内所有已经申请了的物理内存区域;每个mmb通过zone成员知道自己属于哪个mmz区域。

通过/proc/media-mem可以查看mmz和mmb使用情况:

+---ZONE: PHYS(0x4FA00000, 0x4FFFFFFF),GFP=0, nBYTES=6144KB,  NAME="anonymous"

  |-MMB: phys(0x4FA00000, 0x4FA81FFF), kvirt=0x  (null), flags=0x00000000, length=520KB,       name="DCCM_MSG_BUF"

  |-MMB: phys(0x4FA82000, 0x4FA84FFF), kvirt=0x  (null), flags=0x00000000, length=12KB,        name="SYS_scale_coef"

  |-MMB: phys(0x4FA85000, 0x4FA87FFF), kvirt=0x  (null), flags=0x00000000, length=12KB,        name="SYS_scale_coef"

  |-MMB: phys(0x4FA88000, 0x4FB07FFF), kvirt=0x  (null), flags=0x00000000, length=512KB,       name="TDE_MemPool"

   |-MMB: phys(0x4FB08000, 0x4FB3CFFF),kvirt=0x  (null), flags=0x00000000,length=212KB,      name="IVE_QUEUE"

  |-MMB: phys(0x4FB3D000, 0x4FB3DFFF), kvirt=0x  (null), flags=0x00000000, length=4KB,name="IVE_TEMP_NODE"
  
  --MMZ_USE_INFO: total size=6144KB(6MB),used=1272KB(1MB +248KB),remain=4872KB(4MB + 776KB),zone_number=1,block_number=6

2、mmb、mmb_info和mmb_userdev_info关系

下图展示了mmz驱动和应用申请数据结构之间的关系:

当应用打开设备文件/dev/mmz_userdev时会申请一个属于该进程的mmb_userdev_info结构体,mmb_userdev_info成员list指向属于该进程的所有mmb_info,mmb_info的mmb成员指向为其分配的mmb,而*mmaped存放mmb物理内存(phy_addr)进行映射后的虚拟地址供用户空间使用。

由于mmz大部分为媒体业务独立使用,内存在媒体硬件模块流转,应用无需访问,这时不用映射,只有当应用需要访问时才需要进行映射。可以把mmz管理的整个内存看做存储盘上的一个大文件,应用层要访问mmz的物理内存通过mmap方式进行映射(类似文件),映射的文件偏移就是mmb.phy_addr,映射大小就是申请的mmb.length,通过mmap方式映射到内核后根据返回的虚拟地址就可以访问该mmb内存。

hisi mmz模块驱动讲解的更多相关文章

  1. [转]hisi mmz模块驱动讲解

    一.概述 如图所示,在海思平台上将内存分为两个部分:os内存和mmz内存.os内存指:由linux操作系统管理的内存:mmz内存:由mmz驱动模块进行管理供媒体业务单独使用的内存,在驱动加载时可以指定 ...

  2. 看Spring源码不得不会的@Enable模块驱动实现原理讲解

    这篇文章我想和你聊一聊 spring的@Enable模块驱动的实现原理. 在我们平时使用spring的过程中,如果想要加个定时任务的功能,那么就需要加注解@EnableScheduling,如果想使用 ...

  3. 如何为编程爱好者设计一款好玩的智能硬件(九)——LCD1602点阵字符型液晶显示模块驱动封装(下)

    六.温湿度传感器DHT11驱动封装(下):如何为编程爱好者设计一款好玩的智能硬件(六)——初尝试·把温湿度给收集了(下)! 七.点阵字符型液晶显示模块LCD1602驱动封装(上):如何为编程爱好者设计 ...

  4. 如何为编程爱好者设计一款好玩的智能硬件(八)——LCD1602点阵字符型液晶显示模块驱动封装(中)

    六.温湿度传感器DHT11驱动封装(下):如何为编程爱好者设计一款好玩的智能硬件(六)——初尝试·把温湿度给收集了(下)! 七.点阵字符型液晶显示模块LCD1602驱动封装(上):如何为编程爱好者设计 ...

  5. uTenux——LED驱动讲解

    LED驱动讲解,对于一个嵌入式的工程师还是一个刚开是学习相关电子设计的朋友,对于LED的驱动问题应该不甚陌生.我所说的LED驱动并不是类似大功率LED照明的那个驱动,而是简单的控制器对LED的控制驱动 ...

  6. linux模块驱动之led(ioremap)

    一:led内核驱动 (1)在编写led内核驱动时,我们首先要进行内核裁剪,因为友善之臂将LED灯的驱动默认加载到内核中,所以编写模块驱动程序前就要先把原先的LED灯驱动裁剪掉: led驱动在源码里面的 ...

  7. Springboot基于enable模块驱动

    enable作为模块驱动在Spring Farmework.Spring Boot.Spring Cloud使用,都是通过注解的形式以@enable作为前缀,一些常用注解如 | 框架 | 注解 | 模 ...

  8. web自动化测试-模块驱动测试实例和数据驱动测试实例

    一.模块驱动测试实例 把登录和退出统一封装在login类中,若把login类单独放在一个文件中,就可以给任一测试脚本调用,这里就跟测试脚本放一起 from selenium import webdri ...

  9. 自动化测试架构设计 &&自动化持续集成测试任务实战[线性测试、模块驱动测试、数据驱动测试、关键字驱动测试]

    1 为什么设计自动化测试架构 1.1 企业现状分析 压力大:产品需求不明确,上线时间确定,压力山大. 混乱:未立项,开发时间已过半,前期无控制,后期无保障. 疲于应付:开发人员交付的文件质量差,测试跟 ...

随机推荐

  1. numpy中array和matrix的区别

    两者相似但执行相同的运算可能得到不同的结果 显然,array只能通过dot()实现"矩阵乘法",array的"*"运算实现的是两个纬度相同的"矩阵&q ...

  2. Oracle 10g&11g安装卸载Oracle Label Security

    Oracle Label Securit简介   Oracle Label Security是内置于数据库引擎中的过程与约束条件集,该数据引擎实施对在单个表或整个模式上的"行"级访 ...

  3. TP5 ajax请求报500错误

    场景:几个站点从阿里云迁移到腾讯云,然后 TP5项目 ajax请求报500错误 数据返回成功,但是http状态码是500,不走success,一直走error 如下图: 原因分析: 服务器centos ...

  4. Java基础之IO技术(一)

    ---恢复内容开始--- Java基础中的IO技术可谓是非常重要,俗话说的好,万丈高楼起于垒土之间.所以学习Java一定要把基础学好,今天我们来学习IO技术的基础. IO无非就是输入与输出,而其中处理 ...

  5. docker 限制容器能够使用的资源

    docker 限制容器能够使用的内存,CPU,I/O 资源概述,内存是非可压缩资源,cpu是可压缩资源. 内存用超了,就发送Out Of Memory Exception,容器会被kill掉.所以内存 ...

  6. manjaro安装后的配置

    1.添加中科大源 参考https://blog.csdn.net/liyunfu233/article/details/87381017 sudo nano /etc/pacman.conf 在文末添 ...

  7. linux驱动——cmdline原理及利用【转】

    转自:https://blog.csdn.net/qingzhuyuxian/article/details/82895416 最近安卓项目中想要获取内核cmdline特定的启动参数,因为我们在他的U ...

  8. WPF 精修篇 拖拽 DragDrop

    原文:WPF 精修篇 拖拽 DragDrop WPF 实现拖拽 效果 <Grid> <Grid.ColumnDefinitions> <ColumnDefinition ...

  9. Vue 监听鼠标左键 鼠标右键以及鼠标中键修饰符click.left&contextmenu&click.middle

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. 趣谈Linux操作系统学习笔记:第二十五讲

    一.mmap原理 在虚拟内存空间那一节,我们知道,每一个进程都有一个列表vm_area_struct,指向虚拟地址空间的不同内存块,这个变量名字叫mmap struct mm_struct { str ...