欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android Binder通信二 Binder驱动与协议

程序员文章站 2024-03-24 09:07:46
...

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时,示意图如下:
Android Binder通信二 Binder驱动与协议
可以看到,这个时候我们在进行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设备进行通讯的协议,该协议包含以下几种命令:
Android Binder通信二 Binder驱动与协议
Binder的驱动协议描述了对于Binder驱动的具体使用过程。驱动协议又可以分为两类:
• 一类是binder_driver_command_protocol,描述了进程发送给Binder驱动的命令
• 一类是binder_driver_return_protocol,描述了Binder驱动发送给进程的命令
binder_driver_command_protocol共包含17个命令,分别是:
Android Binder通信二 Binder驱动与协议
binder_driver_return_protocol共包含18个命令,分别是:
Android Binder通信二 Binder驱动与协议
这些命令有个大体的影响就行,对应用开发来说并不需要掌握。

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