Android Recovery系统在OTA(Over-The-Air)更新中扮演着核心角色,它提供了一个独立于主操作系统的环境来安全地执行系统升级。其工作原理和执行流程是一个涉及多个组件协同工作的复杂过程。

一、 OTA更新与Recovery的协作框架

OTA更新并非在主系统运行时直接覆盖系统文件,而是通过Recovery系统在设备重启后,在一个干净、受控的环境中完成关键操作。整个流程可以概括为以下几个阶段:

阶段 执行环境 核心任务 关键组件/文件
1. 准备阶段 Android主系统 下载、验证升级包,并准备启动至Recovery。 RecoverySystem.java, BCB (Bootloader Control Block)
2. 重启与切换 Bootloader 读取BCB指令,引导系统进入Recovery模式。 Bootloader, BCB
3. 安装阶段 Recovery系统 验证并执行升级包中的脚本,更新系统分区。 recovery可执行文件, update-binary, updater-script
4. 收尾与重启 Recovery系统 清理环境,指示Bootloader重启至新系统。 BCB

二、 详细执行流程解析

阶段1:准备阶段(在主系统中)

当用户在系统设置中点击“安装更新”后,主系统开始工作。

  1. 触发与验证RecoverySystem.java 中的接口被调用,系统会验证OTA升级包(通常为 update.zip)的签名,确保其完整性和来源合法性。
  2. 数据准备:对于全量更新,升级包会被直接拷贝到缓存分区。对于增量更新,系统会使用 imgdiff 等工具生成的差分包,在Recovery中通过 applypatch 程序将差分包与当前系统镜像合成新镜像。
  3. 写入启动指令:这是关键一步。系统将一条命令(如 “boot-recovery” 和升级包路径)写入到 BCB (Bootloader Control Block)。BCB是Bootloader能读取的一块特殊内存区域,用于传递指令。
  4. 重启系统:准备就绪后,主系统调用重启命令,设备开始重启。
阶段2:重启与模式切换(由Bootloader控制)
  1. Bootloader在启动初期会读取BCB中的信息。
  2. 如果发现BCB中包含 “boot-recovery” 指令,Bootloader将不再加载正常的内核和系统,而是转而加载 Recovery 分区的内核和 ramdisk,从而启动Recovery系统。
阶段3:安装阶段(在Recovery环境中)

Recovery系统启动后,其主程序会执行以下操作:

  1. 读取指令:从BCB或 CACHE:/command 文件中获取之前写入的升级命令和升级包路径。
  2. 挂载分区:挂载必要的分区,如系统分区(/system)、缓存分区(/cache)等。
  3. 验证与解压:再次验证 update.zip 的签名。验证通过后,将其解压到临时目录。升级包中必须包含一个 META-INF/com/google/android/ 目录,其中有两个关键文件:
    • update-binary:一个可执行的二进制程序,是安装过程的实际执行者。
    • updater-script:一个用Edify语言编写的脚本,包含了具体的安装步骤指令。
  4. 执行安装脚本:Recovery系统调用 update-binary,并传入 updater-script 脚本路径。update-binary 会解析并执行该脚本中的命令。典型脚本内容如下:
    # updater-script 示例
    ui_print("开始安装系统更新...");          # 在Recovery界面显示提示
    assert(getprop("ro.product.device") == "my_device"); # 验证设备型号
    block_image_update("/dev/block/bootdevice/by-name/system", package_extract_file("system.transfer.list"), "system.new.dat", "system.patch.dat"); # 更新system分区
    apply_patch_check("EMMC:/dev/block/bootdevice/by-name/boot:...", ...); # 检查基础版本,用于增量更新
    apply_patch("EMMC:/dev/block/bootdevice/by-name/boot:...", "-", ...); # 应用差分包到boot分区
    ui_print("安装完成!");
    
  5. 处理系统加密:如果设备启用了全盘加密(FDE),Recovery在访问 userdata 分区前需要密钥。此时,一个名为 uncrypt 的服务会在主系统重启前,将加密的升级包解密并重新打包到缓存分区,供Recovery读取。
阶段4:收尾与重启
  1. 清理BCB:安装成功后,Recovery会清除BCB中的命令,防止设备循环进入Recovery模式。
  2. 重启系统:Recovery向系统发出重启命令。Bootloader再次启动,此时BCB已无特殊指令,因此正常加载主系统的内核和ramdisk,设备进入更新后的Android系统。

三、 A/B(无缝)系统更新中的Recovery

在采用A/B分区的设备上,流程有所优化:

  1. 当前运行的系统在A分区(slot A)。OTA包被下载并安装到非活动的B分区(slot B)。
  2. Recovery的作用变化:安装过程可能在后台进行,甚至不需要进入完整的Recovery UI界面。一个简化的 recovery 镜像(有时称为 bootloader 阶段)负责直接写入目标分区。
  3. 更新完成后,Bootloader的引导指令被修改为下次从B分区启动。用户重启设备后即直接进入新系统,实现了“无缝”更新,极大地降低了更新失败变砖的风险。

综上所述,Android Recovery系统是OTA更新的安全执行沙箱。它通过一套由主系统准备、Bootloader中转、Recovery执行的精密流程,确保了系统升级过程即便在出现意外时,也不会破坏主系统的可启动性,是Android系统鲁棒性的关键设计之一。


参考来源

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