自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
非 A/B 系统更新
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
非 AB 更新是一种已废弃的 OTA 方法,旧版 Android 设备(Android 6 及更低版本)使用该方法。这些设备可在专用的 recovery 分区中使用软件解压下载的更新软件包并将更新应用到其他分区。
在老款的没有 A/B 分区的 Android 设备上,闪存空间通常包含以下分区:
- boot
-
包含 Linux 内核和最小的根文件系统(加载到 RAM 磁盘)。它装载了系统和其他分区,并启动位于 system 分区上的运行时。
- system
-
包含在 Android 开源项目 (AOSP) 上提供源代码的系统应用和库。在正常操作期间,此分区被装载为只读分区;其内容仅在 OTA 更新期间更改。
- 供应商
-
包含在 Android 开源项目 (AOSP) 上未提供源代码的系统应用和库。在正常操作期间,此分区被装载为只读分区;其内容仅在 OTA 更新期间更改。
- 用户数据
-
存储由用户安装的应用所保存的数据等。OTA 更新过程通常不会触及该分区。
- 缓存
- 供几个应用使用的临时保留区域(访问此分区需要使用特殊的应用权限),用于存储下载的 OTA 更新软件包。其他程序也可使用该空间,但是此类文件可能会随时消失。安装某些 OTA 软件包可能会导致此分区被完全擦除。cache 分区还包含 OTA 更新的更新日志。
- 恢复
- 包含第二个完整的 Linux 系统,其中包括一个内核和特殊的恢复二进制文件,该文件可读取一个软件包并使用其内容来更新其他分区。
- misc
- 执行恢复操作时使用的微小分区,可在应用 OTA 软件包并重新启动设备时,隐藏某些进程的信息。
OTA 更新过程
典型 OTA 更新包含以下步骤:
- 设备会定期与 OTA 服务器进行确认,并在有可用的更新时获得通知,包括更新软件包的 URL 和向用户显示的描述字符串。
-
将更新下载到 cache 或 userdata 分区,并根据
/system/etc/security/otacerts.zip
中的证书验证加密签名。系统提示用户安装更新。
-
设备重新启动进入恢复模式,引导 recovery 分区中的内核和系统(而非 boot 分区中的内核)启动。
-
recovery 分区的二进制文件由 init 启动。它会在
/cache/recovery/command
中寻找将其指向下载软件包的命令行参数。
- 恢复操作会根据
/res/keys
(包含在 recovery 分区中的 RAM 磁盘的一部分)中的公钥来验证软件包的加密签名。
-
从软件包中提取数据,并根据需要使用该数据更新 boot、system 和/或 vendor 分区。system 分区上的某个新文件包含新的 recovery 分区的内容。
-
设备正常重启。
-
加载最新更新的 boot 分区,在最新更新的 system 分区中装载并开始执行二进制文件。
-
作为正常启动的一部分,系统会根据所需内容(预先存储为
/system
中的一个文件)检查 recovery 分区的内容。二者内容不同,所以 recovery 分区会被所需内容重新刷写(在后续引导中,recovery 分区已经包含新内容,因此无需重新刷写)。
系统更新完成!更新日志可以在 /cache/recovery/last_log.#
中找到。
更新软件包
更新软件包是包含可执行二进制文件 META-INF/com/google/android/update-binary
的 .zip
文件。对软件包上的签名进行验证后,recovery
会将该二进制文件解压到 /tmp
并运行该二进制文件,同时传递以下参数:
-
更新二进制 API 版本号。如果向更新二进制文件传递的参数发生变化,此数字将递增。
-
命令管道的文件描述符。更新程序可以使用此管道将命令发送回恢复二进制文件,主要用于界面变化,例如向用户指示进度。
- 更新软件包
.zip
文件的文件名。
更新软件包可以使用任何静态链接的二进制文件作为更新二进制文件。OTA 软件包构建工具使用更新程序 (bootable/recovery/updater
),该程序提供了一种可以执行很多安装任务的简单脚本语言。您可以替换设备上运行的任何其他二进制文件。
如需详细了解更新程序二进制文件、edify 语法和内建函数,请参阅 OTA 软件包内部探秘。
从更早版本迁移
当从 Android 2.3/3.0/4.0 版本进行迁移时,主要变化是将设备专属的功能从一组具有预定义名称的 C 函数转换为 C++ 对象。下表列出了用途大致相同的旧函数和新方法:
C 函数 |
C ++ 方法 |
device_recovery_start() |
Device::RecoveryStart() |
device_toggle_display() device_reboot_now()
|
RecoveryUI::CheckKey() (也称为 RecoveryUI::IsKeyPressed())
|
device_handle_key() |
Device::HandleMenuKey() |
device_perform_action() |
Device::InvokeMenuItem() |
device_wipe_data() |
Device::WipeData() |
device_ui_init() |
ScreenRecoveryUI::Init() |
将旧函数转化为新方法应尽量简单直观。不要忘记添加新的 make_device()
函数来创建并返回新设备子类的实例。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-27。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-07-27。"],[],[],null,["# Non-A/B system updates\n\nNon AB updates are a deprecated OTA methodology used by older Android Devices (Android 6 and\nearlier). These devices have a dedicated recovery partition containing the software needed to\nunpack a downloaded update package and apply the update to the other partitions.\n\n\nOn older Android devices without A/B partitions, the flash space typically contains the\nfollowing partitions:\n\nboot\n:\n Contains the Linux kernel and a minimal root filesystem (loaded into a RAM disk). It mounts\n system and other partitions and starts the runtime located on the system partition.\n\nsystem\n:\n Contains system applications and libraries that have source code available on Android Open\n Source Project (AOSP). During normal operation, this partition is mounted read-only; its\n contents change only during an OTA update.\n\nvendor\n:\n Contains system applications and libraries that do *not* have source code available\n on Android Open Source Project (AOSP). During normal operation, this partition is mounted\n read-only; its contents change only during an OTA update.\n\nuserdata\n:\n Stores the data saved by applications installed by the user, etc. This partition is not\n normally touched by the OTA update process.\n\ncache\n:\n Temporary holding area used by a few applications (accessing this partition requires special\n app permissions) and for storage of downloaded OTA update packages. Other programs use this\n space with the expectation that files can disappear at any time. Some OTA package\n installations may result in this partition being wiped completely. The cache also contains\n the update logs from an OTA update.\n\nrecovery\n:\n Contains a second complete Linux system, including a kernel and the special recovery binary\n that reads a package and uses its contents to update the other partitions.\n\nmisc\n:\n Tiny partition used by recovery to stash some information away about what it is doing in\n case the device is restarted while the OTA package is being applied.\n\nLife of an OTA update\n---------------------\n\nA typical OTA update contains the following steps:\n\n1. Device performs regular check in with OTA servers and is notified of the availability of an update, including the URL of the update package and a description string to show the user.\n2. Update downloads to a cache or data partition, and its cryptographic signature is verified against the certificates in `/system/etc/security/otacerts.zip`. User is prompted to install the update.\n3. Device reboots into recovery mode, in which the kernel and system in the recovery partition are booted instead of the kernel in the boot partition.\n4. Recovery binary is started by init. It finds command-line arguments in `/cache/recovery/command` that point it to the downloaded package.\n5. Recovery verifies the cryptographic signature of the package against the public keys in `/res/keys` (part of the RAM disk contained in the recovery partition).\n6. Data is pulled from the package and used to update the boot, system, and/or vendor partitions as necessary. One of the new files left on the system partition contains the contents of the new recovery partition.\n7. Device reboots normally.\n 1. The newly updated boot partition is loaded, and it mounts and starts executing binaries in the newly updated system partition.\n 2. As part of normal startup, the system checks the contents of the recovery partition against the desired contents (which were previously stored as a file in `/system`). They are different, so the recovery partition is reflashed with the desired contents. (On subsequent boots, the recovery partition already contains the new contents, so no reflash is necessary.)\n\n\nThe system update is complete! The update logs can be found in\n`/cache/recovery/last_log.`\u003cvar translate=\"no\"\u003e#\u003c/var\u003e.\n\nUpdate packages\n---------------\n\n\nAn update package is a `.zip` file that contains the executable binary\n`META-INF/com/google/android/update-binary`. After verifying the signature on the\npackage, `recovery` extracts this binary to `/tmp` and runs the binary,\npassing the following arguments:\n\n- **Update binary API version number**. If the arguments passed to the update binary change, this number increments.\n- **File descriptor of the *command pipe***. The update program can use this pipe to send commands back to the recovery binary, mostly for UI changes, such as indicating progress to the user.\n- **Filename of the update package `.zip` file**.\n\n\nAn update package can use any statically linked binary as the update binary. The OTA package\nconstruction tools use the updater program (`bootable/recovery/updater`), which\nprovides a simple scripting language that can do many installation tasks. You can substitute\nany other binary running on the device.\n\n\nFor details on the updater binary, edify syntax, and builtin functions, see\n[Inside OTA Packages](/docs/core/ota/nonab/inside_packages).\n\nMigrate from previous releases\n------------------------------\n\n\nWhen migrating from Android 2.3/3.0/4.0 release, the major change is the conversion of all the\ndevice-specific functionality from a set of C functions with predefined names to C++ objects.\nThe following table lists the old functions and the new methods that serve a roughly\nequivalent purpose:\n\n| C function | C++ method |\n|---------------------------------------------|----------------------------------------------------------|\n| device_recovery_start() | Device::RecoveryStart() |\n| device_toggle_display() device_reboot_now() | RecoveryUI::CheckKey() (also RecoveryUI::IsKeyPressed()) |\n| device_handle_key() | Device::HandleMenuKey() |\n| device_perform_action() | Device::InvokeMenuItem() |\n| device_wipe_data() | Device::WipeData() |\n| device_ui_init() | ScreenRecoveryUI::Init() |\n\n\nConversion of old functions to new methods should be reasonably straightforward. Don't forget\nto add the new `make_device()`\nfunction to create and return an instance of your new Device subclass."]]