1:binder实体在驱动中的表示(struct binder_node )
binder_node是应用空间的binder实体在内核的表示,它直属于某个特定的进程(binder_proc),其他进程对该binder实体的使用,都会挂在该binder实体的refs哈希列表中。
struct binder_node {
int debug_id;
struct binder_work work;
union {
struct rb_node rb_node;
struct hlist_node dead_node;
};
struct binder_proc *proc;
struct hlist_head refs;
int internal_strong_refs;
int local_weak_refs;
int local_strong_refs;
void __user *ptr;
void __user *cookie;
unsigned has_strong_ref:1;
unsigned pending_strong_ref:1;
unsigned has_weak_ref:1;
unsigned pending_weak_ref:1;
unsigned has_async_transaction:1;
unsigned accept_fds:1;
unsigned min_priority:8;
struct list_head async_todo;
};
struct binder_work work;//通过这个字段来将该binder添加到todo列表中,然后会在binder_thread_read中得到处理。此时这个node->work.type类型为BINDER_WORK_NODE。
struct rb_node rb_node;//通过该字段,以该binder实例在应用空间对应的引用对象(RefBase::weakref_type)的地址为index,将该binder实体连接到该实体所属的进程(bidner_proc)的proc->nodes的红黑树下
struct binder_proc *proc;//指向该binder所属的进程
struct hlist_head refs;//所有其他进程对该binder的引用,以哈希表的形式组织在以refs为表头的哈希表下
int internal_strong_refs;
int local_weak_refs;
int local_strong_refs;//以上各字段用于binder的引用管理的
void __user *ptr;//binder实体对应在应用空间的weakref_type对象(即引用对象)在应用空间的地址
void __user *cookie;//存储用户空间的Binder实体地址的指针,正是通过该字段来调用服务器端在应用空间的处理后台,见下面:
status_t IPCThreadState::executeCommand(int32_t cmd)
{
... ...
case BR_TRANSACTION:
{
... ...
if (tr.target.ptr) {
sp<BBinder> b((BBinder*)tr.cookie);
const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
if (error < NO_ERROR) reply.setError(error);
} else {
const status_t error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
if (error < NO_ERROR) reply.setError(error);
}
上面的cookie值就是我们binder中的cookie值,由于他本身就是服务器端bbinder对象的地址,所以取出来直接可以引用该对象的操作函数(b->transact())了。
2:binder引用在驱动中的表示(struct binder_ref)
为了实现跨进程的通讯,内核空间必须要能够依赖和维护某些信息,准确的找到发起通讯的源进程要去到的目的进程,即binder驱动要能够快速的准确的实现通讯在进程间的路由。而binder驱动实现路由所依赖的主要结构就是binder_node与binder_ref结构体。binder_node对应binder通讯的服务器,而binder_ref对应binder的客服端,而从客服端发起的通讯,要找到这个客服端对应的服务器端,就必须找到这个这次通讯的服务器端对应的binder_node在当前进程中的引用:binder_ref,如果没有这个引用就需要binder驱动负责建立这个引用。待这个引用于binder_node关系建立起来后,就会有如下关系:binder_node->refs的哈希表中包含了这个引用对象,而binder_ref->node则指向目标进程所包含的binder_node结