Binder驱动情景分析

来源:互联网 发布:清华在线网络教育平台 编辑:程序博客网 时间:2024/05/17 01:03

Handle是client对服务器进程服务Service的引用。就相当于fd号对于文件。

client向服务器进程请求多个服务时,对于每一个服务会返回不同的Handle。

client会调用binder_call->ioctl利用handle号进入驱动程序找到目的进程,在驱动程序的内部会维护一个结构体描述引用无非不就是:在这个结构体里加入一个号等于这个Handle,这样只要搜寻这些结构体的desc值就可以找到这个结构体。

名字叫做struct  binder_ref,内核里用这个结构体描述对服务的引用即handle,服务这个东西用binder_node表示。binder_ref中有一项指向binder_node。个人理解一个结构体就是一个对象,ref就是handle对象,node就是服务对象。handle对象包含node对象。服务属于那个进程,同样它可以包含一个描述进程的对象叫做binder_proc结构体。 而进程这个对象必定管理多个服务即binder_node。它会维护一个服务链表。并且维护一个红黑树在这个进程下创建多个线程。以应对对各应用程序。每一个线程对应一个binder_thread结构体。

server为每一个service创建一个binder_node结构体(内核态)驱动做

service_manager创建struct  binder_ref(内核态)

binder_thread用于表示一个线程

多个client程序会向进程server请求服务, 会创建多个线程为client提供服务,每一个线程都有一个binder_thread结构体。就是说可以通过这个结构体找到对应的线程。往进程的todo写数据,然后唤醒线程。

由应用程序发给驱动程序的数据binder_call调用ioctl调到驱动层

static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{    switch (cmd) {
    case BINDER_WRITE_READ: {

binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);

写哪个进程那个线程

里面调用get_user(cmd, (uint32_t __user *)ptr)

        case BC_TRANSACTION:
        case BC_REPLY: {
            struct binder_transaction_data tr;

            if (copy_from_user(&tr, ptr, sizeof(tr)))////////////////从用户空间把数据复制到内核
                return -EFAULT;
            ptr += sizeof(tr);
            binder_transaction(proc, thread, &tr, cmd == BC_REPLY);/////////////发送
            break;
        }

有服务端发给应用程序的数据

r.data_size = t->buffer->data_size;
        tr.offsets_size = t->buffer->offsets_size;
        tr.data.ptr.buffer = (void *)t->buffer->data +
                    proc->user_buffer_offset;/////////////////////////////////数据头并不是数据本身,数据本身只执行一次拷贝。数据头执行两次拷贝。
        tr.data.ptr.offsets = tr.data.ptr.buffer +
                    ALIGN(t->buffer->data_size,
                        sizeof(void *));

        if (put_user(cmd, (uint32_t __user *)ptr))

原创粉丝点击