[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析
[Android取经之路] 系列文章:
《系统启动篇》
Android系统架构
Android是怎么启动的
Android 10.0系统启动之init进程
Android10.0系统启动之Zygote进程
Android 10.0 系统启动之SystemServer进程
Android 10.0 系统服务之ActivityMnagerService
Android10.0系统启动之Launcher(桌面)启动流程
Android10.0应用进程创建过程以及Zygote的fork流程
Android 10.0 PackageManagerService(一)工作原理及启动流程
Android 10.0 PackageManagerService(二)权限扫描
Android 10.0 PackageManagerService(三)APK扫描
Android 10.0 PackageManagerService(四)APK安装流程
《日志系统篇》
Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性
Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化
Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析
Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现
《Binder通信原理》:
Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要
Android10.0 Binder通信原理(二)-Binder入门篇
Android10.0 Binder通信原理(三)-ServiceManager篇
Android10.0 Binder通信原理(四)-Native-C\C++实例分析
Android10.0 Binder通信原理(五)-Binder驱动分析
Android10.0 Binder通信原理(六)-Binder数据如何完成定向打击
Android10.0 Binder通信原理(七)-Framework binder示例
Android10.0 Binder通信原理(八)-Framework层分析
Android10.0 Binder通信原理(九)-AIDL Binder示例
Android10.0 Binder通信原理(十)-AIDL原理分析-Proxy-Stub设计模式
Android10.0 Binder通信原理(十一)-Binder总结
《HwBinder通信原理》
HwBinder入门篇-Android10.0 HwBinder通信原理(一)
HIDL详解-Android10.0 HwBinder通信原理(二)
HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)
HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)
HwServiceManager篇-Android10.0 HwBinder通信原理(五)
Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)
Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)
JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)
JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)
HwBinder驱动篇-Android10.0 HwBinder通信原理(十)
HwBinder原理总结-Android10.0 HwBinder通信原理(十一)
《编译原理》
编译系统入门篇-Android10.0编译系统(一)
编译环境初始化-Android10.0编译系统(二)
make编译过程-Android10.0编译系统(三)
Image打包流程-Android10.0编译系统(四)
Kati详解-Android10.0编译系统(五)
Blueprint简介-Android10.0编译系统(六)
Blueprint代码详细分析-Android10.0编译系统(七)
Android.bp 语法浅析-Android10.0编译系统(八)
Ninja简介-Android10.0编译系统(九)
Ninja提升编译速度的方法-Android10.0编译系统(十)
Android10.0编译系统(十一)
在前面我们写了一个《Binder通信原理》的系列文章,这次准备来写一写HwBinder的系列文章。
HAL binder是Android O(8.0)专门用于HAL(Hardware Abstract Layer)层(native)进程与其clients之间的通信机制(clients可以是native进程,也可以是Java Framework进程)。HAL binder替代了早先使用的socket通信,其kernel层实际是基于原有的binder驱动,但为了配合Client与Server之间的数据传输,需要使用特定的中间层HIDL来进行接口与数据的转换。那么,相对之前的HAL通信方式(socket),基于HIDL的HAL通信有什么优势?从系统架构的角度,HIDL为客户端与服务端提供了清晰的接口;从效率的角度,binder IPC实际在传输数据上只有一次拷贝,而socket实际传输需要两次数据拷贝。
1.概述
在Android 8.0 之前,Binder机制比较简单,只有一个驱动设备"/dev/binder",一个守护进行"/system/bin/servicemanager",一个binder库"/system/lib64/libbinder.so".
在Android 8.0开始,Android引入了Treble的机制,为了方便Android系统的快速移植、升级,提升系统稳定性,Binder机制被拓展成了
"/dev/binder", "/dev/hwbinder","/dev/vndbinder"。
我们原先使用的"/dev/binder",成为框架进程的专有节点,这意味着供应商进程无法再访问此节点。供应商进程可以访问 /dev/hwbinder,但必须将其 AIDL 接口转为使用 HIDL。
对于想要继续在供应商进程之间使用 AIDL 接口的供应商,需要使用 /dev/vndbinder(而非 /dev/binder)。
Android8.0及之后的Binder域如下图所示:
2.HwBinder 框架
Binder和HwBinder的一些差异
Binder -> HwBinder
BpProxy -> BpHwBinder
BBinder -> BHwBinder
JavaBBinder -> JHwBinder
BinderProxy.java -> HwRemoteBinder.java
Binder.java -> HwBinder.java
HwBinder架构如下图所示:
在Android 8.0之前,Android Framework与Android HAL是打包成一个system.img的,而且Framework与HAL之间是紧耦合的,HAL是一个个的.so库,库和framework位于同一个进程。
Android8.0之前 的系统框架当中framework与HAL之间的一般架构框架是:
在上图的这种架构中,每次Android的Framework进行升级时,对应的HAL层都需要跟着升级,费时费力,这也Android最新版本推广较慢的原因。
在Android 8.0及之后,Android觉得这也不行,每次出了新版本,但是用的人很少,得让大家快速使用新版本。于是Android引入了一个Treble的架构,把vendor的一些功能和库与system进行分离,OEM厂商设计的内容都放到vendor中去,Android原生的放到system中,这样Android只要升级System就能快速完成版本的升级,在这个场景下,Android Framework放在了System空间,厂商的HAL库放在了Vendor空间,两者之间使用hwbinder进行通信,通信的接口语言为HIDL。
Android8.0及之后 的系统框架当中framework与HAL之间的一般架构框架是:
下图展示了Android 有Treble和没有Treble的升级方式:
3.Hwbinder 与Binder的区别
3.1 Binder
在Android 8.0之前,这是我们最熟悉也一直使用的Binder。Java层继承Binder,Native C/C++层继承Bbbinder,然后通过servicemanager进程注册实名Binder,然后通过已经创建好的Binder接口传递匿名Binder对象,拿到BinderProxy或者BpBinder以后,就可以Binder通信了。
在Android 8.0后,这个Binder机制继续保留,/dev/binder 设备节点成为框架进程的专有节点,这意味着供应商进程无法再访问此节点。
如果你是系统厂商,在system分区有进程,/dev/biner机制还是可以继续使用,但是你的进程在vendor分区,那只能使用/dev/hwbinder 或者/dev/vndbinder.
Binder机制需要两个进程都同属于System分区
3.2 HwBinder
hwbinder和 binder不同,hwbinder是一套全新的流程,有单独的驱动设备"/dev/hwbinder",独立的守护进程"hwservicemanager",独立的SDK-"libhwbinder"
HwBinder机制可以跨System和Vendor分区使用
4. 为什么要引入hwbinder
Android 8.0中引入了Treble机制,Treble 项目通过将底层供应商实现从 Android 内核框架中剥离出来,使Android更新变得更简单。这种模块化的设计允许分别独立更新平台和供应商提供的组件。让更新变得更轻松、更快速,然而,Treble 加强模块化设计还有一个目的:提高安全性。
Treble引入后,新增了一个vendor.img, 即原先的system分区,被拆分为了system分区和vendor分区,soc及供应商的功能实现都需要放到vendor分区,这样将system和vendor相关的镜像分开,便于能方便地更新和升级system,并且不依赖vendor等底层。
在Android 8.0之前,HAL是一个个的.so库,通过dlopen来进行打开,库和framework位于同一个进程, 在此之前的Android 系统架构当中,Android Framework 与Android HAL是打包成一个system.img的,而且Framework 与HAL之间是紧耦合的,通过链接的方式使用相应的硬件相关so库。
Android 8.0之前的通信机制如下图所示:
所以每次Android framework的升级需要对应的Android HAL升级,这需要供应商花费很多的人力去升级相应的 Vendor HAL Implemetation,这也就是导致Android版本升级很缓慢,很多用户几年之后,Android都不能得到及时更新。
在Android8.0及以后的版本中,Android设计了一套新的机制来隔离HAL层,引入了一个HIDL的语言来定义Framework和HAL之间的接口
在Android 8.0以及以后的版本当中,Android 更新了新的框架设计在新的框架设计当中,引入了一套叫HIDL的语言来定义Freamework与HAL之间的接口,Android Framework会在system分区当中,而VendorHAL Implemetation会在一个新定义的分区(Vendor.img)当中,这样刷新的system.img 才不会影响到Vendor HAL Implemetation。
在Android 8.0及之后,HAL库和framework不在同一个进程,他们之间使用hwbinder进行进程间通信。
Android 8.0引入Treble后,各层的通信机制如下:
5.HwBinder的通信原理
HwBinder 通信采用 C/S 架构,从组件视角来说,包含 Client、 Server、 HwServiceManager 以及 HwBinder 驱动,其中 HwServiceManager 用于管理系统中的各种服务。
HwBinder 在 framework 层进行了封装,通过 JNI 技术调用 Native(C/C++)层的 HwBinder 架构。
HwBinder 在 Native 层以 ioctl 的方式与 Binder 驱动通讯。
HwBinder通信原理图如下:
HwBinder通信流程如下:
首先服务端需要向HwServiceManager进行服务注册,HwServiceManager有一个全局的service列表mServiceMap,用来缓存所有服务的对象和name。
客户端与服务端通信,需要拿到服务端的对象,由于进程隔离,客户端拿到的其实是服务端的代理,也可以理解为引用。客户端通过HwServiceManager从mServiceMap中查找服务,HwServiceManager返回服务的代理。
拿到服务对象后,我们需要向服务发送请求,实现我们需要的功能。通过 BpHwBinder 将我们的请求参数发送给 内核,通过共享内存的方式使用内核方法 copy_from_user() 将我们的参数先拷贝到内核空间,这时我们的客户端进入等待状态。然后 Binder 驱动向服务端的 todo 队列里面插入一条事务,执行完之后把执行结果通过 copy_to_user() 将内核的结果拷贝到用户空间(这里只是执行了拷贝命令,并没有拷贝数据,binder只进行一次拷贝),唤醒等待的客户端并把结果响应回来,这样就完成了一次通讯。
在这里其实会存在一个问题,Client和Server之间通信是称为进程间通信,使用了HwBinder机制,那么Server和HwServiceManager之间通信也叫进程间通信,Client和Server之间还会用到HwServiceManager,也就是说HwBinder进程间通信通过HwBinder进程间通信来完成,这就好比是 孵出鸡前提却是要找只鸡来孵蛋,这是怎么实现的呢?
HwBinder的实现比较巧妙:预先创造一只鸡来孵蛋:HwServiceManager和其它进程同样采用HwBinder通信,HwServiceManager是Server端,有自己的HwBinder对象(实体),其它进程都是Client,需要通过这个HwBinder的引用来实现HwBinder的注册,查询和获取。
HwServiceManager提供的HwBinder比较特殊,它没有名字也不需要注册,当一个进程使用BINDER_SET_CONTEXT_MGR_EXT命令将自己注册成HwServiceManager时HwBinder驱动会自动为它创建HwBinder实体(这就是那只预先造好的鸡)。
其次这个HwBinder的引用在所有Client中都固定为0(handle=0)而无须通过其它手段获得。也就是说,一个Server若要向HwServiceManager注册自己HwBinder就需要通过0这个引用号和HwServiceManager的Binder通信。
类比网络通信,0号引用就好比域名服务器的地址,你必须预先手工或动态配置好。要注意这里说的Client是相对HwServiceManager而言的,一个应用程序可能是个提供服务的Server,但对HwServiceManager来说它仍然是个Client。
/system/tools/hidl/
根据HAL接口 .hal来产生相应的Proxy(client端接口)以及stub(server端接口)
/system/libhidl
HIDL状态与HAL服务管理接口
/hardware/interfaces/
各个模块HAL层接口,每个模块都包含了一个Android.bp的脚步来生成对应的代理(Proxy)与存根对象(stub),如radio接口IRadio.hal,sensors接口ISensors.hal
android_os_HwBinder.java\cpp (JNI)
Java层HAL binder的JNI代码,负责将Java层的请求传递给相应的server进程
/dev/hwbinder
/kernel/msm-4.9/drivers/android/binder.c
/kernel/msm-4.9/drivers/android/binder_alloc.c
hwservicemanager
/system/hwservicemanager/hwservicemanager.rc
/system/hwservicemanager/ServiceManager.cpp
/system/hwservicemanager/HidlService.cpp
/system/hwservicemanager/HidlService.h
libhwbinder
/system/libhwbinder/Binder.cpp
/system/libhwbinder/BpHwBinder.cpp
/system/libhwbinder/IInterface.cpp
/system/libhwbinder/IPCThreadState.cpp
/system/libhwbinder/ProcessState.cpp
/system/libhwbinder/Parcel.cpp
/system/libhwbinder/include/hwbinder/Binder.h
/system/libhwbinder/include/hwbinder/BpHwBinder.h
/system/libhwbinder/include/hwbinder/IBinder.h
/system/libhwbinder/include/hwbinder/IInterface.h
/system/libhwbinder/include/hwbinder/IPCThreadState.h
/system/libhwbinder/include/hwbinder/ProcessState.h
/system/libhwbinder/include/hwbinder/Parcel.h
7.总结
Android引入Treble机制后,扩展了一个vendor分区,为了能够快速的进行升级,做了隔离HAL层的机制,为了System/System、System/Vendor、Vendor/Vendor 之间进行不同的进程间通信,把原有的Binder机制拆分成了Binder、HwBinder、VndBinder。
Binder和VndBinder 共用一套libbinder、servicemanager的代码,使用AIDL接口,两者不能共存。
HwBinder采用了单独的libhwbinder、hwservicemanager的代码,单独管理,使用HIDL接口。
三者之间互不干扰,在方便系统升级的同时,又提升了系统的安全和稳定性。
参考:
《Android Treble Architecture: Part 3 - Changes for Treble[Binder & ServiceManager]》