目前学习binder已经一周了,一直想写一些东西来的,但发现不管是原理还是源代码自己都似懂非懂,还真写不出来,,,今天有幸遇到一篇大神博客,是binder机制系列博客,逐步解决了我的疑惑。当然有说的不对的地方,也请评论指正。
大神系列网址:http://gityuan.com/2015/11/01/binder-driver/
学习第一天,了解了下驱动这块数据处理,解决疑惑如下:
1. 以前看过别人写的博客,在Android 为什么选择binder进行IPC通信时候说过,binder性能仅次于复杂的共享内存,只有一个数据拷贝??? 但是我们知道,进程间数据通信都是需要binder driver的,(一般性的数据操作操作流程是: 先从用户缓存区-》拷贝到内核缓存区-》拷贝到用户缓存区) ,因为linux内存都只有这样的处理方式,copy_from_user()和copy_to_user()实现该功能,但是怎么说binder机制就能实现一次拷贝就搞定这个问题呢?
查找各种资料,说的都很模糊,,,说什么内核空间到用户空间映射什么的,,,但想来想去,还是要经过binder driver才能实现该功能,怎么会直接实现用户态到用户态的一次性拷贝呢? 其实是这样的:
首先在内核虚拟地址空间,申请一块与用户虚拟内存相同大小的内存;然后再申请1个page大小的物理内存,再将同一块物理内存分别映射到内核虚拟地址空间和用户虚拟内存空间,从而实现了用户空间的Buffer和内核空间的Buffer同步操作的功能。
然后要了解一下binder driver对于接收方数据接收缓存的管理。。。其中最主要的
fd = open("/dev/binder", O_RDWR);
mmap(NULL, MAP_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
mmap()函数返回的是内存映射在用户空间的地址,不过这段空间是由驱动管理,用户不必也不能直接访问(映射类型为PROT_READ,只读映射)。。。用来创建数据接收的缓存空间,但核心是在用户态。。。。
怎么理解呢? 其实可以简单把数据传递的拷贝流程理解为: 用户空间拷贝到内核空间(实现一次拷贝,同时这个空间是位于用户空间的,接收方当然可以通过指针直接调用),,,然后copy_to_user()时候,提供简单的解放缓存,实现指针和指针数据偏移量传递就好了(因为用户空间和内核空间有物理内存映射),这样的数据传递是轻量级的,相当于没有这样的拷贝传递,,,,这样就实现了一次拷贝,提高性能的问题。
持续学习,准备完善好该篇文章。