深入内核表明白Android Binder【三】

打印 上一主题 下一主题

主题 1867|帖子 1867|积分 5605

媒介

深入内核表明白Android Binder【一】实现了Binder跨进程通信的客户端和服务端的C语言Demo,并对服务端向service_manager注册服务,客户端向service_manager获取服务的源码举行了详细分析,但分析仅止步于用户态,深入内核表明白Android Binder【二】,详细分析了服务注册过程Binder驱动内核源码,本篇文章继续分析服务获取过程及利用过程的Binder驱动内核源码。相信有了对上一篇文章的基础,这篇文章读起来应该轻松很多,那么我们就开始吧~
一、服务的获取过程内核源码剖析

1. 客户端获取服务的用户态源码回顾

深入内核表明白Android Binder【一】详细分析了客户端获取服务的用户态源码,这里简单回顾一下客户端通过svcmgr_lookup函数获取服务的用户态源码。
  1. int main(int argc, char **argv)
  2. {
  3.     int fd;
  4.     struct binder_state *bs;
  5.     uint32_t svcmgr = BINDER_SERVICE_MANAGER;
  6.     uint32_t handle;
  7.         int ret;
  8.         if (argc < 2){
  9.         fprintf(stderr, "Usage:\n");
  10.         fprintf(stderr, "%s <hello|goodbye>\n", argv[0]);
  11.         fprintf(stderr, "%s <hello|goodbye> <name>\n", argv[0]);
  12.         return -1;
  13.         }
  14.    
  15.     //打开驱动
  16.     bs = binder_open(128*1024);
  17.     if (!bs) {
  18.         fprintf(stderr, "failed to open binder driver\n");
  19.         return -1;
  20.     }
  21.         g_bs = bs;
  22.    
  23.     //向service_manager发送数据,获得hello服务句柄
  24.         handle = svcmgr_lookup(bs, svcmgr, "hello");
  25.         if (!handle) {
  26.         fprintf(stderr, "failed to get hello service\n");
  27.         return -1;
  28.         }
  29.         g_hello_handle = handle;
  30.         fprintf(stderr, "Handle for hello service = %d\n", g_hello_handle);
  31.         /* 向服务端发送数据 */
  32.         if (!strcmp(argv[1], "hello"))
  33.         {
  34.                 if (argc == 2) {
  35.                         sayhello();
  36.                 } else if (argc == 3) {
  37.                         ret = sayhello_to(argv[2]);
  38.                 fprintf(stderr, "get ret of sayhello_to = %d\n", ret);               
  39.                 }
  40.         }
  41.         binder_release(bs, handle);
  42.     return 0;
  43. }
  44. uint32_t svcmgr_lookup(struct binder_state *bs, uint32_t target, const char *name)
  45. {
  46.     uint32_t handle;
  47.     unsigned iodata[512/4];
  48.     struct binder_io msg, reply;
  49.     bio_init(&msg, iodata, sizeof(iodata), 4); // 为msg划分iodata的空间
  50.     bio_put_uint32(&msg, 0);  // strict mode header
  51.     bio_put_string16_x(&msg, SVC_MGR_NAME); // 写入android.os.IServiceManager
  52.     bio_put_string16_x(&msg, name); // 写入服务名 hello
  53.     // target = 0,代表service_manager,SVC_MGR_CHECK_SERVICE代表需要调用service_manager的查找服务的函数
  54.     if (binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE))
  55.         return 0;
  56.     // 获取hello服务的句柄
  57.     handle = bio_get_ref(&reply);
  58.     if (handle)
  59.         binder_acquire(bs, handle);
  60.     binder_done(bs, &msg, &reply);
  61.     return handle;
  62. }
  63. int binder_call(struct binder_state *bs,
  64.                 struct binder_io *msg, struct binder_io *reply,
  65.                 uint32_t target, uint32_t code)
  66. {
  67.     int res;
  68.     struct binder_write_read bwr;
  69.     struct {
  70.         uint32_t cmd;
  71.         struct binder_transaction_data txn;
  72.     } __attribute__((packed)) writebuf;
  73.     unsigned readbuf[32];
  74.     if (msg->flags & BIO_F_OVERFLOW) {
  75.         fprintf(stderr,"binder: txn buffer overflow\n");
  76.         goto fail;
  77.     }
  78.     // 构造binder_transaction_data
  79.     writebuf.cmd = BC_TRANSACTION;//ioclt类型
  80.     writebuf.txn.target.handle = target;//数据发送给哪个进程
  81.     writebuf.txn.code = code;//调用进程的哪个函数
  82.     writebuf.txn.flags = 0;
  83.     writebuf.txn.data_size = msg->data - msg->data0;//数据本身大小
  84.     writebuf.txn.offsets_size = ((char*) msg->offs) - ((char*) msg->offs0);//数据头大小,指向binder_node实体(发送端提供服务函数的地址),bio_put_obj(&msg, ptr);
  85.     writebuf.txn.data.ptr.buffer = (uintptr_t)msg->data0;//指向数据本身内存起点
  86.     writebuf.txn.data.ptr.offsets = (uintptr_t)msg->offs0;//指向数据头内存起点
  87.    
  88.     // 构造binder_write_read
  89.     bwr.write_size = sizeof(writebuf);
  90.     bwr.write_consumed = 0;
  91.     bwr.write_buffer = (uintptr_t) &writebuf;
  92.     hexdump(msg->data0, msg->data - msg->data0);
  93.     for (;;) {
  94.         bwr.read_size = sizeof(readbuf);
  95.         bwr.read_consumed = 0;
  96.         bwr.read_buffer = (uintptr_t) readbuf;
  97.         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);//调用ioctl发送数据给驱动程序
  98.         if (res < 0) {
  99.             fprintf(stderr,"binder: ioctl failed (%s)\n", strerror(errno));
  100.             goto fail;
  101.         }
  102.         // 解析数据,将readbuf中的数据解析给reply
  103.         res = binder_parse(bs, reply, (uintptr_t) readbuf, bwr.read_consumed, 0);
  104.         if (res == 0) return 0;
  105.         if (res < 0) goto fail;
  106.     }
  107. fail:
  108.     memset(reply, 0, sizeof(*reply));
  109.     reply->flags |= BIO_F_IOERROR;
  110.     return -1;
  111. }
复制代码
可以看到svcmgr_lookup函数也是构造好binder_io数据,然后调用binder_call函数,把binder_io数据封装为binder_write_read数据,最后通过ioctl发送给service_manager。
这个过程和深入内核表明白Android Binder【二】中分析的服务端向service_manager注册服务的过程类似,都是构造数据,然后通过ioctl把数据发给service_manager。
那么下面我们就进入linux内核源码,分析数据发给service_manager后,到底干了什么。
2. 客户端获取服务的内核源码分析

服务端调用ioctl,对应会调用到内核Binder驱动程序中的binder_ioctl函数,点击检察源码
2.1 客户端向service_manager发送数据

1. binder_ioctl

  1. // 客户端调用ioctl发送数据给驱动程序
  2. res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
  3. // 对应Binder内核驱动程序调用binder_ioctl函数处理数据
  4. static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  5. {
  6.         int ret;
  7.         // 获取服务的binder_proc,它是在服务打开binder驱动的时候创建的,后面我们会分析
  8.         struct binder_proc *proc = filp->private_data;
  9.         struct binder_thread *thread;
  10.         void __user *ubuf = (void __user *)arg;
  11.         /*pr_info("binder_ioctl: %d:%d %x %lx\n",
  12.                         proc->pid, current->pid, cmd, arg);*/
  13.         binder_selftest_alloc(&proc->alloc);
  14.         trace_binder_ioctl(cmd, arg);
  15.         ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
  16.         if (ret)
  17.                 goto err_unlocked;
  18.         //为服务进程proc创建binder_thread
  19.         thread = binder_get_thread(proc);
  20.         if (thread == NULL) {
  21.                 ret = -ENOMEM;
  22.                 goto err;
  23.         }
  24.    
  25.     // 从上面的分析可知此时cmd=BINDER_WRITE_READ
  26.         switch (cmd) {
  27.         case BINDER_WRITE_READ:
  28.             // 处理服客户端数据
  29.                 ret = binder_ioctl_write_read(filp, arg, thread);
  30.                 if (ret)
  31.                         goto err;
  32.                 break;
  33.                
  34.         ......
  35. }
复制代码
2. binder_ioctl_write_read

  1. static int binder_ioctl_write_read(struct file *filp, unsigned long arg,
  2.                                 struct binder_thread *thread)
  3. {
  4.         int ret = 0;
  5.         struct binder_proc *proc = filp->private_data;
  6.         void __user *ubuf = (void __user *)arg; // 用户空间的数据
  7.         // 从用户空间获取客户端发送的数据binder_write_read
  8.         struct binder_write_read bwr;
  9.         //从用户空间发送的数据头拷贝到内核空间(这部分内核空间被mmap映射到了目标进程)
  10.         if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
  11.                 ret = -EFAULT;
  12.                 goto out;
  13.         }
  14.         binder_debug(BINDER_DEBUG_READ_WRITE,
  15.                      "%d:%d write %lld at %016llx, read %lld at %016llx\n",
  16.                      proc->pid, thread->pid,
  17.                      (u64)bwr.write_size, (u64)bwr.write_buffer,
  18.                      (u64)bwr.read_size, (u64)bwr.read_buffer);
  19.         
  20.         // 上面已经分析过客户端发送的数据保存在binder_write_read,此时它的write_size是大于0的
  21.         if (bwr.write_size > 0) { // 向驱动程序写数据
  22.                 ret = binder_thread_write(proc, thread,
  23.                                           bwr.write_buffer,
  24.                                           bwr.write_size,
  25.                                           &bwr.write_consumed);
  26.                 trace_binder_write_done(ret);
  27.                 if (ret < 0) {
  28.                         bwr.read_consumed = 0;
  29.                         if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
  30.                                 ret = -EFAULT;
  31.                         goto out;
  32.                 }
  33.         }
  34.         if (bwr.read_size > 0) { // 从驱动程序读数据
  35.                 ret = binder_thread_read(proc, thread, bwr.read_buffer,
  36.                                          bwr.read_size,
  37.                                          &bwr.read_consumed,
  38.                                          filp->f_flags & O_NONBLOCK);
  39.                 trace_binder_read_done(ret);
  40.                 binder_inner_proc_lock(proc);
  41.                 if (!binder_worklist_empty_ilocked(&proc->todo))
  42.                         binder_wakeup_proc_ilocked(proc);
  43.                 binder_inner_proc_unlock(proc);
  44.                 if (ret < 0) {
  45.                         if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
  46.                                 ret = -EFAULT;
  47.                         goto out;
  48.                 }
  49.         }
  50.         binder_debug(BINDER_DEBUG_READ_WRITE,
  51.                      "%d:%d wrote %lld of %lld, read return %lld of %lld\n",
  52.                      proc->pid, thread->pid,
  53.                      (u64)bwr.write_consumed, (u64)bwr.write_size,
  54.                      (u64)bwr.read_consumed, (u64)bwr.read_size);
  55.         // 复制数据给到用户空间
  56.         if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
  57.                 ret = -EFAULT;
  58.                 goto out;
  59.         }
  60. out:
  61.         return ret;
  62. }
  63. static inline int copy_from_user(void *to, const void __user volatile *from,
  64.                                  unsigned long n)
  65. {
  66.         volatile_memcpy(to, from, n);
  67.         return 0;
  68. }
  69. static inline int copy_to_user(void __user volatile *to, const void *from,
  70.                                unsigned long n)
  71. {
  72.         volatile_memcpy(to, from, n);
  73.         return 0;
  74. }
复制代码
3. binder_thread_write

此时cmd是BC_TRANSACTION
  1. static int binder_thread_write(struct binder_proc *proc,
  2.                         struct binder_thread *thread,
  3.                         binder_uintptr_t binder_buffer, size_t size,
  4.                         binder_size_t *consumed)
  5. {
  6.         uint32_t cmd;
  7.         struct binder_context *context = proc->context;
  8.         // 获取数据buffer,根据上面总结的发送数据可知,这个buffer由cmd和binder_transcation_data两部分数据组成
  9.         void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
  10.         // 发送来的数据consumed=0,因此ptr指向用户空间数据buffer的起点
  11.         void __user *ptr = buffer + *consumed;
  12.         // 指向数据buffer的末尾
  13.         void __user *end = buffer + size;
  14.         // 逐个读取客户端发送来的数据(cmd+binder_transcation_data)
  15.         while (ptr < end && thread->return_error.cmd == BR_OK) {
  16.                 int ret;
  17.                
  18.                 // 获取用户空间中buffer的cmd值
  19.                 if (get_user(cmd, (uint32_t __user *)ptr))
  20.                         return -EFAULT;
  21.                 // 移动指针到cmd的位置之后,指向binder_transcation_data数据的内存起点
  22.                 ptr += sizeof(uint32_t);
  23.                 trace_binder_command(cmd);
  24.                 if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) {
  25.                         atomic_inc(&binder_stats.bc[_IOC_NR(cmd)]);
  26.                         atomic_inc(&proc->stats.bc[_IOC_NR(cmd)]);
  27.                         atomic_inc(&thread->stats.bc[_IOC_NR(cmd)]);
  28.                 }
  29.                 // 根据上面总结的发送数据可知,cmd是BC_TRANSACTION
  30.                 switch (cmd) {
  31.                    ......
  32.                    /*
  33.                 BC_TRANSACTION:进程发送信息的cmd
  34.                 BR_TRANSACTION:进程接收BC_TRANSACTION发送信息的cmd
  35.                
  36.                 BC_REPLY:进程回复信息的cmd
  37.                 BR_REPLY:进程接收BC_REPLY回复信息的cmd
  38.                 */
  39.                     case BC_TRANSACTION:
  40.                     case BC_REPLY: {
  41.                             struct binder_transaction_data tr;
  42.                            
  43.                             // 从用户空间拷贝binder_transaction_data到内核空间
  44.                             if (copy_from_user(&tr, ptr, sizeof(tr)))
  45.                                     return -EFAULT;
  46.                             // 移动指针到binder_transaction_data的位置之后,指向下一个cmd数据的内存起点
  47.                             ptr += sizeof(tr);
  48.                             // 处理binder_transaction_data数据
  49.                             binder_transaction(proc, thread, &tr,
  50.                                                cmd == BC_REPLY, 0);
  51.                             break;
  52.                     }
  53.                 }
  54.         }
  55.         ......
  56. }
  57. int get_user(int *val, const int __user *ptr) {
  58.     if (copy_from_user(val, ptr, sizeof(int))) {
  59.         return -EFAULT; // 返回错误码
  60.     }
  61.     return 0; // 成功
  62. }
复制代码
4. binder_transaction

4.1 找到目的进程service_manager

  1. static void binder_transaction(struct binder_proc *proc,
  2.                                struct binder_thread *thread,
  3.                                struct binder_transaction_data *tr, int reply,
  4.                                binder_size_t extra_buffers_size)
  5. {
  6.         ......
  7.         // 此时是客户端向内核发送数据,reply为false
  8.         if (reply) { // Binder内核驱动程序向用户空间回复数据的处理逻辑
  9.                 ......
  10.         } else { // 用户空间数据发送给内核空间的处理逻辑
  11.                 //1. 找到目的进程,本次分析的是向service_manager获取服务,因此目的进程就是tr->target.handle=0的service_manager
  12.                 if (tr->target.handle) { // tr->target.handle == 0 代表是service_manager进程,否则是其它进程
  13.                         .......
  14.                 } else { //处理service_manager进程
  15.                         mutex_lock(&context->context_mgr_node_lock);
  16.                         //这个node是在创建service_manager时通过BINDER_SET_CONTEXT_MGR的cmd创建的
  17.                         target_node = context->binder_context_mgr_node;
  18.                         if (target_node)
  19.                                 target_node = binder_get_node_refs_for_txn(
  20.                                                 target_node, &target_proc,
  21.                                                 &return_error);
  22.                         else
  23.                                 return_error = BR_DEAD_REPLY;
  24.                         mutex_unlock(&context->context_mgr_node_lock);
  25.                         if (target_node && target_proc->pid == proc->pid) {
  26.                                 binder_user_error("%d:%d got transaction to context manager from process owning it\n",
  27.                                                   proc->pid, thread->pid);
  28.                                 return_error = BR_FAILED_REPLY;
  29.                                 return_error_param = -EINVAL;
  30.                                 return_error_line = __LINE__;
  31.                                 goto err_invalid_target_handle;
  32.                         }
  33.                 }
  34.                 ......
  35.         }
  36. }
