|
|
51CTO旗下网站
|
|
移动端

3.2.1 匿名共享内存(2)

《Android安全机制解析与应用实践》第3章Android安全机制源代码分析,本章对Android安全模型提供的各种机制包括文件系统权限、进程通信、应用程序权限以及应用程序签名机制进行了从应用层、架构层到内核层的代码分析。本节为大家介绍匿名共享内存。

作者:吴倩/赵晨啸/郭莹来源:机械工业出版社|2013-05-28 09:39

3.2.1 匿名共享内存(2)

2. 映射匿名共享内存

通过MemoryFile类的构造方法创建了共享内存文件以后,接下来需要把共享内存设备文件映射到进程空间,此操作通过调用JNI方法native_mmap来完成。这个JNI方法在frameworks/base/core/jni/adroid_os_MemoryFile.cpp文件中的实现如下:

  1. static jint android_os_MemoryFile_mmap(JNIEnv* env, jobject clazz, jobject fileDescriptor, jint length, jint prot)  
  2. {  
  3.  //获取匿名共享内存文件描述符  
  4.  int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);  
  5.  
  6.  //映射共享内存到进程空间  
  7.  jint result = (jint)mmap(NULL, length, prot, MAP_SHARED, fd, 0);  
  8.  
  9.  //对映射结果进行判断  
  10.  if (!result)  
  11.   jniThrowException(env, "java/io/IOException", "mmap failed");  
  12.  return result;  
  13. }  

在以上代码中,mmap方法中的fd可以通过open打开设备文件/dev/ashmem获得,mmap系统调用最终进入到内核空间的ashmem驱动程序的ashmem_mmap方法中实现:

  1. static int ashmem_mmap(struct file *file, struct vm_area_struct *vma)  
  2. {  
  3.  struct ashmem_area *asma = file->private_data;  
  4.  int ret = 0;  
  5.  mutex_lock(&ashmem_mutex);  //为ashmem上锁  
  6.  
  7.  //用户在调用mapping之前需要设置ashmem 大小  
  8.  if (unlikely(!asma->size)) {  
  9.  ret = -EINVAL;  
  10.  goto out;  
  11.  }  
  12.  //设置的ashmem保护bits需要与保护的mask一致  
  13.  if (unlikely((vma->vm_flags & ~asma->prot_mask) & PROT_MASK)) {  
  14.  ret = -EPERM;  
  15.  goto out;  
  16.  }  
  17.      //如果共享内存文件为空,创建一个备份的共享内存文件  
  18.  if (!asma->file) {  
  19.  char *name = ASHMEM_NAME_DEF;  
  20.  struct file *vmfile;  
  21.  if (asma->name[ASHMEM_NAME_PREFIX_LEN] != '\0')  
  22.  name = asma->name;  
  23.  vmfile = shmem_file_setup(name, asma->size, vma->vm_flags);  
  24.  if (unlikely(IS_ERR(vmfile)))  
  25.  {  
  26.  ret = PTR_ERR(vmfile);  
  27.  goto out;  
  28.  }  
  29.  asma->file = vmfile;  
  30.  }  
  31.  get_file(asma->file);  
  32.  if (vma->vm_flags & VM_SHARED) //如果是共享内存,创建shmem  
  33.  shmem_set_file(vma, asma->file);  
  34.  else {  
  35.  if (vma->vm_file)  
  36.  fput(vma->vm_file);  
  37.  vma->vm_file = asma->file;  
  38.  }  
  39.  vma->vm_flags |= VM_CAN_NONLINEAR;  
  40.  out:  
  41.  mutex_unlock(&ashmem_mutex);   //为ashmem解锁  
  42.  return ret;  
  43. }  

函数ashmem_mmap执行完成后,就得到了虚拟空间的起始地址了,这个起始地址最终返回到应用程序框架层的MemoryFile类的构造函数中,保存在成员变量mAddress中,之后就可以对共享内存进行读写操作。

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

活学活用 Ubuntu Server

活学活用 Ubuntu Server

实战直通车
共35章 | UbuntuServer

226人订阅学习

Java EE速成指南

Java EE速成指南

掌握Java核心
共30章 | 51CTO王波

87人订阅学习

Mysql DBA修炼之路

Mysql DBA修炼之路

MySQL入门到高阶
共24章 | 51CTO叶老师

483人订阅学习

读 书 +更多

网管员必读—服务器与数据存储(第2版)

本书是在第1版的基础上全面更新、改版而成的,仍然是目前图书市场中唯一一本全面介绍硬件服务器的IT图书。本书针对近两年来所出现的新服务...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO播客