binder解析

这里写图片描述

static int binder_open(struct inode *nodp, struct file *filp)
{
    struct binder_proc *proc;
    . . . . . .
    proc = kzalloc(sizeof(*proc), GFP_KERNEL);

    get_task_struct(current);
    proc->tsk = current;
    . . . . . .
    hlist_add_head(&proc->proc_node, &binder_procs);
    proc->pid = current->group_leader->pid;
    . . . . . .
    filp->private_data = proc;
    . . . . . .
}

每当进程打开/dev/binder时,binder驱动就会为其创建binder_proc结构体。

struct binder_proc
{
    struct hlist_node proc_node;
    struct rb_root threads;
    struct rb_root nodes;
    struct rb_root refs_by_desc;
    struct rb_root refs_by_node;
    int pid;
    . . . . . .
    . . . . . .
};

这里写图片描述

struct binder_node {
    int debug_id;
    struct binder_work work;
    union {
        struct rb_node rb_node;         // 如果这个Binder实体还在使用,则将该节点链接到proc->nodes中。
        struct hlist_node dead_node;    // 如果这个Binder实体所属的进程已经销毁,而这个Binder实体又被其它进程所引用,则这个Binder实体通过dead_node进入到一个哈希表中去存放
    };
    struct binder_proc *proc;           // 该binder实体所属的Binder进程
    struct hlist_head refs;             // 该Binder实体的所有Binder引用所组成的链表
    int internal_strong_refs;
    int local_weak_refs;
    int local_strong_refs;
    void __user *ptr;                   // Binder实体在用户空间的地址(为Binder实体对应的Server在用户空间的本地Binder的引用)
    void __user *cookie;                // Binder实体在用户空间的其他数据(为Binder实体对应的Server在用户空间的本地Binder自身)
    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_ref {
    int debug_id;
    struct rb_node rb_node_desc;    // 关联到binder_proc->refs_by_desc红黑树中
    struct rb_node rb_node_node;    // 关联到binder_proc->refs_by_node红黑树中
    struct hlist_node node_entry;   // 关联到binder_node->refs哈希表中
    struct binder_proc *proc;       // 该Binder引用所属的Binder进程
    struct binder_node *node;       // 该Binder引用对应的Binder实体
    uint32_t desc;                  // 描述
    int strong;                     
    int weak;
    struct binder_ref_death *death;
};

大致通信过程:
这里写图片描述

具体过程如下:
进程1的BpBinder发起跨进程调用,向binder驱动传入自己记录的句柄值,binder驱动就会在进程1对应的binder_proc结构的引用树种查找和句柄值相等的binder_ref节点,一旦找到binder_ref节点,就可以通过该节点的node域找到对应的binder_node节点,这个目标binder_node是从属进程2的binder_proc,因为binder_ref和binder_node都处于binder驱动的地址空间中,所以是可以用指针直接指向的。目标binder_node节点的cookie域,记录的其实是进程2中BBinder的地址,binder驱动只需把这个值反映给应用层,应用层就可以直接拿到BBinder了。

这里写图片描述

发起端:发起端的进程以及实际执行传输的线程,BpBinder。
接收端:与发起端对应的目标进程、线程,BBinder。
传输的数据:即IPCThreadState::writeTrasaction()代码中的binder_transaction_data。可能包含简单的数据,也可能传输的是其它Binder对象,或者是Binder代理对象,或者是Binder实体对象。

这里写图片描述

参考文章:

http://wangkuiwu.github.io/2014/09/02/Binder-Datastruct/
http://blog.csdn.net/getnextwindow/article/details/47293751
http://blog.csdn.net/getnextwindow/article/details/47294327
http://qiangbo.space/2017-01-15/AndroidAnatomy_Binder_Driver/

欢迎关注微信公众号:DroidMind
精品内容独家发布平台


呈现与博客不一样的技术干货

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值