复制代码
4.2 拷贝客户端binder_transaction_data数据中的data.ptr.offsets到service_manager的mmap内核空间

  1. static void binder_transaction(struct binder_proc *proc,
  2.                                struct binder_thread *thread,
  3.                                struct binder_transaction_data *tr, int reply,
  4.                                binder_size_t extra_buffers_size)
  5. {
  6.         int ret;
  7.         struct binder_transaction *t;
  8.         struct binder_work *w;
  9.         struct binder_work *tcomplete;
  10.         binder_size_t buffer_offset = 0;
  11.         binder_size_t off_start_offset, off_end_offset;
  12.         binder_size_t off_min;
  13.         binder_size_t sg_buf_offset, sg_buf_end_offset;
  14.         binder_size_t user_offset = 0;
  15.         struct binder_proc *target_proc = NULL;
  16.         struct binder_thread *target_thread = NULL;
  17.         struct binder_node *target_node = NULL;
  18.         struct binder_transaction *in_reply_to = NULL;
  19.         struct binder_transaction_log_entry *e;
  20.         uint32_t return_error = 0;
  21.         uint32_t return_error_param = 0;
  22.         uint32_t return_error_line = 0;
  23.         binder_size_t last_fixup_obj_off = 0;
  24.         binder_size_t last_fixup_min_off = 0;
  25.         struct binder_context *context = proc->context;
  26.         int t_debug_id = atomic_inc_return(&binder_last_id);
  27.         ktime_t t_start_time = ktime_get();
  28.         char *secctx = NULL;
  29.         u32 secctx_sz = 0;
  30.         struct list_head sgc_head;
  31.         struct list_head pf_head;
  32.         const void __user *user_buffer = (const void __user *)
  33.                                 (uintptr_t)tr->data.ptr.buffer;
  34.         INIT_LIST_HEAD(&sgc_head);
  35.         INIT_LIST_HEAD(&pf_head);
  36.         e = binder_transaction_log_add(&binder_transaction_log);
  37.         e->debug_id = t_debug_id;
  38.         e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
  39.         e->from_proc = proc->pid;
  40.         e->from_thread = thread->pid;
  41.         e->target_handle = tr->target.handle;
  42.         e->data_size = tr->data_size;
  43.         e->offsets_size = tr->offsets_size;
  44.         strscpy(e->context_name, proc->context->name, BINDERFS_MAX_NAME);
  45.         binder_inner_proc_lock(proc);
  46.         binder_set_extended_error(&thread->ee, t_debug_id, BR_OK, 0);
  47.         binder_inner_proc_unlock(proc);
  48.         if (reply) {// 找到要回复的进程
  49.                 ......
  50.         } else {// 1. 找到要发送的目的进程
  51.                 if (tr->target.handle) { // 目的进程非service_manager进程
  52.                        .....
  53.                 } else { //目的进程是service_manager进程
  54.                         // 找到service_manager的binder_node节点
  55.                         .....
  56.                 }
  57.                 ......
  58.         }
  59.         if (target_thread)
  60.                 e->to_thread = target_thread->pid;
  61.         e->to_proc = target_proc->pid;
  62.         /* TODO: reuse incoming transaction for reply */
  63.         // 为binder_transcation分配内存
  64.         t = kzalloc(sizeof(*t), GFP_KERNEL);
  65.         
  66.         .....
  67.         if (!reply && !(tr->flags & TF_ONE_WAY))
  68.                 t->from = thread;
  69.         else
  70.                 t->from = NULL;
  71.         // 存储发送双方的基本信息
  72.         t->from_pid = proc->pid;
  73.         t->from_tid = thread->pid;
  74.         t->sender_euid = task_euid(proc->tsk);
  75.         t->to_proc = target_proc;
  76.         t->to_thread = target_thread;
  77.         t->code = tr->code;
  78.         t->flags = tr->flags;
  79.         t->priority = task_nice(current);
  80.         ......
  81.         t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size,
  82.                 tr->offsets_size, extra_buffers_size,
  83.                 !reply && (t->flags & TF_ONE_WAY));
  84.         ......
  85.         
  86.         t->buffer->debug_id = t->debug_id;
  87.         t->buffer->transaction = t;
  88.         t->buffer->target_node = target_node;
  89.         t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF);
  90.         trace_binder_transaction_alloc_buf(t->buffer);
  91.         
  92.         // 把客户端的数据拷贝到目的进程service_manager mmap的内存空间,即t->buffer指向的内存空间
  93.         if (binder_alloc_copy_user_to_buffer(
  94.                                 &target_proc->alloc,
  95.                                 t->buffer,
  96.                                 ALIGN(tr->data_size, sizeof(void *)),
  97.                                 (const void __user *)
  98.                                         (uintptr_t)tr->data.ptr.offsets,
  99.                                 tr->offsets_size)) {
  100.                 binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
  101.                                 proc->pid, thread->pid);
  102.                 return_error = BR_FAILED_REPLY;
  103.                 return_error_param = -EFAULT;
  104.                 return_error_line = __LINE__;
  105.                 goto err_copy_data_failed;
  106.         }
  107.         ......
  108. }
  109. /**
  110. * binder_alloc_copy_user_to_buffer() - copy src user to tgt user
  111. * @alloc: binder_alloc for this proc
  112. * @buffer: binder buffer to be accessed
  113. * @buffer_offset: offset into @buffer data
  114. * @from: userspace pointer to source buffer
  115. * @bytes: bytes to copy
  116. *
  117. * Copy bytes from source userspace to target buffer.
  118. *
  119. * Return: bytes remaining to be copied
  120. */
  121. unsigned long
  122. binder_alloc_copy_user_to_buffer(struct binder_alloc *alloc,
  123.                                  struct binder_buffer *buffer,
  124.                                  binder_size_t buffer_offset,
  125.                                  const void __user *from,
  126.                                  size_t bytes)
  127. {
  128.         if (!check_buffer(alloc, buffer, buffer_offset, bytes))
  129.                 return bytes;
  130.         while (bytes) {
  131.                 unsigned long size;
  132.                 unsigned long ret;
  133.                 struct page *page;
  134.                 pgoff_t pgoff;
  135.                 void *kptr;
  136.                 page = binder_alloc_get_page(alloc, buffer,
  137.                                              buffer_offset, &pgoff);
  138.                 size = min_t(size_t, bytes, PAGE_SIZE - pgoff);
  139.                 kptr = kmap_local_page(page) + pgoff;
  140.                 // 拷贝服务端数据到service_manager mmap的内核内存空间
  141.                 ret = copy_from_user(kptr, from, size);
  142.                 kunmap_local(kptr);
  143.                 if (ret)
  144.                         return bytes - size + ret;
  145.                 bytes -= size;
  146.                 from += size;
  147.                 buffer_offset += size;
  148.         }
  149.         return 0;
  150. }
复制代码
4.3 拷贝客户端binder_transaction_data数据中的data.ptr.buffer到service_manager的mmap内核空间

  1. static void binder_transaction(struct binder_proc *proc,
  2.                                struct binder_thread *thread,
  3.                                struct binder_transaction_data *tr, int reply,
  4.                                binder_size_t extra_buffers_size)
  5. {
  6.         int ret;
  7.         struct binder_transaction *t;
  8.         struct binder_work *w;
  9.         struct binder_work *tcomplete;
  10.         binder_size_t buffer_offset = 0;
  11.         binder_size_t off_start_offset, off_end_offset;
  12.         binder_size_t off_min;
  13.         binder_size_t sg_buf_offset, sg_buf_end_offset;
  14.         binder_size_t user_offset = 0;
  15.         struct binder_proc *target_proc = NULL;
  16.         struct binder_thread *target_thread = NULL;
  17.         struct binder_node *target_node = NULL;
  18.         struct binder_transaction *in_reply_to = NULL;
  19.         struct binder_transaction_log_entry *e;
  20.         uint32_t return_error = 0;
  21.         uint32_t return_error_param = 0;
  22.         uint32_t return_error_line = 0;
  23.         binder_size_t last_fixup_obj_off = 0;
  24.         binder_size_t last_fixup_min_off = 0;
  25.         struct binder_context *context = proc->context;
  26.         int t_debug_id = atomic_inc_return(&binder_last_id);
  27.         ktime_t t_start_time = ktime_get();
  28.         char *secctx = NULL;
  29.         u32 secctx_sz = 0;
  30.         struct list_head sgc_head;
  31.         struct list_head pf_head;
  32.         const void __user *user_buffer = (const void __user *)
  33.                                 (uintptr_t)tr->data.ptr.buffer;
  34.         INIT_LIST_HEAD(&sgc_head);
  35.         INIT_LIST_HEAD(&pf_head);
  36.         e = binder_transaction_log_add(&binder_transaction_log);
  37.         e->debug_id = t_debug_id;
  38.         e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
  39.         e->from_proc = proc->pid;
  40.         e->from_thread = thread->pid;
  41.         e->target_handle = tr->target.handle;
  42.         e->data_size = tr->data_size;
  43.         e->offsets_size = tr->offsets_size;
  44.         strscpy(e->context_name, proc->context->name, BINDERFS_MAX_NAME);
  45.         binder_inner_proc_lock(proc);
  46.         binder_set_extended_error(&thread->ee, t_debug_id, BR_OK, 0);
  47.         binder_inner_proc_unlock(proc);
  48.         if (reply) {// 找到要回复的进程
  49.                 ......
  50.         } else {// 1. 找到要发送的目的进程
  51.                 if (tr->target.handle) { // 目的进程非service_manager进程
  52.                        .....
  53.                 } else { //目的进程是service_manager进程
  54.                         // 找到service_manager的binder_node节点
  55.                         .....
  56.                 }
  57.                 ......
  58.         }
  59.         if (target_thread)
  60.                 e->to_thread = target_thread->pid;
  61.         e->to_proc = target_proc->pid;
  62.         /* TODO: reuse incoming transaction for reply */
  63.         // 为binder_transcation分配内存
  64.         t = kzalloc(sizeof(*t), GFP_KERNEL);
  65.         
  66.         .....
  67.         if (!reply && !(tr->flags & TF_ONE_WAY))
  68.                 t->from = thread;
  69.         else
  70.                 t->from = NULL;
  71.         // 存储发送双方的基本信息
  72.         t->from_pid = proc->pid;
  73.         t->from_tid = thread->pid;
  74.         t->sender_euid = task_euid(proc->tsk);
  75.         t->to_proc = target_proc;
  76.         t->to_thread = target_thread;
  77.         t->code = tr->code;
  78.         t->flags = tr->flags;
  79.         t->priority = task_nice(current);
  80.         ......
  81.         t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size,
  82.                 tr->offsets_size, extra_buffers_size,
  83.                 !reply && (t->flags & TF_ONE_WAY));
  84.         ......
  85.         
  86.         t->buffer->debug_id = t->debug_id;
  87.         t->buffer->transaction = t;
  88.         t->buffer->target_node = target_node;
  89.         t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF);
  90.         trace_binder_transaction_alloc_buf(t->buffer);
  91.         
  92.         // 把客户端的数据拷贝到目的进程service_manager mmap的内存空间,即t->buffer指向的内存空间
  93.         if (binder_alloc_copy_user_to_buffer(
  94.                                 &target_proc->alloc,
  95.                                 t->buffer,
  96.                                 ALIGN(tr->data_size, sizeof(void *)),
  97.                                 (const void __user *)
  98.                                         (uintptr_t)tr->data.ptr.offsets,
  99.                                 tr->offsets_size)) {
  100.                 binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
  101.                                 proc->pid, thread->pid);
  102.                 return_error = BR_FAILED_REPLY;
  103.                 return_error_param = -EFAULT;
  104.                 return_error_line = __LINE__;
  105.                 goto err_copy_data_failed;
  106.         }
  107.         
  108.         ......
  109.                 /* Done processing objects, copy the rest of the buffer */
  110.                 if (binder_alloc_copy_user_to_buffer(
  111.                                         &target_proc->alloc,
  112.                                         t->buffer, user_offset,
  113.                                         user_buffer + user_offset,
  114.                                         tr->data_size - user_offset)) {
  115.                         binder_user_error("%d:%d got transaction with invalid data ptr\n",
  116.                                         proc->pid, thread->pid);
  117.                         return_error = BR_FAILED_REPLY;
  118.                         return_error_param = -EFAULT;
  119.                         return_error_line = __LINE__;
  120.                         goto err_copy_data_failed;
  121.                 }
  122.                
  123.                 ......
  124. }
复制代码
4.4 把待处理的数据放到目的进程service_manager的binder_proc或binder_thread的todo链表

  1. static void binder_transaction(struct binder_proc *proc,
  2.                                struct binder_thread *thread,
  3.                                struct binder_transaction_data *tr, int reply,
  4.                                binder_size_t extra_buffers_size)
  5. {
  6.         int ret;
  7.         struct binder_transaction *t;
  8.         struct binder_work *w;
  9.         struct binder_work *tcomplete;
  10.         binder_size_t buffer_offset = 0;
  11.         binder_size_t off_start_offset, off_end_offset;
  12.         binder_size_t off_min;
  13.         binder_size_t sg_buf_offset, sg_buf_end_offset;
  14.         binder_size_t user_offset = 0;
  15.         struct binder_proc *target_proc = NULL;
  16.         struct binder_thread *target_thread = NULL;
  17.         struct binder_node *target_node = NULL;
  18.         struct binder_transaction *in_reply_to = NULL;
  19.         struct binder_transaction_log_entry *e;
  20.         uint32_t return_error = 0;
  21.         uint32_t return_error_param = 0;
  22.         uint32_t return_error_line = 0;
  23.         binder_size_t last_fixup_obj_off = 0;
  24.         binder_size_t last_fixup_min_off = 0;
  25.         struct binder_context *context = proc->context;
  26.         int t_debug_id = atomic_inc_return(&binder_last_id);
  27.         ktime_t t_start_time = ktime_get();
  28.         char *secctx = NULL;
  29.         u32 secctx_sz = 0;
  30.         struct list_head sgc_head;
  31.         struct list_head pf_head;
  32.         const void __user *user_buffer = (const void __user *)
  33.                                 (uintptr_t)tr->data.ptr.buffer;
  34.         INIT_LIST_HEAD(&sgc_head);
  35.         INIT_LIST_HEAD(&pf_head);
  36.         e = binder_transaction_log_add(&binder_transaction_log);
  37.         e->debug_id = t_debug_id;
  38.         e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
  39.         e->from_proc = proc->pid;
  40.         e->from_thread = thread->pid;
  41.         e->target_handle = tr->target.handle;
  42.         e->data_size = tr->data_size;
  43.         e->offsets_size = tr->offsets_size;
  44.         strscpy(e->context_name, proc->context->name, BINDERFS_MAX_NAME);
  45.         binder_inner_proc_lock(proc);
  46.         binder_set_extended_error(&thread->ee, t_debug_id, BR_OK, 0);
  47.         binder_inner_proc_unlock(proc);
  48.         if (reply) {// 找到要回复的进程
  49.                 ......
  50.         } else {// 1. 找到要发送的目的进程
  51.                 if (tr->target.handle) { // 目的进程非service_manager进程
  52.                        .....
  53.                 } else { //目的进程是service_manager进程
  54.                         // 找到service_manager的binder_node节点
  55.                         .....
  56.                 }
  57.                 ......
  58.         }
  59.         if (target_thread)
  60.                 e->to_thread = target_thread->pid;
  61.         e->to_proc = target_proc->pid;
  62.         /* TODO: reuse incoming transaction for reply */
  63.         // 为binder_transcation分配内存
  64.         t = kzalloc(sizeof(*t), GFP_KERNEL);
  65.         
  66.         .....
  67.         if (!reply && !(tr->flags & TF_ONE_WAY))
  68.                 t->from = thread;
  69.         else
  70.                 t->from = NULL;
  71.         // 存储发送双方的基本信息
  72.         t->from_pid = proc->pid;
  73.         t->from_tid = thread->pid;
  74.         t->sender_euid = task_euid(proc->tsk);
  75.         t->to_proc = target_proc;
  76.         t->to_thread = target_thread;
  77.         t->code = tr->code;
  78.         t->flags = tr->flags;
  79.         t->priority = task_nice(current);
  80.         ......
  81.         t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size,
  82.                 tr->offsets_size, extra_buffers_size,
  83.                 !reply && (t->flags & TF_ONE_WAY));
  84.         ......
  85.         
  86.         t->buffer->debug_id = t->debug_id;
  87.         t->buffer->transaction = t;
  88.         t->buffer->target_node = target_node;
  89.         t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF);
  90.         trace_binder_transaction_alloc_buf(t->buffer);
  91.         
  92.         // 把客户端的数据拷贝到目的进程service_manager mmap的内存空间,即t->buffer指向的内存空间
  93.         if (binder_alloc_copy_user_to_buffer(
  94.                                 &target_proc->alloc,
  95.                                 t->buffer,
  96.                                 ALIGN(tr->data_size, sizeof(void *)),
  97.                                 (const void __user *)
  98.                                         (uintptr_t)tr->data.ptr.offsets,
  99.                                 tr->offsets_size)) {
  100.                 binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
  101.                                 proc->pid, thread->pid);
  102.                 return_error = BR_FAILED_REPLY;
  103.                 return_error_param = -EFAULT;
  104.                 return_error_line = __LINE__;
  105.                 goto err_copy_data_failed;
  106.         }
  107.         
  108.         ......
  109.                 /* Done processing objects, copy the rest of the buffer */
  110.                 if (binder_alloc_copy_user_to_buffer(
  111.                                         &target_proc->alloc,
  112.                                         t->buffer, user_offset,
  113.                                         user_buffer + user_offset,
  114.                                         tr->data_size - user_offset)) {
  115.                         binder_user_error("%d:%d got transaction with invalid data ptr\n",
  116.                                         proc->pid, thread->pid);
  117.                         return_error = BR_FAILED_REPLY;
  118.                         return_error_param = -EFAULT;
  119.                         return_error_line = __LINE__;
  120.                         goto err_copy_data_failed;
  121.                 }
  122.                
  123.                 ......
  124.                
  125.                 t->work.type = BINDER_WORK_TRANSACTION;
  126.                 if (reply) {
  127.                         ......
  128.                 } else if (!(t->flags & TF_ONE_WAY)) {
  129.                         BUG_ON(t->buffer->async_transaction != 0);
  130.                         binder_inner_proc_lock(proc);
  131.                         /*
  132.                          * Defer the TRANSACTION_COMPLETE, so we don't return to
  133.                          * userspace immediately; this allows the target process to
  134.                          * immediately start processing this transaction, reducing
  135.                          * latency. We will then return the TRANSACTION_COMPLETE when
  136.                          * the target replies (or there is an error).
  137.                          */
  138.                         binder_enqueue_deferred_thread_work_ilocked(thread, tcomplete);
  139.                         t->need_reply = 1;
  140.                         t->from_parent = thread->transaction_stack;
  141.                         //入栈
  142.                         thread->transaction_stack = t;
  143.                         binder_inner_proc_unlock(proc);
  144.                         //将数据放入目的进程的binder_proc或binder_thread的todo链表
  145.                         return_error = binder_proc_transaction(t,
  146.                                         target_proc, target_thread);
  147.                         if (return_error) {
  148.                                 binder_inner_proc_lock(proc);
  149.                                 binder_pop_transaction_ilocked(thread, t);
  150.                                 binder_inner_proc_unlock(proc);
  151.                                 goto err_dead_proc_or_thread;
  152.                         }
  153.                 } else {
  154.                         ......
  155.                 }
  156. }
