HAL的存在意义
硬件抽象层是介于android内核kernel和上层之间的抽象出来的一层结构。他是对linux驱动的一个封装,对上层提供统一接口,上层应用不必知道下层硬件具体怎么实现工作的,它屏蔽了底层的实现细节。
它在整个android架构中的位置如下图所示:
传统的linux对硬件的操作基本上在内核空间的linux驱动程序中实现了,那么现在为什么要多此一举把对硬件的操作分为HAL和linux驱动两部分呢?而且HAL是属于用户空间,linux驱动属于内核空间。
其实并不多余,理由是很多的:
1.谷歌搭好了HAL的框架,为上层framework通过JNI调用HAL提供了统一的API,硬件开发商或者移植人员只需要按照框架开发即可,无需话费精力在与上层的交互上的实现上,将精力放在hal层本身的实现上即可。
2.从商业角度,许多硬件厂商不愿意将自己硬件相关一些核心的东西开源出去,假如将对自己硬件的驱动程序全部放入内核空间驱动程序实现,那么必须遵循GPL协议,是必需开源的。有了HAL层之后,他们可以把一些核心的算法之类的东西的实现放在HAL层,而HAL层位于用户空间,不属于linux内核,和android源码一样遵循的是Apache协议,这个是可以不用开源的。
以上就是HAL层存在的意义,下面来根据HAL层源码分析一下HAL到底是怎么样个架构和实现原理,深入剖析一下。
HAL重要数据结构
android HAL层的代码主要位于/hardware/libhardware下面我们从上往下走。
在HAL层中,各类硬件的都是以硬件模块的形式描述的,是用hw_module_t结构体来描述的,而每一类硬件模块中又有各个独立的硬件,是用hw_device_t结构体来描述的。
上层app通过JNI调用硬件时,首先得获取到hw_module_t结构体,也即是硬件模块,有了这个才能再对硬件进行操作。那么我们来看看看看这两个结构体定义是什么样子的。
它们的定义在/hardware/libhardware/include/hardware/hardware.h里面。
A. hw_module_t表示硬件模块,它主要包含了一些硬件模块的信息,结构体的定义:
/**
* Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
* and the fields of this data structure must begin with hw_module_t
* followed by module specific information.
*/
typedef struct hw_module_t {
/** tag must be initialized to HARDWARE_MODULE_TAG */
uint32_t tag;
/**
* The API version of the implemented module. The module owner is
* responsible for updating the version when a module interface has
* changed.
*
* The derived modules such as gralloc and audio own and manage this field.
* The module user must interpret the version field to decide whether or
* not to inter-operate with the supplied module implementation.
* For example, SurfaceFlinger is responsible for making sure that
* it knows how to manage different versions of the gralloc-module API,
* and AudioFlinger must know how to do the same for audio-module API.
*
* The module API version should include a major and a minor component.
* For example, version 1.0 could be represented as 0x0100. This format
* implies that versions 0x0100-0x01ff are all API-compatible.
*
* In the future, libhardware will expose a hw_get_module_version()
* (or equivalent) function that will take minimum/maximum supported
* versions as arguments and would be able to reject modules with
* versions outside of the supplied range.
*/
uint16_t module_api_version;
#define version_major module_api_version
/**
* version_major/version_minor defines are supplied here for temporary
* source code compatibility. They will be removed in the next version.
* ALL clients must convert to the new version format.
*/
/**
* The API version of the HAL module interface. This is meant to
* version the hw_module_t, hw_module_methods_t, and hw_device_t
* structures and definitions.
*
* The HAL interface owns this field. Module users/implementations
* must NOT rely on this value for version information.
*
* Presently, 0 is the only valid value.
*/
uint16_t hal_api_version;
#define version_minor hal_api_version
/** Identifier of module */
const char *id;
/** Name of this module */
const char *name;
/** Author/owner/implementor of the module */
const char *author;
/** Modules methods */