Android Telephony框架结构简析
Android Telephony涉及的框架结构如图1所示。
图1 Android Telephony框架结构
通过图1可以发现Android Telephony框架结构的一些规律,具体如下。
- Android Telephony的业务应用跨越了AP和BP。AP与BP相互通信,符合前面介绍的智能手机硬件基本结构。
- Android系统在AP上运行,而Telephony运行在Linux Kernel之上的User Space空间。
- Android Telephony也采用了分层结构的设计,共跨越了三层Java Applications、Java Frameworks和User Libraries层,与Android操作系统整体分层结构保持一致。
- Android Telephony从上到下共分三层:Telephony应用、Telephony框架、RIL(Radio Interface Layer,无线通信接口层,主要位于UserLibraries层中的HAL层,接下来详细介绍HAL)。
- BP SoftWare在BP上运行,主要负责实际的无线通信能力处理。
1 系统运行库层的HAL层
HAL(Hardware Abstraction Layer,硬件抽象层)在Linux和Windows操作系统平台下有不同的实现方式。
Windows下的HAL位于操作系统的最底层,它直接操作物理硬件设备,使用抽象接口来隔离不同硬件的具体实现,为上层的操作系统和设备驱动程序 提供一个统一接口,起到对硬件的抽象作用。这样更换硬件时,编写硬件的驱动只要实现符合HAL定义的标准接口即可,而上层应用并不会受到影响,不必关心具 体来实现的是什么硬件。
Linux 下的HAL与Windows下的HAL不太一样,HAL并不是位于操作系统的最底层直接操作硬件,相反,它位于操作系统核心层和驱动程序之上,是一个运行在User Space用户空间中的服务程序。
2 简析HAL结构
通过前面的学习,我们知道Android是基于Linux Kernel的开源智能手机操作系统,所以在这里重点介绍Linux下的HAL,就不单独介绍Windows下的HAL结构了。
要想知道HAL结构,先看看来自于HAL 0.4.0 Specification的框架图吧,如图1-4所示(引用自http://people.redhat.com/davidz/hal-spec/hal-spec.html)。
图2 HAL 0.4.0 Specification框架结构
HAL是一个位于操作系统和驱动程序之上,运行在用户空间中的服务程序。其目的是为上层应用提供一个统一的查询硬件设备的接口。我们都知道,抽象就 是为了隔离变化,那么这里的HAL可以带给我们什么?首先,有了HAL接口,可以提前开始应用的开发,而不必关心具体实现的是什么硬件;其次,硬件厂家如 果需要更改硬件设备,只要按照HAL接口规范和标准提供对应的硬件驱动,而不需要改变应用;最后,HAL简化了应用程序查询硬件的逻辑,把这一部分的复杂 性转移给HAL统一处理,这样当一些应用程序使用HAL时,可以把对不同硬件的实际操作的复杂性也交给不同硬件厂家提供的库函数来处理。
总之,HAL所谓的抽象并不提供对硬件的实际操作,对硬件的操作仍然由具体的驱动程序来完成。
3 Android为什么引入HAL
HAL的一些优势在前面章节已经提到,这里回顾一下。Android引入HAL不仅因为其自身的优势,而且还有一个非常重要的原因,就是为了保障在 Android平台基于Linux开发的硬件驱动和应用程序不必遵循GPL(General Public License)许可而保持封闭,这保障了更多厂家的利益。我们都知道,Linux Kernel是开源的而且遵循GPL许可证,根据GPL许可证规定,对源码的任何修改都必须向社会开源。
那么Android是如何做到的呢?Linux Kernel和Android的许可证不一样,Linux Kernel是GPL许可证,Android是ASL(Apache Software License)许可证。ASL许可证规定,可以随意使用源码,不必开源,所以建立在Android之上的硬件驱动和应用程序都可以保持封闭。也就是说, 只要把关键的驱动处理相关的主要逻辑转移到Android平台内,在LinuxKernel中仅保留基础的通信功能,即使开源一部分代码,对厂家来讲也不 会有什么损失。
Google选择了这样做,并且特意修改Kernel,原本应该包括在Linux Kernel中的某些驱动关键处理逻辑,被转移到了HAL层之中而达到了不必开源的目的。
4 Android中HAL的运行结构
Android源码中实现了一部分HAL,包括Wi-Fi、GPS、RIL、Sensor等,这些代码主要储存于以下目录:
- Android_src/hardware/libhardware_legacy:老式HAL结构,采用直接调用so动态链接库方式;
- Android_src/hardware/libhardware:新式HAL结构,采用Stub代理方式调用;
- Android_src/hardware/ril:RIL(Radio Interface Layer,无线通信接口层),作为本书重点关注和学习的内容,后面将以独立章节详细讲解。
在Android中,HAL的运行机制是什么样的呢?它有两种运行机制,老式HAL和新式HAL,如图3所示。
图3 Android中HAL两种运行结构
从图3中不难看出,左边是老的HAL结构,应用或框架通过so动态链接库调用而达到对硬件驱动的访问。在so动态链接库里,实现了对驱动的访问逻辑处理。我们重点学习和理解HAL Stub方式, RIL也采用了此方式的设计思想。
HAL Stub 是一种Proxy代理概念,Stub虽然仍是以 *.so 的形式存在,但 HAL 已经将 *.so 的具体实现隐藏了起来。 Stub 向 HAL 提供operations方法,Runtime通过Stub提供的so获取它的 operations方法,并告知Runtime的callback方法。这样Runtime和Stub都有对方调用的方法,一个应用的请求通过 Runtime调用Stub的operations方法,而Stub响应operations方法并完成后,再调用Runtime的callback方法 进行返回。这里可能有一点绕,根据前面的描述再结合图4所示会更容易理解。
图4 HAL Stub结构
上层通过HAL提供的functions调用底层硬件,而底层硬件处理完成上层请求后或硬件状态发生变化后,HAL层通过Runtime提供的callback接口回调上层应用。
HAL Stub 有一种包含关系,即 HAL 里包含了很多的 Stub。 Runtime 只要说明请求类型,就可以取得并操作Stub对应的operations。其实现主要在 hardware.c 和 hardware.h 文件中,实质也是通过dlopen方法加载 .so动态链接库,从而呼叫 *.so 里的符号( symbol )实现。
------------------------------
本文节选自《深入理解Android
: Telephony原理剖析与最佳实践》,作者:杨青平。
豆瓣网址:http://book.douban.com/subject/20480692/
样章试读:http://download.csdn.net/detail/hzbooks/5068008
《深入理解Android : Telephony原理剖析与最佳实践》从源代码角度深入解析了 Android Telephony的架构设计与实现原理,深刻揭示了Android系统的通信机制。对于Android应用开发工程师和系统工程师而言,《深入理解 Android:Telephony原理剖析与最佳实践》都是难得的研究和学习资料。全书共13章,分为五部分:第一部分(1~3章),首先介绍了智能手 机的系统结构、Android系统的架构、Telephony框架的结构,然后详细介绍了Android源代码编译环境和阅读环境的搭建方法,以及阅读 《深入理解Android:Telephony原理剖析与最佳实践》要做的技术准备;第二部分(4~6章),对Android的通话功能进行了深入的分 析,包括对通话流程的分析、对主动拨号和来电流程的分析、对通话应用机制的分析,以及对手机通信功能在框架层和应用层中的实现机制的分析;第三部分 (7~9章),对Android的通信功能进行了深入的分析,包括对网络服务状态的运行机制的分析、对Android手机上网的实现机制的分析,以及对短 息发送和接收流程的分析;第四部分(10~12章),对Android RIL的工作机制进行了深入的分析,包括对框架层中的RILJ运行机制的分析、对RILC系统结构及LibRIL运行机制的分析,以及对 Reference-RIL框架的原理的分析;第五部分(13章),分析了Telephony模块所提供的系统服务,包括系统服务的注册入口以及调用系统 服务接口的实例。