注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

民主与科学

独立之人格,自由之思想

 
 
 

日志

 
 

Binder驱动中的基本结构体  

2012-06-09 17:53:08|  分类: 深入研究 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
本文编辑整理自:http://hi.baidu.com/tianylj/blog/item/7b99f42abeb77d81023bf636.html
一、前言
  现代操作系统里,一个进程的地址空间是确定的,地址是没有二义性的,进程里的一个指针就对应一个内存地址,不可能同时对应到多个地址,给定一个指针,就能获得想要的东西。但跨进程的情况下,事情就完全不一样了,不同进程的线性地址空间都是一样的,一个进程里的指针放到另一个进程里,就是完全不同的东西了。要实现跨进程的指针,就必须通过操作系统层,只有在系统底层才能将一个进程里的地址映射到另一个进程里的地址,这也就是Binder驱动所做的事情。
      对于Binder实体,在本地进程里来看,很简单,用他自己的一个指针就能表示,但是从驱动角度来看,光一个进程内指针是不够的,驱动需要区分所有进程的指针,必须再加上一个参数,由于进程本身是操作系统独一无二的,所以驱动里用进程和进程中的内指针这两个参数就能唯一代表一个Binder实体。加上一些附带的信息,驱动用struct binder_node结构来指向Binder实体,我们暂称为‘Binder实体节点’或Binder节点对于Binder实体在远程进程中的引用,在驱动里也是用二元组来表示的,第一维依旧是进程,驱动必须知道这个表示是为哪个远程进程维护的,第二维是一个数,一个32位标识uint32_t desc它是一个从0开始编排的数字,它只跟这个binder在这个进程中的出场顺序有关,进程中出现的第一个非本地(远程)的binder被记住0,第二个被记住1,以此类推,跟这个binder实际所在的进程,实际的指针都没关系。另外,一个进程里的所有Binder节点引用uint32_t desc都是统一排序的。加上一些附带信息,对于binder在远程进程中的表示,驱动struct binder_ref结构体来表示,我们暂称它为驱动中的Binder引用Binder节点引用Binder节点引用中有一个指向Binder实体节点指针node。通过该指针Binder节点引用就和Binder实体节联系起来了。因为对于一个Binder实体节,在一个进程中最多只有一个Binder节点引用指向它,所以对于一个进程,确定了指向Binder实体节点指针node就能确定,也能确定一个Binder节点引用
   如果对于Binder驱动中的基本结构体,不能很好的理解;那么要理解整个Binder驱动就非常困难。
因此,写本文来对Binder驱动中的基本结构体做些归纳和总结。
二、结构体binder_proc
 首先,binder_proc这个结构体得能表示一个进程以及记录一个进程的资源,成员变量pid, tsk, files就是用来干这些的,另外还有threads和page, buffer之类的成员也是用来表示进程资源的,不过他们还有其他用途。其次,既然进程在两种存在方式里都是第一维,那么通过它,我们应该能够得到进程所有的binder(本地的以及远程的),他的nodes, refs_by_desc, refs_by_node就是用来实现这个的,这三个都是红黑树根节点。debugfs_entry对应于proc文件/proc/binder/proc/pid。
binder_proc结构体定义各成员变量的含义如下表所示
表1

struct hlist_node proc_node 

                                                                                                                        

 struct rb_root threads

 

 struct rb_root nodes

它是Binder节点ptr域为索引用来挂载该进程所有Binder节点的红黑树的根节点。

 struct rb_root refs_by_desc

它是以Binder节点引用desc域为索引来挂载该进程所有Binder节点引用的红黑树的根节点

 struct rb_root refs_by_node

 它是Binder节点引用node域为索引来挂载该进程所有Binder节点引用的红黑树的根节点

 int pid

 进程ID

 struct vm_area_struct *vma

 

 struct task_struct *tsk

 

 struct files_struct *files

 

 struct hlist_node deferred_work_node

 

 int deferred_work

 

 void *buffer

 

 ptrdiff_t user_buffer_offset

 

 struct list_head buffers;

 

 struct rb_root free_buffers

 

 struct rb_root allocated_buffers;

 

 size_t free_async_space

 

 struct page **pages

 

 size_t buffer_size

 

 uint32_t buffer_free

 

 struct list_head todo

 

 wait_queue_head_t wait

 

 struct binder_stats stats

 

 struct list_head delivered_death

 

 int max_threads

 

 int requested_threads;

 

 int requested_threads_started

 

 int ready_threads

 

 long default_priority

 

 struct dentry *debugfs_entry

 对应于proc文件/proc/binder/proc/pid

三、结构体binder_node
  驱动用struct binder_node结构来指向Binder实体,我们暂称它为‘Binder实体节点’或Binder节点,通过这个结构体能找到binder所在进程,也能找到binder在这个进程里的指针。
关于binder_node结构体定义各成员变量的含义请参照《Binder的表述形式》中的表三
四、结构体binder_ref
  驱动用struct binder_ref结构来指向Binder节点我们暂称它为Binder节点引用.
关于binder_node结构体定义各成员变量的含义请参照《Binder的表述形式》中的表四
五、相关函数
下面列几个相关的函数,以下省略struct关键字。
1.binder_node* binder_get_node(binder_proc *proc, void __user *ptr)给定ptr(binder_node中的ptr)和进程proc,在proc的nodes树中查找并获取binder_node结构,如果这个proc的这个指针在驱动里还没有建立本地binder,则返回null。
2. binder_node* binder_new_node(binder_proc *proc, void __user *ptr, void __user *cookie)
给定ptr和cookie以及进程proc,在驱动中创建该指针的本地binder项,并添加到proc的nodes树中。
3. binder_ref *binder_get_ref(binder_proc *proc, uint32_t desc)
给定desc和proc,获取远程binder的表示binder_desc,如果没有则返回null。
4. binder_ref *binder_get_ref_for_node(binder_proc *proc, binder_node *node)
给定proc和node,获取某个本地binder在该proc进程里的远程表示,如果该本地binder在该proc中还没有建立远程表示,则创建它并返回。此函数会用到并可能更新proc的refs_by_desc, refs_by_node树以及node的refs链表。
5. binder_delete_ref(binder_ref *ref)
删除给定的远程binder。并不存在binder_delete_node函数,node的删除是在node的引用计数减到0时发生的,被整合到了binder_dec_node函数。结束!
  评论这张
 
阅读(932)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017