复制代码
4.5 binder_proc_transaction将待处理的数据放到service_manager的todo链表,并叫醒service_manager

  1. static int binder_proc_transaction(struct binder_transaction *t,
  2.                                     struct binder_proc *proc,
  3.                                     struct binder_thread *thread)
  4. {
  5.         struct binder_node *node = t->buffer->target_node;
  6.         bool oneway = !!(t->flags & TF_ONE_WAY);
  7.         bool pending_async = false;
  8.         struct binder_transaction *t_outdated = NULL;
  9.         bool frozen = false;
  10.         BUG_ON(!node);
  11.         binder_node_lock(node);
  12.         if (oneway) {
  13.                 BUG_ON(thread);
  14.                 if (node->has_async_transaction)
  15.                         pending_async = true;
  16.                 else
  17.                         node->has_async_transaction = true;
  18.         }
  19.         binder_inner_proc_lock(proc);
  20.         if (proc->is_frozen) {
  21.                 frozen = true;
  22.                 proc->sync_recv |= !oneway;
  23.                 proc->async_recv |= oneway;
  24.         }
  25.         if ((frozen && !oneway) || proc->is_dead ||
  26.                         (thread && thread->is_dead)) {
  27.                 binder_inner_proc_unlock(proc);
  28.                 binder_node_unlock(node);
  29.                 return frozen ? BR_FROZEN_REPLY : BR_DEAD_REPLY;
  30.         }
  31.         if (!thread && !pending_async)
  32.                 thread = binder_select_thread_ilocked(proc);
  33.         if (thread) {
  34.                 binder_enqueue_thread_work_ilocked(thread, &t->work);//将数据放入目的进程的binder_thread
  35.         } else if (!pending_async) {
  36.                 binder_enqueue_work_ilocked(&t->work, &proc->todo);//将数据放入目的进程的binder_proc
  37.         } else {
  38.                 if ((t->flags & TF_UPDATE_TXN) && frozen) {
  39.                         t_outdated = binder_find_outdated_transaction_ilocked(t,
  40.                                                                               &node->async_todo);
  41.                         if (t_outdated) {
  42.                                 binder_debug(BINDER_DEBUG_TRANSACTION,
  43.                                              "txn %d supersedes %d\n",
  44.                                              t->debug_id, t_outdated->debug_id);
  45.                                 list_del_init(&t_outdated->work.entry);
  46.                                 proc->outstanding_txns--;
  47.                         }
  48.                 }
  49.                 binder_enqueue_work_ilocked(&t->work, &node->async_todo);
  50.         }
  51.         if (!pending_async)
  52.                 binder_wakeup_thread_ilocked(proc, thread, !oneway /* sync */);
  53.         proc->outstanding_txns++;
  54.         binder_inner_proc_unlock(proc);
  55.         binder_node_unlock(node);
  56.         /*
  57.          * To reduce potential contention, free the outdated transaction and
  58.          * buffer after releasing the locks.
  59.          */
  60.         if (t_outdated) {
  61.                 struct binder_buffer *buffer = t_outdated->buffer;
  62.                 t_outdated->buffer = NULL;
  63.                 buffer->transaction = NULL;
  64.                 trace_binder_transaction_update_buffer_release(buffer);
  65.                 binder_release_entire_buffer(proc, NULL, buffer, false);
  66.                 binder_alloc_free_buf(&proc->alloc, buffer);
  67.                 kfree(t_outdated);
  68.                 binder_stats_deleted(BINDER_STAT_TRANSACTION);
  69.         }
  70.         if (oneway && frozen)
  71.                 return BR_TRANSACTION_PENDING_FROZEN;
  72.         return 0;
  73. }
  74. static void
  75. binder_enqueue_thread_work_ilocked(struct binder_thread *thread,
  76.                                    struct binder_work *work)
  77. {
  78.         WARN_ON(!list_empty(&thread->waiting_thread_node));
  79.         binder_enqueue_work_ilocked(work, &thread->todo); // 将待处理的数据放到thread的todo链表
  80.         /* (e)poll-based threads require an explicit wakeup signal when
  81.          * queuing their own work; they rely on these events to consume
  82.          * messages without I/O block. Without it, threads risk waiting
  83.          * indefinitely without handling the work.
  84.          */
  85.         if (thread->looper & BINDER_LOOPER_STATE_POLL &&
  86.             thread->pid == current->pid && !thread->process_todo)
  87.             // 唤醒service_manager
  88.                 wake_up_interruptible_sync(&thread->wait);
  89.         thread->process_todo = true;
  90. }
  91. static void
  92. binder_enqueue_work_ilocked(struct binder_work *work,
  93.                            struct list_head *target_list)
  94. {
  95.         BUG_ON(target_list == NULL);
  96.         BUG_ON(work->entry.next && !list_empty(&work->entry));
  97.         list_add_tail(&work->entry, target_list);
  98. }
复制代码
2.2. service_manager被叫醒

1. service_manager发送ioctl读取内核中的数据

  1. int main(int argc, char **argv)
  2. {
  3.     struct binder_state *bs;
  4.     bs = binder_open(128*1024);
  5.     if (!bs) {
  6.         ALOGE("failed to open binder driver\n");
  7.         return -1;
  8.     }
  9.     if (binder_become_context_manager(bs)) {
  10.         ALOGE("cannot become context manager (%s)\n", strerror(errno));
  11.         return -1;
  12.     }
  13.     svcmgr_handle = BINDER_SERVICE_MANAGER;
  14.     binder_loop(bs, svcmgr_handler);
  15.     return 0;
  16. }
  17. void binder_loop(struct binder_state *bs, binder_handler func)
  18. {
  19.     int res;
  20.     struct binder_write_read bwr;
  21.     uint32_t readbuf[32];
  22.     bwr.write_size = 0;
  23.     bwr.write_consumed = 0;
  24.     bwr.write_buffer = 0;
  25.     readbuf[0] = BC_ENTER_LOOPER;
  26.     binder_write(bs, readbuf, sizeof(uint32_t));
  27.     for (;;) {
  28.         bwr.read_size = sizeof(readbuf);
  29.         bwr.read_consumed = 0;
  30.         bwr.read_buffer = (uintptr_t) readbuf;
  31.         
  32.         // 发起读操作
  33.         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
  34.         if (res < 0) {
  35.             ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
  36.             break;
  37.         }
  38.         res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
  39.         if (res == 0) {
  40.             ALOGE("binder_loop: unexpected reply?!\n");
  41.             break;
  42.         }
  43.         if (res < 0) {
  44.             ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
  45.             break;
  46.         }
  47.     }
  48. }
复制代码
2. binder_ioctl

  1. // res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);进入binder驱动程序
  2. static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  3. {
  4.         int ret;
  5.         struct binder_proc *proc = filp->private_data;
  6.         struct binder_thread *thread;
  7.         void __user *ubuf = (void __user *)arg;
  8.         /*pr_info("binder_ioctl: %d:%d %x %lx\n",
  9.                         proc->pid, current->pid, cmd, arg);*/
  10.         binder_selftest_alloc(&proc->alloc);
  11.         trace_binder_ioctl(cmd, arg);
  12.         ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
  13.         if (ret)
  14.                 goto err_unlocked;
  15.         //为进程proc创建binder_thread
  16.         thread = binder_get_thread(proc);
  17.         if (thread == NULL) {
  18.                 ret = -ENOMEM;
  19.                 goto err;
  20.         }
  21.         switch (cmd) {
  22.         case BINDER_WRITE_READ:
  23.                 ret = binder_ioctl_write_read(filp, arg, thread);
  24.                 if (ret)
  25.                         goto err;
  26.                 break;
  27.                 ......
  28.         }
  29.         ......
  30. }
复制代码
3. binder_ioctl_write_read

  1. static int binder_ioctl_write_read(struct file *filp, unsigned long arg,
  2.                                 struct binder_thread *thread)
  3. {
  4.         int ret = 0;
  5.         struct binder_proc *proc = filp->private_data;
  6.         void __user *ubuf = (void __user *)arg;
  7.         struct binder_write_read bwr;
  8.     //从用户空间拷贝数据到内核空间(这部分内核空间被mmap映射到了目标进程)
  9.         if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
  10.                 ret = -EFAULT;
  11.                 goto out;
  12.         }
  13.         binder_debug(BINDER_DEBUG_READ_WRITE,
  14.                      "%d:%d write %lld at %016llx, read %lld at %016llx\n",
  15.                      proc->pid, thread->pid,
  16.                      (u64)bwr.write_size, (u64)bwr.write_buffer,
  17.                      (u64)bwr.read_size, (u64)bwr.read_buffer);
  18.         if (bwr.write_size > 0) {
  19.                 ......
  20.         }
  21.         if (bwr.read_size > 0) {
  22.                 ret = binder_thread_read(proc, thread, bwr.read_buffer,
  23.                                          bwr.read_size,
  24.                                          &bwr.read_consumed,
  25.                                          filp->f_flags & O_NONBLOCK);
  26.                 trace_binder_read_done(ret);
  27.                 binder_inner_proc_lock(proc);
  28.                 if (!binder_worklist_empty_ilocked(&proc->todo))
  29.                         binder_wakeup_proc_ilocked(proc);
  30.                 binder_inner_proc_unlock(proc);
  31.                 if (ret < 0) {
  32.                         if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
  33.                                 ret = -EFAULT;
  34.                         goto out;
  35.                 }
  36.         }
  37.         binder_debug(BINDER_DEBUG_READ_WRITE,
  38.                      "%d:%d wrote %lld of %lld, read return %lld of %lld\n",
  39.                      proc->pid, thread->pid,
  40.                      (u64)bwr.write_consumed, (u64)bwr.write_size,
  41.                      (u64)bwr.read_consumed, (u64)bwr.read_size);
  42.         if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
  43.                 ret = -EFAULT;
  44.                 goto out;
  45.         }
  46. out:
  47.         return ret;
  48. }
复制代码
4. binder_thread_read

读取service_manager内核空间的数据,写入service_manager用户空间
  1. static int binder_thread_read(struct binder_proc *proc,
  2.                               struct binder_thread *thread,
  3.                               binder_uintptr_t binder_buffer, size_t size,
  4.                               binder_size_t *consumed, int non_block)
  5. {
  6.         void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
  7.         void __user *ptr = buffer + *consumed;
  8.         void __user *end = buffer + size;
  9.         int ret = 0;
  10.         int wait_for_proc_work;
  11.         if (*consumed == 0) {
  12.                 if (put_user(BR_NOOP, (uint32_t __user *)ptr))//对于所有的读操作,数据头部都是BR_NOOP
  13.                         return -EFAULT;
  14.                 ptr += sizeof(uint32_t);
  15.         }
  16. retry:
  17.         binder_inner_proc_lock(proc);
  18.         wait_for_proc_work = binder_available_for_proc_work_ilocked(thread);
  19.         binder_inner_proc_unlock(proc);
  20.         thread->looper |= BINDER_LOOPER_STATE_WAITING;
  21.         trace_binder_wait_for_work(wait_for_proc_work,
  22.                                    !!thread->transaction_stack,
  23.                                    !binder_worklist_empty(proc, &thread->todo));
  24.         if (wait_for_proc_work) {
  25.                 if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED |
  26.                                         BINDER_LOOPER_STATE_ENTERED))) {
  27.                         binder_user_error("%d:%d ERROR: Thread waiting for process work before calling BC_REGISTER_LOOPER or BC_ENTER_LOOPER (state %x)\n",
  28.                                 proc->pid, thread->pid, thread->looper);
  29.                         wait_event_interruptible(binder_user_error_wait,
  30.                                                  binder_stop_on_user_error < 2);
  31.                 }
  32.                 binder_set_nice(proc->default_priority);
  33.         }
  34.     //没有数据就休眠
  35.         if (non_block) {
  36.                 if (!binder_has_work(thread, wait_for_proc_work))
  37.                         ret = -EAGAIN;
  38.         } else {
  39.                 ret = binder_wait_for_work(thread, wait_for_proc_work);
  40.         }
  41.         thread->looper &= ~BINDER_LOOPER_STATE_WAITING;
  42.        
  43.         if (ret)
  44.                 return ret;
  45.         while (1) {
  46.                 uint32_t cmd;
  47.                 struct binder_transaction_data_secctx tr;
  48.                 struct binder_transaction_data *trd = &tr.transaction_data;
  49.                 struct binder_work *w = NULL;
  50.                 struct list_head *list = NULL;
  51.                 struct binder_transaction *t = NULL;
  52.                 struct binder_thread *t_from;
  53.                 size_t trsize = sizeof(*trd);
  54.                 binder_inner_proc_lock(proc);
  55.                 //如果proc的thread->todo链表有数据,拿到链表数据
  56.                 if (!binder_worklist_empty_ilocked(&thread->todo))
  57.                         list = &thread->todo;
  58.                 //如果proc->todo链表有数据,拿到链表数据
  59.                 else if (!binder_worklist_empty_ilocked(&proc->todo) &&
  60.                            wait_for_proc_work)
  61.                         list = &proc->todo;
  62.                 else {
  63.                         binder_inner_proc_unlock(proc);
  64.                         /* no data added */
  65.                         if (ptr - buffer == 4 && !thread->looper_need_return)
  66.                                 goto retry;
  67.                         break;
  68.                 }
  69.                 if (end - ptr < sizeof(tr) + 4) {
  70.                         binder_inner_proc_unlock(proc);
  71.                         break;
  72.                 }
  73.                 w = binder_dequeue_work_head_ilocked(list);
  74.                 if (binder_worklist_empty_ilocked(&thread->todo))
  75.                         thread->process_todo = false;
  76.                 //逐个处理相关类型的数据,server唤醒service_manager,将数据添加到链表时,binder_work.type是BINDER_WORK_TRANSACTION
  77.                 switch (w->type) {
  78.                 case BINDER_WORK_TRANSACTION: {
  79.                         binder_inner_proc_unlock(proc);
  80.                          t= container_of(w, struct binder_transaction, work);//构造出发送方发来的binder_transaction
  81.                 } break;
  82.                
  83.                 ......
  84.                
  85.                 }
  86.                 if (!t)
  87.                         continue;
  88.                 BUG_ON(t->buffer == NULL);
  89.                 if (t->buffer->target_node) {
  90.                         struct binder_node *target_node = t->buffer->target_node;
  91.                         trd->target.ptr = target_node->ptr;
  92.                         trd->cookie =  target_node->cookie;
  93.                         t->saved_priority = task_nice(current);
  94.                         if (t->priority < target_node->min_priority &&
  95.                             !(t->flags & TF_ONE_WAY))
  96.                                 binder_set_nice(t->priority);
  97.                         else if (!(t->flags & TF_ONE_WAY) ||
  98.                                  t->saved_priority > target_node->min_priority)
  99.                                 binder_set_nice(target_node->min_priority);
  100.             //从server发送数据给service_manager,cmd是BC_TRANSACTION
  101.             //从service_manager返回数据给server,将cmd设为BR_TRANSACTION,
  102.                         cmd = BR_TRANSACTION;
  103.                 } else {
  104.                         trd->target.ptr = 0;
  105.                         trd->cookie = 0;
  106.                         cmd = BR_REPLY;
  107.                 }
  108.                 trd->code = t->code;
  109.                 trd->flags = t->flags;
  110.                 trd->sender_euid = from_kuid(current_user_ns(), t->sender_euid);
  111.                 ......
  112.                
  113.                 trd->data_size = t->buffer->data_size;
  114.                 trd->offsets_size = t->buffer->offsets_size;
  115.                 trd->data.ptr.buffer = t->buffer->user_data;
  116.                 trd->data.ptr.offsets = trd->data.ptr.buffer +
  117.                                         ALIGN(t->buffer->data_size,
  118.                                             sizeof(void *));
  119.                 tr.secctx = t->security_ctx;
  120.                 if (t->security_ctx) {
  121.                         cmd = BR_TRANSACTION_SEC_CTX;
  122.                         trsize = sizeof(tr);
  123.                 }
  124.                 // 把cmd写入service_manager的用户空间
  125.                 if (put_user(cmd, (uint32_t __user *)ptr)) {
  126.                         if (t_from)
  127.                                 binder_thread_dec_tmpref(t_from);
  128.                         binder_cleanup_transaction(t, "put_user failed",
  129.                                                    BR_FAILED_REPLY);
  130.                         return -EFAULT;
  131.                 }
  132.                 ptr += sizeof(uint32_t);
  133.                 // 把tr写入service_manager的用户空间,tr.transaction_data中包括了客户端发送来的数据
  134.                 if (copy_to_user(ptr, &tr, trsize)) {
  135.                         if (t_from)
  136.                                 binder_thread_dec_tmpref(t_from);
  137.                         binder_cleanup_transaction(t, "copy_to_user failed",
  138.                                                    BR_FAILED_REPLY);
  139.                         return -EFAULT;
  140.                 }
  141.                 ptr += trsize;
  142.                 ......
  143. done:
  144.         ......
  145.        
  146.         return 0;
  147. }
