4. 下载Android内核源码:使用repo工具同步AOSP内核、选择合适的分支与tag

Android内核源码的获取是独立编译环境搭建的核心环节。由于AOSP(Android Open Source Project)包含数百个Git仓库,Google推荐使用repo工具进行批量管理。本节将详细讲解repo工具的安装、清单文件配置、分支与标签选择策略,以及同步过程中的常见问题。

核心原则:选择与目标设备Android版本完全匹配的内核分支。例如,Android 13设备必须使用android-13.0.0_rX系列标签,混用分支会导致驱动不兼容或编译失败。

4.1 repo工具的工作原理与安装

repo是一个基于Python的脚本工具,本质是对Git命令的封装。它通过一个manifest.xml清单文件描述所有需要同步的Git仓库列表、分支和路径,实现“一次命令,同步百库”的效果。

repo vs Git:Git管理单个仓库,repo管理由多个Git仓库组成的项目群。repo不替代Git,而是作为Git的“调度器”。

4.1.1 安装repo

在Ubuntu 22.04 LTS环境中,执行以下步骤安装repo:

# 1. 创建bin目录并加入PATH
mkdir -p ~/bin
export PATH=~/bin:$PATH

# 2. 下载repo脚本(使用国内镜像加速)
curl -sSL 'https://storage.googleapis.com/git-repo-downloads/repo' -o ~/bin/repo

# 3. 设置可执行权限
chmod a+x ~/bin/repo

# 4. 验证安装
repo --version
网络注意事项:如果无法访问Google域名,请使用清华镜像源:https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/repo。同时,后续的repo init命令也需要指定镜像URL。

4.1.2 repo工作流程示意

下图展示了repo从清单解析到多仓库同步的完整流程:

repo 同步工作流程 repo init manifest.xml 仓库列表解析 repo sync 并行Git clone 本地源码目录 说明:repo init 下载清单文件,repo sync 根据清单并行拉取所有仓库。 默认并行数为4,可通过 -j 参数调整(如 repo sync -j8)。

4.2 选择合适的分支与标签

Android内核源码的分支命名遵循严格的规范。选择错误的分支会导致内核版本与Android系统不匹配,进而引发驱动加载失败、系统服务崩溃等问题。

4.2.1 分支命名规则

分支类型 命名示例 适用场景
通用内核分支 android-13.0.0_rX 通用系统开发、模拟器、AOSP编译
设备专用分支 android-msm-pixel-13.0.0_rX Pixel设备、高通平台定制
长期支持分支 android-13.0.0_lts_rX 安全补丁持续更新、产品化阶段
开发分支 android-14.0.0_rX 新功能验证、预览版开发
如何确定设备的分支?查看设备的/proc/version文件,或从设备厂商的公开内核仓库中查找对应的manifest.xml。Pixel设备可在Google官方清单仓库中找到对应条目。

4.2.2 标签(Tag)与分支(Branch)的选择策略

分支是持续移动的指针,标签是固定不变的快照。对于可复现的编译环境,应优先使用标签而非分支。

对比维度 分支(Branch) 标签(Tag)
可变性 可变,新提交会更新分支指针 不可变,指向固定commit
适用阶段 日常开发、持续集成 发布版本、基线锁定
可复现性 低(分支内容随时间变化) 高(标签内容永久固定)
推荐场景 团队协作开发 课程实验、产品发布

4.3 使用repo init初始化清单

初始化操作会从远程服务器下载manifest.xml文件,该文件定义了所有需要同步的仓库及其分支信息。

4.3.1 基本初始化命令

# 创建内核源码目录
mkdir ~/aosp-kernel
cd ~/aosp-kernel

# 初始化通用内核清单(使用清华镜像)
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/kernel/manifest \
          -b android-13.0.0_r83 \
          --depth=1

# 参数说明:
# -u:指定manifest仓库URL
# -b:指定分支或标签
# --depth=1:浅克隆,只下载最新commit,节省空间
浅克隆注意事项:--depth=1会大幅减少下载量(从数十GB降至数GB),但后续无法使用git log查看历史。如果需要完整历史,请去掉该参数。

4.3.2 查看清单文件内容

初始化完成后,.repo/manifest.xml文件包含了所有仓库的配置信息:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <remote name="aosp" fetch="https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/kernel"/>
  <default revision="refs/tags/android-13.0.0_r83" remote="aosp"/>

  <project path="common" name="kernel/common" groups="common"/>
  <project path="goldfish" name="kernel/goldfish" groups="goldfish"/>
  <project path="msm" name="kernel/msm" groups="msm"/>
  <project path="tegra" name="kernel/tegra" groups="tegra"/>
</manifest>

关键字段说明:

  • remote:定义远程仓库的别名和基础URL
  • default:设置默认的分支/标签和远程仓库
  • project:每个Git仓库的本地路径和远程名称
  • groups:仓库分组标签,用于选择性同步

4.4 执行repo sync同步源码

初始化完成后,使用repo sync命令开始下载所有内核仓库的源码。

4.4.1 同步命令详解

# 完整同步所有仓库
repo sync -j4 --force-sync --no-clone-bundle

# 参数说明:
# -j4:并行任务数,根据CPU核心数调整(建议为CPU核心数+1)
# --force-sync:强制覆盖本地修改,保持与远程一致
# --no-clone-bundle:不使用clone bundle(避免某些网络环境下的错误)

# 仅同步指定分组(如仅同步通用内核)
repo sync -j4 --force-sync common

# 断点续传(如果同步中断)
repo sync --force-sync --fail-fast

4.4.2 同步过程中的常见问题与解决方案

错误现象 可能原因 解决方案
fatal: unable to access 网络连接失败或URL错误 检查网络代理设置,更换镜像源
error: revision refs/tags/xxx not found 指定的标签不存在 使用git ls-remote验证标签是否存在
sync -j4 卡住不动 某个仓库下载缓慢或挂起 按Ctrl+C中断,使用--fail-fast重试
disk space不足 完整同步需要约30-50GB空间 使用--depth=1浅克隆,或只同步必要分组

4.5 验证同步结果与切换分支

同步完成后,需要验证源码完整性,并根据实验需求切换到特定分支或标签。

4.5.1 验证同步状态

# 查看所有仓库的当前分支状态
repo status

# 查看当前所在的分支
cd common
git branch -a

# 查看当前commit的标签
git describe --tags

# 查看所有远程标签
git tag -l "android-13*"

4.5.2 切换分支/标签

# 切换到特定标签(所有仓库)
repo forall -c 'git checkout android-13.0.0_r83'

# 仅切换common仓库
cd common
git checkout android-13.0.0_r83

# 创建本地开发分支
git checkout -b my-kernel-dev android-13.0.0_r83
最佳实践:始终在标签基础上创建本地分支进行开发。不要直接在标签上提交,因为标签是只读的。使用git checkout -b <新分支名> <标签名>创建可写分支。

4.6 本章小结

通过本节学习,你已经掌握了:

  • repo工具的安装与核心概念(manifest清单、多仓库管理)
  • Android内核分支命名规则与选择策略(通用分支 vs 设备专用分支)
  • 标签与分支的适用场景对比(可复现性优先选择标签)
  • 完整的repo init + repo sync操作流程
  • 同步错误的诊断与修复方法