Android硬件抽象层(HAL)定义了一个标准的接口,这个接口需要硬件厂商来实现,HAL使Android和底层的驱动隔离开来,HAL实现被打包成so文件,由Android系统在适当的时候加载。设备厂商必须实现对应硬件的HAL和驱动,HAL lib位于/system/lib/hw
目录下。
标准的HAL结构
HAL模块包含两个通用的组件:模块(module)和设备(device),它们在hardware/libhardware/include/hardware/hardware.h
中定义。
typedef struct hw_module_t {
uint32_t tag;
uint16_t module_api_version;
#define version_major module_api_version
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 */
struct hw_module_methods_t* methods;
/** module's dso */
void* dso;
#ifdef __LP64__
uint64_t reserved[32-7];
#else
/** padding to 128 bytes, reserved for future use */
uint32_t reserved[32-7];
#endif
} hw_module_t;
结构体hw_module_t
代表一个模块,它包含了模块的版本、名字、作者等信息,Android利用这些信息来发现和加载正确的模块。另外,hw_module_t
中包含一个指向hw_module_methods_t
结构的指针,这个结构包含一个指向模块open
函数的指针,
typedef struct hw_module_methods_t {
/** Open a specific device */
int (*open)(const struct hw_module_t* module, const char* id,
struct hw_device_t** device);
} hw_module_methods_t;
open函数用于打开一个设备,每一个特定的硬件HAL实现一般扩展hw_module_t
结构,增加模块自己特有的信息。一个设备抽象了实际的硬件,结构hw_device_t
表示一个设备,
typedef struct hw_device_t {
/** tag must be initialized to HARDWARE_DEVICE_TAG */
uint32_t tag;
uint32_t version;
/** reference to the module this device belongs to */
struct hw_module_t* module;
/** padding reserved for future use */
#ifdef __LP64__
uint64_t reserved[12];
#else
uint32_t reserved[12];
#endif
/** Close this device */
int (*close)(struct hw_device_t* device);
} hw_device_t;
实际的设备实现会扩展这个结构,并包含硬件特有功能的函数指针。
实现
我们以Audio HAL为例来说明HAL的实现以及如何被系统加载。我们看一下Audio的module和device的定义,
struct audio_module {
struct hw_module_t common;
};
struct audio_hw_device {
struct hw_device_t common;
uint32_t (*get_supported_devices)(const struct audio_hw_device *dev);
int (*init_check)(const struct audio_hw_device *dev);
...
每一个硬件模块必须包含一个名字为HAL_MODULE_INFO_SYM
的结构,并且这个结构必须以hw_module_t
结构开头,device定义必须以hw_device_t
结构开头。
static struct hw_module_methods_t hal_module_methods = {
.open = adev_open,
};
struct audio_module HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_M