复制代码
5. 从service_manager内核空间读取到的数据构造形式


6. binder_parse剖析客户端发送给service_manager的数据

此时cmd是BR_TRANSACTION
  1. void binder_loop(struct binder_state *bs, binder_handler func)
  2. {
  3.     int res;
  4.     struct binder_write_read bwr;
  5.     uint32_t readbuf[32];
  6.     bwr.write_size = 0;
  7.     bwr.write_consumed = 0;
  8.     bwr.write_buffer = 0;
  9.     readbuf[0] = BC_ENTER_LOOPER;
  10.     binder_write(bs, readbuf, sizeof(uint32_t));
  11.     for (;;) {
  12.         bwr.read_size = sizeof(readbuf);
  13.         bwr.read_consumed = 0;
  14.         bwr.read_buffer = (uintptr_t) readbuf;
  15.         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);//读到数据
  16.         if (res < 0) {
  17.             ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
  18.             break;
  19.         }
  20.         
  21.         //解析读到的数据
  22.         res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
  23.         if (res == 0) {
  24.             ALOGE("binder_loop: unexpected reply?!\n");
  25.             break;
  26.         }
  27.         if (res < 0) {
  28.             ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
  29.             break;
  30.         }
  31.     }
  32. }
  33. int binder_parse(struct binder_state *bs, struct binder_io *bio,
  34.                  uintptr_t ptr, size_t size, binder_handler func)
  35. {
  36.     int r = 1;
  37.     uintptr_t end = ptr + (uintptr_t) size;
  38.     while (ptr < end) {
  39.         uint32_t cmd = *(uint32_t *) ptr;
  40.         ptr += sizeof(uint32_t);
  41. #if TRACE
  42.         fprintf(stderr,"%s:\n", cmd_name(cmd));
  43. #endif
  44.         switch(cmd) {
  45.         case BR_NOOP:
  46.             break;
  47.         ......
  48.         //收到数据的处理情况,(收到的数据中有服务名称,服务的handle)
  49.         case BR_TRANSACTION: {
  50.             struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
  51.             if ((end - ptr) < sizeof(*txn)) {
  52.                 ALOGE("parse: txn too small!\n");
  53.                 return -1;
  54.             }
  55.             binder_dump_txn(txn);
  56.             if (func) {
  57.                 unsigned rdata[256/4];
  58.                 struct binder_io msg;
  59.                 struct binder_io reply;
  60.                 int res;
  61.                 //构造binder_io
  62.                 bio_init(&reply, rdata, sizeof(rdata), 4);
  63.                 bio_init_from_txn(&msg, txn);
  64.                 //处理binde_io
  65.                 res = func(bs, txn, &msg, &reply); // func = svcmgr_handler,用于添加/获取服务
  66.                 //将处理完的数据,发送给server
  67.                 binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
  68.             }
  69.             ptr += sizeof(*txn);
  70.             break;
  71.         }
  72.         ......
  73.         default:
  74.             ALOGE("parse: OOPS %d\n", cmd);
  75.             return -1;
  76.         }
  77.     }
  78.     return r;
  79. }
复制代码
7. svcmgr_handler处理客户端发送给service_manager的数据,获取客户端请求的服务handle

  1. int svcmgr_handler(struct binder_state *bs,
  2.                    struct binder_transaction_data *txn,
  3.                    struct binder_io *msg,
  4.                    struct binder_io *reply)
  5. {
  6.     struct svcinfo *si;
  7.     uint16_t *s;
  8.     size_t len;
  9.     uint32_t handle;
  10.     uint32_t strict_policy;
  11.     int allow_isolated;
  12.     //ALOGI("target=%x code=%d pid=%d uid=%d\n",
  13.     //  txn->target.handle, txn->code, txn->sender_pid, txn->sender_euid);
  14.     if (txn->target.handle != svcmgr_handle)
  15.         return -1;
  16.     if (txn->code == PING_TRANSACTION)
  17.         return 0;
  18.     // Equivalent to Parcel::enforceInterface(), reading the RPC
  19.     // header with the strict mode policy mask and the interface name.
  20.     // Note that we ignore the strict_policy and don't propagate it
  21.     // further (since we do no outbound RPCs anyway).
  22.     strict_policy = bio_get_uint32(msg);
  23.     s = bio_get_string16(msg, &len); //传入的是android.os.IServiceManager
  24.     if (s == NULL) {
  25.         return -1;
  26.     }
  27.     if ((len != (sizeof(svcmgr_id) / 2)) ||
  28.         memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {//传入的必须是android.os.IServiceManager
  29.         fprintf(stderr,"invalid id %s\n", str8(s, len));
  30.         return -1;
  31.     }
  32.     switch(txn->code) {
  33.     case SVC_MGR_GET_SERVICE:
  34.     case SVC_MGR_CHECK_SERVICE:
  35.         s = bio_get_string16(msg, &len); // 获取客户端要获取的服务的名字"hello"
  36.         if (s == NULL) {
  37.             return -1;
  38.         }
  39.         // 在service_manager的服务列表中寻找服务名为hello的服务的handle
  40.         handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
  41.         if (!handle)
  42.             break;
  43.             
  44.         // 将服务handle写入reply
  45.         bio_put_ref(reply, handle);
  46.         return 0;
  47.     ......
  48.     bio_put_uint32(reply, 0);//处理完后,最后要构造一个reply,并放入0
  49.     return 0;
  50. }
  51. uint32_t do_find_service(struct binder_state *bs, const uint16_t *s, size_t len, uid_t uid, pid_t spid)
  52. {
  53.     struct svcinfo *si;
  54.     if (!svc_can_find(s, len, spid)) {
  55.         ALOGE("find_service('%s') uid=%d - PERMISSION DENIED\n",
  56.              str8(s, len), uid);
  57.         return 0;
  58.     }
  59.     si = find_svc(s, len);
  60.     //ALOGI("check_service('%s') handle = %x\n", str8(s, len), si ? si->handle : 0);
  61.     if (si && si->handle) {
  62.         if (!si->allow_isolated) {
  63.             // If this service doesn't allow access from isolated processes,
  64.             // then check the uid to see if it is isolated.
  65.             uid_t appid = uid % AID_USER;
  66.             if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
  67.                 return 0;
  68.             }
  69.         }
  70.         return si->handle;
  71.     } else {
  72.         return 0;
  73.     }
  74. }
  75. struct svcinfo *find_svc(const uint16_t *s16, size_t len)
  76. {
  77.     struct svcinfo *si;
  78.     for (si = svclist; si; si = si->next) {
  79.         if ((len == si->len) &&
  80.             !memcmp(s16, si->name, len * sizeof(uint16_t))) {
  81.             return si;
  82.         }
  83.     }
  84.     return NULL;
  85. }
  86. void bio_put_ref(struct binder_io *bio, uint32_t handle)
  87. {
  88.     struct flat_binder_object *obj;
  89.     if (handle)
  90.         obj = bio_alloc_obj(bio);
  91.     else
  92.         obj = bio_alloc(bio, sizeof(*obj));
  93.     if (!obj)
  94.         return;
  95.     obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
  96.     obj->type = BINDER_TYPE_HANDLE;
  97.     obj->handle = handle;
  98.     obj->cookie = 0;
  99. }
复制代码
8. binder_send_reply将获取到的服务handle数据复兴给驱动程序

  1. int binder_parse(struct binder_state *bs, struct binder_io *bio,
  2.                  uintptr_t ptr, size_t size, binder_handler func)
  3. {
  4.     int r = 1;
  5.     uintptr_t end = ptr + (uintptr_t) size;
  6.     while (ptr < end) {
  7.         uint32_t cmd = *(uint32_t *) ptr;
  8.         ptr += sizeof(uint32_t);
  9. #if TRACE
  10.         fprintf(stderr,"%s:\n", cmd_name(cmd));
  11. #endif
  12.         switch(cmd) {
  13.         case BR_NOOP:
  14.             break;
  15.         ......
  16.         //收到数据的处理情况,(收到的数据中有服务名称,服务的handle)
  17.         case BR_TRANSACTION: {
  18.             struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
  19.             if ((end - ptr) < sizeof(*txn)) {
  20.                 ALOGE("parse: txn too small!\n");
  21.                 return -1;
  22.             }
  23.             binder_dump_txn(txn);
  24.             if (func) {
  25.                 unsigned rdata[256/4];
  26.                 struct binder_io msg;
  27.                 struct binder_io reply;
  28.                 int res;
  29.                 //构造binder_io
  30.                 bio_init(&reply, rdata, sizeof(rdata), 4);
  31.                 bio_init_from_txn(&msg, txn);
  32.                 //处理binde_io
  33.                 res = func(bs, txn, &msg, &reply); // func = svcmgr_handler,用于添加/获取服务
  34.                 //将处理完的数据,发送给server
  35.                 binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
  36.             }
  37.             ptr += sizeof(*txn);
  38.             break;
  39.         }
  40.         ......
  41.         default:
  42.             ALOGE("parse: OOPS %d\n", cmd);
  43.             return -1;
  44.         }
  45.     }
  46.     return r;
  47. }
  48. void binder_send_reply(struct binder_state *bs,
  49.                        struct binder_io *reply,
  50.                        binder_uintptr_t buffer_to_free,
  51.                        int status)
  52. {
  53.     struct {
  54.         uint32_t cmd_free;
  55.         binder_uintptr_t buffer;
  56.         uint32_t cmd_reply;
  57.         struct binder_transaction_data txn;
  58.     } __attribute__((packed)) data;
  59.     data.cmd_free = BC_FREE_BUFFER;//server拷贝到service_manager映射的内核态缓冲区的数据,用完后,就可以释放了
  60.     data.buffer = buffer_to_free;
  61.     data.cmd_reply = BC_REPLY; // service_manager处理完数据后,将结果回复回去,cmd = BC_REPLY
  62.     data.txn.target.ptr = 0;
  63.     data.txn.cookie = 0;
  64.     data.txn.code = 0;
  65.     if (status) {
  66.         data.txn.flags = TF_STATUS_CODE;
  67.         data.txn.data_size = sizeof(int);
  68.         data.txn.offsets_size = 0;
  69.         data.txn.data.ptr.buffer = (uintptr_t)&status;
  70.         data.txn.data.ptr.offsets = 0;
  71.     } else {
  72.         data.txn.flags = 0;
  73.         data.txn.data_size = reply->data - reply->data0;
  74.         data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0);
  75.         data.txn.data.ptr.buffer = (uintptr_t)reply->data0;
  76.         data.txn.data.ptr.offsets = (uintptr_t)reply->offs0;
  77.     }
  78.     binder_write(bs, &data, sizeof(data));
  79. }
  80. int binder_write(struct binder_state *bs, void *data, size_t len)
  81. {
  82.     struct binder_write_read bwr;
  83.     int res;
  84.     bwr.write_size = len;
  85.     bwr.write_consumed = 0;
  86.     bwr.write_buffer = (uintptr_t) data;
  87.     bwr.read_size = 0;
  88.     bwr.read_consumed = 0;
  89.     bwr.read_buffer = 0;
  90.     res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
  91.     if (res < 0) {
  92.         fprintf(stderr,"binder_write: ioctl failed (%s)\n",
  93.                 strerror(errno));
  94.     }
  95.     return res;
  96. }
复制代码
2.3 binder驱动接收到service_manager剖析完客户端发送的数据的数据

1. binder_ioctl

  1. static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  2. {
  3.         int ret;
  4.         struct binder_proc *proc = filp->private_data;
  5.         struct binder_thread *thread;
  6.         void __user *ubuf = (void __user *)arg;
  7.         /*pr_info("binder_ioctl: %d:%d %x %lx\n",
  8.                         proc->pid, current->pid, cmd, arg);*/
  9.         binder_selftest_alloc(&proc->alloc);
  10.         trace_binder_ioctl(cmd, arg);
  11.         ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
  12.         if (ret)
  13.                 goto err_unlocked;
  14.         //为进程proc创建binder_thread
  15.         thread = binder_get_thread(proc);
  16.         if (thread == NULL) {
  17.                 ret = -ENOMEM;
  18.                 goto err;
  19.         }
  20.         switch (cmd) {
  21.         case BINDER_WRITE_READ:
  22.                 ret = binder_ioctl_write_read(filp, arg, thread);
  23.                 if (ret)
  24.                         goto err;
  25.                 break;
  26.                 ......
  27.         }
  28.         ......
  29. }
复制代码
2. binder_ioctl_write_read

  1. static int binder_ioctl_write_read(struct file *filp, unsigned long arg,
  2.                                 struct binder_thread *thread)
  3. {
  4.         int ret = 0;
  5.         struct binder_proc *proc = filp->private_data;
  6.         void __user *ubuf = (void __user *)arg;
  7.         struct binder_write_read bwr;
  8.     //从用户空间拷贝数据到内核空间(这部分内核空间被mmap映射到了目标进程)
  9.         if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
  10.                 ret = -EFAULT;
  11.                 goto out;
  12.         }
  13.         binder_debug(BINDER_DEBUG_READ_WRITE,
  14.                      "%d:%d write %lld at %016llx, read %lld at %016llx\n",
  15.                      proc->pid, thread->pid,
  16.                      (u64)bwr.write_size, (u64)bwr.write_buffer,
  17.                      (u64)bwr.read_size, (u64)bwr.read_buffer);
  18.         if (bwr.write_size > 0) {
  19.                 ret = binder_thread_write(proc, thread,
  20.                                           bwr.write_buffer,
  21.                                           bwr.write_size,
  22.                                           &bwr.write_consumed);
  23.                 trace_binder_write_done(ret);
  24.                 if (ret < 0) {
  25.                         bwr.read_consumed = 0;
  26.                         if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
  27.                                 ret = -EFAULT;
  28.                         goto out;
  29.                 }
  30.         }
  31.         if (bwr.read_size > 0) {
  32.                 ......
  33.         }
  34.         ......
  35. out:
  36.         return ret;
  37. }
复制代码
3. binder_thread_write

