Android Framework-Binder

113 阅读4分钟

什么是 Binder

Binder 是 Android 系统中进程间通信机制(IPC)的一种方式。Binder基于C/S架构。
-   Client:是对 Binder 代理对象,是 Binder 实体对象的一个远程代理。
-   Server:是 Server 中的 Binder 实体对象。

Binder机制是如何跨进程的

1.Binder驱动在内核空间创建一块接收缓存区,将内核缓存区、接收进程用户空间映射到同一接收缓存区

2.发送进程通过系统调用(copy_from_user)将数据发送到内核缓存区。由于内核缓存区和接收进程用户空间存在映射关系,故相当于也发送了接收进程的用户空间,实现了跨进程通信。

Binder特点

标题Binder共享内存Socket
性能一次拷贝无需拷贝两次拷贝
特点基于C/S架构,易用性高控制复杂,易用性差基于C/S架构,通用接口,传输效率低、开销大
安全每个APP分配UID,同时支持实名和匿名依赖上层协议,访问接入点是开放的不安全依赖上层协议,访问接入点是开放的不安全

Binder是如何做到一次拷贝的

主要是因为Linux是使用的虚拟内存寻址方式,它有如下特性:

用户空间的虚拟内存地址是映射到物理内存中的对虚拟内存的读写实际上是对物理内存的读写,这个过程就是内存映射这个内存映射过程是通过系统调用mmap()来实现的Binder借助了内存映射的方法,在内核空间和接收方用户空间的数据缓存区之间做了一层内存映射,就相当于直接拷贝到了接收方用户空间的数据缓存区,从而减少了一次数据拷贝

Binder传输数据的大小限制?

对于内核可以传输的是4M,但是应用层限制在1M-8K范围内

MMAP的内存映射原理

(一)进程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域 1.进程在用户空间调用库函数mmap,原型:void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);

2.在当前进程的虚拟地址空间中,寻找一段空闲的满足要求的连续的虚拟地址

3.为此虚拟区分配一个vm_area_struct结构,接着对这个结构的各个域进行了初始化

4.将新建的虚拟区结构(vm_area_struct)插入进程的虚拟地址区域链表或树中

(二)调用内核空间的系统调用函数mmap(不同于用户空间函数),实现文件物理地址和进程虚拟地址的一一映射关系 5.为映射分配了新的虚拟地址区域后,通过待映射的文件指针,在文件描述符表中找到对应的文件描述符,通过文件描述符,链接到内核“已打开文件集”中该文件的文件结构体(struct file),每个文件结构体维护着和这个已打开文件相关各项信息。

6.通过该文件的文件结构体,链接到file_operations模块,调用内核函数mmap,其原型为:int mmap(struct file *filp, struct vm_area_struct *vma),不同于用户空间库函数。

7.内核mmap函数通过虚拟文件系统inode模块定位到文件磁盘物理地址。

8.通过remap_pfn_range函数建立页表,即实现了文件地址和虚拟地址区域的映射关系。此时,这片虚拟地址并没有任何数据关联到主存中。

(三)进程发起对这片映射空间的访问,引发缺页异常,实现文件内容到物理内存(主存)的拷贝 注:前两个阶段仅在于创建虚拟区间并完成地址映射,但是并没有将任何文件数据的拷贝至主存。真正的文件读取是当进程发起读或写操作时。

9.进程的读或写操作访问虚拟地址空间这一段映射地址,通过查询页表,发现这一段地址并不在物理页面上。因为目前只建立了地址映射,真正的硬盘数据还没有拷贝到内存中,因此引发缺页异常。

10.缺页异常进行一系列判断,确定无非法操作后,内核发起请求调页过程。

11.调页过程先在交换缓存空间(swap cache)中寻找需要访问的内存页,如果没有则调用nopage函数把所缺的页从磁盘装入到主存中。

12.之后进程即可对这片主存进行读或者写的操作,如果写操作改变了其内容,一定时间后系统会自动回写脏页面到对应磁盘地址,也即完成了写入到文件的过程

注:修改过的脏页面并不会立即更新回文件中,而是有一段时间的延迟,可以调用msync()来强

制同步, 这样所写的内容就能立即保存到文件里了。

## mmap()优缺点总结