Android AB分区说明

1. 前言

本文档主要介绍关于AB分区的相关的配置。

2. 相关的BoardConfig配置

因为AB分区主要用于支持Android A/B无缝更新,所以主要涉及到的device配置有:

配置项 说明
TARGET_NO_RECOVERY 因为启用了A/B分区就不再需要独立的recovery分区,可以将该配置设置"True"
AB_OTA_UPDATER 整个AB无缝更新的总开关
AB_OTA_PARTITIONS OTA需要升级的分区
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT 将Recovery的根文件系统编译到vendor boot ramdisk中

以pioneer5为例,目前设定如下:

# device/sigmastar/pioneer5/BoardConfig-common.mk
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT := true
TARGET_NO_RECOVERY := true
AB_OTA_UPDATER := true
ifeq ($(SSTAR_ENABLE_DYNAMIC_PARTITIONS),true)
AB_OTA_PARTITIONS := \
    boot \
    vendor_boot \
    dtbo \
    vbmeta \
    vbmeta_system \
    vbmeta_vendor \
    system \
    vendor
else
AB_OTA_PARTITIONS := \
    boot \
    vendor_boot \
    dtbo \
    vbmeta \
    system \
    vendor
endif

3. 分区相关配置

请先阅读Android分区说明了解基本的分区配置方法,对于生成分区表的json配置文件,不难发现目前只有如下的配置区分:

~/workspace/AOSP$ ls -1 device/sigmastar/common/partition/*.json
partition-table-8GB.json # 使能动态分区 + 使能AVB
partition-table-8GB-noavb.json # 使能动态分区 + 关闭AVB
partition-table-8GB-nondynamic.json # 关闭动态分区 + 使能AVB
partition-table-8GB-nondynamic-noavb.json # 关闭动态分区 + 关闭AVB

因为Android接下来会全面支持A/B分区特性,所以SigmaStar Android平台当前默认只提供使能A/B分区的配置。

需要配置为A/B分区的分区可以在json对应的entry添加"ab": true的设定,以partition-table-8GB-nondynamic-noavb.json为例:

{
    "settings": {
        "disk_alignment": 512,
        "disk_size": "7 GB"
    },
    "partitions": [
+-- 52 lines: {------------------------------------------------------------------------------------------------------------------------------------------------------------------------
        {
            "ab": true,
            "label": "boot",
            "size": 33554432,
            "guid": "auto",
            "type_guid": "brillo_boot",
            "hw_part_name": "UDA",
            "image_name": "boot.img",
            "is_spare_image": false,
            "is_download": true
        },
        {
            "ab": true,
            "label": "vendor_boot",
            "size": 33554432,
            "guid": "auto",
            "type_guid": "brillo_boot",
            "hw_part_name": "UDA",
            "image_name": "vendor_boot.img",
            "is_download": true
        },
+-- 58 lines: {------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    ]
}

添加"ab": true标记的分区实际上在最终生成的分区表中会生成两条大小相同,分区名分别为<label>_a<label>_b的分区。

原则上,启动完整系统依赖的镜像都要设置成A/B,这样才能确保A/B无缝更新机制的正确运行。

4. Fstab相关配置

请先阅读Android Fstab配置说明了解基本的fatab配置方法。

在设定dev时无需考虑AB分区的情况,以system为例,即存在system_asystem_b时,system条目中的dev也是写成/dev/block/platform/soc/soc:emmc/by-name/system即可,该分区是否是AB分区是通过fs_mgr_flags中是否有slotselect决定的,至于最后是选/dev/block/platform/soc/soc:emmc/by-name/system_a还是/dev/block/platform/soc/soc:emmc/by-name/system_b挂载到/system是由bootloader传过来的cmdline参数androidboot.slot_suffix决定的。

5. Bootloader相关支持

由于目前SigmaStar平台默认开启A/B,其中有如下相关的Kconfig:

# arch/arm/mach-sstar/Kconfig.Android
config SSTAR_ANDROID_AB
    bool "SigmaStar Android A/B updates"
    depends on ANDROID_AB
    default n
    help
      If enabled, support SigmaStar additional code for
      Android A/B update.

# common/Kconfig
config ANDROID_AB
    bool "Android A/B updates"
    default n
    help
      If enabled, adds support for the new Android A/B update model. This
      allows the bootloader to select which slot to boot from based on the
      information provided by userspace via the Android boot_ctrl HAL. This
      allows a bootloader to try a new version of the system but roll back
      to previous version if the new one didn't boot all the way.

# cmd/sstar/Kconfig
config CMD_SSTAR_AB_RESET
    bool "ab_reset"
    default n
    depends on ANDROID_AB
    help
      Init ab control block at Android "misc" partition

其中CMD_SSTAR_AB_RESET会去选中编译cmd/sstar/ab_reset.c会得到U-boot的命令:ab_reset,主要用于ab retry count异常归零的情况,它可以将misc分中的ab metadata重置为初始状态。更多A/B相关的启动流程介绍请参考Android启动流程相关章节。

ab_reset命令使用方法大致如下:

SigmaStar # ab_reset
ab_reset - Execute the SimaStar init android control block.

Usage:
ab_reset example:
ab_reset mmc 0#misc

SigmaStar # ab_reset mmc 0#misc

6. Fastboo刷机相关支持

对于fastboot烧录,有如下相关的命令:

  • fastboot getvar all
    fastboot.exe getvar all
    ......
    (bootloader) has-slot:factory:no
    (bootloader) has-slot:env:no
    (bootloader) has-slot:logo:no
    (bootloader) has-slot:misc:no
    (bootloader) has-slot:boot:yes
    (bootloader) has-slot:vendor_boot:yes
    (bootloader) has-slot:dtbo:yes
    (bootloader) has-slot:system:yes
    (bootloader) has-slot:vendor:yes
    (bootloader) has-slot:odm:yes
    (bootloader) has-slot:cache:no
    (bootloader) has-slot:userdata:no
    ......
    

可以看到,有A/B分区的分区会在对应的has-slot条目标记上yes

  • fastboot flash <partition name>_[a|b] image_path
    fastboot.exe flash boot boot.img
    Sending 'boot_a' (16392 KB)                        OKAY [  3.060s]
    Writing 'boot_a'                                   OKAY [  0.482s]
    Finished. Total time: 3.845s
    fastboot.exe flash boot_a boot.img
    Sending 'boot_a' (16392 KB)                        OKAY [  3.056s]
    Writing 'boot_a'                                   OKAY [  0.482s]
    Finished. Total time: 3.887s
    fastboot.exe flash boot_b boot.img
    Sending 'boot_b' (16392 KB)                        OKAY [  3.059s]
    Writing 'boot_b'                                   OKAY [  0.502s]
    Finished. Total time: 3.930s
    

不难发现,对于has-slot:yes的分区,执行fastboot flash命令时或去获取当前启动的slot,自动添加后缀到分区名。

  • fastboot set_active <a|b>:该命令可以切换当前启动的slot
    fastboot.exe set_active b
    Setting current slot to 'b'                        OKAY [  0.025s]
    Finished. Total time: 0.053s
    fastboot.exe flash boot boot.img
    Sending 'boot_b' (16392 KB)                        OKAY [  3.076s]
    Writing 'boot_b'                                   OKAY [  0.486s]
    Finished. Total time: 3.839s