此时cmd是BC_REPLY
  1. static int binder_thread_write(struct binder_proc *proc,
  2.                         struct binder_thread *thread,
  3.                         binder_uintptr_t binder_buffer, size_t size,
  4.                         binder_size_t *consumed)
  5. {
  6.         uint32_t cmd;
  7.         struct binder_context *context = proc->context;
  8.         // 获取数据buffer,根据上面总结的发送数据可知,这个buffer由cmd和binder_transcation_data两部分数据组成
  9.         void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
  10.         // 发送来的数据consumed=0,因此ptr指向用户空间数据buffer的起点
  11.         void __user *ptr = buffer + *consumed;
  12.         // 指向数据buffer的末尾
  13.         void __user *end = buffer + size;
  14.         // 逐个读取客户端发送来的数据(cmd+binder_transcation_data)
  15.         while (ptr < end && thread->return_error.cmd == BR_OK) {
  16.                 int ret;
  17.                
  18.                 // 获取用户空间中buffer的cmd值
  19.                 if (get_user(cmd, (uint32_t __user *)ptr))
  20.                         return -EFAULT;
  21.                 // 移动指针到cmd的位置之后,指向binder_transcation_data数据的内存起点
  22.                 ptr += sizeof(uint32_t);
  23.                 trace_binder_command(cmd);
  24.                 if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) {
  25.                         atomic_inc(&binder_stats.bc[_IOC_NR(cmd)]);
  26.                         atomic_inc(&proc->stats.bc[_IOC_NR(cmd)]);
  27.                         atomic_inc(&thread->stats.bc[_IOC_NR(cmd)]);
  28.                 }
  29.                 // 根据上面总结的发送数据可知,cmd是BC_TRANSACTION
  30.                 switch (cmd) {
  31.                    ......
  32.                    /*
  33.                 BC_TRANSACTION:进程发送信息的cmd
  34.                 BR_TRANSACTION:进程接收BC_TRANSACTION发送信息的cmd
  35.                
  36.                 BC_REPLY:进程回复信息的cmd
  37.                 BR_REPLY:进程接收BC_REPLY回复信息的cmd
  38.                 */
  39.                     case BC_TRANSACTION:
  40.                     case BC_REPLY: {
  41.                             struct binder_transaction_data tr;
  42.                            
  43.                             // 从用户空间拷贝binder_transaction_data到内核空间
  44.                             if (copy_from_user(&tr, ptr, sizeof(tr)))
  45.                                     return -EFAULT;
  46.                             // 移动指针到binder_transaction_data的位置之后,指向下一个cmd数据的内存起点
  47.                             ptr += sizeof(tr);
  48.                             // 处理binder_transaction_data数据
  49.                             binder_transaction(proc, thread, &tr,
  50.                                                cmd == BC_REPLY, 0);
  51.                             break;
  52.                     }
  53.                 }
  54.         }
  55.         ......
  56. }
  57. int get_user(int *val, const int __user *ptr) {
  58.     if (copy_from_user(val, ptr, sizeof(int))) {
  59.         return -EFAULT; // 返回错误码
  60.     }
  61.     return 0; // 成功
  62. }
复制代码
4. binder_transaction

4.1. 找到要复兴的进程

  1. static void binder_transaction(struct binder_proc *proc,
  2.                                struct binder_thread *thread,
  3.                                struct binder_transaction_data *tr, int reply,
  4.                                binder_size_t extra_buffers_size)
  5. {
  6.         ......
  7.         if (reply) {// 找到要回复的进程
  8.                 binder_inner_proc_lock(proc);
  9.                                 in_reply_to = thread->transaction_stack;//从栈中取出binder_transaction,获得要回复给谁
  10.                                 if (in_reply_to == NULL) {
  11.                                         binder_inner_proc_unlock(proc);
  12.                                         binder_user_error("%d:%d got reply transaction with no transaction stack\n",
  13.                                                           proc->pid, thread->pid);
  14.                                         return_error = BR_FAILED_REPLY;
  15.                                         return_error_param = -EPROTO;
  16.                                         return_error_line = __LINE__;
  17.                                         goto err_empty_call_stack;
  18.                                 }
  19.                                 if (in_reply_to->to_thread != thread) {
  20.                                         spin_lock(&in_reply_to->lock);
  21.                                         binder_user_error("%d:%d got reply transaction with bad transaction stack, transaction %d has target %d:%d\n",
  22.                                                 proc->pid, thread->pid, in_reply_to->debug_id,
  23.                                                 in_reply_to->to_proc ?
  24.                                                 in_reply_to->to_proc->pid : 0,
  25.                                                 in_reply_to->to_thread ?
  26.                                                 in_reply_to->to_thread->pid : 0);
  27.                                         spin_unlock(&in_reply_to->lock);
  28.                                         binder_inner_proc_unlock(proc);
  29.                                         return_error = BR_FAILED_REPLY;
  30.                                         return_error_param = -EPROTO;
  31.                                         return_error_line = __LINE__;
  32.                                         in_reply_to = NULL;
  33.                                         goto err_bad_call_stack;
  34.                                 }
  35.                                 thread->transaction_stack = in_reply_to->to_parent;//出栈
  36.                                 binder_inner_proc_unlock(proc);
  37.                                 binder_set_nice(in_reply_to->saved_priority);
  38.                                 target_thread = binder_get_txn_from_and_acq_inner(in_reply_to);
  39.                                 if (target_thread == NULL) {
  40.                                         /* annotation for sparse */
  41.                                         __release(&target_thread->proc->inner_lock);
  42.                                         binder_txn_error("%d:%d reply target not found\n",
  43.                                                 thread->pid, proc->pid);
  44.                                         return_error = BR_DEAD_REPLY;
  45.                                         return_error_line = __LINE__;
  46.                                         goto err_dead_binder;
  47.                                 }
  48.                                 if (target_thread->transaction_stack != in_reply_to) {
  49.                                         binder_user_error("%d:%d got reply transaction with bad target transaction stack %d, expected %d\n",
  50.                                                 proc->pid, thread->pid,
  51.                                                 target_thread->transaction_stack ?
  52.                                                 target_thread->transaction_stack->debug_id : 0,
  53.                                                 in_reply_to->debug_id);
  54.                                         binder_inner_proc_unlock(target_thread->proc);
  55.                                         return_error = BR_FAILED_REPLY;
  56.                                         return_error_param = -EPROTO;
  57.                                         return_error_line = __LINE__;
  58.                                         in_reply_to = NULL;
  59.                                         target_thread = NULL;
  60.                                         goto err_dead_binder;
  61.                                 }
  62.                                 // 找到要回复的进程
  63.                                 target_proc = target_thread->proc;
  64.                                 target_proc->tmp_ref++;
  65.                                 binder_inner_proc_unlock(target_thread->proc);
  66.         } else {// 1. 找到要发送的目的进程
  67.                 ......
  68.         }
  69. ......
  70. }
复制代码
4.2 处理flat_binder_object

  1. static void binder_transaction(struct binder_proc *proc,
  2.                                struct binder_thread *thread,
  3.                                struct binder_transaction_data *tr, int reply,
  4.                                binder_size_t extra_buffers_size)
  5. {
  6.         ......
  7.         if (reply) {// 找到要回复的进程
  8.                 binder_inner_proc_lock(proc);
  9.                                 in_reply_to = thread->transaction_stack;//从栈中取出binder_transaction,获得要回复给谁
  10.                                 if (in_reply_to == NULL) {
  11.                                         binder_inner_proc_unlock(proc);
  12.                                         binder_user_error("%d:%d got reply transaction with no transaction stack\n",
  13.                                                           proc->pid, thread->pid);
  14.                                         return_error = BR_FAILED_REPLY;
  15.                                         return_error_param = -EPROTO;
  16.                                         return_error_line = __LINE__;
  17.                                         goto err_empty_call_stack;
  18.                                 }
  19.                                 if (in_reply_to->to_thread != thread) {
  20.                                         spin_lock(&in_reply_to->lock);
  21.                                         binder_user_error("%d:%d got reply transaction with bad transaction stack, transaction %d has target %d:%d\n",
  22.                                                 proc->pid, thread->pid, in_reply_to->debug_id,
  23.                                                 in_reply_to->to_proc ?
  24.                                                 in_reply_to->to_proc->pid : 0,
  25.                                                 in_reply_to->to_thread ?
  26.                                                 in_reply_to->to_thread->pid : 0);
  27.                                         spin_unlock(&in_reply_to->lock);
  28.                                         binder_inner_proc_unlock(proc);
  29.                                         return_error = BR_FAILED_REPLY;
  30.                                         return_error_param = -EPROTO;
  31.                                         return_error_line = __LINE__;
  32.                                         in_reply_to = NULL;
  33.                                         goto err_bad_call_stack;
  34.                                 }
  35.                                 thread->transaction_stack = in_reply_to->to_parent;//出栈
  36.                                 binder_inner_proc_unlock(proc);
  37.                                 binder_set_nice(in_reply_to->saved_priority);
  38.                                 target_thread = binder_get_txn_from_and_acq_inner(in_reply_to);
  39.                                 if (target_thread == NULL) {
  40.                                         /* annotation for sparse */
  41.                                         __release(&target_thread->proc->inner_lock);
  42.                                         binder_txn_error("%d:%d reply target not found\n",
  43.                                                 thread->pid, proc->pid);
  44.                                         return_error = BR_DEAD_REPLY;
  45.                                         return_error_line = __LINE__;
  46.                                         goto err_dead_binder;
  47.                                 }
  48.                                 if (target_thread->transaction_stack != in_reply_to) {
  49.                                         binder_user_error("%d:%d got reply transaction with bad target transaction stack %d, expected %d\n",
  50.                                                 proc->pid, thread->pid,
  51.                                                 target_thread->transaction_stack ?
  52.                                                 target_thread->transaction_stack->debug_id : 0,
  53.                                                 in_reply_to->debug_id);
  54.                                         binder_inner_proc_unlock(target_thread->proc);
  55.                                         return_error = BR_FAILED_REPLY;
  56.                                         return_error_param = -EPROTO;
  57.                                         return_error_line = __LINE__;
  58.                                         in_reply_to = NULL;
  59.                                         target_thread = NULL;
  60.                                         goto err_dead_binder;
  61.                                 }
  62.                                 // 找到要回复的进程
  63.                                 target_proc = target_thread->proc;
  64.                                 target_proc->tmp_ref++;
  65.                                 binder_inner_proc_unlock(target_thread->proc);
  66.         } else {// 1. 找到要发送的目的进程
  67.                 ......
  68.         }
  69.         if (target_thread)
  70.                 e->to_thread = target_thread->pid;
  71.         e->to_proc = target_proc->pid;
  72.         /* TODO: reuse incoming transaction for reply */
  73.         // 为binder_transcation分配内存
  74.         t = kzalloc(sizeof(*t), GFP_KERNEL);
  75.         
  76.         .....
  77.         if (!reply && !(tr->flags & TF_ONE_WAY))
  78.                 t->from = thread;
  79.         else
  80.                 t->from = NULL;
  81.         // 存储发送双方的基本信息
  82.         t->from_pid = proc->pid;
  83.         t->from_tid = thread->pid;
  84.         t->sender_euid = task_euid(proc->tsk);
  85.         t->to_proc = target_proc;
  86.         t->to_thread = target_thread;
  87.         t->code = tr->code;
  88.         t->flags = tr->flags;
  89.         t->priority = task_nice(current);
  90.         ......
  91.         t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size,
  92.                 tr->offsets_size, extra_buffers_size,
  93.                 !reply && (t->flags & TF_ONE_WAY));
  94.         ......
  95.         
  96.         t->buffer->debug_id = t->debug_id;
  97.         t->buffer->transaction = t;
  98.         t->buffer->target_node = target_node;
  99.         t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF);
  100.         trace_binder_transaction_alloc_buf(t->buffer);
  101.         
  102.         // 把客户端的数据拷贝到目的进程test_client mmap的内存空间
  103.         if (binder_alloc_copy_user_to_buffer(
  104.                                 &target_proc->alloc,
  105.                                 t->buffer,
  106.                                 ALIGN(tr->data_size, sizeof(void *)),
  107.                                 (const void __user *)
  108.                                         (uintptr_t)tr->data.ptr.offsets,
  109.                                 tr->offsets_size)) {
  110.                 binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
  111.                                 proc->pid, thread->pid);
  112.                 return_error = BR_FAILED_REPLY;
  113.                 return_error_param = -EFAULT;
  114.                 return_error_line = __LINE__;
  115.                 goto err_copy_data_failed;
  116.         }
  117.         ......
  118.                
  119.                 //处理server传入的binder_io.offs数据,这个数据指向用于构建binder_node实体的                flat_binder_object
  120.                 for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
  121.                      buffer_offset += sizeof(binder_size_t)) {
  122.                         struct binder_object_header *hdr;
  123.                         size_t object_size;
  124.                         struct binder_object object;
  125.                         binder_size_t object_offset;
  126.                         binder_size_t copy_size;
  127.        
  128.                         if (binder_alloc_copy_from_buffer(&target_proc->alloc,
  129.                                                           &object_offset,
  130.                                                           t->buffer,
  131.                                                           buffer_offset,
  132.                                                           sizeof(object_offset))) {
  133.                                 binder_txn_error("%d:%d copy offset from buffer failed\n",
  134.                                         thread->pid, proc->pid);
  135.                                 return_error = BR_FAILED_REPLY;
  136.                                 return_error_param = -EINVAL;
  137.                                 return_error_line = __LINE__;
  138.                                 goto err_bad_offset;
  139.                         }
  140.        
  141.                         /*
  142.                          * Copy the source user buffer up to the next object
  143.                          * that will be processed.
  144.                          */
  145.                         copy_size = object_offset - user_offset;
  146.                         if (copy_size && (user_offset > object_offset ||
  147.                                         binder_alloc_copy_user_to_buffer(
  148.                                                 &target_proc->alloc,
  149.                                                 t->buffer, user_offset,
  150.                                                 user_buffer + user_offset,
  151.                                                 copy_size))) {
  152.                                 binder_user_error("%d:%d got transaction with invalid data ptr\n",
  153.                                                 proc->pid, thread->pid);
  154.                                 return_error = BR_FAILED_REPLY;
  155.                                 return_error_param = -EFAULT;
  156.                                 return_error_line = __LINE__;
  157.                                 goto err_copy_data_failed;
  158.                         }
  159.                         // 将指向flat_binder_object的指针拷贝给object
  160.                         object_size = binder_get_object(target_proc, user_buffer,
  161.                                         t->buffer, object_offset, &object);
  162.                         if (object_size == 0 || object_offset < off_min) {
  163.                                 binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n",
  164.                                                   proc->pid, thread->pid,
  165.                                                   (u64)object_offset,
  166.                                                   (u64)off_min,
  167.                                                   (u64)t->buffer->data_size);
  168.                                 return_error = BR_FAILED_REPLY;
  169.                                 return_error_param = -EINVAL;
  170.                                 return_error_line = __LINE__;
  171.                                 goto err_bad_offset;
  172.                         }
  173.                         /*
  174.                          * Set offset to the next buffer fragment to be
  175.                          * copied
  176.                          */
  177.                         user_offset = object_offset + object_size;
  178.        
  179.                         hdr = &object.hdr;
  180.                         off_min = object_offset + object_size;
  181.                         // 此处 binder类型的是BINDER_TYPE_HANDLE,通过handle在service_manager的binder-ref中找到hello服务的binder_node
  182.                         switch (hdr->type) {
  183.                         //处理binder实体
  184.                         case BINDER_TYPE_BINDER:
  185.                         case BINDER_TYPE_WEAK_BINDER: {
  186.                                 ......
  187.                                
  188.                         } break;
  189.                         //处理binder引用
  190.                         case BINDER_TYPE_HANDLE:
  191.                         case BINDER_TYPE_WEAK_HANDLE: {
  192.                                 struct flat_binder_object *fp;
  193.        
  194.                                 fp = to_flat_binder_object(hdr);
  195.                                 ret = binder_translate_handle(fp, t, thread);
  196.                                 if (ret < 0 ||
  197.                                     binder_alloc_copy_to_buffer(&target_proc->alloc,
  198.                                                                 t->buffer,
  199.                                                                 object_offset,
  200.                                                                 fp, sizeof(*fp))) {
  201.                                         binder_txn_error("%d:%d translate handle failed\n",
  202.                                                 thread->pid, proc->pid);
  203.                                         return_error = BR_FAILED_REPLY;
  204.                                         return_error_param = ret;
  205.                                         return_error_line = __LINE__;
  206.                                         goto err_translate_failed;
  207.                                 }
  208.                         } break;
  209.                         ......
  210.          }
  211. ......
  212. }
