免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1252 | 回复: 0
打印 上一主题 下一主题

[20100504]Android PMEM驱动研究(2) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-22 08:51 |只看该作者 |倒序浏览
Android PMEM驱动研究(2)——在应用程序中使用PMEM

放假结束,继续研究PMEM。

======================================================================================
Android PMEM主要有两个作用(来自android mail list):
1. GPU or VPU buffers shared with CPU core
2. Android service heap.
其中1是不能cache的,2可以cache,平台设备注册中cached = X即控制是否可以被cache。

=======================================================================================
简单看PMEM驱动,主要有以下内容:

pmem_init()驱动加载
|
pmem_probe()platform加载
|
pmem_setup()
初始化 pmem[id]
启动时输出信息,格式为[名称][是否可以被cache] eg:pmem_adsp: 0 init
misc_register()
初始化所有的bitmap
通过ioremap获取所有pmem[id].vbase

pmem_map() 提供mmap接口

pmem_ioctl()
#define PMEM_GET_PHYS 获取物理地址
#define PMEM_MAP pmem_remap()
#define PMEM_GET_SIZE pmem_getsize()
#define PMEM_UNMAP pmem_remap(&region, file, PMEM_UNMAP);
#define PMEM_ALLOCATE 分配pmem空间,len是参数,如果文件已被分配则失败
#define PMEM_CONNECT 将一个pmem file与其他相连接
#define PMEM_GET_TOTAL_SIZE 返回pmem region的全部尺寸

这而也有篇文章值得参考http://linux.chinaunix.net/techdoc/net/2009/04/21/1108452.shtml
=======================================================================================

应用程序中使用PMEM,有待深入研究

#include "android_pmem.h"

int pmem_fd;
void *pmem_base;
unsigned int size;
struct pmem_region region;

pmem_fd = open("/dev/pmem_adsp", O_RDWR, 0);//打开设备,为了操作硬件引擎,要noncache的

if (pmem_fd >= 0) 
{
        
        if (ioctl(pmem_fd, PMEM_GET_TOTAL_SIZE, &region) < 0) //获取全部空间
  {
            printf("PMEM_GET_TOTAL_SIZE failed\n");
            size = 4<<20;   // 4 MiB
 
else 
{
            size = region.len;
        }
      pmem_base = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);//mmap操作
      if (pmem_base == MAP_FAILED) 
{
            pmem_base = 0;
            close(pmem_fd);
            pmem_fd = -1;
   printf("mmap pmem error!\n");
        }

if ( ioctl(pmem_fd, PMEM_GET_PHYS, &region) < 0)//获取物理地址
{
            printf("PMEM_GET_PHYS failed\n");
 

}

其实第一个ioctl无用,只是为了获取长度。
经过以上操作,region.offset为物理地址,其空间和虚拟地址pmem_base相对应。
在程序中填充pmem_base数据,配置VPU、GPU时使用region.offset该物理地址。

=======================================================================================
最后来看看驱动调用流程

1)open操作
[drivers/misc/pmem.c:pmem_open:336] current 55 file c7355c80(1)

2)mmap 会自动调用allocate
[drivers/misc/pmem.c:pmem_allocate:398] order 0
[drivers/misc/pmem.c:pmem_map_pfn_range:511] map offset 0 len 10000

3)ioctl PMEM_GET_PHYS 感觉物理地址是根据pid来确定的
[drivers/misc/pmem.c:pmem_ioctl:1081] get_phys
pmem: request for physical address of pmem region from process 55.

4)munmap
[drivers/misc/pmem.c:pmem_vma_close:555] current 55 ppid 47 file c7355c80 count 2

不知道如果有两个设备操作该驱动会怎么样?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP