binder驱动-------之数据结构篇2

本文详细介绍了Android Binder驱动中的数据结构,包括binder_node、binder_ref以及在传输过程中的表示struct flat_binder_object。阐述了binder实体和引用如何在驱动中表示,以及如何实现跨进程通信和数据路由。通过binder_transaction结构体,解释了事务的通讯过程,展示了从BC_TRANSACTION到BR_REPLY的完整流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值