hisi mmz模块驱动讲解
一、概述
如图所示,在海思平台上将内存分为两个部分: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模块驱动讲解的更多相关文章
- [转]hisi mmz模块驱动讲解
一.概述 如图所示,在海思平台上将内存分为两个部分:os内存和mmz内存.os内存指:由linux操作系统管理的内存:mmz内存:由mmz驱动模块进行管理供媒体业务单独使用的内存,在驱动加载时可以指定 ...
- 看Spring源码不得不会的@Enable模块驱动实现原理讲解
这篇文章我想和你聊一聊 spring的@Enable模块驱动的实现原理. 在我们平时使用spring的过程中,如果想要加个定时任务的功能,那么就需要加注解@EnableScheduling,如果想使用 ...
- 如何为编程爱好者设计一款好玩的智能硬件(九)——LCD1602点阵字符型液晶显示模块驱动封装(下)
六.温湿度传感器DHT11驱动封装(下):如何为编程爱好者设计一款好玩的智能硬件(六)——初尝试·把温湿度给收集了(下)! 七.点阵字符型液晶显示模块LCD1602驱动封装(上):如何为编程爱好者设计 ...
- 如何为编程爱好者设计一款好玩的智能硬件(八)——LCD1602点阵字符型液晶显示模块驱动封装(中)
六.温湿度传感器DHT11驱动封装(下):如何为编程爱好者设计一款好玩的智能硬件(六)——初尝试·把温湿度给收集了(下)! 七.点阵字符型液晶显示模块LCD1602驱动封装(上):如何为编程爱好者设计 ...
- uTenux——LED驱动讲解
LED驱动讲解,对于一个嵌入式的工程师还是一个刚开是学习相关电子设计的朋友,对于LED的驱动问题应该不甚陌生.我所说的LED驱动并不是类似大功率LED照明的那个驱动,而是简单的控制器对LED的控制驱动 ...
- linux模块驱动之led(ioremap)
一:led内核驱动 (1)在编写led内核驱动时,我们首先要进行内核裁剪,因为友善之臂将LED灯的驱动默认加载到内核中,所以编写模块驱动程序前就要先把原先的LED灯驱动裁剪掉: led驱动在源码里面的 ...
- Springboot基于enable模块驱动
enable作为模块驱动在Spring Farmework.Spring Boot.Spring Cloud使用,都是通过注解的形式以@enable作为前缀,一些常用注解如 | 框架 | 注解 | 模 ...
- web自动化测试-模块驱动测试实例和数据驱动测试实例
一.模块驱动测试实例 把登录和退出统一封装在login类中,若把login类单独放在一个文件中,就可以给任一测试脚本调用,这里就跟测试脚本放一起 from selenium import webdri ...
- 自动化测试架构设计 &&自动化持续集成测试任务实战[线性测试、模块驱动测试、数据驱动测试、关键字驱动测试]
1 为什么设计自动化测试架构 1.1 企业现状分析 压力大:产品需求不明确,上线时间确定,压力山大. 混乱:未立项,开发时间已过半,前期无控制,后期无保障. 疲于应付:开发人员交付的文件质量差,测试跟 ...
随机推荐
- Linux命令(自己工作常用)
添加用户--root角色才有权限 useradd -d主目录 -m username useradd -d /home/hadoop2 -m hadoop2; 删除用户 userdel -f user ...
- Dom对象与jQuery对象的互转
1.Dom对象转换为jQuery对象 a.直接获取视频,得到就是jQuery对象 $('video'); b.我们已经使用原生js,获取过来 Dom对象 var myvide = document.q ...
- MYSQL的备份与恢复--逻辑备份mysqldump
目录 0.备份与恢复概述 1.逻辑备份-完整备份与恢复 2.逻辑备份-增量备份与恢复 (1)环境准备 (2)恢复全量数据 (3)恢复增量备份 3.新来的开发妹子删了库! (1)模拟环境准备 (2)全备 ...
- C++ 标准库,可变参数模板。可变参数数量,可变参数类型【转】
#include <iostream> // 可变模板参数 // 此例:可以构造可变数量,可变类型的函数输入. // 摘自:https://www.cnblogs.com/qicosmos ...
- 【2019.10.7 CCF-CSP-2019模拟赛 T3】未知的数组(unknown)(并查集+动态规划)
预处理 考虑模数\(10\)是合数不好做,所以我们可以用一个常用套路: \(\prod_{i=l}^ra_i\equiv x(mod\ 10)\)的方案数等于\(\prod_{i=l}^ra_i\eq ...
- Codeforces Round #597 (Div. 2) E. Hyakugoku and Ladders 概率dp
E. Hyakugoku and Ladders Hyakugoku has just retired from being the resident deity of the South Black ...
- iOS: 线程中那些常见的锁
一.介绍 在多线程开发中,锁的使用基本必不可少,主要是为了解决资源共享时出现争夺而导致数据不一致的问题,也就是线程安全问题.锁的种类很多,在实际开发中,需要根据情况选择性的选取使用,毕竟使用锁也是消耗 ...
- Python画一棵漂亮的樱花树(不同种樱花+玫瑰+圣诞树喔)
不少用Python(大多是turtle库)绘制的树图,感觉很漂亮,我整理了一下,挑了一些我觉得不错的代码分享给大家(这些我都测试过,确实可以生成喔~)one 樱花树 动态生成樱花效果图(这个是动态的) ...
- IT兄弟连 HTML5教程 HTML和CSS的关系
HTML是描述网页的标记语言,是将内容放到网页上,虽然HTML本身也自带一些样式功能,通过自身的属性,来实现一些特定的效果,制作出来的只能是一个网页,而不是一个美观的网页.最主要的是在HTML里面,一 ...
- Python extend函数解读
num = [1,2] print('将1迭代2次') num.extend([1]*2) print(num) print('将2迭代3次') num.extend([2] * 3) print(n ...