复制代码
4.3 根据handle找到服务的binder_node,

  1. static int binder_translate_handle(struct flat_binder_object *fp,
  2.                                    struct binder_transaction *t,
  3.                                    struct binder_thread *thread)
  4. {
  5.         struct binder_proc *proc = thread->proc;
  6.         struct binder_proc *target_proc = t->to_proc;
  7.         struct binder_node *node;
  8.         struct binder_ref_data src_rdata;
  9.         int ret = 0;
  10.    
  11.     // 根据handle从service_manager中找到服务的binder_node
  12.         node = binder_get_node_from_ref(proc, fp->handle,
  13.                         fp->hdr.type == BINDER_TYPE_HANDLE, &src_rdata);
  14.         if (!node) {
  15.                 binder_user_error("%d:%d got transaction with invalid handle, %d\n",
  16.                                   proc->pid, thread->pid, fp->handle);
  17.                 return -EINVAL;
  18.         }
  19.         if (security_binder_transfer_binder(proc->cred, target_proc->cred)) {
  20.                 ret = -EPERM;
  21.                 goto done;
  22.         }
  23.         binder_node_lock(node);
  24.         if (node->proc == target_proc) {
  25.                 if (fp->hdr.type == BINDER_TYPE_HANDLE)
  26.                         fp->hdr.type = BINDER_TYPE_BINDER;
  27.                 else
  28.                         fp->hdr.type = BINDER_TYPE_WEAK_BINDER;
  29.                 fp->binder = node->ptr;
  30.                 fp->cookie = node->cookie;
  31.                 if (node->proc)
  32.                         binder_inner_proc_lock(node->proc);
  33.                 else
  34.                         __acquire(&node->proc->inner_lock);
  35.                 binder_inc_node_nilocked(node,
  36.                                          fp->hdr.type == BINDER_TYPE_BINDER,
  37.                                          0, NULL);
  38.                 if (node->proc)
  39.                         binder_inner_proc_unlock(node->proc);
  40.                 else
  41.                         __release(&node->proc->inner_lock);
  42.                 trace_binder_transaction_ref_to_node(t, node, &src_rdata);
  43.                 binder_debug(BINDER_DEBUG_TRANSACTION,
  44.                              "        ref %d desc %d -> node %d u%016llx\n",
  45.                              src_rdata.debug_id, src_rdata.desc, node->debug_id,
  46.                              (u64)node->ptr);
  47.                 binder_node_unlock(node);
  48.         } else {
  49.                 struct binder_ref_data dest_rdata;
  50.                 binder_node_unlock(node);
  51.                 // 为客户端创建binder_ref指向服务的binder_node
  52.                 ret = binder_inc_ref_for_node(target_proc, node,
  53.                                 fp->hdr.type == BINDER_TYPE_HANDLE,
  54.                                 NULL, &dest_rdata);
  55.                 if (ret)
  56.                         goto done;
  57.                 fp->binder = 0;
  58.                 fp->handle = dest_rdata.desc;
  59.                 fp->cookie = 0;
  60.                 trace_binder_transaction_ref_to_ref(t, node, &src_rdata,
  61.                                                     &dest_rdata);
  62.                 binder_debug(BINDER_DEBUG_TRANSACTION,
  63.                              "        ref %d desc %d -> ref %d desc %d (node %d)\n",
  64.                              src_rdata.debug_id, src_rdata.desc,
  65.                              dest_rdata.debug_id, dest_rdata.desc,
  66.                              node->debug_id);
  67.         }
  68. done:
  69.         binder_put_node(node);
  70.         return ret;
  71. }
  72. static struct binder_node *binder_get_node_from_ref(
  73.                 struct binder_proc *proc,
  74.                 u32 desc, bool need_strong_ref,
  75.                 struct binder_ref_data *rdata)
  76. {
  77.         struct binder_node *node;
  78.         struct binder_ref *ref;
  79.         binder_proc_lock(proc);
  80.         // 根据handle找到binder_ref
  81.         ref = binder_get_ref_olocked(proc, desc, need_strong_ref);
  82.         if (!ref)
  83.                 goto err_no_ref;
  84.                
  85.         // 根据binder_ref找到binder_node
  86.         node = ref->node;
  87.         /*
  88.          * Take an implicit reference on the node to ensure
  89.          * it stays alive until the call to binder_put_node()
  90.          */
  91.         binder_inc_node_tmpref(node);
  92.         if (rdata)
  93.                 *rdata = ref->data;
  94.         binder_proc_unlock(proc);
  95.         return node;
  96. err_no_ref:
  97.         binder_proc_unlock(proc);
  98.         return NULL;
  99. }
  100. static struct binder_ref *binder_get_ref_olocked(struct binder_proc *proc,
  101.                                                  u32 desc, bool need_strong_ref)
  102. {
  103.         struct rb_node *n = proc->refs_by_desc.rb_node;
  104.         struct binder_ref *ref;
  105.         while (n) {
  106.                 ref = rb_entry(n, struct binder_ref, rb_node_desc);
  107.                 if (desc < ref->data.desc) {
  108.                         n = n->rb_left;
  109.                 } else if (desc > ref->data.desc) {
  110.                         n = n->rb_right;
  111.                 } else if (need_strong_ref && !ref->data.strong) {
  112.                         binder_user_error("tried to use weak ref as strong ref\n");
  113.                         return NULL;
  114.                 } else {
  115.                         return ref;
  116.                 }
  117.         }
  118.         return NULL;
  119. }
复制代码
4.4 为客户端创建binder_ref,指向服务的binder_node

  1. static int binder_inc_ref_for_node(struct binder_proc *proc,
  2.                         struct binder_node *node,
  3.                         bool strong,
  4.                         struct list_head *target_list,
  5.                         struct binder_ref_data *rdata)
  6. {
  7.         struct binder_ref *ref;
  8.         struct binder_ref *new_ref = NULL;
  9.         int ret = 0;
  10.         binder_proc_lock(proc);
  11.         // 先查找客户端是否已经有对应的binder_ref,若没有则新建binder_ref
  12.         ref = binder_get_ref_for_node_olocked(proc, node, NULL);
  13.         if (!ref) {
  14.                 binder_proc_unlock(proc);
  15.                 new_ref = kzalloc(sizeof(*ref), GFP_KERNEL);
  16.                 if (!new_ref)
  17.                         return -ENOMEM;
  18.                 binder_proc_lock(proc);
  19.                 ref = binder_get_ref_for_node_olocked(proc, node, new_ref);
  20.         }
  21.         //增加引用计数
  22.         ret = binder_inc_ref_olocked(ref, strong, target_list);
  23.         *rdata = ref->data;
  24.         if (ret && ref == new_ref) {
  25.                 /*
  26.                  * Cleanup the failed reference here as the target
  27.                  * could now be dead and have already released its
  28.                  * references by now. Calling on the new reference
  29.                  * with strong=0 and a tmp_refs will not decrement
  30.                  * the node. The new_ref gets kfree'd below.
  31.                  */
  32.                 binder_cleanup_ref_olocked(new_ref);
  33.                 ref = NULL;
  34.         }
  35.         binder_proc_unlock(proc);
  36.         if (new_ref && ref != new_ref)
  37.                 /*
  38.                  * Another thread created the ref first so
  39.                  * free the one we allocated
  40.                  */
  41.                 kfree(new_ref);
  42.         return ret;
  43. }
  44. static struct binder_ref *binder_get_ref_for_node_olocked(
  45.                                         struct binder_proc *proc,
  46.                                         struct binder_node *node,
  47.                                         struct binder_ref *new_ref)
  48. {
  49.         struct binder_context *context = proc->context;
  50.         struct rb_node **p = &proc->refs_by_node.rb_node;
  51.         struct rb_node *parent = NULL;
  52.         struct binder_ref *ref;
  53.         struct rb_node *n;
  54.         while (*p) {
  55.                 parent = *p;
  56.                 ref = rb_entry(parent, struct binder_ref, rb_node_node);
  57.                 if (node < ref->node)
  58.                         p = &(*p)->rb_left;
  59.                 else if (node > ref->node)
  60.                         p = &(*p)->rb_right;
  61.                 else
  62.                         return ref;
  63.         }
  64.         if (!new_ref)
  65.                 return NULL;
  66.         binder_stats_created(BINDER_STAT_REF);
  67.         new_ref->data.debug_id = atomic_inc_return(&binder_last_id);
  68.         new_ref->proc = proc;
  69.         new_ref->node = node;
  70.         rb_link_node(&new_ref->rb_node_node, parent, p);
  71.         rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node);
  72.    
  73.     // 更新binder_ref的handle值,后续客户端通过handle值找到这个binder_ref,进而找到binder_node
  74.         new_ref->data.desc = (node == context->binder_context_mgr_node) ? 0 : 1;
  75.         for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) {
  76.                 ref = rb_entry(n, struct binder_ref, rb_node_desc);
  77.                 if (ref->data.desc > new_ref->data.desc)
  78.                         break;
  79.                 // 客户端引用服务的handle加1
  80.                 new_ref->data.desc = ref->data.desc + 1;
  81.         }
  82.         p = &proc->refs_by_desc.rb_node;
  83.         while (*p) {
  84.                 parent = *p;
  85.                 ref = rb_entry(parent, struct binder_ref, rb_node_desc);
  86.                 if (new_ref->data.desc < ref->data.desc)
  87.                         p = &(*p)->rb_left;
  88.                 else if (new_ref->data.desc > ref->data.desc)
  89.                         p = &(*p)->rb_right;
  90.                 else
  91.                         BUG();
  92.         }
  93.         rb_link_node(&new_ref->rb_node_desc, parent, p);
  94.         rb_insert_color(&new_ref->rb_node_desc, &proc->refs_by_desc);
  95.         binder_node_lock(node);
  96.         hlist_add_head(&new_ref->node_entry, &node->refs);
  97.         binder_debug(BINDER_DEBUG_INTERNAL_REFS,
  98.                      "%d new ref %d desc %d for node %d\n",
  99.                       proc->pid, new_ref->data.debug_id, new_ref->data.desc,
  100.                       node->debug_id);
  101.         binder_node_unlock(node);
  102.         return new_ref;
  103. }
复制代码
4.5 把数据放到客户端的todo链表,叫醒客户端

  1. static void binder_transaction(struct binder_proc *proc,
  2.                                struct binder_thread *thread,
  3.                                struct binder_transaction_data *tr, int reply,
  4.                                binder_size_t extra_buffers_size)
  5. {
  6.         ......
  7.         if (reply) {// 找到要回复的进程
  8.                 binder_inner_proc_lock(proc);
  9.                                 in_reply_to = thread->transaction_stack;//从栈中取出binder_transaction,获得要回复给谁
  10.                                 if (in_reply_to == NULL) {
  11.                                         binder_inner_proc_unlock(proc);
  12.                                         binder_user_error("%d:%d got reply transaction with no transaction stack\n",
  13.                                                           proc->pid, thread->pid);
  14.                                         return_error = BR_FAILED_REPLY;
  15.                                         return_error_param = -EPROTO;
  16.                                         return_error_line = __LINE__;
  17.                                         goto err_empty_call_stack;
  18.                                 }
  19.                                 if (in_reply_to->to_thread != thread) {
  20.                                         spin_lock(&in_reply_to->lock);
  21.                                         binder_user_error("%d:%d got reply transaction with bad transaction stack, transaction %d has target %d:%d\n",
  22.                                                 proc->pid, thread->pid, in_reply_to->debug_id,
  23.                                                 in_reply_to->to_proc ?
  24.                                                 in_reply_to->to_proc->pid : 0,
  25.                                                 in_reply_to->to_thread ?
  26.                                                 in_reply_to->to_thread->pid : 0);
  27.                                         spin_unlock(&in_reply_to->lock);
  28.                                         binder_inner_proc_unlock(proc);
  29.                                         return_error = BR_FAILED_REPLY;
  30.                                         return_error_param = -EPROTO;
  31.                                         return_error_line = __LINE__;
  32.                                         in_reply_to = NULL;
  33.                                         goto err_bad_call_stack;
  34.                                 }
  35.                                 thread->transaction_stack = in_reply_to->to_parent;//出栈
  36.                                 binder_inner_proc_unlock(proc);
  37.                                 binder_set_nice(in_reply_to->saved_priority);
  38.                                 target_thread = binder_get_txn_from_and_acq_inner(in_reply_to);
  39.                                 if (target_thread == NULL) {
  40.                                         /* annotation for sparse */
  41.                                         __release(&target_thread->proc->inner_lock);
  42.                                         binder_txn_error("%d:%d reply target not found\n",
  43.                                                 thread->pid, proc->pid);
  44.                                         return_error = BR_DEAD_REPLY;
  45.                                         return_error_line = __LINE__;
  46.                                         goto err_dead_binder;
  47.                                 }
  48.                                 if (target_thread->transaction_stack != in_reply_to) {
  49.                                         binder_user_error("%d:%d got reply transaction with bad target transaction stack %d, expected %d\n",
  50.                                                 proc->pid, thread->pid,
  51.                                                 target_thread->transaction_stack ?
  52.                                                 target_thread->transaction_stack->debug_id : 0,
  53.                                                 in_reply_to->debug_id);
  54.                                         binder_inner_proc_unlock(target_thread->proc);
  55.                                         return_error = BR_FAILED_REPLY;
  56.                                         return_error_param = -EPROTO;
  57.                                         return_error_line = __LINE__;
  58.                                         in_reply_to = NULL;
  59.                                         target_thread = NULL;
  60.                                         goto err_dead_binder;
  61.                                 }
  62.                                 // 找到要回复的进程
  63.                                 target_proc = target_thread->proc;
  64.                                 target_proc->tmp_ref++;
  65.                                 binder_inner_proc_unlock(target_thread->proc);
  66.         } else {// 1. 找到要发送的目的进程
  67.                 ......
  68.         }
  69.         if (target_thread)
  70.                 e->to_thread = target_thread->pid;
  71.         e->to_proc = target_proc->pid;
  72.         /* TODO: reuse incoming transaction for reply */
  73.         // 为binder_transcation分配内存
  74.         t = kzalloc(sizeof(*t), GFP_KERNEL);
  75.         
  76.         .....
  77.         if (!reply && !(tr->flags & TF_ONE_WAY))
  78.                 t->from = thread;
  79.         else
  80.                 t->from = NULL;
  81.         // 存储发送双方的基本信息
  82.         t->from_pid = proc->pid;
  83.         t->from_tid = thread->pid;
  84.         t->sender_euid = task_euid(proc->tsk);
  85.         t->to_proc = target_proc;
  86.         t->to_thread = target_thread;
  87.         t->code = tr->code;
  88.         t->flags = tr->flags;
  89.         t->priority = task_nice(current);
  90.         ......
  91.         t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size,
  92.                 tr->offsets_size, extra_buffers_size,
  93.                 !reply && (t->flags & TF_ONE_WAY));
  94.         ......
  95.         
  96.         t->buffer->debug_id = t->debug_id;
  97.         t->buffer->transaction = t;
  98.         t->buffer->target_node = target_node;
  99.         t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF);
  100.         trace_binder_transaction_alloc_buf(t->buffer);
  101.         
  102.         // 把客户端的数据拷贝到目的进程test_client mmap的内存空间
  103.         if (binder_alloc_copy_user_to_buffer(
  104.                                 &target_proc->alloc,
  105.                                 t->buffer,
  106.                                 ALIGN(tr->data_size, sizeof(void *)),
  107.                                 (const void __user *)
  108.                                         (uintptr_t)tr->data.ptr.offsets,
  109.                                 tr->offsets_size)) {
  110.                 binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
  111.                                 proc->pid, thread->pid);
  112.                 return_error = BR_FAILED_REPLY;
  113.                 return_error_param = -EFAULT;
  114.                 return_error_line = __LINE__;
  115.                 goto err_copy_data_failed;
  116.         }
  117.         ......
  118.                
  119.                 //处理server传入的binder_io.offs数据,这个数据指向用于构建binder_node实体的                flat_binder_object
  120.                 for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
  121.                      buffer_offset += sizeof(binder_size_t)) {
  122.                         struct binder_object_header *hdr;
  123.                         size_t object_size;
  124.                         struct binder_object object;
  125.                         binder_size_t object_offset;
  126.                         binder_size_t copy_size;
  127.        
  128.                         if (binder_alloc_copy_from_buffer(&target_proc->alloc,
  129.                                                           &object_offset,
  130.                                                           t->buffer,
  131.                                                           buffer_offset,
  132.                                                           sizeof(object_offset))) {
  133.                                 binder_txn_error("%d:%d copy offset from buffer failed\n",
  134.                                         thread->pid, proc->pid);
  135.                                 return_error = BR_FAILED_REPLY;
  136.                                 return_error_param = -EINVAL;
  137.                                 return_error_line = __LINE__;
  138.                                 goto err_bad_offset;
  139.                         }
  140.        
  141.                         /*
  142.                          * Copy the source user buffer up to the next object
  143.                          * that will be processed.
  144.                          */
  145.                         copy_size = object_offset - user_offset;
  146.                         if (copy_size && (user_offset > object_offset ||
  147.                                         binder_alloc_copy_user_to_buffer(
  148.                                                 &target_proc->alloc,
  149.                                                 t->buffer, user_offset,
  150.                                                 user_buffer + user_offset,
  151.                                                 copy_size))) {
  152.                                 binder_user_error("%d:%d got transaction with invalid data ptr\n",
  153.                                                 proc->pid, thread->pid);
  154.                                 return_error = BR_FAILED_REPLY;
  155.                                 return_error_param = -EFAULT;
  156.                                 return_error_line = __LINE__;
  157.                                 goto err_copy_data_failed;
  158.                         }
  159.                         // 将指向flat_binder_object的指针拷贝给object
  160.                         object_size = binder_get_object(target_proc, user_buffer,
  161.                                         t->buffer, object_offset, &object);
  162.                         if (object_size == 0 || object_offset < off_min) {
  163.                                 binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n",
  164.                                                   proc->pid, thread->pid,
  165.                                                   (u64)object_offset,
  166.                                                   (u64)off_min,
  167.                                                   (u64)t->buffer->data_size);
  168.                                 return_error = BR_FAILED_REPLY;
  169.                                 return_error_param = -EINVAL;
  170.                                 return_error_line = __LINE__;
  171.                                 goto err_bad_offset;
  172.                         }
  173.                         /*
  174.                          * Set offset to the next buffer fragment to be
  175.                          * copied
  176.                          */
  177.                         user_offset = object_offset + object_size;
  178.        
  179.                         hdr = &object.hdr;
  180.                         off_min = object_offset + object_size;
  181.                         // 此处 binder类型的是BINDER_TYPE_HANDLE,通过handle在service_manager的binder-ref中找到hello服务的binder_node
  182.                         switch (hdr->type) {
  183.                         //处理binder实体
  184.                         case BINDER_TYPE_BINDER:
  185.                         case BINDER_TYPE_WEAK_BINDER: {
  186.                                 ......
  187.                                
  188.                         } break;
  189.                         //处理binder引用
  190.                         case BINDER_TYPE_HANDLE:
  191.                         case BINDER_TYPE_WEAK_HANDLE: {
  192.                                 struct flat_binder_object *fp;
  193.        
  194.                                 fp = to_flat_binder_object(hdr);
  195.                                 ret = binder_translate_handle(fp, t, thread);
  196.                                 if (ret < 0 ||
  197.                                     binder_alloc_copy_to_buffer(&target_proc->alloc,
  198.                                                                 t->buffer,
  199.                                                                 object_offset,
  200.                                                                 fp, sizeof(*fp))) {
  201.                                         binder_txn_error("%d:%d translate handle failed\n",
  202.                                                 thread->pid, proc->pid);
  203.                                         return_error = BR_FAILED_REPLY;
  204.                                         return_error_param = ret;
  205.                                         return_error_line = __LINE__;
  206.                                         goto err_translate_failed;
  207.                                 }
  208.                         } break;
  209.                         ......
  210.          }
  211.         ......
  212.         t->work.type = BINDER_WORK_TRANSACTION;
  213.         if (reply) {
  214.                 binder_enqueue_thread_work(thread, tcomplete);
  215.                 binder_inner_proc_lock(target_proc);
  216.                 if (target_thread->is_dead) {
  217.                         return_error = BR_DEAD_REPLY;
  218.                         binder_inner_proc_unlock(target_proc);
  219.                         goto err_dead_proc_or_thread;
  220.                 }
  221.                 BUG_ON(t->buffer->async_transaction != 0);
  222.                 binder_pop_transaction_ilocked(target_thread, in_reply_to);//再次出栈
  223.                 // 将数据放到客户端target_thread的todo链表
  224.                 binder_enqueue_thread_work_ilocked(target_thread, &t->work);
  225.                 target_proc->outstanding_txns++;
  226.                 binder_inner_proc_unlock(target_proc);
  227.                 // 唤醒客户端
  228.                 wake_up_interruptible_sync(&target_thread->wait);
  229.                 binder_free_transaction(in_reply_to);
  230.         } else if (!(t->flags & TF_ONE_WAY)) {
  231.                 ......
  232.         } else {
  233.                 ......
  234.         }
  235.         if (target_thread)
  236.                 binder_thread_dec_tmpref(target_thread);
  237.         binder_proc_dec_tmpref(target_proc);
  238.         if (target_node)
  239.                 binder_dec_node_tmpref(target_node);
  240.         /*
  241.          * write barrier to synchronize with initialization
  242.          * of log entry
  243.          */
  244.         smp_wmb();
  245.         WRITE_ONCE(e->debug_id_done, t_debug_id);
  246.         return;
  247.         ......
  248. }
  249. static void
  250. binder_enqueue_thread_work_ilocked(struct binder_thread *thread,
  251.                                    struct binder_work *work)
  252. {
  253.         WARN_ON(!list_empty(&thread->waiting_thread_node));
  254.         binder_enqueue_work_ilocked(work, &thread->todo);
  255.         /* (e)poll-based threads require an explicit wakeup signal when
  256.          * queuing their own work; they rely on these events to consume
  257.          * messages without I/O block. Without it, threads risk waiting
  258.          * indefinitely without handling the work.
  259.          */
  260.         if (thread->looper & BINDER_LOOPER_STATE_POLL &&
  261.             thread->pid == current->pid && !thread->process_todo)
  262.                 wake_up_interruptible_sync(&thread->wait);
  263.         thread->process_todo = true;
  264. }
  265. static void
  266. binder_enqueue_work_ilocked(struct binder_work *work,
  267.                            struct list_head *target_list)
  268. {
  269.         BUG_ON(target_list == NULL);
  270.         BUG_ON(work->entry.next && !list_empty(&work->entry));
  271.         list_add_tail(&work->entry, target_list);
  272. }
