Android-Framework:Binder全解析(一,Android小程序开发实例

本文深入探讨了Android中的Binder机制,包括Binder原理、为何选择Binder、Binder如何减少内存拷贝提升性能、以及Binder在Android系统中的角色。文章通过MediaServer服务注册的实例,详细解析了Binder的注册流程,涉及ProcessState、open_driver、mmap等关键步骤,揭示了Binder如何实现跨进程通信并确保系统安全和稳定性。
摘要由CSDN通过智能技术生成

为了保护用户进程不能直接操作内核,保证内核的安全,操作系统从逻辑上将虚拟空间划分为用户空间和内核空间。Linux 操作系统将最高的1GB字节供内核使用,称为内核空间,较低的3GB 字节供各进程使用,称为用户空间。

内核空间是Linux内核的运行空间,用户空间是用户程序的运行空间。为了安全,它们是隔离的,即使用户的程序崩溃了,内核也不会受到影响。内核空间的数据是可以进程间共享的,而用户空间则不可以。

那万一用户空间需要用到内核空间的数据或者需要访问内核空间怎么办呢?那这就需要借助系统调用了。系统调用是用户空间访问内核空间的唯一方式,保证了所有的资源访问都是在内核的控制下进行的,避免了用户程序对系统资源的越权访问,提升了系统安全性和稳定性。

好,基本知识了解了,我们看一下Linux上IPC是怎么实现的。

首先发送进程通过copy_from_user方法将发送的数据发送到内核缓存区,这期间会发生一次内存拷贝。

然后内核空间再通过copy_to_user方法将发送进程发送的数据传给接收进程,这期间会再一次发生内存拷贝。注意这两个方法是关键:

  • copy_from_user:将用户空间的数据拷贝到内核空间。
  • copy_to_user:将内核空间的数据拷贝到用户空间。

这就完成了一次跨进程通信,是不是感觉很简单?没错,确实不复杂,但是这个方式有两个问题,就是发送一次数据需要内存拷贝两次。第二个就是接收进程不知道发送进程要发送多大的数据,所以只能尽可能地往大了开辟内存或者事先在读取一次消息头来知晓数据大小,不是浪费空间就是浪费时间。那么Binder是怎么解决这个问题的呢?

Binder原理

emmmm看不懂,什么是映射?这都是啥?

先来讲一下这个映射,什么是映射呢?映射就是内存映射(mmap),是一种内存映射文件的方法,即将一个文件或者其他对象映射到进程的地址空间,实现文件磁盘地址和应用程序进程虚拟地址空间中一段虚拟地址的一一映射关系。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。

说得好,不过什么意思?

简单地说就是存在映射关系的双方,只要修改其中一方的内容,另一方也会发生改变。这个实现的手段是通过mmap方法来实现的。

**Binder没有物理介质,Binder是基于内存映射来实现的。**Binder这么做目的就是为了跨进程通信。如上图

  1. Binder首先在内核空间创建了一个内核缓存区,然后又创建了一个数据接收缓存区。然后将内核缓存区和数据接收缓存区进行映射。

  2. Binder再将接收缓存区和接收进程的用户空间地址建立映射关系。

  3. 发送进程通过copy_from_user发送了数据到内核缓存区,这里进行了一次内存拷贝。由于映射关系的存在,数据立马被同步到了接收进程的内存空间。完成跨进程通信。整个过程只进行了一次内存拷贝。

哇塞,看起来好像是这样啊。Google果然是牛X,这么好的方法都能想得到,Linux发展这么多年怎么搞不出来Binder呢?其实也不是,Linux上也很早就有Binder了,Android系统之所以采用Binder机制来进行跨进程通信是有原因的。

Android为什么使用Binder

  1. 性能上 Binder内存拷贝只需要一次,除了共享内存一次也不需要以外,Binder的性能是最高的。

  2. 稳定性 Binder是基于C/S架构的,这个架构通常采用两层结构,在技术上已经很成熟了,稳定性是没有问题的。共享内存没有分层,难以控制,并发同步访问临界资源时,可能还会产生死锁。从稳定性的角度讲,Binder是优于共享内存的。

  3. 安全 传统Linux IPC的接收方无法获得对方进程可靠的UID/PID,从而无法鉴别对方身份;而Android作为一个开放的开源体系,拥有非常多的开发平台,App来源甚广,因此手机的安全显得额外重要;对于普通用户,绝不希望从App商店下载偷窥隐射数据、后台造成手机耗电等等问题,传统Linux IPC无任何保护措施,完全由上层协议来确保。Android系统中对外只暴露Client端,Client端将任务发送给Server端,Server端会根据权限控制策略,判断UID/PID是否满足访问权限,目前权限控制很多时候是通过弹出权限询问对话框,让用户选择是否运行

  4. 语言 Linux是基于C语言(面向过程的语言),而Android是基于Java语言(面向对象的语句),而对于Binder恰恰也符合面向对象的思想,将进程间通信转化为通过对某个Binder对象的引用调用该对象的方法,而其独特之处在于Binder对象是一个可以跨进程引用的对象,它的实体位于一个进程中,而它的引用却遍布于系统的各个进程之中

  5. 开源协议 Linux内核是开源的系统,所开放源代码许可协议GPL保护。该协议具有“病毒式感染”的能力,只要进行了系统调用,调用到内核,那么也必须遵守GPL开源协议。Android 之父 Andy Rubin对于GPL显然是不能接受的,为此,Google巧妙地将GPL协议控制在内核空间,将用户空间的协议采用Apache-2.0协议。同时在GPL协议与Apache-2.0之间的Lib库中采用BSD证授权方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值