1. HAL 接口定义演进概述:从 Android 早期 HAL 到 Treble 架构的演进历程与设计哲学
1.1 背景:为什么需要 HAL?
Android 操作系统运行在数以万计的不同硬件平台上。从 SoC(骁龙、Exynos、Tensor)到外设(Camera、GPS、NFC),每个硬件厂商都有自己独特的实现方式。如果没有一个标准化的抽象层,Google 每发布一次 Android 大版本升级,芯片厂商和 OEM 都需要重写大量内核驱动和用户空间代码,导致碎片化严重、升级周期漫长。
HAL(Hardware Abstraction Layer) 正是为了解决这一问题而诞生。它位于 Android 框架(Framework)与 Linux 内核驱动之间,为上层提供统一的接口,屏蔽底层硬件的差异。
核心设计目标: 一次编写 HAL 实现,多版本 Android 框架兼容;厂商只需关注 HAL 接口适配,无需修改上层框架。
1.2 早期 HAL 架构(Android 1.0 ~ 7.x):模块化与动态加载
在 Android 早期版本中,HAL 以 共享库(.so) 的形式存在。每个硬件模块(如 camera、audio、gps)对应一个动态链接库,由 Android 的 hw_get_module() 函数在运行时加载。
关键特征
- 模块化定义: 每个 HAL 模块通过
hw_module_t和hw_device_t结构体暴露接口。 - 动态加载: 框架通过模块 ID(如
CAMERA_HARDWARE_MODULE_ID)查找并加载对应的.so文件。 - 厂商绑定: HAL 库与框架运行在同一个进程(
mediaserver或cameraserver)中,直接函数调用,性能高但耦合紧密。
早期 HAL 的痛点: 由于 HAL 库与框架进程紧耦合,一旦 HAL 库出现内存泄漏或崩溃,会导致整个系统服务(如 camera service)挂掉。此外,每次 Android 版本升级,HAL 接口可能发生变化,厂商必须重新编译并发布新的 HAL 库。
1.3 Treble 架构的诞生(Android 8.0+):接口与实现分离
为了解决早期 HAL 的紧耦合问题,Google 在 Android 8.0 中推出了 Project Treble。这是 Android 系统架构史上最大的一次重构。其核心思想是:将 HAL 接口定义与厂商实现彻底分离,并通过稳定的 IPC 机制进行通信。
Treble 带来的关键变化
| 维度 | 早期 HAL | Treble HAL(HIDL) |
|---|---|---|
| 接口定义语言 | C 结构体 + 头文件 | HIDL(HAL Interface Definition Language) |
| 通信方式 | 同进程直接函数调用 | Binderized(跨进程 RPC)或 Passthrough(同进程直通) |
| 框架与 HAL 耦合 | 紧耦合,同进程 | 松耦合,跨进程隔离 |
| 版本升级影响 | HAL 接口变更需厂商重新编译 | HIDL 接口稳定,厂商实现可独立更新 |
| 稳定性 | HAL 崩溃导致系统服务挂掉 | HAL 运行在独立进程,崩溃不影响框架 |
注意: Treble 架构并非完全抛弃了早期 HAL 的模块化思想,而是将接口定义提升为一种正式的、版本化的契约(HIDL .hal 文件)。厂商必须实现 HIDL 接口,而框架则通过 HIDL 服务发现机制与 HAL 通信。
1.4 设计哲学演进:从“模块化”到“契约化”
回顾从早期 HAL 到 Treble 的演进,其背后设计哲学的变化可以归纳为以下几点:
- 从“实现共享”到“接口共享”: 早期 HAL 共享的是
.so二进制库,厂商直接提供代码;Treble 共享的是.hal接口定义文件,厂商提供符合接口的服务实现。 - 从“进程内信任”到“进程间隔离”: 早期 HAL 假设厂商代码与框架代码运行在同一进程,彼此完全信任;Treble 通过进程边界隔离,即使 HAL 实现崩溃也不会影响框架稳定性。
- 从“隐式约定”到“显式版本化”: 早期 HAL 接口变更通过头文件修改和重新编译来同步,版本管理松散;Treble 的 HIDL 接口自带版本号(如
@1.0、@1.1),框架和 HAL 可以独立演进,只要遵守版本兼容规则即可。 - 从“厂商锁定”到“生态解耦”: 早期 HAL 使得 Android 系统升级高度依赖厂商提供新 HAL 库;Treble 允许框架单独升级(通过 Project Mainline 等),厂商 HAL 实现可以保持不变,大大加速了系统安全补丁和版本升级的推送速度。
总结: Treble 架构的引入,本质上是将 HAL 从“一组 C 函数指针”演变为“一个正式的、版本化的、跨进程的接口契约”。这一转变不仅提升了系统的稳定性和安全性,也为后续的 Camera HAL3 等复杂 HAL 的兼容性设计奠定了坚实的基础。
1.5 演进路线图
| Android 版本 | HAL 架构阶段 | 关键特征 |
|---|---|---|
| 1.0 ~ 4.4 | 早期 HAL | hw_get_module() 动态加载 .so,同进程调用 |
| 5.0 ~ 7.x | 早期 HAL + 部分 Binder 化 | 部分服务开始使用 Binder 通信,但 HAL 层仍以 .so 为主 |
| 8.0 ~ 9.0 | Treble (HIDL) | 引入 HIDL,HAL 接口与实现分离,支持 Binderized 和 Passthrough 模式 |
| 10.0+ | Treble + AIDL HAL | 引入 AIDL 作为 HIDL 的替代,统一接口定义语言,进一步简化 HAL 开发 |