复制代码
2.4 客户端被叫醒,获取客户端binder_ref对应的handle

  1. handle = svcmgr_lookup(bs, svcmgr, "hello");
  2. uint32_t svcmgr_lookup(struct binder_state *bs, uint32_t target, const char *name)
  3. {
  4.     uint32_t handle;
  5.     unsigned iodata[512/4];
  6.     struct binder_io msg, reply;
  7.     bio_init(&msg, iodata, sizeof(iodata), 4);
  8.     bio_put_uint32(&msg, 0);  // strict mode header
  9.     bio_put_string16_x(&msg, SVC_MGR_NAME);
  10.     bio_put_string16_x(&msg, name);
  11.    
  12.     // ioctl到内核处理
  13.     if (binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE))
  14.         return 0;
  15.    
  16.     // 获取引用服务binder_node的客户端binder_ref的handle
  17.     handle = bio_get_ref(&reply);
  18.     if (handle)
  19.         binder_acquire(bs, handle);
  20.     binder_done(bs, &msg, &reply);
  21.     return handle;
  22. }
  23. uint32_t bio_get_ref(struct binder_io *bio)
  24. {
  25.     struct flat_binder_object *obj;
  26.     obj = _bio_get_obj(bio);
  27.     if (!obj)
  28.         return 0;
  29.     if (obj->type == BINDER_TYPE_HANDLE)
  30.         return obj->handle;
  31.     return 0;
  32. }
复制代码
3 服务注册和获取过程的简要总结图


二、服务的利用过程内核源码剖析

上面我们通过源码分析,获得了客户端想要利用的服务的handle,下面我们接着分析,如何利用该服务。
1. 服务利用过程思路

有了之前Binder源码阅读的经验,我们直接看服务利用的思路,应该很轻易可以或许明白,我们基于这个思路举行分析源码,也更轻易明白源码。

2. 客户端利用服务内核源码剖析

2.1 向服务端发送数据

  1. int main(int argc, char **argv)
  2. {
  3.     int fd;
  4.     struct binder_state *bs;
  5.     uint32_t svcmgr = BINDER_SERVICE_MANAGER;
  6.     uint32_t handle;
  7.         int ret;
  8.         if (argc < 2){
  9.         fprintf(stderr, "Usage:\n");
  10.         fprintf(stderr, "%s <hello|goodbye>\n", argv[0]);
  11.         fprintf(stderr, "%s <hello|goodbye> <name>\n", argv[0]);
  12.         return -1;
  13.         }
  14.    
  15.     //打开驱动
  16.     bs = binder_open(128*1024);
  17.     if (!bs) {
  18.         fprintf(stderr, "failed to open binder driver\n");
  19.         return -1;
  20.     }
  21.         g_bs = bs;
  22.    
  23.     //向service_manager发送数据,获得hello服务句柄
  24.         handle = svcmgr_lookup(bs, svcmgr, "hello");
  25.         if (!handle) {
  26.         fprintf(stderr, "failed to get hello service\n");
  27.         return -1;
  28.         }
  29.         g_hello_handle = handle;
  30.         fprintf(stderr, "Handle for hello service = %d\n", g_hello_handle);
  31.         /* 向服务端发送数据 */
  32.         if (!strcmp(argv[1], "hello"))
  33.         {
  34.                 if (argc == 2) {
  35.                         sayhello();
  36.                 } else if (argc == 3) {
  37.                         ret = sayhello_to(argv[2]);
  38.                 fprintf(stderr, "get ret of sayhello_to = %d\n", ret);               
  39.                 }
  40.         }
  41.         binder_release(bs, handle);
  42.     return 0;
  43. }
复制代码
1. sayhello_to

以调用服务端的sayhello_to函数为例,分析客户端利用服务的过程
  1. int sayhello_to(char *name)
  2. {
  3.         unsigned iodata[512/4];
  4.         struct binder_io msg, reply;
  5.         int ret;
  6.         int exception;
  7.         /* 构造binder_io */
  8.         bio_init(&msg, iodata, sizeof(iodata), 4);
  9.         bio_put_uint32(&msg, 0);  // strict mode header
  10.     bio_put_string16_x(&msg, "IHelloService");
  11.         /* 放入参数 */
  12.     bio_put_string16_x(&msg, name);
  13.         /* 调用binder_call
  14.         msg:客户端的数据
  15.         reply:携带服务端返回的数据
  16.         g_hello_handle:服务端进程的handle
  17.         HELLO_SVR_CMD_SAYHELLO_TO:要调用的服务端提供的服务
  18.          */
  19.         if (binder_call(g_bs, &msg, &reply, g_hello_handle, HELLO_SVR_CMD_SAYHELLO_TO))
  20.                 return 0;
  21.        
  22.         /* 从reply中解析出返回值 */
  23.         exception = bio_get_uint32(&reply);
  24.         if (exception)
  25.                 ret = -1;
  26.         else
  27.                 ret = bio_get_uint32(&reply);
  28.         binder_done(g_bs, &msg, &reply);
  29.         return ret;
  30.        
  31. }
复制代码
2. binder_call

binder_call函数,已经分析很多遍了,这里不再详细分析,贴下代码
  1. int binder_call(struct binder_state *bs,
  2.                 struct binder_io *msg, struct binder_io *reply,
  3.                 uint32_t target, uint32_t code)
  4. {
  5.     int res;
  6.     struct binder_write_read bwr;
  7.     struct {
  8.         uint32_t cmd;
  9.         struct binder_transaction_data txn;
  10.     } __attribute__((packed)) writebuf;
  11.     unsigned readbuf[32];
  12.     if (msg->flags & BIO_F_OVERFLOW) {
  13.         fprintf(stderr,"binder: txn buffer overflow\n");
  14.         goto fail;
  15.     }
  16.     writebuf.cmd = BC_TRANSACTION;//ioclt类型
  17.     writebuf.txn.target.handle = target;//数据发送给哪个进程
  18.     writebuf.txn.code = code;//调用进程的哪个函数
  19.     writebuf.txn.flags = 0;
  20.     writebuf.txn.data_size = msg->data - msg->data0;//数据本身大小
  21.     writebuf.txn.offsets_size = ((char*) msg->offs) - ((char*) msg->offs0);//数据头大小,指向binder_node实体(发送端提供服务函数的地址),bio_put_obj(&msg, ptr);
  22.     writebuf.txn.data.ptr.buffer = (uintptr_t)msg->data0;//指向数据本身内存起点
  23.     writebuf.txn.data.ptr.offsets = (uintptr_t)msg->offs0;//指向数据头内存起点
  24.     bwr.write_size = sizeof(writebuf);
  25.     bwr.write_consumed = 0;
  26.     bwr.write_buffer = (uintptr_t) &writebuf;
  27.     hexdump(msg->data0, msg->data - msg->data0);
  28.     for (;;) {
  29.         bwr.read_size = sizeof(readbuf);
  30.         bwr.read_consumed = 0;
  31.         bwr.read_buffer = (uintptr_t) readbuf;
  32.         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);//调用ioctl发送数据给驱动程序
  33.         if (res < 0) {
  34.             fprintf(stderr,"binder: ioctl failed (%s)\n", strerror(errno));
  35.             goto fail;
  36.         }
  37.         res = binder_parse(bs, reply, (uintptr_t) readbuf, bwr.read_consumed, 0);
  38.         if (res == 0) return 0;
  39.         if (res < 0) goto fail;
  40.     }
  41. fail:
  42.     memset(reply, 0, sizeof(*reply));
  43.     reply->flags |= BIO_F_IOERROR;
  44.     return -1;
  45. }
复制代码
3. binder_ioctl

用户态的ioctl调用到内核Binder驱动程序binder_ioctl函数,这个函数也分析很多遍了,相信看到这儿的博友,对这些函数已经很熟悉了。
  1. // res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);进入binder驱动程序
  2. static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  3. {
  4.         int ret;
  5.         struct binder_proc *proc = filp->private_data;
  6.         struct binder_thread *thread;
  7.         void __user *ubuf = (void __user *)arg;
  8.         /*pr_info("binder_ioctl: %d:%d %x %lx\n",
  9.                         proc->pid, current->pid, cmd, arg);*/
  10.         binder_selftest_alloc(&proc->alloc);
  11.         trace_binder_ioctl(cmd, arg);
  12.         ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
  13.         if (ret)
  14.                 goto err_unlocked;
  15.         //为进程proc创建binder_thread
  16.         thread = binder_get_thread(proc);
  17.         if (thread == NULL) {
  18.                 ret = -ENOMEM;
  19.                 goto err;
  20.         }
  21.         switch (cmd) {
  22.         case BINDER_WRITE_READ:
  23.                 ret = binder_ioctl_write_read(filp, arg, thread);
  24.                 if (ret)
  25.                         goto err;
  26.                 break;
  27.                 ......
  28.         }
  29.         ......
  30. }
复制代码
4. binder_ioctl_write_read

  1. static int binder_ioctl_write_read(struct file *filp, unsigned long arg,
  2.                                 struct binder_thread *thread)
  3. {
  4.         int ret = 0;
  5.         struct binder_proc *proc = filp->private_data;
  6.         void __user *ubuf = (void __user *)arg;
  7.         struct binder_write_read bwr;
  8.     //从用户空间拷贝数据到内核空间(这部分内核空间被mmap映射到了目标进程)
  9.         if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
  10.                 ret = -EFAULT;
  11.                 goto out;
  12.         }
  13.         binder_debug(BINDER_DEBUG_READ_WRITE,
  14.                      "%d:%d write %lld at %016llx, read %lld at %016llx\n",
  15.                      proc->pid, thread->pid,
  16.                      (u64)bwr.write_size, (u64)bwr.write_buffer,
  17.                      (u64)bwr.read_size, (u64)bwr.read_buffer);
  18.         if (bwr.write_size > 0) {
  19.                 ret = binder_thread_write(proc, thread,
  20.                                           bwr.write_buffer,
  21.                                           bwr.write_size,
  22.                                           &bwr.write_consumed);
  23.                 trace_binder_write_done(ret);
  24.                 if (ret < 0) {
  25.                         bwr.read_consumed = 0;
  26.                         if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
  27.                                 ret = -EFAULT;
  28.                         goto out;
  29.                 }
  30.         }
  31.         if (bwr.read_size > 0) {
  32.                 ......
  33.         }
  34.         binder_debug(BINDER_DEBUG_READ_WRITE,
  35.                      "%d:%d wrote %lld of %lld, read return %lld of %lld\n",
  36.                      proc->pid, thread->pid,
  37.                      (u64)bwr.write_consumed, (u64)bwr.write_size,
  38.                      (u64)bwr.read_consumed, (u64)bwr.read_size);
  39.         if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
  40.                 ret = -EFAULT;
  41.                 goto out;
  42.         }
  43. out:
  44.         return ret;
  45. }
