Android Binder通信二 Binder驱动与协议
1 前言
在Binder通信整体框架这篇文章中已经说过Binder驱动是Binder通信的底层载体和支撑。Binder驱动支撑着整个Binder IPC过程。因此还是有必要稍微了解Binder驱动的一些基本概念
2 Binder驱动简介
Binder驱动在Linux内核并不对应于真实的设备,它只是一个虚拟的内存区域。
Binder驱动在内核中是以一个misc device类型驱动注册到内核中,并且不支持动态的添加和移除,主设备号为10,次设备号动态分配
Binder驱动的源码在Linux内核的drivers/staging/android
binder驱动的file_operations 定义如下
static const struct file_operations binder_fops = {
.owner = THIS_MODULE,
.poll = binder_poll,
.unlocked_ioctl = binder_ioctl,
.mmap = binder_mmap,
.open = binder_open,
.flush = binder_flush,
.release = binder_release,
};
可以看到,binder驱动提供给应用层的接口主要有 open,mmap,poll,ioctl等几个,其中常用的就open,mmap,ioctl三个,其中open表示打开驱动,mmap主要把驱动的内核空间地址映射到用户空间,便于数据的交换,而ioctl主要用于binder协议的通信
3 Binder驱动与应用的交互
要与Binder驱动通信,第一部就是打开打开binder驱动
binder_open
打开binder驱动代码如下:
struct binder_state *bs;
void *svcmgr = BINDER_SERVICE_MANAGER;
bs = binder_open(128*1024);
其中binder_open定义如下:
struct binder_state *binder_open(unsigned mapsize)
{
struct binder_state *bs;
bs = malloc(sizeof(*bs));
if (!bs) {
errno = ENOMEM;
return 0;
}
bs->fd = open("/dev/binder", O_RDWR);
if (bs->fd < 0) {
fprintf(stderr,"binder: cannot open device (%s)\n",
strerror(errno));
goto fail_open;
}
....
fail_map:
close(bs->fd);
fail_open:
free(bs);
return 0;
}
可以看到关键语句就是open(“/dev/binder”, O_RDWR);并返回一个fd。
打开了binder驱动接下来一般还需要将binder驱动设备与应用程序建立mmap映射内存,这样在用户空间就可以直接操作binder设备上的数据了。映射调用mmap函数,会调用到binder驱动的binder_mmap函数
binde_mmap
映射代码如下:
bs->mapsize = mapsize;
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
if (bs->mapped == MAP_FAILED) {
fprintf(stderr,"binder: cannot map device (%s)\n",
strerror(errno));
goto fail_map;
}
可以看到,主要调用mmap函数来做映射,并且映射的大小就是传入的参数128K。
一旦我们做了映射,那么当有另外一个应用程序B时,示意图如下:
可以看到,这个时候我们在进行IPC时,要将应用B的数据拷贝到应用程序A,只需要在binder驱动中执行一次copy_from_user复制一次数据即可。
上面binder驱动的初始化有两个过程,binder_open和binder_mmap,在真实的Binder通信体系中这个工作一般有ProcessState这个类来完成,这里就不再详细的讨论了,后期会有讨论。
4 Binder协议简介与ioctl
所谓的binder协议就是binder在进行ioctl操作所支持的一些命令以及。下面是binder协议的介绍
Binder协议
Binder协议可以分为控制协议和驱动协议两类。
控制协议是进程通过ioctl(“/dev/binder”) 与Binder设备进行通讯的协议,该协议包含以下几种命令:
Binder的驱动协议描述了对于Binder驱动的具体使用过程。驱动协议又可以分为两类:
• 一类是binder_driver_command_protocol,描述了进程发送给Binder驱动的命令
• 一类是binder_driver_return_protocol,描述了Binder驱动发送给进程的命令
binder_driver_command_protocol共包含17个命令,分别是:
binder_driver_return_protocol共包含18个命令,分别是:
这些命令有个大体的影响就行,对应用开发来说并不需要掌握。
5 binder驱动总结
binder驱动本质上仍然是一个典型的Linux设备驱动,它主要为binder的IPC过程服务,并且google设计了一套binder协议保证binder通信的顺利进行。下一节将结合ServiceManager来介绍通过Binder驱动,client与ServiceManager是如何交互的。
以上就是有关binder驱动的一些相关知识,下一遍将介绍binder通信体系中servicemanager的角色
参考:
深入理解Android内核设计思想 第二版 林学森著
走进Android Binder机制(驱动篇上
http://blog.csdn.net/ming_147/article/details/65633571
上一篇: Android基础——框架模式MVC在安卓中的实践
下一篇: Binder进程间通信二次总结