在非 A/B 设备上,恢复映像应包含设备树 blob (DTB) 或高级配置与电源接口 (ACPI) 叠加层映像的信息。当此类设备启动进入恢复模式时,引导加载程序可以加载与恢复映像兼容的叠加层映像。支持 A/B(无缝)更新的设备应将恢复用作启动,而非单独的恢复分区(如需了解详情,请参阅实现 A/B 更新)。
在不同的 Android 版本中,用于将恢复 DTBO/ACPIO 作为启动/恢复映像的一部分的选项有所不同。
| 版本 | 更新方案 | GKI 合规性 | 启动头文件版本(发布设备) | 启动头文件版本(升级设备) | 需要专用恢复映像 | 
|---|---|---|---|---|---|
| 11 | A/B、 虚拟 A/B | 是 | 3* | 不适用 | 否 | 
| A/B、 虚拟 A/B | 否 | 2、3 | 0、1、2、3 | 否 | |
| 非 A/B | 是 | 3 | 不适用 | 是 | |
| 非 A/B | 否 | 2、3 | 0、1、2、3 | 是 | |
| 10 (Q) | A/B | 不适用 | 2 | 0、1、2 | 否 | 
| 非 A/B | 不适用 | 2 | 0、1、2 | 是 | |
| 9 (P) | A/B | 不适用 | 1 | 0、1 | 否 | 
| 非 A/B | 不适用 | 1 | 0、1 | 是 | |
| 8 (O) | A/B | 不适用 | 不适用(视为 0) | 不适用(视为 0) | 否 | 
| 非 A/B | 不适用 | 不适用(视为 0) | 不适用(视为 0) | 是 | 
* 搭载 Android 11 或更高版本并使用通用内核映像 (GKI) 的 A/B 设备必须使用主启动头文件版本 3,才能与供应商启动分区相兼容。
要点:
- A/B 设备不需要指定恢复映像,因为 A/B 更新使用两组分区(包括 - boot和- dtbo),且在更新期间在两者间切换,从而无需恢复映像。A/B 设备仍然可以使用专用恢复映像。
- 发布时搭载 Android 11 或更高版本且使用启动头文件版本 3 的非 A/B 设备必须单独为恢复映像显式指定启动头文件版本 2。例如: - BOARD_RECOVERY_MKBOOTIMG_ARGS := --header_version 2
- 对于不支持设备树的架构,恢复映像可能包含 ACPIO 映像而不是 DTBO 映像。 
关于 OTA 失败和恢复映像
为了防止非 A/B 设备上出现无线下载 (OTA) 失败的情况,恢复映像应该“自给自足”,不依赖于其他映像。在 OTA 更新期间,如果在叠加层映像更新后(但在完成全部更新之前)出现问题,设备会尝试启动进入恢复模式,以完成 OTA 更新。不过,由于叠加层分区已更新,恢复映像(尚未更新)可能会出现不匹配的情况。
为阻止恢复在更新过程中依赖于 DTBO/ACPIO 分区,搭载 Android 9 或更高版本的非 A/B 设备可以将包含来自叠加层映像的信息的恢复 DTBO/ACPIO 映像指定为启动映像格式的单独部分(必须使用启动头文件版本 1 或 2)。
启动映像更改
为允许恢复映像包含搭载 Android 9 或更高版本的非 A/B 设备上的恢复 DTBO 或 ACPIO,请按如下所示更新启动映像结构。
| 启动映像部分 | 页数 | 
|---|---|
| 启动头文件(1 页) | 1 | 
| 内核(l 页) | l = ( kernel_size+page_size- 1) /page_size | 
| Ramdisk(m 页) | m = ( ramdisk_size+page_size- 1) /page_size | 
| 第二阶段引导加载程序(n 页) | n = ( second_size+page_size- 1) /page_size | 
| 恢复 DTBO 或 ACPIO(o 页) | o = ( recovery_[dtbo|acpio]_size+page_size- 1) /page_size | 
如需详细了解用于指定启动映像头文件版本和叠加层映像路径的 mkbootimg 工具参数,请参阅启动映像头文件版本编号。
实现 DTBO
搭载 9 或更高版本的非 A/B 设备可以填充恢复映像的 recovery_dtbo 部分。如需在 BoardConfig.mk 设备的 recovery.img 中添加 recovery_dtbo 映像,请执行以下操作:
- 将 - BOARD_INCLUDE_RECOVERY_DTBO配置设置为- true:- BOARD_INCLUDE_RECOVERY_DTBO := true
- 扩展 - BOARD_MKBOOTIMG_ARGS变量以指定启动映像头文件版本:- BOARD_MKBOOTIMG_ARGS := --ramdisk_offset $(BOARD_RAMDISK_OFFSET) --tags_offset $(BOARD_KERNEL_TAGS_OFFSET) --header_version $(BOARD_BOOTIMG_HEADER_VERSION)
- 确保将 - BOARD_PREBUILT_DTBOIMAGE变量设置为 DTBO 映像的路径。Android 构建系统使用该变量在创建恢复映像期间设置- mkbootimg工具的- recovery_dtbo参数。
如果变量 BOARD_INCLUDE_RECOVERY_DTBO、BOARD_MKBOOTIMG_ARGS 和 BOARD_PREBUILT_DTBOIMAGE 均正确设置,Android 构建系统会将变量 BOARD_PREBUILT_DTBOIMAGE 指定的 DTBO 添加到 recovery.img 中。
实现 ACPIO
搭载 Android 9 或更高版本的非 A/B 设备可以使用 ACPIO 叠加层映像(而不是 DTBO 映像),并且可以填充恢复映像的 recovery_acpio 部分(而不是 recovery_dtbo 部分)。如需在 BoardConfig.mk 设备的 recovery.img 中添加 recovery_acpio 映像,请执行以下操作:
- 将 - BOARD_INCLUDE_RECOVERY_ACPIO配置设置为- true:- BOARD_INCLUDE_RECOVERY_ACPIO := true
- 扩展 - BOARD_MKBOOTIMG_ARGS变量以指定启动映像头文件版本。变量必须大于或等于 1,才能支持恢复 ACPIO。- BOARD_MKBOOTIMG_ARGS += --header_version $(BOARD_BOOTIMG_HEADER_VERSION)
- 确保将 - BOARD_RECOVERY_ACPIO变量设置为 ACPIO 映像的路径。Android 构建系统使用该变量在创建恢复映像期间设置- mkbootimg工具的- recovery_acpio参数。
如果变量 BOARD_INCLUDE_RECOVERY_ACPIO、BOARD_MKBOOTIMG_ARGS 和 BOARD_RECOVERY_ACPIO 均正确设置,Android 构建系统会将变量 BOARD_RECOVERY_ACPIO 指定的 ACPIO 添加到 recovery.img 中。