复制代码
5. binder_thread_write

  1. static int binder_thread_write(struct binder_proc *proc,
  2.                         struct binder_thread *thread,
  3.                         binder_uintptr_t binder_buffer, size_t size,
  4.                         binder_size_t *consumed)
  5. {
  6.         uint32_t cmd;
  7.         struct binder_context *context = proc->context;
  8.         // 获取数据buffer,根据上面总结的发送数据可知,这个buffer由cmd和binder_transcation_data两部分数据组成
  9.         void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
  10.         // 发送来的数据consumed=0,因此ptr指向用户空间数据buffer的起点
  11.         void __user *ptr = buffer + *consumed;
  12.         // 指向数据buffer的末尾
  13.         void __user *end = buffer + size;
  14.         // 逐个读取客户端发送来的数据(cmd+binder_transcation_data)
  15.         while (ptr < end && thread->return_error.cmd == BR_OK) {
  16.                 int ret;
  17.                
  18.                 // 获取用户空间中buffer的cmd值
  19.                 if (get_user(cmd, (uint32_t __user *)ptr))
  20.                         return -EFAULT;
  21.                 // 移动指针到cmd的位置之后,指向binder_transcation_data数据的内存起点
  22.                 ptr += sizeof(uint32_t);
  23.                 trace_binder_command(cmd);
  24.                 if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) {
  25.                         atomic_inc(&binder_stats.bc[_IOC_NR(cmd)]);
  26.                         atomic_inc(&proc->stats.bc[_IOC_NR(cmd)]);
  27.                         atomic_inc(&thread->stats.bc[_IOC_NR(cmd)]);
  28.                 }
  29.                 // 根据上面总结的发送数据可知,cmd是BC_TRANSACTION
  30.                 switch (cmd) {
  31.                    ......
  32.                    /*
  33.                 BC_TRANSACTION:进程发送信息的cmd
  34.                 BR_TRANSACTION:进程接收BC_TRANSACTION发送信息的cmd
  35.                
  36.                 BC_REPLY:进程回复信息的cmd
  37.                 BR_REPLY:进程接收BC_REPLY回复信息的cmd
  38.                 */
  39.                     case BC_TRANSACTION:
  40.                     case BC_REPLY: {
  41.                             struct binder_transaction_data tr;
  42.                            
  43.                             // 从用户空间拷贝binder_transaction_data到内核空间
  44.                             if (copy_from_user(&tr, ptr, sizeof(tr)))
  45.                                     return -EFAULT;
  46.                             // 移动指针到binder_transaction_data的位置之后,指向下一个cmd数据的内存起点
  47.                             ptr += sizeof(tr);
  48.                             // 处理binder_transaction_data数据
  49.                             binder_transaction(proc, thread, &tr,
  50.                                                cmd == BC_REPLY, 0);
  51.                             break;
  52.                     }
  53.                 }
  54.         }
  55.         ......
  56. }
  57. int get_user(int *val, const int __user *ptr) {
  58.     if (copy_from_user(val, ptr, sizeof(int))) {
  59.         return -EFAULT; // 返回错误码
  60.     }
  61.     return 0; // 成功
  62. }
复制代码
6. binder_transaction

这个函数也分析了很多很多遍了,这里简要分析下
  1. static void binder_transaction(struct binder_proc *proc,
  2.                                struct binder_thread *thread,
  3.                                struct binder_transaction_data *tr, int reply,
  4.                                binder_size_t extra_buffers_size)
  5. {
  6.         int ret;
  7.         struct binder_transaction *t;
  8.         struct binder_work *w;
  9.         struct binder_work *tcomplete;
  10.         binder_size_t buffer_offset = 0;
  11.         binder_size_t off_start_offset, off_end_offset;
  12.         binder_size_t off_min;
  13.         binder_size_t sg_buf_offset, sg_buf_end_offset;
  14.         binder_size_t user_offset = 0;
  15.         struct binder_proc *target_proc = NULL;
  16.         struct binder_thread *target_thread = NULL;
  17.         struct binder_node *target_node = NULL;
  18.         struct binder_transaction *in_reply_to = NULL;
  19.         struct binder_transaction_log_entry *e;
  20.         uint32_t return_error = 0;
  21.         uint32_t return_error_param = 0;
  22.         uint32_t return_error_line = 0;
  23.         binder_size_t last_fixup_obj_off = 0;
  24.         binder_size_t last_fixup_min_off = 0;
  25.         struct binder_context *context = proc->context;
  26.         int t_debug_id = atomic_inc_return(&binder_last_id);
  27.         ktime_t t_start_time = ktime_get();
  28.         char *secctx = NULL;
  29.         u32 secctx_sz = 0;
  30.         struct list_head sgc_head;
  31.         struct list_head pf_head;
  32.         // 客户端发送来的数据buffer
  33.         const void __user *user_buffer = (const void __user *)
  34.                                 (uintptr_t)tr->data.ptr.buffer;
  35.         INIT_LIST_HEAD(&sgc_head);
  36.         INIT_LIST_HEAD(&pf_head);
  37.         e = binder_transaction_log_add(&binder_transaction_log);
  38.         e->debug_id = t_debug_id;
  39.         e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
  40.         e->from_proc = proc->pid;
  41.         e->from_thread = thread->pid;
  42.         e->target_handle = tr->target.handle;
  43.         e->data_size = tr->data_size;
  44.         e->offsets_size = tr->offsets_size;
  45.         strscpy(e->context_name, proc->context->name, BINDERFS_MAX_NAME);
  46.         binder_inner_proc_lock(proc);
  47.         binder_set_extended_error(&thread->ee, t_debug_id, BR_OK, 0);
  48.         binder_inner_proc_unlock(proc);
  49.         if (reply) {//找到要回复的进程
  50.                 ......
  51.         } else {
  52.             //1. 找到要发送的目的进程
  53.                 if (tr->target.handle) {// tr->target.handle == 0 代表是service_manager进程,否则是其它进程
  54.                         struct binder_ref *ref;
  55.                         /*
  56.                          * There must already be a strong ref
  57.                          * on this node. If so, do a strong
  58.                          * increment on the node to ensure it
  59.                          * stays alive until the transaction is
  60.                          * done.
  61.                          */
  62.                         binder_proc_lock(proc);
  63.                         //根据客户端发送来的handle找到获取binder_ref
  64.                         ref = binder_get_ref_olocked(proc, tr->target.handle,
  65.                                                      true);
  66.                         if (ref) {
  67.                             // 根据binder_ref拿到目的进程的binder_node和binder_proc
  68.                                 target_node = binder_get_node_refs_for_txn(
  69.                                                 ref->node, &target_proc,
  70.                                                 &return_error);
  71.                         } else {
  72.                                 binder_user_error("%d:%d got transaction to invalid handle, %u\n",
  73.                                                   proc->pid, thread->pid, tr->target.handle);
  74.                                 return_error = BR_FAILED_REPLY;
  75.                         }
  76.                         binder_proc_unlock(proc);
  77.                 } else {
  78.                     //处理service_manager进程
  79.                         ......
  80.                 }
  81.                
  82.                 ......
  83.                
  84.                 binder_inner_proc_unlock(proc);
  85.         }
  86.        
  87.         ......
  88.        
  89.         t->work.type = BINDER_WORK_TRANSACTION;
  90.     if (reply) {
  91.                 ......
  92.         } else if (!(t->flags & TF_ONE_WAY)) {
  93.                 BUG_ON(t->buffer->async_transaction != 0);
  94.                 binder_inner_proc_lock(proc);
  95.                 /*
  96.                  * Defer the TRANSACTION_COMPLETE, so we don't return to
  97.                  * userspace immediately; this allows the target process to
  98.                  * immediately start processing this transaction, reducing
  99.                  * latency. We will then return the TRANSACTION_COMPLETE when
  100.                  * the target replies (or there is an error).
  101.                  */
  102.                 binder_enqueue_deferred_thread_work_ilocked(thread, tcomplete);
  103.                 t->need_reply = 1;
  104.                 t->from_parent = thread->transaction_stack;
  105.                 //入栈
  106.                 thread->transaction_stack = t;
  107.                 binder_inner_proc_unlock(proc);
  108.                 //将数据放入目的进程的binder_proc或binder_thread,并唤醒目的进程
  109.                 return_error = binder_proc_transaction(t,
  110.                                 target_proc, target_thread);
  111.                 if (return_error) {
  112.                         binder_inner_proc_lock(proc);
  113.                         binder_pop_transaction_ilocked(thread, t);
  114.                         binder_inner_proc_unlock(proc);
  115.                         goto err_dead_proc_or_thread;
  116.                 }
  117.         } else {
  118.                 ......
  119.         }
复制代码
2.2 服务端被被叫醒,处理客户端发送的数据

服务端的binder_loop函数中有一个死循环,一直在等待数据,如今数据来了,可以开始读取和处理数据了
  1. int main(int argc, char **argv)
  2. {
  3.     int fd;
  4.     struct binder_state *bs;
  5.     uint32_t svcmgr = BINDER_SERVICE_MANAGER;
  6.     uint32_t handle;
  7.         int ret;
  8.     bs = binder_open(128*1024);
  9.     if (!bs) {
  10.         fprintf(stderr, "failed to open binder driver\n");
  11.         return -1;
  12.     }
  13.         /* add service */
  14.         ret = svcmgr_publish(bs, svcmgr, "hello", hello_service_handler);
  15.     if (ret) {
  16.         fprintf(stderr, "failed to publish hello service\n");
  17.         return -1;
  18.     }
  19.         ret = svcmgr_publish(bs, svcmgr, "goodbye", goodbye_service_handler);
  20.     if (ret) {
  21.         fprintf(stderr, "failed to publish goodbye service\n");
  22.     }
  23. #if 0
  24.         while (1)
  25.         {
  26.                 /* read data */
  27.                 /* parse data, and process */
  28.                 /* reply */
  29.         }
  30. #endif
  31.         binder_set_maxthreads(bs, 10);
  32.    
  33.     // 死循环等待读取客户端发送来的数据
  34.     binder_loop(bs, test_server_handler);
  35.     return 0;
  36. }
  37. void binder_loop(struct binder_state *bs, binder_handler func)
  38. {
  39.     int res;
  40.     struct binder_write_read bwr;
  41.     uint32_t readbuf[32];
  42.     bwr.write_size = 0;
  43.     bwr.write_consumed = 0;
  44.     bwr.write_buffer = 0;
  45.     readbuf[0] = BC_ENTER_LOOPER;
  46.     binder_write(bs, readbuf, sizeof(uint32_t));
  47.      
  48.     // 死循环等待读取客户端的数据
  49.     for (;;) {
  50.         bwr.read_size = sizeof(readbuf);
  51.         bwr.read_consumed = 0;
  52.         bwr.read_buffer = (uintptr_t) readbuf;
  53.         // 读取客户端发送来的数据(这个内核源码过程和上面service_manager被唤醒后的过程一样,不再赘述)
  54.         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
  55.         if (res < 0) {
  56.             ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
  57.             break;
  58.         }
  59.         // 解析客户端发送来的数据
  60.         res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
  61.         if (res == 0) {
  62.             ALOGE("binder_loop: unexpected reply?!\n");
  63.             break;
  64.         }
  65.         if (res < 0) {
  66.             ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
  67.             break;
  68.         }
  69.     }
  70. }
  71. int binder_parse(struct binder_state *bs, struct binder_io *bio,
  72.                  uintptr_t ptr, size_t size, binder_handler func)
  73. {
  74.     int r = 1;
  75.     uintptr_t end = ptr + (uintptr_t) size;
  76.     while (ptr < end) {
  77.         uint32_t cmd = *(uint32_t *) ptr;
  78.         ptr += sizeof(uint32_t);
  79. #if TRACE
  80.         fprintf(stderr,"%s:\n", cmd_name(cmd));
  81. #endif
  82.         switch(cmd) {
  83.         ......
  84.         case BR_TRANSACTION: {
  85.             struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
  86.             if ((end - ptr) < sizeof(*txn)) {
  87.                 ALOGE("parse: txn too small!\n");
  88.                 return -1;
  89.             }
  90.             binder_dump_txn(txn);
  91.             if (func) {
  92.                 unsigned rdata[256/4];
  93.                 struct binder_io msg;
  94.                 struct binder_io reply;
  95.                 int res;
  96.                 bio_init(&reply, rdata, sizeof(rdata), 4);
  97.                 bio_init_from_txn(&msg, txn);
  98.                 // 这里的msg就是客户端发送来的数据,func是服务端的函数test_server_handler
  99.                 res = func(bs, txn, &msg, &reply);
  100.                 binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
  101.             }
  102.             ptr += sizeof(*txn);
  103.             break;
  104.         }
  105.         ......
  106.         }
  107.     }
  108.     return r;
  109. }
  110. int test_server_handler(struct binder_state *bs,
  111.                    struct binder_transaction_data *txn,
  112.                    struct binder_io *msg,
  113.                    struct binder_io *reply)
  114. {
  115.         int (*handler)(struct binder_state *bs,
  116.                    struct binder_transaction_data *txn,
  117.                    struct binder_io *msg,
  118.                    struct binder_io *reply);
  119.         handler = (int (*)(struct binder_state *bs,
  120.                    struct binder_transaction_data *txn,
  121.                    struct binder_io *msg,
  122.                    struct binder_io *reply))txn->target.ptr; // 服务端的函数指针,在向service_manager注册服务的时候写入的,此处是hello_service_handler
  123.        
  124.         return handler(bs, txn, msg, reply);
  125. }
  126. int hello_service_handler(struct binder_state *bs,
  127.                    struct binder_transaction_data *txn,
  128.                    struct binder_io *msg,
  129.                    struct binder_io *reply)
  130. {
  131.         /* 根据txn->code知道要调用哪一个函数
  132.          * 如果需要参数, 可以从msg取出
  133.          * 如果要返回结果, 可以把结果放入reply
  134.          */
  135.         /* sayhello
  136.          * sayhello_to
  137.          */
  138.        
  139.     uint16_t *s;
  140.         char name[512];
  141.     size_t len;
  142.     uint32_t handle;
  143.     uint32_t strict_policy;
  144.         int i;
  145.     // Equivalent to Parcel::enforceInterface(), reading the RPC
  146.     // header with the strict mode policy mask and the interface name.
  147.     // Note that we ignore the strict_policy and don't propagate it
  148.     // further (since we do no outbound RPCs anyway).
  149.     strict_policy = bio_get_uint32(msg);
  150.     switch(txn->code) {
  151.     case HELLO_SVR_CMD_SAYHELLO:
  152.                 sayhello();
  153.                 bio_put_uint32(reply, 0); /* no exception */
  154.         return 0;
  155.     case HELLO_SVR_CMD_SAYHELLO_TO:
  156.                 /* 从msg里取出字符串 */
  157.                 s = bio_get_string16(msg, &len);  //"IHelloService"
  158.                 s = bio_get_string16(msg, &len);  // name
  159.                 if (s == NULL) {
  160.                         return -1;
  161.                 }
  162.                 for (i = 0; i < len; i++)
  163.                         name[i] = s[i];
  164.                 name[i] = '\0';
  165.                 /* 调用服务函数处理客户端的数据 */
  166.                 i = sayhello_to(name);
  167.                 /* 把结果放入reply */
  168.                 bio_put_uint32(reply, 0); /* no exception */
  169.                 bio_put_uint32(reply, i);
  170.                
  171.         break;
  172.     default:
  173.         fprintf(stderr, "unknown code %d\n", txn->code);
  174.         return -1;
  175.     }
  176.     return 0;
  177. }
复制代码
2.3 客户端收到服务端处理的数据

从reply中获取服务端处理后的数据
  1. int sayhello_to(char *name)
  2. {
  3.         unsigned iodata[512/4];
  4.         struct binder_io msg, reply;
  5.         int ret;
  6.         int exception;
  7.         /* 构造binder_io */
  8.         bio_init(&msg, iodata, sizeof(iodata), 4);
  9.         bio_put_uint32(&msg, 0);  // strict mode header
  10.     bio_put_string16_x(&msg, "IHelloService");
  11.         /* 放入参数 */
  12.     bio_put_string16_x(&msg, name);
  13.         /* 调用binder_call */
  14.         if (binder_call(g_bs, &msg, &reply, g_hello_handle, HELLO_SVR_CMD_SAYHELLO_TO))
  15.                 return 0;
  16.        
  17.         /* 从reply中解析出返回值 */
  18.         exception = bio_get_uint32(&reply);
  19.         if (exception)
  20.                 ret = -1;
  21.         else
  22.                 ret = bio_get_uint32(&reply);
  23.         binder_done(g_bs, &msg, &reply);
  24.         return ret;
  25.        
  26. }
复制代码
三、后记

自此,我们通过三篇文章完成了Binder跨进程通信的源码分析,我们深入内核去分析Binder跨进程通信实现的源码,相信通过这三篇文章,我们已经非常深入地明白了Binder跨进程通信的实现方案。其实内核的源码我们只是分析了大概,更加细节的源码没有深入分析,但我相信有了如今的基础,我们再独立去更深入的分析内核源码,应该会轻松不少,至少不会像无头苍蝇一下,无从动手。
说实话,Android Binder的内核源码分析,我自以为写的不是很好,另有很多改善空间,另有很多没有讲清楚的地方,背面我也会不停加强自己的技术本领,希望未来有一天,我会再重新写一篇更加普通易懂的Binder驱动内核源码分析。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

刘俊凯

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表