4. HAL开发环境搭建
HAL Service 开发不是“写一个 Java/Kotlin 应用”那么简单,它位于 Android 系统框架与 Linux 内核之间,最终要以 native 进程或 binder 服务的形式运行在设备上。因此,开发环境必须同时具备三块能力:能获取并编译 AOSP 源码、能高效阅读与跳转 C++/AIDL 代码、能通过 adb/fastboot 把产物推入设备并观察运行状态。本节围绕这三块能力,给出可落地的搭建路径。
一、核心原理:HAL 开发环境的三层结构
从工具链角度看,HAL 开发环境可以拆成“源码层—编辑层—设备层”。源码层负责提供 Android 平台代码、HAL 接口定义(AIDL/HIDL)以及编译系统(Soong/Blueprint、Make);编辑层负责代码索引、跳转、补全和远程调试;设备层负责刷机、推送、日志抓取和权限验证。三者缺一不可,否则会出现“能编译但无法调试”或“能调试但改不动系统”的尴尬局面。
二、AOSP 源码下载与编译
AOSP 源码体积大、依赖多,建议使用 Ubuntu 20.04/22.04 LTS,至少 16GB 内存、250GB 以上 SSD 空间。下载前先安装 repo 工具并配置 Git 身份,然后按分支初始化。以 Android 13 为例:
mkdir ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
export PATH=~/bin:$PATH
mkdir aosp && cd aosp
repo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r1
repo sync -c -j8 --no-tags
同步完成后,进入源码根目录执行环境初始化并选择目标设备。若使用 Pixel 真机,可选用对应 aosp_<device> 配置;若使用 Cuttlefish 模拟器,则选择 aosp_cf_x86_64_phone。编译前务必执行 source build/envsetup.sh 和 lunch,否则 m 命令不可用。
source build/envsetup.sh
lunch aosp_cf_x86_64_phone-userdebug
m -j$(nproc)
首次全编通常需要 1~3 小时。若只修改了某个 HAL 模块,可用 m <module_name> 增量编译,例如 m android.hardware.light-service.example。编译产物位于 out/target/product/<device>/,其中 system.img、vendor.img 可用于刷机,system/bin 与 vendor/bin 下可找到 HAL 可执行文件。
ccache 打开(export USE_CCACHE=1),可显著缩短二次编译时间。三、Android Studio 与 VSCode 配置
Android Studio 适合查看 AIDL、Java/Kotlin 框架层以及使用 adb 面板;VSCode 更适合 C++ HAL 实现、Soong 脚本和快速全局搜索。两者可以共存,关键是让它们都能正确索引 AOSP 源码。
- Android Studio:安装 Android SDK、Platform-Tools,配置
ANDROID_HOME;通过 “Open” 打开 AOSP 根目录下的development/tools/idegen生成的android.ipr,可获得较完整的模块索引。 - VSCode:安装 C/C++、clangd、AIDL、Soong 语法高亮等插件;在 AOSP 根目录执行
source build/envsetup.sh && lunch <target>后,用bear -- make -j8或compdb生成compile_commands.json,clangd 才能准确跳转。 - 远程调试:VSCode 安装 “Remote - SSH”,直接连接编译服务器;Android Studio 可使用 “Remote Development” 或通过
adb连接设备进行 native 调试。
# VSCode 生成编译数据库示例
source build/envsetup.sh
lunch aosp_cf_x86_64_phone-userdebug
bear -- make -j$(nproc) # 生成 compile_commands.json
四、adb 与 fastboot 调试环境准备
adb 负责设备在线时的安装、推送、shell 和日志;fastboot 负责 bootloader 模式下的分区刷写。二者都来自 Android SDK Platform-Tools,安装后需把路径加入 PATH,并配置 udev 规则,避免 Linux 下出现 “no permissions” 问题。
sudo apt install android-tools-adb android-tools-fastboot
adb version
fastboot --version
# 查看设备
adb devices -l
adb shell getprop ro.build.version.release
# 推送 HAL 可执行文件并赋权
adb root
adb remount
adb push out/target/product/<device>/vendor/bin/hw/vendor.example.hal@1.0-service /vendor/bin/hw/
adb shell chmod 755 /vendor/bin/hw/vendor.example.hal@1.0-service
# 抓取 HAL 日志
adb logcat -b all | grep -i "example_hal"
adb shell dmesg | grep -i "example"
若需要刷入自编译镜像,先进入 bootloader:adb reboot bootloader,再执行 fastboot flashall -w 或按分区刷写。注意 -w 会清除用户数据,调试阶段建议保留,量产验证时再决定是否擦除。
adb push 到 /vendor 验证,确认无误后再整体刷机。五、常见误区与复盘清单
| 误区 | 现象 | 正确做法 |
|---|---|---|
| 未执行 lunch 就编译 | m 命令找不到或目标错误 |
先 source build/envsetup.sh 再 lunch |
| VSCode 无法跳转 C++ | 头文件标红、符号找不到 | 生成 compile_commands.json 并配置 clangd |
| adb 提示 no permissions | Linux 下设备列表为空 | 配置 udev 规则并重新插拔设备 |
| 直接刷全量镜像验证 HAL | 耗时且风险高 | 先用 adb push + logcat 快速验证 |
| 忽略 SELinux 权限 | HAL 进程启动即被拒绝 | 检查 avc: denied 并补充 vendor.te 规则 |
环境搭建完成后,建议做一次最小闭环验证:编译一个示例 HAL、push 到设备、启动服务、用 logcat 确认注册成功,再用 adb shell service list 或 lshal 查看服务是否可见。只有这条链路跑通,后续的接口实现、权限配置和性能调优才有稳定的调试基础。