Внедрить виртуальный A/B

Для реализации виртуального A/B-тестирования на новом устройстве или для модернизации уже выпущенного устройства необходимо внести изменения в код, специфичный для данного устройства.

Создать флаги

Устройства, использующие виртуальный A/B, должны быть настроены как устройства A/B и запускаться с динамическими разделами .

Для устройств, запускаемых с виртуальным A/B, настройте их на наследование базовой конфигурации виртуального устройства A/B:

$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)

Для устройств, запускаемых с виртуальными A/B, размер платы для BOARD_SUPER_PARTITION_SIZE должен быть вдвое меньше, поскольку слоты B больше не находятся в суперслоте. То есть, BOARD_SUPER_PARTITION_SIZE должен быть больше или равен сумме (размер групп обновления) + накладные расходы , которая, в свою очередь, должна быть больше или равна сумме (размер разделов) + накладные расходы .

Для Android 13 и выше, чтобы включить сжатые снимки с использованием Virtual A/B, унаследуйте следующую базовую конфигурацию:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/vabc_features.mk)

Это позволяет создавать снимки пользовательского пространства с помощью Virtual A/B, используя метод сжатия, не выполняющий никаких действий. Затем вы можете настроить метод сжатия на один из поддерживаемых методов: zstd или lz4 . Для Android 15 сжатие можно дополнительно настроить в соответствии с потребностями устройства. Для получения дополнительной информации см. раздел «Тонкая настройка сжатия» .

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4
PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536

Для Android 12, чтобы включить сжатые снимки с использованием Virtual A/B, необходимо унаследовать следующую базовую конфигурацию:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)

Сжатие XOR

На устройствах, обновляемых до Android 13 и выше, функция сжатия XOR по умолчанию отключена. Чтобы включить сжатие XOR, добавьте следующее в файл .mk устройства.

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true

Сжатие XOR включено по умолчанию для устройств, наследующих свойства из android_t_baseline.mk .

Слияние пользовательского пространства

В современных версиях Virtual A/B (Android T и более поздние) процесс слияния снимков происходит полностью в пользовательском пространстве. Это изменение стало возможным благодаря snapuserd и dm-user. На устройствах, выпущенных с Android 13 и выше, слияние снимков в пользовательском пространстве включено по умолчанию, а для более старых устройств, обновляемых до Android 13, это свойство можно установить следующим образом:

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true

Управление загрузкой HAL

HAL управления загрузкой предоставляет интерфейс для OTA-клиентов, позволяющий управлять загрузочными слотами. Для виртуальных A/B требуется обновление HAL управления загрузкой до минорной версии, поскольку необходимы дополнительные API для обеспечения защиты загрузчика во время прошивки или сброса к заводским настройкам. См. IBootControl.hal и types.hal для получения последней версии определения HAL.

// hardware/interfaces/boot/1.1/types.hal
enum MergeStatus : uint8_t {
    NONE, UNKNOWN, SNAPSHOTTED, MERGING, CANCELLED };

// hardware/interfaces/boot/1.1/IBootControl.hal
package android.hardware.boot@1.1;
interface IBootControl extends @1.0::IBootControl {
    setSnapshotMergeStatus(MergeStatus status)
        generates (bool success);
    getSnapshotMergeStatus()
        generates (MergeStatus status);
}
// Recommended implementation

Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus v) {
    // Write value to persistent storage
    // e.g. misc partition (using libbootloader_message)
    // bootloader rejects wipe when status is SNAPSHOTTED
    // or MERGING
}

Изменения в файле Fstab

Целостность раздела метаданных имеет решающее значение для процесса загрузки, особенно сразу после применения OTA-обновления. Поэтому раздел метаданных необходимо проверить перед монтированием его функцией first_stage_init . Для этого добавьте флаг check fs_mgr к записи для /metadata . Ниже приведен пример:

/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check

Требования ядра

Чтобы включить создание моментальных снимков, установите параметр CONFIG_DM_SNAPSHOT в true .

Для устройств, использующих F2FS, добавьте флаг f2fs: export FS_NOCOW_FL в патч ядра пользователя , чтобы исправить привязку файлов. Также добавьте патч ядра f2fs: support aligned pinned file .

Виртуальный A/B-тестирование основано на функциях, добавленных в версии ядра 4.3: бите состояния переполнения в целевых объектах snapshot и snapshot-merge . Все устройства, запускаемые с Android 9 и более поздними версиями, должны уже иметь версию ядра 4.4 или более позднюю.

