一、总体概述
Binder 采用的是 CS 服务的机制,提供服务的成为 Server 进程而访问服务的进程成为
Client 进程。同一个 Server 进程可以同时运行多个组件来向 Client 进程提供服务,这些组件
称为 Service 组件;同时一个 Client 进程也可以同时向多个 Service 组件请求服务,每次请求
都对应一个 Cilent 组件。Server 进程和 Client 进程之间的通信要依靠运行在内核控件的
Binder 驱动程序来进行,Binder 驱动程序向用户控件暴露了一个设备文件/dev/binder,使
得应用程序进程可以间接的通过它来建立通信信道。Service 组件在启动时,会将自己注册
到 一 个 ServiceManager 中 , 以 便 Client 组 件 通 过 ServiceManager 来 找 到 他 , 可 以 说
ServiceManager 是一个上下文的管理者。
二、基础数据结构
binder_work:表示一个工作项
binder_node:表示一个 Binder 实体对象,每一个 Service 组件在 Binder 驱动程序中都对应
一个 Binder 实体对象,用来描述他在内核中的状态,Binder 驱动程序通过强引计数和弱引
用计数来维护它的生命周期。它是存在一个宿主进程中的,宿主进程中用一个红黑树来维
护它内部所有的 Binder 实体对象,它可能会被多个 Client 组件所引用,所以它内部使用一
个 hash 列表来保存引用了它的 Binder 引用对象。它内部的成员变量 ptr 和 cookie 用来描述
一个用户空间的 Service 组件。
binder_ref:表示一个 Binder 引用对象,每一个 Client 组件在 Binder 驱动程序中都对应一个
Binder 引用对象,用来描述它在内核中的状态,Binder 驱动程序通过强引计数和弱引用计
数来维护它的生命周期。成员变量 node 是用来描述一个 Binder 引用对象所引用的 Binder
实体对象的。binder_ref 内部有一个 desc 变量是一个描述符,在 Client 进程的用户空间中,
一个 Binder 引用对象是使用一个句柄值来描述的。当 Client 进程的用户空间通过 Binder 驱
动来访问一个 Service 组件时,只需要指定一个句柄值,通过它来找到 Binder 引用对象,在
从上面提到的 node 中就可以找到对应的实体对象,然后就可以通过实体对象找到要访问的
Service 组件。
binder_buer:用来描述一个内核缓冲区,它是用来在进程间传递数据的。每一个使用
Binder 进程间通讯机制的进程在 Binder 驱动程序中都有一个内核缓冲区列表,用来保存
Binder 驱动程序为它所分配的内核缓冲区,而这个成员变量 entry 正是这个内核缓冲区列表
中的一个节点。同时进程有使用了两个红黑树分别保存正在使用的内核缓冲区和空闲的内
核缓冲区。
transacon 和 target_node 事用来描述一个内核缓冲区正在交给哪个事物以及哪一个 Binder
实体来使用。
binder_proc:用来描述一个正在使用 Binder 进程间通信机制的进程。当一个进程调用函数
open 来打开设备文件/dev/binder 是,Binder 驱动程序就会为它创建一个 binder_proc 结构
体,并且将它保存在一个全局的 hash 列表中,而成员变量 proc_node 就正好是该 hash 列表
中的一个节点。进程打开了设备文件/dev/binder 后,还必须调用 mmap 将它映射到进程的
地址空间中来,实际上是请求 Binder 驱动程序为它分配一块内核缓冲区,以便可以用来进
程间传输数据。这些内核缓冲区实际上有两个地址,其中一个是内核空间地址,另一个是
用户空间地址,内核控件地址是在 Binder 驱动程序内部使用的,保存在 buer 中而用户空
间是在应用程序进程中使用的,保存在成员变量 vma 中,这两个地址相差一个固定的保存
下来的值,给定一个就可以计算出另一个的大小。他们实际上都是虚拟内存,对应的真正
的物理内存保存在成员变量 pages 中,只有分配一个物理页面不够时才分配新的。
成员变量 buer 指向的是一个大的内核缓冲区,Binder 驱动为了方便对它的管理,把
评论0