binder解析

来源:互联网 发布:日式装修风格知乎 编辑:程序博客网 时间:2024/06/08 02:25

这里写图片描述

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/