第九章 硬件抽象层:HAL
HAL,全称为Hardware Abstract Layer,即硬件抽象层,它是建立在Linux驱动之上的一套程序库,程序库并不属于Linux内核,而是属于Linux内核层之上的应用层。为Android增加HAL的目的除了尽量避免应用程序直接访问Linux驱动外,还会保护私人财产。
一、在Android中加入HAL的原因如下:
在传统的Linux系统中Linux驱动一般有两种类型的代码:访问硬件寄存器的代码和业务逻辑代码。
对于访问硬件寄存器的代码,都是调用Linux内核的标准函数进行标准操作。而Linux驱动的业务逻辑部分开发人员并不想将源代码公开,这些Linux驱动的实现涉及一些技术专利和商业机密,公开会有麻烦。但作为Linux驱动,又不得不公开源代码,因为Linux内核采用了GPL协议,而此协议要求所有使用基于GPL协议的源代码的程序必须开源。为了满足不想开源的要求,Google在Android层次结构中的系统运行库层增加了一个HAL,HAL并不是Linux内核的一部分,它位于Android的系统运行库层,Android采用Apache license2.0协议,该协议并未要求基于此协议的源代码的软件也必须开源,HAL属于Android的一部分,不必开源。对于不想开源的Linux驱动作者,Linux驱动只相当于一个“数据二传”,在Linux驱动中只保留与寄存器交互的代码,访问寄存器只有Linux内核的相关函数能做到,不想公开的业务逻辑代码放在HAL中。这样的话,Linux驱动就只剩下一个空壳,唯一的功能就是接收由HAL传来的数据,并将这些数据写入指定的寄存器中,或从寄存器中读取数据,并返回给HAL。带HAL的Linux驱动相当于将数据从HAL传到寄存器,或从寄存器传到HAL的“数据二传”。对于拥有完整功能的Linux驱动,也可加入HAL,不过HAL就成一个空壳了,它只负责与Linux设备驱动进行交互。
二、Google为Android加入HAL主要目的有:
①统一硬件的调用接口。
②解决了GPL版权问题。
③针对一些特殊的要求。
起初简单的HAL架构基本原理是在Android系统中使用程序库.so文件调用位于内核空间的一半通过设备文件访问的Linux驱动。然后Android应用程序apk文件可通过NDK程序访问HAL中的程序库,或直接在Android应用程序中访问HAL中的程序库,可直接使用Java代码访问。HAL架构中,HAL模块中的核心代码没有改变,只是增加了一些新的HAL架构要求的入口代码,使这些程序库可自动被Android系统识别。而调用HAL模块的代码并不需要直接装载.so文件,只需要通过一个ID定位相应的.so文件-Stub。在Stub和JNI间还有一层service程序库,该层的库文件使用Android系统提供的调用HAL的机制访问HAL中的service程序库,在这层通过ID定位了HAL library,然后Android应用程序再调用service程序库。Android HAL的源代码存储位置并不固定,一般会存储在<Android源代码>/hardware目录中。最终生成的.so文件主要放在Android系统的/system/lib/hw目录。
三、编写HAL模块的步骤和原理如下:
第一步:定义结构体和宏
3个重要的结构体hw_module_t、hw_device_t、hw_module_methods_t
第二步:编写HAL模块的open函数
Open函数是HAL模块的入口点。初始化hw_device_t的子结构体;打开设备文件;初始化寄存器
第三步:定义hw_module_methods_t结构体变量
HAL模块需要hw_module_methods_t结构体的open函数指针变量指定open入口函数
第四步:定义HAL_MODULE_INFO_SYM变量
id表示HAL模块中Android系统中的标识。通过id找到并装载HAL模块。
methods变量需要指向第3步定义的hw_module_methods_t结构体的地址,当调用者通过id找到并装载HAL模块后,就会通过methods变量找到hw_module_methods_t结构体,并调用hw_module_methods_t.open函数。
第五步:编写HAL模块的close函数
当HAL模块被卸载后会调用close函数
第六步:编写控制LED的函数
根据设备类型和功能的不同,编写相应的函数
http://home.cnblogs.com/u/ligang1307/