Binder系列4 Binder传输原理之请求发起

一 Binder是如何做到精确打击的?

我们先问一个问题,Binder 机制到底是如何从代理对象 BpBinder 找到其对应的 Binder 实体呢?难道它有某种制导装置吗?要回答这个问题,我们只能静下心来研究 Binder 驱动的代码。在 Binder系列2 Binder概念及相关接口和类 中,我们曾经介绍过 ProcessState,这个结构是属于应用层次的东西,仅靠它当然无法完成精确打击。其实在 Binder 驱动层,还有个与之相对应的结构,叫做 binder_proc。为了说明问题,我修改了系列2中的示意图,得到下图:
在这里插入图片描述

1.1 创建binder_proc

在系列2中我们知道当构造 ProcessState 并打开 Binder 驱动之时,会调用到驱动层的 binder_open() 函数,而 binder_proc 就是在 binder_open() 函数中创建的。新创建的 binder_proc 会作为一个节点,插入一个总链表 binder_procs 中。binder_open() 函数在系列3介绍SMgr 中已经介绍过了,咱们再次回顾下,具体代码可参考 kernel/drivers/staging/android/Binder.c。

驱动层的 binder_open() 的代码如下:

static int binder_open(struct inode *nodp, struct file *filp)
{
   
	struct binder_proc *proc; //对应的进程结构体
	struct binder_device *binder_dev;//对应的binder_device
	........
	proc = kzalloc(sizeof(*proc), GFP_KERNEL);//在驱动层创建binder_proc
	........
	INIT_LIST_HEAD(&proc->todo); //初始化进程的todo等待队列
	........
   //获取binder_device,这个binder_device在Binder驱动初始化的时候生成
	binder_dev = container_of(filp->private_data, struct binder_device,
				  miscdev);
    //每个进程的context都对应着同一个binder_dev的context
	proc->context = &binder_dev->context;
	binder_alloc_init(&proc->alloc);
 
	binder_stats_created(BINDER_STAT_PROC);
	proc->pid = current->group_leader->pid;
	INIT_LIST_HEAD(&proc->delivered_death);
	INIT_LIST_HEAD(&proc->waiting_threads);
    //把代表当前进程的binder_proc赋值给filp的private_data
    //这个非常重要,以后Binder驱动就是根据这个域找到对应的是哪个进程的.
	filp->private_data = proc;
 
	mutex_lock(&binder_procs_lock);
    //把这个binder_proc链入到全局的 binder_procs中
	hlist_add_head(&proc->proc_node, &binder_procs);
	mutex_unlock(&binder_procs_lock);
	........
	return 0;
}

注意,新创建的 binder_proc 会被记录在参数 filp 的 private_data 域中,以后每次执行 binder_ioctl(),都会从 filp->private_data 域重新读取 binder_proc 的。

binder_procs 总表的定义如下:

static HLIST_HEAD(binder_procs);

我们可以在List.h中看到 HLIST_HEAD 的定义:

tools/include/linux/list.h

#define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }

于是 binder_procs 的定义相当于:

struct hlist_head binder_procs  = {
    .first = NULL };

随着后续不断向 binder_procs 表中添加节点,这个表会不断加长,示意图如下:
在这里插入图片描述

1.2 binder_proc中的4棵红黑树

binder_proc 里含有很多重要内容,不过目前我们只需关心其中的几个域:

struct binder_proc {
   
	struct hlist_node proc_node;//用于链接binder_proc到binder_procs中
	struct rb_root threads;//Binder线程树,一系列binder_thread的集合
	struct rb_root nodes;//Binder节点树,一系列binder_node的集合
	struct rb_root refs_by_desc;//引用树,用句柄做索引,一系列binder_ref的集合
	struct rb_root refs_by_node;//引用树,用binder_node做索引,一系列binder_ref的集合
	struct list_head waiting_threads;
	int pid;
	struct task_struct *tsk;
	struct hlist_node deferred_work_node;
	int deferred_work;
	bool is_dead;

	struct list_head todo;
	struct binder_stats stats;
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值