0%

Android系统Binder驱动分析(2)

引言

我的文章比较多是对自己知识的梳理,有些概念没讲得那么清楚,但会贴出参考的链接,请大家自便

Binder 概述

基础概念

IPC : Inter-Process Communication (进程间的通信)
RPC : Remote Procedure Call (远程过程调用)
RPC是IPC的基础上进行了封装

简单例子: 大致有个概念

再简单的分析下要素 (led是例子)

1
2
3
4
5
A(①封装数据 ②发送给B) ===>(IPC) B(①取出数据 @调用数据) 
源 : A
目的 B 先向 ServerManger注册led服务
A 向 ServerManger 查询led服务,得到一个Handler
数据:char_Buff -->

Binder究竟是什么#

Binder是Android系统中负责每个用户进程内核通信的驱动模块。

Binder的优势

推荐文章
主要是基于性能、稳定性和安全性几方面的原因。

性能

IPC 数据拷贝次数 MORE
共享内存 0
Binder 1
Socket 2
管道 2
消息队列 2

稳定性

Binder 基于 C/S 架构,架构清晰、职责明确又相互独立

安全性

传统的 IPC 没有任何安全措施,完全依赖上层协议来确保。
首先传统的 IPC 接收方无法获得对方可靠的进程用户ID/进程ID(UID/PID),从而无法鉴别对方身份。
Android 为每个安装好的 APP 分配了自己的 UID,故而进程的 UID 是鉴别进程身份的重要标志。

传统的 IPC 只能由用户在数据包中填入 UID/PID,但这样不可靠,容易被恶意程序利用。
可靠的身份标识只有由 IPC 机制在内核中添加。其次传统的 IPC 访问接入点是开放的,只要知道这些接入点的程序都可以和对端建立连接,不管怎样都无法阻止恶意程序通过猜测接收方地址获得连接。同时 Binder 既支持实名 Binder,又支持匿名 Binder,安全性高。

IPC

以下对比 Binder IPC 对比 传统IPC 的区别

Linux 下的传统 IPC 通信原理

Linux传统 IPC

这种传统的 IPC 通信方式有两个问题:

性能低下,一次数据传递需要经历:内存缓存区 –> 内核缓存区 –> 内存缓存区,需要 2 次数据拷贝;
接收数据的缓存区由数据接收进程提供,但是接收进程并不知道需要多大的空间来存放将要传递过来的数据,因此只能开辟尽可能大的内存空间或者先调用 API 接收消息头来获取消息体的大小,这两种做法不是浪费空间就是浪费时间。

专栏:Android十万个为什么

什么是实名Binder?

什么是匿名Binder?

“内核缓存区” 和 “数据接收缓存区” 存在的意义

Linux是使用的虚拟内存寻址方式,虚拟内存需要映射一块真的的物理内存,
内核缓存区和数据接收区的映射就是指向了同一块物理内存。接收方下次也可能是发送方,如果共用一块缓存那么岂不是发送方,内核,接收方都指向了同一块物理内存,违反了进程隔离的设计原则。