4. 开发环境搭建
GKI内核构建不是“下载一个内核源码、敲一条make”就能完成的事情。它依赖一整套与AOSP版本严格匹配的主机环境、源码树和工具链。本章把开发环境拆成五个可验证的环节:Ubuntu主机准备、编译依赖安装、repo工具与AOSP源码下载、Android内核源码获取、目录结构解析。每个环节都给出可执行的命令和判断标准,避免“装完却编不过”的常见困境。
一、核心原理:为什么环境必须“版本对齐”
Android内核构建的本质是“用AOSP提供的构建系统,把内核源码编译成boot.img中的kernel”。这里的依赖关系是双向的:内核源码的构建脚本(如build/build.sh、build_abi.sh)来自AOSP的kernel/build仓库;而AOSP的构建又依赖主机上的Python、JDK、GCC/Clang、libc等版本。任何一处版本漂移,都会在编译中途以“找不到符号”“ABI不匹配”“Python模块缺失”等形式爆发。
因此,环境搭建的目标不是“装上最新版”,而是“装上与目标Android版本匹配的版本”。例如Android 13的GKI内核通常要求Ubuntu 20.04/22.04、Python 3.8+、OpenJDK 11,并使用AOSP预置的Clang工具链,而不是系统自带的GCC。
android13-5.15内核分支对应android-13.0.0_r*的AOSP标签)。二、Ubuntu主机配置与编译依赖安装
推荐使用Ubuntu 20.04 LTS或22.04 LTS的物理机/虚拟机,磁盘至少400GB(AOSP+内核源码+编译产物),内存建议32GB以上,否则链接阶段极易OOM。首先安装基础依赖:
sudo apt update
sudo apt install -y git curl python3 python3-pip openjdk-11-jdk \
build-essential zip unzip flex bison libssl-dev libelf-dev \
bc rsync ccache libncurses5-dev libncursesw5-dev \
gcc-multilib g++-multilib libc6-dev-i386 lib32z1-dev
接着配置git身份与repo工具。repo是Google用Python写的多仓库管理脚本,必须放在PATH中:
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
mkdir -p ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
export PATH=~/bin:$PATH
验证依赖是否齐全,可用AOSP自带的检查脚本(下载源码后执行):source build/envsetup.sh后运行lunch,若提示缺少包,按提示补装即可。
三、AOSP源码下载与repo工作流
AOSP源码体积巨大,必须使用repo init指定分支和清单,再repo sync拉取。以Android 13为例:
mkdir ~/aosp && cd ~/aosp
repo init -u https://android.googlesource.com/platform/manifest \
-b android-13.0.0_r3 --depth=1
repo sync -c -j8 --no-tags --no-clone-bundle
-c只拉当前分支,--depth=1浅克隆,能显著减少下载量。若网络不稳定,可配置国内镜像源,但需注意镜像的同步时间可能滞后。同步完成后,repo status应无报错,ls能看到build/、kernel/、device/等目录。
repo sync -c增量同步;repo start <分支名> --all为所有仓库创建本地分支;repo forall -c "git reset --hard"批量重置。四、Android内核源码获取与目录结构解析
GKI内核源码不在AOSP主manifest中,而是独立的kernel/common仓库。获取方式有两种:一是用repo初始化内核manifest,二是直接git clone。推荐前者,便于管理多个内核分支:
mkdir ~/kernel && cd ~/kernel
repo init -u https://android.googlesource.com/kernel/manifest \
-b common-android13-5.15
repo sync -c -j8
同步后目录结构如下,理解它是后续配置和编译的基础:
| 目录/文件 | 作用 | GKI适配关注点 |
|---|---|---|
common/ | 内核主体源码(Linux 5.15) | 驱动、Kconfig、Makefile所在 |
common/arch/arm64/ | ARM64架构相关代码 | 设备树、defconfig、boot协议 |
common/drivers/ | 设备驱动 | 厂商驱动常以模块形式加入 |
build/ | 构建脚本与工具链配置 | build.sh、build_abi.sh |
prebuilts/ | 预编译Clang、GCC工具链 | 必须使用此处的Clang |
common/abi/ | ABI符号列表 | GKI ABI稳定性校验 |
其中build/build.sh是内核编译入口,build/build_abi.sh用于生成和校验ABI。GKI的核心约束是“内核镜像与厂商模块之间的ABI必须稳定”,因此common/abi/下的符号列表是适配时的红线,不能随意增删导出符号。
五、案例场景:从零到可编译的验证路径
假设目标设备是Pixel 6(Android 13,内核5.15)。完整验证路径如下:
- 在Ubuntu 22.04上安装依赖,配置repo并加入PATH。
- 下载AOSP
android-13.0.0_r3,执行source build/envsetup.sh和lunch aosp_oriole-userdebug,确认无缺包报错。 - 下载内核
common-android13-5.15,进入common/执行BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh。 - 编译成功后,在
out/android13-5.15/dist/下应看到Image.lz4、System.map、vmlinux等产物。 - 用
build/build_abi.sh --update检查ABI是否与common/abi/一致,若不一致需分析新增/删除的符号。
prebuilts/clang/host/linux-x86/下的Clang,否则会出现“unknown register name”或ABI校验失败。另一个误区是忽略--depth=1导致下载数百GB历史数据,磁盘瞬间占满。六、复盘与检查清单
环境搭建完成后,用以下清单逐项确认,可避免90%的编译失败:
- Ubuntu版本是否为20.04/22.04,磁盘剩余是否大于200GB。
repo是否在PATH中,repo --version能否正常输出。- AOSP分支与内核分支是否来自同一Android版本说明。
build/build.sh是否使用prebuilts中的Clang。common/abi/下的符号列表是否与当前内核分支匹配。- 编译产物是否包含
Image.lz4和System.map。
完成以上步骤后,主机环境、AOSP源码、repo工具、编译依赖和内核源码树均已就绪,且目录结构清晰可查。后续的GKI内核配置、编译与ABI校验,都将在这个基础上展开。