您的位置:首页 > 移动开发 > Android开发

Android Binder通信二 Binder驱动与协议

2018-01-07 18:33 169 查看

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息