ashmem的意思就是Anonymous Shared Memory,即匿名共享内存。Android系统主要包括五个部分,分别是Linux 内核、本地库、Dalvik 虚拟机、应用程序框架和应用程序。对于其中的Linux内核部分,最初Android是基于2.6.25的,而且Android内核基本是同Linux内核同步更新的,AndroidLinux内核的基础上做了一些修改和功能上的添加。目前最新的开源版本是Android2.3,它是基于Linux-2.6.35的,它于2010127日公布。 

其中AndroidLinux内核的功能上的添加,就有ashmem,它为进程提供大块共享内存,同时为内核提供回收和管理这个内存的机制,其源代码位于Android源码中的kernel/mm/ashmem.c中:(Android内核版本2.0Eclair),它是基于2.6.29

1、用到的数据结构:

(1)struct ashmem_areaAndroid共享内存区,当父文件(应该也可以理解成父进程)调用open()函数时有效,至它调用release()函数消亡,通过“ashmem_mutex”来保护其互斥性。具体定义如下:

char name[ASHMEM_NAME_LEN];  /* 申请的一块ashmem的名称 */

struct list_head unpinned_list;  /* ashmem区的链表,用来把所有区连接起来 */

struct file *file;       /* 支持shmem-based的文件,struct file结构体定义 */

size_t size;          /* 内存映射的大小,以bytes为单位 */

unsigned long prot_mask; /* 一个类似于标志位的变量 */

(2)struct ashmem_range:代表unpinnedevictable)页的区间,生命周期从unpinpin,同样由“ashmem_mutex”来保证其互斥性。

struct list_head lru;         /* LRU(最近最少使用)链表 */

struct list_head unpinned;    /* unpinned区域链表 */

struct ashmem_area *asma;  /* 相关的ashmem区域 */

size_t pgstart;             /* 页开始位置(包含在页内) */

size_t pgend;             /* 页结束位置(包含在页内) */

unsigned int purged;       /* 标志变量,ASHMEM_NOTASHMEM_WAS_PURGED */

定义的几个全局变量:

/* LRU链表的定义 */

/* LRU链表计数器 */

/* 用来保证互斥性的ashmem_mutex初始化 */

* 指向ashmem_area的指针变量 */

/* 指向ashmem_range的指针变量 */

宏定义实现的函数:

/* 用来返回unpinned页的size */

/* 修改标志purged的值为ASHMEM_NOT_PURGED,表示这段内存没有清空*/

/* 判断是否在页内,参数为range结构体、起始地址、结束地址 */

/* 判断是否在页外 */

/* 判断是否在页内,参数为range结构体、页号 */

/* 判断是否在页内参数为range结构体、起始地址、结束地址 */

/* 判断rangge结构体定义的页时候在page之前 */

4、函数实现:

(1)内联函数:

/* LRU链表进行添加结点 */

/* LRU链表进行删除结点 */

/* 修改range结构体定义的内存的大小,可以进行缩短 */

基本函数:

 

/* 初始化一个ashmem_area结构体 */

/* 删除一个ashmem_area,就是从链表中删除 */

static struct file_operations ashmem_fops 成员函数:

成员函数定义如下:

/* 创建一个文件对象,也就是为一个ashmem_area结构体申请一段空间 */

/* 释放文件对象,也就是释放ashmem_area结构体 */

/* 将制定的文件映射到制定的进程区域中 */

说明:函数实现如下:

其中ashmem_ioctl函数可以实现的功能有:

ASHMEM_SET_NAME 设置名称,调用set_name函数。

ASHMEM_GET_NAME 获取名称,调用get_name函数。

ASHMEM_SET_SIZE 设置ashmem的大小,通过改变ashmem_area中的成员变量设置。

ASHMEM_GET_SIZE 获得ashmem的大小,通过读ashmem_area的成员变量获取。

ASHMEM_SET_PROT_MASK 设置prot_mask,调用set_prot_mask函数。

ASHMEM_GET_PROT_MASK 获取prot_mask,通过读ashmem_area的成员变量获取。

ASHMEM_PIN 使用pin语法,调用ashmem_pin_upin函数,通过判断再调用ashmem_pin函数。

ASHMEM_UNPIN 使用upin语法,调用ashmem_pin_upin函数,通过判断再调用ashmem_upin函数。

ASHMEM_GET_PIN_STATUS 获取pin状态,调用ashmem_pin_upin函数,通过判断再调用ashmem_get_pin_status函数。

⑩ASHMEM_PURGE_ALL_CACHES "净化"所有cache,调用ashmem_shrink函数。

(4)模块函数:定义模块的入口函数和出口函数。

static int __init ashmem_init(void)

/* 模块编程的规范,入口函数 */

static void __exit ashmem_exit(void)

/* 模块编程的规范,出口函数 */

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