05 binder驱动传输机制 上

0

1 binder数据结构体

binder_proc

在讲binder驱动 数据传递原理之前,我们先思考一个问题?
binder的数据是如何从一个进程传送到另一个进程?底层binder驱动是如何识别进程的概念

甚至是如何从一个进程的某个线程精准地发送到目标进程的线程中?

要搞清楚这些问题,我们需要先了解binder中非常重要的结构体binder_proc,

它是用来描述进程上下文信息以及管理IPC的一个结构体,被定义在drivers/android/binder.c中,是一个私有的结构体.
binder 初始化的时候会初始化一个全局链表binder_procs,,在binder通信之前都会会调用到驱动层的binder_open()函数进行初始化,而binder_proc就是在binder_open()函数中创建的。新创建的binder_proc会作为一个节点,插入全局链表binder_procs中供binder驱动调度,一个进程对应一个binder_proc。可以说binder_proc 是 binder驱动层通信最基础的数据结构。

下面我们就来分析下binder_proc中包含哪些成员对象以及作用:

//binder.c
struct binder_proc {
    //hash链表中的一个节点
    struct hlist_node proc_node;
    //处理用户请求的线程组成的红黑树
    struct rb_root threads;
    //binder实体组成的红黑树
    struct rb_root nodes;
    //binder引用组成的红黑树,以句柄来排序
    struct rb_root refs_by_desc;
    //binder引用组成的红黑树,以它对应的binder实体的地址来排序
    struct rb_root refs_by_node;
     ························
};

其中主要需要重点关注的就是里面的四颗红黑树。

  • 1 threads,处理用户请求的线程组成的红黑树 元素对应结构体为binder_thread
  • 2 nodes, binder实体组成的红黑树, 元素对应结构体 为binder_node
  • 3 refs_by_desc, binder引用组成的红黑树,以句柄来排序。元素对应结构体为 binder_ref
  • 4 refs_by_node,也是binder引用 组成的红黑树,以它对应的binder实体的地址来排序元素对应结构体为 binder_ref

file

1.1 threads

threads很好理解,每个进程在开始进行binder通信之前可以设置处理binder通信的线程,threads就是记录这些线程。

1.2 nodes

nodes,由binder实体 binder_node组成测红黑树,binder实体可以理解为应用层服务在内核binder驱动层的具体实现,一个服务对应一个binder实体。在应用层获取某个服务的过程,也可以映射成在驱动层获取相应的binder_node节点过程。

file

1.3 refs_by_desc & refs_by_node

refs_by_desc 和 refs_by_node 这两颗树的元素都是 binder_ref,这两颗树的主要作用就是用来不同进程之间的binder 和 binder引用相互查找。

struct binder_ref {
    /* Lookups needed: */
    /*   node + proc => ref (transaction) */
    /*   desc + proc => ref (transaction, inc/dec ref) */
    /*   node => refs + procs (proc exit) */
    struct binder_ref_data data;
    struct rb_node rb_node_desc;
    struct rb_node rb_node_node;
    struct hlist_node node_entry;
    struct binder_proc *proc;
    struct binder_node *node;
    struct binder_ref_death *death;
};

file