当前位置:网站首页>Binder机制详解(一)
Binder机制详解(一)
2022-08-02 03:27:00 【浮空over】
系列目录
文章目录
前言
Binder通信机制是android中不同于Linux的通信机制,那么为什么会有Binder通信机制,为什么不能用linux中已有的进程框架呢?Google工程师究竟是如何考量的?这一切需要从一场恋爱说起
一、爱情例子
1.普通Linux间进程通信方式
故事:男孩和女孩在某次旅游一见钟情,而旅行结束的他们不得不返回各自的工作城市,那个时代还没有微信,由于相隔在不同的城市。相思念的他们只能通过邮局抒发彼此爱慕之情
如果男孩想要给女孩发送信封,需要向本地邮局 寄信。再有全国邮局转发到 女孩所在的本地邮局
最后由女孩所在的本地邮局送到女孩手中
故事中在进程中的角色:
男孩** 称为进程A,工作城市A城,女孩称为进程B,工作城市B城
本地邮局称为用户空间, 全国邮局称为内核空间
本地邮局是他们彼此 离的最近的地方。他们能够在本地邮局直接接受和发送信封
这是普通linux进程通信的方式,那么问题来了:
男孩写好信之后,发送信件给本地邮局 , 相当于一次拷贝 我们把这个过程称为(copy_from_user)
女孩收到当地邮局通知,需要从本地邮局取信。相当于第二次拷贝,我们把这个过程称为(copy_to_user)
两次拷贝究竟性能怎么样,当然拷贝是非常耗性能的,而两次拷贝可以再优化优化。
那binder是怎么做到一次拷贝的呢
2.接着讲爱情的例子(Binder的实现机制)
后来在疫情结束后,这个女孩去了全国邮局依赖的快递公司上班去了,所有的邮件需要用快递公司来处理,刚好这家快递公司处理的是他们两个城市的信件。
这就给女孩创造了便利,不用去本地邮件取信件
但是男孩还是要发送信件。 binder拷贝也是发生在男孩这个地方copy_from_user,女孩由于在快递公司上班,可以随意浏览男孩的信件。不需要再取信件了。也就减少了从本地邮局取快递这次拷贝过程
思考: 大家还记不记的 接收端怎么写的,对! 接收端一定必须是服务Service,接收端不能是其他java对象。Service就是那个女孩。她必须在快递公司上班才能减少一次拷贝。所以这个Service,在通信前会注册在ServiceManager中。而男孩可以是任意对象,出现在任意地方
Linux 已有的进程通信,发送端和接收端可以是任意对象。出现在任意类中。但是必须牺牲多拷贝一次
Android的Binder通信,接受端不能是任意对象,只能是Service,这也节约了一次拷贝,牺牲了开发者的体验
3.Binder少拷贝一次的原理:
全国邮局 相当于内核空间的内存,所有的应用都与内核空间的内存发生频繁的调用,在Binder中传递数据本质上是通过文件读取来实现的
大家记不记得Linux系统 是文件操作系统,都是基于文件展开的。进程通信中 File也能实现进程通信
Binder机制中 在内存与文件中设计了一层映射关系。内核空间的内存是虚的的。文件IO是实的。 映射指的是内存与文件的映射,映射是通过mmap函数,
而mmap函数 需要依赖一个文件,这个文件叫做“binder”。 对! 他没有后缀名,他就是一个文件。但是人们习惯性的把它称为binder驱动。
我们再来看看实际的是如何映射的
- 全国邮局中的A城与B城的信件,相当于内核空间内存一部分虚拟内存区域。
- A城与B城的快递公司,相当于文件实体。实际上邮件是由快递公司转发。邮局与快递公司的合作关系,可以理解内存与文件形成了映射关系(mmap)
4.服务端Service 也通过mmap函数监听文件的变化
一旦有信件到达女孩的公司直接读取出来,而不用去本地邮件取信件。
女孩怎么在公司取出来呢? 大家忘记了女孩在快递公司上班呢,快递公司会给员工分布工作内容
女孩的工作内容是查看快递接收站和快递发送站
这样你说能不能看到男朋友发过来的信件,还不用亲自跑到本地邮局,那不是爽歪歪
绿色部分 是女孩进程,绿色内有两个角色(女孩接触到的 接收站和收发站)
这一套机制的实现基于 aidl文件编译机制
在编译时生成了一个继承自Binder中的IInterface接口(女孩)。接口中有这样一个内部类叫Stub(女孩工作接触的接收站)和一个内部类叫Proxy(女孩工作接触的发送站)
男孩有邮件到了,女孩直接在 快递接收站查看男孩发过来的邮件(Stub中的 onTransact方法)
女孩思恋男孩,跟男孩发送邮件(Proxy中的transact方法)
Stub与Proxy中所有的方法是native直接调用过来的。参数是直接从内核空间传递过来的,不需要发生拷贝。
如果女孩需要给男孩发送消息,也不用跑到本地邮局,直接在 快递发送站,插入一个邮件就好了(调用Proxy的transct方法)
减少一次拷贝发生在 服务端service。直接有nativie层 的Binder调起。不需要再次拷贝
大家看完了 是不是对整个Binder机制有深刻的认识呢
从Binder的底层原理分析,让Android开发者真正了解到Binder的通信机制。从Linux进程通信技术认知到为什么Android会选择Binder作为通信方式,到Linux的进程原理,最后借鉴Binder中mmap函数打造优异的存储框架。
二、用户空间和内核空间
现代计算机都有两种以上的运行模式(普通模式、特权模式),
linux系统只有两层:
用户空间
- 高优先级模式(特权模式)
- 低优先级模式(普通模式)
linux系统在高优先级模式中运行系统内核代码以及与硬件密切相关的代码。低优先级运行应用程序与硬件无关部分。
应用程序不能直接操控硬件或者调用内核函数,需借助一系列接口函数申请让系统调用相关代码在内核空间运行,获取代码运行权限。
1.好处
应用程序崩溃不会造成内核崩溃,拿windows举例来说,QQ崩溃掉不会造成程序死机。
每个应用程序或者进程都会有自己特定的地址、私有数据空间,程序之间一般不会相互影响
例如QQ崩溃不会造成微信的崩溃。空间的隔离极大地提高了系统运行的稳定性。
2.计算机蓝屏带来的启示
计算机蓝屏主要是因为计算机硬件驱动不兼容问题造成,硬件驱动代码运行在内核空间,与kernel运行在相同空间内,所以驱动程序发生问题容易造成系统的崩溃。将用户空间与内核空间隔离开,可减少系统崩溃的可能,提高系统的稳定性。毕竟现实情况中,应用程序崩溃的情况比蓝屏出现的概率要多的多得多。在linux中这种情况可以类比。
window有上百个驱动,如蓝牙驱动,主板驱动,声卡驱动,麦克风驱动,显卡驱动,USB驱动等等!驱动过多容易造成蓝屏的出现。他们都运行在内核中。为什么会有这么多驱动。电脑中每一个配件都可以随意组合。形成一个完整的电脑
Android 发现
在Android系统中,虽然也是基于Linux系统,但是这些驱动在Android厂商都已经消失了。全部集成化了、除了Binder驱动外,屏幕驱动,蓝牙驱动外几乎看不到其他驱动,这也是蓝屏比较少的原因
3.在linux中
每一个系统进程都拥有自己私有的地址空间和数据,用户空间造成的进程错误会被局部化,而不会影响到内核或者其他进程。(上面所说QQ和微信的例子)。
当用户进程需要完成在特权模式下才能完成的某些工作时,通过linux向上提供的系统调用接口进入特权模式,然后执行调用所提供的有限功能
应用程序正常情况下都是运行在普通模式下,这部分代码运行的空间称为用户空间,当代码通过系统调用计入到特权级别运行的时候,对应的代码执行空间称为内核空间。
linux系统中每个进程占有4G空间(虚拟空间,并不一定真实占用)
空间分布如下:
- 用户空间: 0~(3G-1) 普通的应用程序代码运行在此部分空间中
- 内核空间: 3G~(4G-1) 内核代码段,其中驱动就是运行在此部分空间中
4.用户空间与内核空间交流
用户空间应用程序往往需要调用硬件(QQ调用相机拍照)或者运行与系统核心相关的内容(360清理进程),免不了与内核打交道,他们之间调用关系又是怎样呢?
交流关系以open()文件打开函数为例
上层应用在用户空间执行到 open() API函数时,会触发系统软中断,系统调用 系统调用函数 sys_open()系统调用函数,在内核空间执行open代码,这样用户空间的open函数内部代码就取得了在内核空间运行的权限,可以做一些比较牛比较核心的事情。
应用层API函数还有很多,大约有250个左右,涵盖范围包括文件操作、进程控制、网络操作等等。调用原理大致相同。
总结
Binder机制要完全搞懂,我会分几章来讲解,这章通过一个例子让我们认识了Binder通信机制不同于Linux的地方,还了解了用户空间和内核空间
边栏推荐
- 完整安装 Laravel-Admin 框架
- How to determine the direction based on two coordinate points on the map
- C language uses stack to calculate infix expressions
- 一个网络安全小白鼠的学习之路——nmap的基本使用
- ES6 array extension methods map, filter, reduce, fill and array traversal for…in for…of arr.forEach
- Glide中图片处理
- 文件上传漏洞
- CTF-Neting Cup Past Topics
- Google Hacking
- Larave 自定义公共函数以及引入使用
猜你喜欢
随机推荐
[Hello World教程] 使用HBuilder和Uni-app 生成一个简单的微信小程序DEMO
真·杂项:资本论阅读笔记(随缘更新)
Activity
Cookie is used to collect the admin privileges CTF foundation problem
ES6 three-dot operator, array method, string extension method
Debian 12 Bookworm 尝鲜记
Windows下MySQL数据库报“ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost:8000‘ (10061)”错误解决
英语每日打卡
强化学习笔记:DDPG
CSRF(跨站请求伪造)
Gradle源码解析:生命周期的三个阶段
财产清查概述、 全面清查的情况、局部清查的情况、财产清查的方法、财产清查结果的处理
Jetpack中各个组件简介
同时安装VirtualBox和VMware,虚拟机如何上网
redis未授权访问(4-unacc)
重点考:从债劵的角度来看交易性金融资产
How to calculate the distance between two points on the earth (with formula derivation)
一个网络安全小白鼠的学习之路——nmap的基本使用
文件包含漏洞
ontop-vkg 学习1