3、源码结构解析:AOSP 顶层目录详解
拿到 AOSP 源码之后,第一件事是什么?
我个人习惯,不是急着编译,而是先逛一圈顶层目录。就像搬进新房子,总得先看看客厅、厨房、卧室都在哪。AOSP 的顶层目录,就是整栋房子的户型图。搞懂了它,后面编译、调试、定制 ROM 的时候,你才知道该去哪找东西。
3.1 整体俯瞰:AOSP 顶层目录长什么样?
你同步完源码,在根目录下执行 ls,会看到几十个文件夹。别慌,核心的就那么几个。我画了一张图,帮你快速建立全局认知:
3.2 build —— 编译系统的总指挥部
build/ 目录,说白了就是整个 AOSP 的编译引擎。你执行 source build/envsetup.sh 和 lunch 的时候,调用的就是这里的东西。
里面主要有三块:
- soong/:Android 新的构建系统,基于 Go 语言。现在新项目都用它。
- make/:传统的 Makefile 构建。老项目还在用,但 Google 在逐步迁移。
- blueprint/:soong 的底层构建描述语言。你写的
Android.bp文件,就是 blueprint 格式。
Android.bp,别再用 Android.mk 了。我在 2022 年接手一个项目时,发现还有人在用 Makefile 写新模块,结果编译报错查了半天,最后发现是 soong 和 make 的混合模式出了问题。
3.3 device —— 你的硬件平台在这里安家
device/ 目录,是每个硬件平台的「身份证」。你想想看,不同的手机厂商、不同的芯片方案,它们的硬件配置、内核参数、分区大小都不一样。这些差异,全写在这里。
目录结构一般是:device/<厂商名>/<产品名>/
举个例子:
device/google/pixel/
├── BoardConfig.mk # 主板配置:芯片、内存、分区大小
├── device.mk # 产品定义:包含哪些模块
├── system.prop # 系统属性默认值
├── overlay/ # 资源覆盖层
└── sepolicy/ # SELinux 策略
这里有个坑,我踩过好几次:BoardConfig.mk 里的 TARGET_BOARD_PLATFORM 一定要写对。有一次我帮同事排查编译错误,发现他写了个不存在的平台名,结果编译链直接报找不到 HAL 实现。嗯,这种低级错误,查起来最费时间。
3.4 hardware —— 硬件抽象层的大本营
hardware/ 目录,存放的是 Android 硬件抽象层(HAL)的接口定义和参考实现。说白了,就是告诉上层「硬件长什么样,该怎么操作」。
重点看这几个:
- libhardware/:HAL 的核心框架。里面定义了
hw_module_t、hw_device_t这些基础结构体。 - interfaces/:HIDL 接口定义。Android 8.0 之后,HAL 都用 HIDL 来描述了。
- broadcom/、ti/、qcom/:芯片厂商的参考实现。不过现在很多厂商都把这些移到
vendor/里了。
hardware/interfaces/ 里的 HIDL 文件。这些是 Google 定义的稳定接口。我曾经见过有人为了加一个私有接口,直接改了官方的 types.hal,结果升级 Android 版本时,所有依赖这个接口的模块全崩了。
3.5 system —— Android 系统的核心守护者
system/ 目录,是 Android 系统服务的「心脏」。里面跑着各种核心守护进程和库。
| 子目录 | 作用 | 我常改的地方 |
|---|---|---|
| core/ | init、logd、adbd 等核心守护进程 | init.rc 启动脚本,定制开机流程时必改 |
| bt/ | 蓝牙协议栈(Fluoride) | 很少动,除非要修蓝牙兼容性问题 |
| net/ | 网络相关服务(netd、dns) | 改过 DNS 缓存策略,解决过网页加载慢的问题 |
| vold/ | 存储管理(挂载、加密) | 定制分区加密方案时必看 |
| sepolicy/ | SELinux 安全策略 | 加新设备节点时,这里不配好,服务直接起不来 |
我个人觉得,system/core/init/ 是定制 ROM 时最常打交道的地方。你想想看,开机动画怎么改?开机自启服务怎么加?selinux 权限怎么放?全在这。
3.6 vendor —— 厂商私货的藏身之处
vendor/ 目录,是芯片厂商和 OEM 放「私货」的地方。比如高通的 GPU 驱动、博通的 WiFi 固件、还有各种闭源的 HAL 实现。
为什么要有这个目录?
- 闭源二进制:很多硬件驱动不开源,只能以 .so 或 .img 形式提供。
- 厂商定制:比如小米的快充方案、华为的相机算法,都放在这里。
- 分区独立:编译时
vendor/会单独打包成vendor.img,方便 OTA 升级时只更新 vendor 分区。
vendor/ 里的东西尽量不要动。动了之后,厂商的 OTA 包可能就刷不进去了。我见过有人为了精简系统,把 vendor 里的某个 .so 删了,结果相机直接打不开——因为那个 .so 是相机 HAL 的依赖。
3.7 其他值得关注的目录
除了上面五个核心目录,还有几个也值得了解:
- frameworks/:Android 框架层,Java 代码为主。改 UI、加系统服务都在这里。
- packages/:系统应用,比如 Settings、Launcher、Phone。
- external/:第三方开源库,比如 SQLite、libpng、curl。
- kernel/:有些 AOSP 版本会包含内核源码,但大部分厂商会单独维护。
嗯,这里要注意:external/ 里的库,尽量不要自己改版本。有一次我想把 libcurl 升级到最新版,结果发现 AOSP 里好几个模块都依赖特定版本的 API,一升级编译直接报几百个错误。后来我学乖了,除非有安全漏洞,否则不动它。
3.8 实战建议:如何快速定位你要改的目录?
刚开始接触 AOSP 时,最头疼的就是「我要改某个功能,该去哪个目录找?」
我总结了一个简单的方法:
- 改开机流程 →
system/core/init/+device/<厂商>/<产品>/init.rc - 改系统属性 →
device/<厂商>/<产品>/system.prop - 加硬件支持 →
hardware/interfaces/+vendor/<厂商>/ - 改系统 UI →
frameworks/base/+packages/apps/ - 改编译配置 →
build/soong/+device/<厂商>/<产品>/BoardConfig.mk
这个方法,我在带新人时一直在用。你想想看,只要记住「功能对应目录」这个映射关系,AOSP 源码就不再是一团乱麻了。
公众号:蓝海资料掘金营,微信deep3321