赞
踩
Android OS = Linux Kernel + Android Runtime
Kernel主要负责管理硬件,CPU,内存,外界硬件,传感器等,同时提供接口给上层使用。
Kernel以上的软件层被称为用户空间,包括,HAL层、FrameWork层、应用层。
HAL是硬件抽象层,是安卓特有的一个软件层,是设备驱动的一部分,在传统的Kernel中,设备驱动运行在Kernel中;
安卓为了规避Kernel的GPL license,把设备驱动一分为二,一部分在Kernel,一部分在用户空间(HAL层)。
FrameWork分为Native FrameWork 和 Java FrameWork,Native由C++开发包括常用的基础库和安卓特有的框架服务,lib-c,open-ssl,open-gl等,这些库在安卓诞生之前就存在。
安卓系统的显示、多媒体等也会用C++开发,Native FrameWork还负责虚拟机以及JAVA核心库。
javaframework包含安卓特有的框架服务,例如ams、pms等,这些框架服务是谷歌从零开始实现的。
安卓手机用来存储数据的芯片,通常是一片emmc闪存,被划分为不同的块,用来存储不同的信息。RPMB用来存储防止被串改的数据,如IMEI号等;
硬件分区划分好就固定好了,现在手机默认没有通用分区了。剩下的为userData 分区可以使用软件进行进一步的划分,于是就形成了软件分区。
recovery分区包含一个小的Linux系统,用来进行系统升级以及清除数据等。
TOS是一个与安卓隔离的系统,称为可信OS,用来运行安全相关的模块,例如指纹识别等。
vendor即属于HAL模块。
手机分区由手机厂商自由划分,我们划分了四个保留分区。
启动模式:
四种不同的启动模式,download启动模式不开放给用户使用;fastboot——线刷,可以对recovery模式和normal模式用到的分区进行写入。
Recovery模式就是卡刷,对系统进行OTA升级,以及清除数据等。
Bootloader分为三个阶段;
Kernel
User Space 运行的就是安卓的FrameWork及APP,通过系统调用接口来与Kernel Space进行通信,系统调用是软中断,使用起来比较麻烦;
可以用GNU C Library(包含了系统调用)来进行与Kernel通信。
设备驱动占了很大一部分,设备驱动不一定是与硬件相关,也会用设备驱动的框架通过虚拟的设备来扩展Kernel功能(Androidism)。
编程问题可以划分为两部分:提供哪些能力(机制),如何使用这些能力(策略)。这两部分用不同的程序来表达,比较好。
create_process 创建进程,需要传入程序的入口并执行,创建进程后来分为两步fork, execute,做了一个解耦合。
Kernel添加的代码必须开源出来。
硬件抽象层采用Apache 协议,可以不用开源。
安卓FrameWork一般使用 JNI 形式来使用硬件抽象层提供的服务,以SDK形式(Binder IPC)对外提供接口。
硬件抽象层由模块和设备组成:一个模块就是一个so文件,so文件以文件类型与设备名称来命名。
一个模块对应一类设备,可以包含若干设备,每个设备都用一个hw_device_t来描述。
nativeFrameWork主要包括多媒体相关以及显示相关等对性能要求比较高的模块以及包含开源框架的服务;javaFrameWordk包含安卓特有的服务,WMS,等
OpenGL会渲染在一块GPU的Buffer中,这块GPU buffer是通过SurfaceFlinger中的dq_buffer获得的。
activity —— UI
service —— 后台
Broadcast Receiver
content Provider 组件之间,系统与组件之间做了一个松耦合,消息发送层不需要知道消息接收方的存在。
安卓应用层,组件是对系统更高一层的抽象。
download - (芯片固件最开始运行时进入的)primarybootloader固化在芯片;
fastboot bootloader第三阶段 主要由abl.elf来实现。
内部与售后使用的模式,通过fileHost等协议与PC的客户端进行通信,在客户端F5可以选择要刷入的image.
bootloader的第三阶段就会从boot.image中找到内核,加载kernel,启动后,再从boot.image挂载根文件系统,
再从根文件系统找到init进程进行加载,init负责初始化安卓framework(Zygote))
安卓代码分为两大类,一类是谷歌维护的原生代码 AOSP - OS FrameWork代码,另一类是芯片厂商和手机厂商定制的代码,的硬件抽象层代码-vendor代码。
之前是耦合在一起的代码。
Treble架构要解决的问题就是将这两部分解耦合。
使得安卓升级,可以继续使用厂商的Vendor代码,这样安卓可以升级,而厂商没必要跟着升级,这样厂商就能更愿意升级高版本的安卓系统了。
将framework层与硬件抽象层分离出来,之前是进程内调用so文件,现在做了两个进程。
做一个分离,进程内调用改为进程间调用,势必会造成性能损失。于是引入HIDL的通信机制,用于安卓OSFrameWork和HAL之间的通信。
HIDL也是基于Binder实现的;
HIDL 是用于指定 HAL 与其用户之间接口的一个接口描述语言(Interface Description Language),它允许将指定的类型与函数调用收集到接口(Interface)和包(Package)中。更广泛地说,HIDL 是一个可以让那些独立编译的代码库(Libraries)之间进行通信的系统。 HIDL 实际上是用于进行进程间通信(Inter-process Communication,IPC)的。进程间的通信可以称为 Binder 化(Binderized)。对于必须连接到进程的库,也可以使用 passthough 模式(但在Java中不支持)。 HIDL 将指定的数据结构与方法签名组织到接口中,这些接口又会被收集到包中以供使用。它的语法与 C++、JAVA 是类似的,不过关键字集合不尽相同。其注释风格与 JAVA 是一致的。
HIDL的全称是HAL interface definition language(硬件抽象层接口定义语言),在此之前Android 有AIDL,架构在Android binder 之上,用来定义Android 基于Binder通信的Client 与Service之间的接口。HIDL也是类似的作用,只不过定义的是Android Framework与Android HAL实现之间的接口。
在AIDL机制中Android 会提供一系列工具会将用户定义的*.aidl文件编译生成Client端代码与Service端代码,用户仅仅 需要1)在Service端实现所需要实现的接口。2)在Client端调用相关接口。基于Binder机制,在Clinet端的调用会自动通过 binder驱动跨进程到service进程当中。
而在HIDL里,与AIDL比较类似,底层也是基于binder机制。但是也有稍微不一样的地方。为了支持HIDL,Android 对BInder做了一定程度的修改。
设计 HIDL 这个机制的目的,主要是想把框架(framework)与 HAL 进行隔离,使得框架部分可以直接被覆盖、更新,而不需要重新对 HAL 进行编译。HAL 的部分将会放在设备的 /vendor
分区中,并且是由设备供应商(vendors)或 SOC 制造商来构建。这使得框架部分可以通过 OTA
方式更新,同时不需要重新编译 HAL。
为了将以往设备的 Android 版本更新到 Android O,开发者需要将传统的 HAL 封装到新的 HIDL 接口中,这个接口为 HAL 提供了 Binder 化以及 Passthrough 模式。这个封装过程对 HAL 以及 Android Framework 都是透明的。
Passthrough 模式仅对 C++ 客户端与实现适用,以往的 Android 版本设备中,HAL 不会采用 JAVA 语言来写,所以 JAVA HAL 必然是 Binder 化的。
绑定式 HAL。以 HAL 接口定义语言 (HIDL) 表示的 HAL。这些 HAL 取代了早期 Android 版本中使用的传统 HAL 和旧版 HAL。在绑定式 HAL 中,Android 框架和 HAL 之间通过 Binder 进程间通信 (IPC) 调用进行通信。所有在推出时即搭载了 Android 8.0 或后续版本的设备都必须只支持绑定式 HAL。大致框架图如下,对于Android O之前的设备,对应图1,对于从之前的设备升级到O的版本,对应图2、图3. 对于直接基于Android O开发的设备,对应图4。
在Android O之前,HAL是一个个的.so库,通过dlopen来进行打开,库和framework位于同一个进程。
在Android O之后,framework和hal运行于不同的进程,所有的HAL采用新的HIDL技术来完成。
Scatter - gather 分离收集的技术,减少数据传输过程中数据拷贝技术,;
共享内存 - 数据拷贝
快速消息队列 进程间高效消息传递
对性能要求高的,支持在进程内直接加载vendor代码 通过 HIDL调用 —— Passthrough
treble两项关键的技术 HIDL 和VNDK
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。