上篇介绍完了 Binder 驱动内部会使用的数据结构,本文继续介绍 Binder 驱动和用户空间都会使用的数据结构。这部分数据结构有一个显著的特点,就是用于进程间通信过程所传输数据的封装,使得通信数据在用户空间和 Binder 驱动之间能够高效传输。
本文涉及到 Binder 通信模型的一些基本概念,如果还不太了解的话,可以参考Binder之基本概念这篇文章了解一下基本的概念。
进程间通信数据在 Client 进程用户空间的封装过程如下图所示:
上图主要涉及到三个结构体,下面按照数据封装顺序介绍:
1.1 struct flat_binder_object
struct flat_binder_object {
/* 8 bytes for large_flat_header. */
unsigned long type; [1]
unsigned long flags; [2]
/* 8 bytes of data. */
union {
void __user *binder; /* local object */ [3]
signed long handle; /* remote object */ [4]
};
/* extra data associated with local object */
void __user *cookie; [5]
};
结构体 flat_binder_object 主要用于描述一个 Binder 实体对象或者一个 Binder 引用对象,会被封装在结构体 binder_transaction_data 的成员变量 data中。
[1] type 用于说明 flat_binder_object 结构体表示的是一个 Binder 实体对象还是一个 Binder 引用对象。
[2] flags 只有在 flat_binder_object 结构体表示一个 Binder 实体对象时才有意义。目前只使用了它的第0位到第8位,其中第0位到第7位表示 Binder 实体所在线程应该具有的最小线程优先级;第8位表示 Binder 实体对象是否接收文件描述符。
[3] binder 用于指向对应 Service 组件内部的一个弱引用计数对象的地址,当 flat_binder_object 结构体表示