binder(二) 相关结构体以及handle

IBinder构造成flat_binder_object对象到
binder_write_read里面的binder_transtion_data结构体里面,在通过ioctl函数和驱动进行交互

flat_binder_object

struct flat_binder_object {
    /* 8 bytes for large_flat_header. */
    __u32       type;
    __u32       flags;

    /* 8 bytes of data. */
    union {
        binder_uintptr_t    binder; /* local object */
        __u32           handle; /* remote object */
    };

    /* extra data associated with local object */
    binder_uintptr_t    cookie;
};

在驱动层会创建bindle_ref,
handle对应bindle_ref结构里面的desc

binder_ref

struct binder_ref {
    //...
    struct binder_proc *proc;
    struct binder_node *node;
    uint32_t desc; //handle
    int strong;
    int weak;
    //...
};

bindle_ref里面指向具体的binder_node

binder_node


struct binder_node {
    //...
    struct binder_proc *proc;
    //...
};

binder_node里面指向具体的binder_proc

struct binder_proc {
    //...
    struct rb_root threads;
    struct rb_root refs_by_desc;
    struct rb_root refs_by_node;
    struct list_head todo;
    //...
}

binder_proc里面指向要执行指令的threads

struct binder_thread {
    //...
    struct binder_proc *proc;
    struct rb_node rb_node;
    //引用的服务
    struct rb_root refs_by_desc;
    struct rb_root refs_by_node;
    //...
    struct list_head todo;
    //...
    ..
};

threads里面指向具体要执行的指令todo

流程

  1. server层组装flat_binder_objectbinder_write_read通过ioctl和驱动进行交互,在内核态会(为每一个服务)创建binder_node,这个binder_nodeproc指向当前进程binder_proc
  2. servicemanager在驱动中创建binder_ref,node指向这个binder_node,desc就是对应该服务在该进程的handle,依次增加。并且在用户态创建服务链表用来对应servernamehandle
  3. clienservicemanager通过name查询服务
  4. servicemanager返回handle给驱动程序
  5. 驱动程序在servicemanagerbinder_ref红黑树中根据handle找到对应的binder_ref,在根据binder_refnode找到对应的binder_node,给client创建新的binder_ref,它的desc从1开始,驱动程序返回descclient,也就是handle
  6. client根据handle就可以找到对应的binder_ref,就可以获取对应的binder_node,也最终就获取到了binder_proc,也就是对应的server进程。

handle是进程A(比如SystemServer)对进程B(应用进程)提供的服务(比如ams,pms)的引用

推荐阅读更多精彩内容