加载中…
个人资料
Steven天天Helloworld
Steven天天Helloworld
  • 博客等级:
  • 博客积分:0
  • 博客访问:4,491
  • 关注人气:4
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
正文 字体大小:

Binder IPC数据封装

(2012-07-23 17:06:46)
标签:

it

android

分类: Android驱动学习笔记

前面概述了一下binder到底是什么东西,能为我们解决什么问题,本博把讨论的焦点集中在binder的数据封装上。

数据在用户空间和内核空间的传递

Binder <wbr>IPC数据封装

Binder driver是字符设备驱动程序,通过调用open()和ioctl()函数访问。如上图,反应的是系统调用和文件运算函数之间的连接关系。例如open()系统调用顺序是:open()->__open()->binder_open()。

在应用程序通过binder尝试RPC操作时,会进行open()系统调用,获取bender driver的文件描述符。而后,通过mmap()在内核中开辟一块与用户空间相映射的内存空间,以便存放IPC数据。最后通过调用ioctl()函数,将IPC数据作为参数,传递binder driver。然后binder driver的ioctl()的格式如下:

ioctl(文件描述符,ioctl命令,数据)

ioctl()函数的第一个参数是文件描述符,因为在linux中,设备使用文件标识的,意思就是说用文件描述符来标识binder driver,然后用ioctl命令来控制binder driver的行为,数据是传送给bingder driver的数据。

下面是binder ioctl命令种类:

ioctl命令

Binder driver动作

数据类型

BINDER_WEITE_READ

在进程间接收发送binder IPC数据

Struct binder_write_read

BINDER_SET_IDLE_TIMEOUT

未使用

Int64_t

BINDER_SET_MAX_THREADS

设定注册在binder driver中的binder线程的(binder thread)最大个数

Size_t

BINDER_SET_IDLE_PRIORITY

未使用

Int

BINDER_SET_CONTEXT_MGR

设定bindrr driver的特殊节点(specical node)

Int

BINDER_THREAD_EXIT

删除binder线程

Int

BINDER_VERSION

提供binder协议的版本

Struct binder_version

下面先对其中两个命令简单的说一下:

1,第3个命令,BINDER_SET_MAX_THREADS中的thread的意思是进程中和binder driver打交道的那些线程。当客户服务端请求使用服务的时候,binder driver会将IPC DATA中名为BR_SVAN_LOOPER的RPC代码传递给service server,service server接收到BR_SWAN_LOOPER后就生成相应的服务线程。这种服务线程在参考文献1中,被作者称为“劳者”,也就是进程中干活的伙计。就是这些“伙计”不停的查看binder driver,看有没有自己的活,有的话就把相应的数据分析并呈递上层。

2,第5条命令, BINDER_SET_CONTEXT_MGR。这条命令式设置,context manager的,这个context manager是一个全局变量,就是我们在整个binder架构中所说的server manager。是统管所有service的进程。这个进程的实现涉及到binder架构的方方面面,这里暂时不多做介绍,当把所有其他的部分介绍完了,在回头看一下这个context manager是如何实现的。现在只要知道这个context manager是一个服务的管理者,每一个新增的服务要在它这里注册,每一个需要服务的客户端,要在它这里查询服务端的远程RPC位置。

 

这下面就要看表中的第一个命令,BINDER_WEITE_READ这是Binder最核心的功能,其后所跟的数据类型struct binder_write_read,这可以看做是一个数据包,里面包含了所谓的接收或发送端信息,RPC函数的信息,RPC数据信息等等等等。下面讨论这个RPC数据是如何封装成IPC数据流的。

 

Binder IPC数据封装

上面讲的是IPC数据流如何传到binder driver的,下面来说说IPC数据流是怎么封装和处理的,首先上一幅图:

 Binder <wbr>IPC数据封装

首先在客户端和service server端这一层,是所谓的业务层,就是在客户端只需虚拟的调用相应的服务函数就行,而实际的调用是在service server端。

其次,是生成和解析RPC代码,这个任务我姑且把它称为RPC层,这里是做函数调用和IPC数据包的转换,就是所谓的RPC数据封装。

接下来的IPC数据包,以及数据包中的handle,RPC数据,RPC代码,binder协议就是下面要讨论的。这里IPC的数据直接和binder driver所产生的动作相对应。那么我们来逐条分析每一段数据究竟干了什么。

 

Binder协议(Binder Protocol

Binder协议包含在binder IPC中 ,它从IPC层传递到binder driver,或者从binder driver层传递到IPC层。由传递方向,我们可以把协议分成两大类:一类是从IPC层传递到binder driver层的,BINDER COMMAND PROTOCOL,另一种是从binder driver层传输到IPC层的BINDER RETURN PROTOCOL。两种协议区别在于前者是BC_打头,后者是BR_打头的。

Binder协议类似于网络协议,是接收方和发送方共同遵守的的规定和规则。这里只讨论两个最关键的协议:BC_TRANSATION(在binder IPC数据发送端通过binder driver向接收端发送IPC数据时使用)和BR_TRANSATION(用于Binder IPC数据接收端分析数据)。

但是在讨论协议之前,首先要解释一下什么是handle,如果熟悉windows编程的人,应该见过handle,这是一个所谓的资源编号。在这里可以理解为对远程服务进程的标识。

然后通过handle,binder driver可以查到service server,然后把BC_TRANSATION,改为BR_TRANSATION,然后把IPC数据呈交上层函数。

然后上层RPC层接收到BR_TRANSACTION协议头的话,则解析IPC数据,通过RPC代码来定位服务,然后把RPC数据作为参数传入服务函数中。

 

RPC代码和RPC数据

上面闲扯半天,应该比较熟悉RPC层怎么对RPC函数和RPC数据处理了,下面就举一个简单的例子就好了。

假如一个MP3应用程序调整音量大小,于是MP3应用程序向提供Audio音频服务的Service Server提出请求,打包了一个RPC代码(SET_MASTER_VOLUME指定调整音量函数)与RPC数据(音量大小),然后把这个IPC数据包发送到Service Server,然后Service Server转到程序片段:

Switch(RPC代码)

{

Case SET_MASTER_VOLUME:

   setMasterVolume(50);

   break;

……

}

然后调用setMasterVolume(50)函数调整音量大小。

 

 

最后handle字段,是对Service Server的资源标识,用于binder Driver查找service server。不过这个要对Binder Driver中的一些数据结构有初步了解才能搞懂handle字段是如何定位服务的。这里就先卖个关子,就初步知道,反正binder driver有一套办法通过handle找到service server。其他东西,等到介绍binder driver的时候再说。

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有