第1章:开发环境搭建
AOSP源码下载与编译
做Camera HAL开发,第一步就是把AOSP环境搭起来。说实话,这一步看着简单,但坑不少。我刚开始带团队时,就有人因为环境没配好,白白浪费了两天时间。
先说说硬件要求。AOSP全量编译,说白了就是吃资源。我个人习惯用Ubuntu 20.04 LTS,内存至少16GB,硬盘留出300GB以上。为什么?因为一次完整编译下来,中间产物就能吃掉100多GB。你想想看,要是硬盘不够,编译到一半报错,那才叫崩溃。
下载源码,我推荐用清华或中科大的镜像站。速度比Google官方快太多了。具体操作:
# 安装repo工具
mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
# 初始化仓库
mkdir aosp
cd aosp
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-13.0.0_r41
# 同步源码
repo sync -c -j8
这里有个细节:-j8是并行下载线程数,根据你的网络带宽和CPU核心数调整。我一般设成CPU核心数的两倍。
编译前,记得安装依赖库。Ubuntu 20.04上,我常用的命令:
sudo apt-get install git-core gnupg flex bison build-essential \
zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 \
libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev \
lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig
嗯,这里要注意。不同Android版本依赖略有差异。比如Android 13开始,需要Python 3.8以上。我遇到过有人用Python 3.6编译,结果报了一堆语法错误。
编译命令很简单:
source build/envsetup.sh
lunch aosp_arm64-eng
make -j16
lunch时选哪个target?做Camera HAL开发,我建议选aosp_arm64-eng。eng版本带debug工具,方便调试。userdebug也行,但有些权限限制。
make -j$(nproc)自动检测CPU核心数。但如果你在虚拟机里,建议手动设小一点,比如-j4。否则内存爆了,编译会直接卡死。
Camera HAL模块单独编译
全量编译一次太慢了,动辄一两个小时。实际开发中,我们只改Camera HAL的代码,没必要每次都全编。单独编译HAL模块,能省下大量时间。
Camera HAL的代码一般在hardware/interfaces/camera或hardware/qcom/camera(高通平台)。我以AOSP原生HAL为例:
# 先source环境
source build/envsetup.sh
lunch aosp_arm64-eng
# 单独编译camera HAL模块
make android.hardware.camera.provider@2.4-impl -j8
# 或者编译整个camera相关模块
make camera -j8
编译完后,输出文件在out/target/product/xxx/vendor/lib/hw/下。比如camera.xxx.so。你可以用adb push直接推到设备上替换。
我曾经犯过一个错误:只编译了HAL模块,但忘了更新对应的manifest文件。结果刷进去后,Treble机制检测不到新模块,直接回退到旧版本。排查了半天才发现问题。
刷机与调试环境配置
刷机这块,不同设备差异很大。我以Pixel设备为例,讲一下通用流程。
首先,解锁bootloader:
adb reboot bootloader
fastboot flashing unlock
# 按音量键确认解锁
解锁后,刷入我们编译好的镜像:
# 进入fastboot模式
adb reboot bootloader
# 刷入所有分区
fastboot flashall -w
# 或者只刷指定分区
fastboot flash boot boot.img
fastboot flash system system.img
fastboot flash vendor vendor.img
-w参数会清除用户数据。第一次刷机建议加上,避免旧数据干扰。后续迭代开发,可以不加-w,保留数据。
调试环境配置,我习惯用以下工具链:
| 工具 | 用途 | 安装方式 |
|---|---|---|
| adb | 设备通信、文件传输 | AOSP自带 |
| logcat | 抓取日志 | adb logcat |
| gdb | Native调试 | sudo apt install gdb-multiarch |
| strace | 系统调用跟踪 | adb shell strace |
| perf | 性能分析 | adb shell perf |
抓取Camera HAL日志,我常用的命令:
# 过滤Camera相关日志
adb logcat -s CameraService:V CameraHal:V
# 保存到文件
adb logcat -s CameraService:V CameraHal:V > camera_log.txt
# 实时查看并过滤关键字
adb logcat | grep -E "Camera|HAL|error"
调试Native代码时,我推荐用gdb配合gdbserver。具体步骤:
# 在设备上启动gdbserver
adb shell gdbserver :5039 --attach [pid]
# 在主机上连接
adb forward tcp:5039 tcp:5039
gdb-multiarch out/target/product/xxx/symbols/vendor/lib/hw/camera.xxx.so
(gdb) target remote :5039
Android.mk或Android.bp中,确保LOCAL_STRIP_MODULE := false。否则你看到的堆栈全是地址,根本没法定位问题。
最后,说一个我踩过的坑。有一次刷机后,Camera HAL一直加载失败。查了半天,发现是SELinux策略没更新。新编译的HAL模块需要对应的te文件权限。解决方案:要么关闭SELinux(adb shell setenforce 0),要么更新sepolicy并重新编译boot.img。
嗯,环境搭建就这些。看似繁琐,但一次配好,后面开发就顺畅了。下一章,我们开始讲Camera HAL的架构和初始化流程。