我们将使用 Google 官方推荐的 AOSP (Android Open Source Project) 的 ota_tools 来搭建一个功能齐全的 OTA 服务器,这套工具包含了生成差分包、签名以及提供更新服务所需的一切。

第一部分:核心概念与准备工作
在开始之前,你需要理解几个关键概念:
-
OTA 包的类型:
- Full OTA (完整包): 包含整个系统镜像,适用于从旧版本直接升级到新版本,或者首次安装,文件体积大。
- Incremental OTA (差分包/增量包): 只包含新旧版本之间的差异,文件体积小,更新速度快,节省服务器带宽和用户流量,这是 OTA 的核心优势。
-
ota_tools的工作流程:ota_from_target_files: 这是核心脚本,它接收两个版本的系统镜像(旧版本和新版本)作为输入,生成一个可刷入的 OTA 包(zip文件)。brunch/lunch: 用于编译 AOSP 并生成target-files.zip,这是ota_from_target_files所需的输入文件。signapk: 用于对生成的 OTA 包进行签名,确保其完整性和来源可信。
-
服务器要求:
(图片来源网络,侵删)- 一台可以运行 Linux(推荐 Ubuntu)的服务器。
- 稳定的网络连接。
- 足够的存储空间来存放不同版本的系统镜像和 OTA 包。
- 能够配置 Web 服务器(如 Nginx 或 Apache)来提供文件下载。
-
准备工作:
- 安装 AOSP 编译环境: 确保你的服务器上安装了所有必要的依赖,如
repo,git,make,gcc,openjdk-8-jdk等。 - 下载 AOSP 源码: 使用
repo工具下载完整的 AOSP 源码。mkdir -p ~/aosp cd ~/aosp repo init -u https://android.googlesource.com/platform/manifest repo sync -j$(nproc)
- 下载
ota_tools:ota_tools通常包含在 AOSP 的build/make目录中,如果你使用的是较新的 AOSP 版本,它可能已经被集成,如果没有,你需要单独下载并确保它在你的PATH中。
- 安装 AOSP 编译环境: 确保你的服务器上安装了所有必要的依赖,如
第二部分:构建新版本的系统镜像
你需要一个旧版本的系统镜像(target-files.zip)和一个新版本的系统镜像(target-files.zip)来生成差分包。
假设你已经有一个旧版本的 target-files.zip(my_device-ou-v1.0-target-files.zip),现在我们来构建新版本。
-
选择设备配置并编译:
(图片来源网络,侵删)# 进入 AOSP 源码目录 cd ~/aosp # 设置编译环境 export LC_ALL=C # 选择你的产品配置 (aosp_marlin) lunch aosp_marlin-userdebug # 开始编译,这会生成 system.img, boot.img 等以及最终的 target-files.zip make -j$(nproc) target-files-package
编译成功后,你会在
out/dist/目录下找到类似aosp_marlin-target_files-eng-username.zip的文件,我们将其重命名为my_device-ou-v2.0-target-files.zip。
第三部分:生成 OTA 更新包
现在你有了新旧两个 target-files.zip 文件,可以使用 ota_from_target_files 脚本来生成 OTA 包。
-
生成 Full OTA 包: Full OTA 包可以直接从旧版本刷入到新版本。
# 进入 ota_tools 目录 (通常在 build/make/tools/releasetools/) # 或者直接使用 aosp 源码中的路径 cd ~/aosp/build/make/tools/releasetools/ # 生成 Full OTA 包 ./ota_from_target_files \ -v \ --block \ --extra_script=/path/to/your/custom_script.txt \ # 可选,用于自定义更新逻辑 /path/to/old/target-files.zip \ /path/to/new/target-files.zip \ /path/to/output/MyDevice-OU-v1.0-to-v2.0.zip
-v: 显示详细输出。--block: 生成block映像 OTA 包,这是现代 Android 设备的标准格式。--extra_script: 指定一个自定义脚本,可以在更新前后执行命令(例如备份用户数据、清除缓存等)。
-
生成 Incremental OTA 包: Incremental OTA 包从指定版本升级到新版本。
./ota_from_target_files \ -v \ --block \ --incremental_from=/path/to/old/target-files.zip \ /path/to/new/target-files.zip \ /path/to/output/MyDevice-OU-v1.0-to-v2.0-Incremental.zip
第四部分:签名 OTA 包
这是至关重要的一步! 未签名的 OTA 包会被设备拒绝。
你需要一个与你的系统 ROM 签名相同的密钥,如果你使用的是 AOSP 默认的 testkey,可以直接用它来签名,对于正式发布,你应该使用自己的密钥对。
-
使用
signapk签名:# 进入 ota_tools 目录 cd ~/aosp/build/make/tools/releasetools/ # 签名 Full OTA 包 ./signapk \ -v \ /path/to/platform.x509.pem \ # 证书公钥 /path/to/platform.pk8 \ # 证书私钥 /path/to/output/MyDevice-OU-v1.0-to-v2.0.zip \ /path/to/output/MyDevice-OU-v1.0-to-v2.0-signed.zip # 签名 Incremental OTA 包 ./signapk \ -v \ /path/to/platform.x509.pem \ /path/to/platform.pk8 \ /path/to/output/MyDevice-OU-v1.0-to-v2.0-Incremental.zip \ /path/to/output/MyDevice-OU-v1.0-to-v2.0-Incremental-signed.zip
platform.x509.pem和platform.pk8密钥通常位于build/make/target/product/security/目录下。
最终产物: MyDevice-OU-v1.0-to-v2.0-signed.zip 和 MyDevice-OU-v1.0-to-v2.0-Incremental-signed.zip 就是你可以分发给用户的更新包。
第五部分:搭建 OTA 服务器
现在你需要一个 Web 服务器来托管这些 OTA 包,并告知设备如何获取它们。
-
设置 Web 服务器 (以 Nginx 为例):
# 安装 Nginx sudo apt update sudo apt install nginx # 创建存放 OTA 包的目录 sudo mkdir -p /var/www/ota/my_device/ou/ sudo chown -R $USER:$USER /var/www/ota/my_device/ou/ # 将你签好名的 OTA 包复制到该目录 cp /path/to/output/*-signed.zip /var/www/ota/my_device/ou/
-
配置 Nginx: 编辑 Nginx 的站点配置文件,
/etc/nginx/sites-available/default或创建一个新的配置文件。server { listen 80; server_name your_server_ip; # 替换成你的服务器域名或IP location / { root /var/www/ota; index index.html; autoindex on; # 允许目录列表,方便查看文件 } # 为 OTA 包设置正确的 MIME 类型 location ~* \.zip$ { types { application/zip zip; } root /var/www/ota; } }然后启用配置并重启 Nginx:
sudo ln -s /etc/nginx/sites-available/your_config /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx
你可以通过浏览器访问
http://your_server_ip/my_device/ou/来查看和下载你的 OTA 包。
第六部分:配置设备端检查更新
设备如何知道有新更新?这通常由一个配置文件控制,这个文件通常放在系统分区的 system/etc/otacert.zip 中,或者在启动时由 Recovery 从特定 URL 下载。
- 创建
update_engine配置文件: 在你的设备源码中,你需要修改update_engine的配置,使其指向你的 OTA