Для включения сжатых снимков минимальная поддерживаемая версия ядра — 4.19. Установите CONFIG_DM_USER=m или CONFIG_DM_USER=y . При использовании первого варианта (модуля) модуль должен быть загружен в виртуальный диск в оперативной памяти первого этапа. Этого можно добиться, добавив следующую строку в Makefile устройства:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

Изменения в инструментах Fastboot

В Android 11 внесены следующие изменения в протокол fastboot:

  • getvar snapshot-update-status — Возвращает значение, которое HAL управления загрузкой передал загрузчику:
    • Если состояние — MERGING , загрузчик должен вернуть merging .
    • Если состояние равно SNAPSHOTTED , загрузчик должен вернуть snapshotted .
    • В противном случае загрузчик должен вернуть none .
  • snapshot-update merge — Завершает операцию слияния, при необходимости загружая систему в режим восстановления/fastbootd. Эта команда действительна только в том случае, если snapshot-update-status имеет merging , и поддерживается только в fastbootd.
  • snapshot-update cancel — Устанавливает статус слияния HAL управления загрузкой в ​​значение CANCELLED . Эта команда недействительна, если устройство заблокировано.
  • erase или wipe — При erase или wipe metadata , userdata или раздела, содержащего статус слияния для HAL управления загрузкой, необходимо проверить статус слияния снимков. Если статус — MERGING или SNAPSHOTTED , устройство должно прервать операцию.
  • set_active — Команда set_active , изменяющая активный слот, должна проверять статус слияния снимков. Если статус MERGING , устройство должно прервать операцию. Слот можно безопасно изменить в состоянии SNAPSHOTTED .

Эти изменения призваны предотвратить случайное отключение устройства от загрузки, но они могут нарушить работу автоматизированных инструментов. При использовании этих команд в процессе прошивки всех разделов, например, при запуске fastboot flashall , рекомендуется использовать следующий алгоритм действий:

  1. Запрос getvar snapshot-update-status .
  2. Если merging или snapshotted , выполните snapshot-update cancel .
  3. Перейдите к этапам мигания.

Сокращение требований к хранению

Для устройств, которым не выделено полное хранилище A/B в super и которые ожидают использования /data по мере необходимости, настоятельно рекомендуется использовать инструмент блочного сопоставления. Инструмент блочного сопоставления обеспечивает согласованность распределения блоков между сборками, уменьшая количество ненужных записей в снимок. Это описано в разделе «Уменьшение размера OTA-обновлений» .

алгоритмы сжатия OTA

OTA-пакеты можно настраивать под различные показатели производительности. Android предоставляет несколько поддерживаемых методов сжатия ( lz4 , zstd и none ), которые имеют компромисс между временем установки, использованием пространства COW, временем загрузки и временем слияния снимков. По умолчанию для виртуального ab включен lz4 compression method .

Точная настройка сжатия

Алгоритмы сжатия можно дополнительно настроить двумя способами: ( уровень сжатия ) (степень сжатия, достигаемая за счет скорости) и ( коэффициент сжатия ) (максимальный размер сжимаемого окна). Уровень сжатия доступен для некоторых алгоритмов, таких как zstd , и изменение уровня влечет за собой компромисс между скоростью и коэффициентом сжатия. Коэффициент сжатия описывает максимальный размер окна сжатия, используемый во время установки OTA. По умолчанию установлено значение 64 КБ, но его можно изменить, настроив параметр сборки PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR . Поддерживаемые коэффициенты сжатия: 4 КБ, 8 КБ, 16 КБ, 32 КБ, 64 КБ, 128 КБ и 256 КБ.

PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536

Постепенная OTA-обновление на Pixel 8 Pro

Время установки без этапа после установки. Использование пространства COW Время после загрузки по воздуху (OTA) Время слияния снимков
лз4 18 мин 15 с 2,5 ГБ 32,7 сек 98,6 сек
zstd 24 мин 49 с 2,05 ГБ 36,3 сек. 133,2 сек
никто 16 мин 42 с 4,76 ГБ 28,7 сек 76,6 сек

Полное обновление по воздуху (OTA) на Pixel 8 Pro

Время установки без этапа после установки. Использование пространства COW Время после загрузки по воздуху (OTA) Время слияния снимков
лз4 15 мин 11 с 4,16 ГБ 17,6 сек 82,2 сек
zstd 16 мин 19 с 3,46 ГБ 21,0 сек. 106,3 сек
никто 13 мин 33 с 6,39 ГБ 18,5 сек. 92,5 сек.