Binder驱动情景分析
2017-12-09 11:14
381 查看
Handle是client对服务器进程服务Service的引用。就相当于fd号对于文件。
client向服务器进程请求多个服务时,对于每一个服务会返回不同的Handle。
client会调用binder_call->ioctl利用handle号进入驱动程序找到目的进程,在驱动程序的内部会维护一个结构体描述引用无非不就是:在这个结构体里加入一个号等于这个Handle,这样只要搜寻这些结构体的desc值就可以找到这个结构体。
名字叫做struct binder_ref,内核里用这个结构体描述对服务的引用即handle,服务这个东西用binder_node表示。binder_ref中有一项指向binder_node。个人理解一个结构体就是一个对象,ref就是handle对象,node就是服务对象。handle对象包含node对象。服务属于那个进程,同样它可以包含一个描述进程的对象叫做binder_proc结构体。
而进程这个对象必定管理多个服务即binder_node。它会维护一个服务链表。并且维护一个红黑树在这个进程下创建多个线程。以应对对各应用程序。每一个线程对应一个binder_thread结构体。
server为每一个service创建一个binder_node结构体(内核态)驱动做
service_manager创建struct binder_ref(内核态)
binder_thread用于表示一个线程
多个client程序会向进程server请求服务, 会创建多个线程为client提供服务,每一个线程都有一个binder_thread结构体。就是说可以通过这个结构体找到对应的线程。往进程的todo写数据,然后唤醒线程。
由应用程序发给驱动程序的数据binder_call调用ioctl调到驱动层
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{ switch (cmd) {
case BINDER_WRITE_READ: {
binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
写哪个进程那个线程
里面调用get_user(cmd, (uint32_t __user *)ptr)
case BC_TRANSACTION:
case BC_REPLY: {
struct binder_transaction_data tr;
if (copy_from_user(&tr, ptr, sizeof(tr)))////////////////从用户空间把数据复制到内核
return -EFAULT;
ptr += sizeof(tr);
binder_transaction(proc, thread, &tr, cmd == BC_REPLY);/////////////发送
break;
}
有服务端发给应用程序的数据
r.data_size = t->buffer->data_size;
tr.offsets_size = t->buffer->offsets_size;
tr.data.ptr.buffer = (void *)t->buffer->data +
proc->user_buffer_offset;/////////////////////////////////数据头并不是数据本身,数据本身只执行一次拷贝。数据头执行两次拷贝。
tr.data.ptr.offsets = tr.data.ptr.buffer +
ALIGN(t->buffer->data_size,
sizeof(void *));
if (put_user(cmd, (uint32_t __user *)ptr))
client向服务器进程请求多个服务时,对于每一个服务会返回不同的Handle。
client会调用binder_call->ioctl利用handle号进入驱动程序找到目的进程,在驱动程序的内部会维护一个结构体描述引用无非不就是:在这个结构体里加入一个号等于这个Handle,这样只要搜寻这些结构体的desc值就可以找到这个结构体。
名字叫做struct binder_ref,内核里用这个结构体描述对服务的引用即handle,服务这个东西用binder_node表示。binder_ref中有一项指向binder_node。个人理解一个结构体就是一个对象,ref就是handle对象,node就是服务对象。handle对象包含node对象。服务属于那个进程,同样它可以包含一个描述进程的对象叫做binder_proc结构体。
而进程这个对象必定管理多个服务即binder_node。它会维护一个服务链表。并且维护一个红黑树在这个进程下创建多个线程。以应对对各应用程序。每一个线程对应一个binder_thread结构体。
server为每一个service创建一个binder_node结构体(内核态)驱动做
service_manager创建struct binder_ref(内核态)
binder_thread用于表示一个线程
多个client程序会向进程server请求服务, 会创建多个线程为client提供服务,每一个线程都有一个binder_thread结构体。就是说可以通过这个结构体找到对应的线程。往进程的todo写数据,然后唤醒线程。
由应用程序发给驱动程序的数据binder_call调用ioctl调到驱动层
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{ switch (cmd) {
case BINDER_WRITE_READ: {
binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
写哪个进程那个线程
里面调用get_user(cmd, (uint32_t __user *)ptr)
case BC_TRANSACTION:
case BC_REPLY: {
struct binder_transaction_data tr;
if (copy_from_user(&tr, ptr, sizeof(tr)))////////////////从用户空间把数据复制到内核
return -EFAULT;
ptr += sizeof(tr);
binder_transaction(proc, thread, &tr, cmd == BC_REPLY);/////////////发送
break;
}
有服务端发给应用程序的数据
r.data_size = t->buffer->data_size;
tr.offsets_size = t->buffer->offsets_size;
tr.data.ptr.buffer = (void *)t->buffer->data +
proc->user_buffer_offset;/////////////////////////////////数据头并不是数据本身,数据本身只执行一次拷贝。数据头执行两次拷贝。
tr.data.ptr.offsets = tr.data.ptr.buffer +
ALIGN(t->buffer->data_size,
sizeof(void *));
if (put_user(cmd, (uint32_t __user *)ptr))
相关文章推荐
- Android系统--Binder系统具体框架分析(二)Binder驱动情景分析
- Android系统--Binder系统具体框架分析(二)Binder驱动情景分析
- Linux 2.6.11 MTD驱动情景分析
- 字符设备驱动之笔记-中断处理过程情景分析
- I2C驱动情景分析——怎样增加I2C设备
- I2C驱动情景分析——怎样增加I2C设备
- 深入分析Android Binder 驱动
- Linux 2.6.11 MTD驱动情景分析[转]
- I2C驱动情景分析——怎样增加I2C设备
- I2C驱动情景分析——怎样控制I2C时序
- Android Binder 驱动分析 - 数据结构
- Linux 2.6.11 MTD驱动情景分析
- 深入分析Android Binder 驱动
- Binder 驱动分析C(一)示例代码
- Linux 2.6.11 MTD驱动情景分析
- Android Binder 驱动分析1
- android binder驱动源码分析(一)
- Android Binder 驱动分析 - 数据结构
- Android Binder驱动分析2
- android binder驱动源码分析(二)