1. HAL层概述:Android HAL架构演进与系统定位
HAL(Hardware Abstraction Layer,硬件抽象层)是Android系统中连接Framework与Linux内核的关键中间层。它屏蔽了硬件驱动的具体实现细节,为上层应用提供统一的硬件访问接口。理解HAL的架构演进、系统位置与核心作用,是进行驱动移植与问题排查的基础。
1.1 HAL在Android系统中的位置与作用
HAL位于Android系统架构的中间位置,其上下层关系如下图所示:
HAL的核心作用可以归纳为以下五点:
- 统一硬件接口:为上层Framework提供标准化的硬件访问API,无论底层硬件如何变化,上层调用方式保持一致。
- 屏蔽驱动差异:将不同芯片厂商(Qualcomm、MTK、Rockchip等)的驱动实现细节封装在HAL内部,上层无需感知。
- 支持多厂商实现:允许同一硬件类型(如Camera、GPS)存在多个HAL实现,通过系统属性或配置文件动态加载。
- 解耦Framework:Framework与硬件驱动之间通过HAL隔离,驱动变更不会影响Framework的稳定性。
- 简化移植工作:在新硬件平台上移植Android系统时,只需实现对应的HAL模块,无需修改上层框架代码。
1.2 Android HAL架构演进:Legacy HAL → HIDL → AIDL
Android HAL架构经历了三个主要阶段的演进,每个阶段都解决了前一阶段的核心痛点。下表对比了三种架构的关键差异:
| 对比维度 | Legacy HAL | HIDL HAL | AIDL HAL |
|---|---|---|---|
| 引入版本 | Android 1.0 ~ 7.x | Android 8.0 (Treble) | Android 11 (持续演进) |
| 接口定义语言 | 无标准IDL,依赖.h头文件 | HIDL (.hal文件) | AIDL (.aidl文件) |
| 通信方式 | 直接函数调用(dlopen + dlsym) | Binder化IPC(hwbinder) | 标准Binder IPC |
| 进程模型 | 同进程(加载到调用方进程) | 跨进程(HAL服务独立进程) | 跨进程(HAL服务独立进程) |
| 版本管理 | 无版本管理,依赖头文件 | 显式版本号(@1.0, @2.0) | 显式版本号 + 向后兼容 |
| 稳定性 | 低(Framework与HAL紧耦合) | 高(Framework与HAL解耦) | 高(统一Binder生态) |
| 典型场景 | 早期Android设备 | Android 8~10设备 | Android 11+新设备 |
1.3 Legacy HAL架构详解
Legacy HAL是Android早期(1.0 ~ 7.x)使用的架构,其核心特征是通过动态库加载(dlopen)实现硬件访问。每个硬件模块对应一个共享库(.so),存放在/system/lib/hw/或/vendor/lib/hw/目录下。
Legacy HAL的工作流程如下:
- 模块注册:HAL实现者定义
hw_module_t结构体,并通过HAL_MODULE_INFO_SYM符号导出。 - 模块加载:Framework调用
hw_get_module(),根据模块ID和硬件特性查找并加载对应的.so文件。 - 函数获取:通过
dlsym()获取open()函数指针,打开硬件设备并获取操作接口。 - 直接调用:Framework通过返回的接口指针直接调用HAL函数,所有操作在同一个进程内完成。
1. 确认目标Android版本是否仍支持Legacy HAL(Android 9+已移除部分Legacy HAL支持)。
2. 检查
hw_get_module()的搜索路径是否被SELinux策略限制。3. 注意
HAL_MODULE_INFO_SYM符号的导出方式,避免被编译器优化掉。
1.4 HIDL HAL架构详解
HIDL(HAL Interface Definition Language)是Android 8.0 Treble项目引入的架构,旨在将Framework与HAL彻底解耦。HIDL使用.hal文件定义接口,通过hwbinder实现跨进程通信。
HIDL HAL的核心概念包括:
- 接口定义(.hal文件):使用HIDL语言定义服务接口,支持方法、回调、枚举、联合体等。接口包含版本号(如@1.0、@2.0),支持向后兼容。
- hwbinder通信:HIDL使用独立的hwbinder域进行IPC通信,与Framework的binder域隔离,避免相互影响。
- 服务注册与发现:HAL服务启动后向
hwservicemanager注册,Framework通过IServiceManager::get()获取服务代理。 - passthrough模式:为兼容Legacy HAL,HIDL支持passthrough模式,将HAL库加载到调用方进程(同进程调用),但接口仍使用HIDL定义。
// android.hardware.light@2.0::ILight.hal
package android.hardware.light@2.0;
interface ILight {
enum Type : uint32_t {
BACKLIGHT = 0,
KEYBOARD = 1,
BUTTONS = 2,
BATTERY = 3,
NOTIFICATIONS = 4,
ATTENTION = 5,
BLUETOOTH = 6,
WIFI = 7
};
struct LightState {
uint32_t color;
uint32_t flashMode;
uint32_t flashOnMs;
uint32_t flashOffMs;
uint32_t brightnessMode;
};
getLights() generates (vec<Type> types);
setLight(Type type, LightState state) generates (Status ret);
getLightState(Type type) generates (Status ret, LightState state);
};
1.5 AIDL HAL架构详解
AIDL HAL是Android 11开始推广的架构,它使用标准的Android AIDL(Android Interface Definition Language)定义HAL接口,并复用系统binder域进行通信。AIDL HAL旨在统一Android系统的IPC生态,减少HIDL和AIDL两套接口定义语言的维护成本。
AIDL HAL相比HIDL的主要改进点:
- 统一Binder域:不再使用独立的hwbinder,而是复用系统标准binder域,简化了IPC架构。
- 统一的IDL语言:Framework与HAL使用同一种AIDL语言定义接口,开发者只需掌握一种IDL。
- 多语言支持:AIDL HAL支持Java、C++、Rust三种语言实现,而HIDL仅支持C++。
- 更简洁的构建系统:使用
android.hardware_interface模块类型,与HIDL的hidl_interface相比更简洁。 - 向后兼容:AIDL HAL通过
@VintfStability注解和版本号机制保证接口的稳定性。
// android.hardware.light.ILight.aidl
package android.hardware.light;
@VintfStability
interface ILight {
@Backing(type="int")
enum Type {
BACKLIGHT,
KEYBOARD,
BUTTONS,
BATTERY,
NOTIFICATIONS,
ATTENTION,
BLUETOOTH,
WIFI,
};
struct LightState {
int color;
int flashMode;
int flashOnMs;
int flashOffMs;
int brightnessMode;
};
Type[] getLights();
int setLight(Type type, in LightState state);
LightState getLightState(Type type);
}
1.6 三种HAL架构的演进关系与选型建议
三种HAL架构并非完全替代关系,在Android系统中可能同时存在。理解它们的演进关系有助于在移植时做出正确的选型决策。
在实际的驱动移植工作中,建议遵循以下选型原则:
| 场景 | 推荐架构 | 理由 |
|---|---|---|
| 新项目(Android 11+) | AIDL HAL | Google官方推荐,统一Binder生态,多语言支持,维护成本低 |
| 旧项目升级(Android 8~10) | HIDL HAL | 保持与现有BSP兼容,避免大规模重构 |
| 旧项目升级(Android 7.x及以下) | HIDL HAL(passthrough模式) | 可复用Legacy HAL实现,逐步迁移至HIDL |
| 快速原型验证 | Legacy HAL | 开发简单,无需处理IPC,适合快速验证硬件功能 |
| 性能敏感场景(如显示、GPU) | AIDL HAL(或HIDL passthrough) | 减少IPC开销,但需权衡架构统一性 |
# 查看HIDL服务
adb shell lshal
# 查看AIDL服务
adb shell dumpsys | grep "aidl.*hal"
# 查看Legacy HAL模块
adb shell ls /vendor/lib/hw/
adb shell ls /system/lib/hw/
1.7 本章小结
HAL层作为Android系统硬件抽象的核心,其架构演进反映了Android系统对模块化、可维护性和升级友好性的持续追求。从Legacy HAL的同进程直接调用,到HIDL的跨进程解耦,再到AIDL的统一Binder生态,每一次演进都解决了前一阶段的关键痛点。在驱动移植工作中,理解这三种架构的差异、适用场景和迁移路径,是快速定位和解决HAL层问题的前提。