Внедрить виртуальный 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 должен быть больше или равен sum(size of update groups) + overhead , который, в свою очередь, должен быть больше или равен sum(size of partitions) + overhead .

Для 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/android_t_baseline.mk)

Это позволяет создавать моментальные снимки пользовательского пространства с виртуальным A/B при использовании метода сжатия без операций. Затем вы можете настроить метод сжатия на один из поддерживаемых методов, gz и brotli .

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := gz

Для 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 .

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

Для устройств, обновляющихся до Android 13 и более поздних версий, процесс слияния пользовательского пространства, как описано в разделе Устройство-сопоставитель, не включен по умолчанию. Чтобы включить слияние пользовательского пространства, добавьте следующую строку в файл .mk устройства:

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

Слияние пользовательского пространства включено по умолчанию на устройствах с версией 13 и выше.

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
}

изменения фстаба

Целостность раздела метаданных важна для процесса загрузки, особенно сразу после применения обновления 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: поддержка выровненного закрепленного файла .

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

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

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

Модернизация на устройствах с обновлением до Android 11

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

  • Расположение файлов COW — для устройств запуска клиент OTA использует все доступное пустое пространство в суперразделе перед использованием пространства в /data . Для модифицированных устройств в суперразделе всегда достаточно места, чтобы файл COW никогда не создавался в /data .

  • Флаги функций времени сборки — для устройств, модернизирующих виртуальные A/B, для PRODUCT_VIRTUAL_AB_OTA и PRODUCT_VIRTUAL_AB_OTA_RETROFIT установлено значение true , как показано ниже:

    (call inherit-product, \
        (SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
    
  • Размер суперраздела . Устройства, запускаемые с виртуальными разделами A/B, могут сократить BOARD_SUPER_PARTITION_SIZE вдвое, поскольку слоты B отсутствуют в суперразделе. Устройства, модернизирующие виртуальные A/B, сохраняют старый размер суперраздела, поэтому BOARD_SUPER_PARTITION_SIZE больше или равен 2 * sum(размер групп обновлений) + накладные расходы , что, в свою очередь, больше или равно 2 * sum(размер разделов) + накладные расходы .

Изменения загрузчика

На этапе слияния обновления /data содержит единственный полный экземпляр ОС Android. После начала миграции собственные разделы system , vendor и product остаются незавершенными, пока не завершится копирование. Если во время этого процесса устройство будет сброшено до заводских настроек либо путем восстановления, либо через диалоговое окно настроек системы, то устройство будет невозможно загрузить.

Перед стиранием /data завершите слияние в режиме восстановления или отката в зависимости от состояния устройства:

  • Если новая сборка ранее успешно загружалась, завершите миграцию.
  • В противном случае откат к старому слоту:
    • Для динамических разделов выполните откат к предыдущему состоянию.
    • Для статических разделов установите в качестве активного слота старый слот.

И загрузчик, и fastbootd могут стереть раздел /data , если устройство разблокировано. В то время как fastbootd может принудительно завершить миграцию, загрузчик этого сделать не может. Загрузчик не знает, происходит ли слияние или какие блоки в /data составляют разделы ОС. Устройства должны препятствовать тому, чтобы пользователь по незнанию вывел устройство из строя (заблокировал), выполнив следующие действия:

  1. Реализуйте HAL управления загрузкой, чтобы загрузчик мог считывать значение, установленное методом setSnapshotMergeStatus() .
  2. Если статус слияния — MERGING или если статус слияния — SNAPSHOTTED , а слот изменился на недавно обновленный слот, то запросы на удаление userdata , metadata или раздела, хранящего статус слияния, должны быть отклонены в загрузчике.
  3. Реализуйте команду fastboot snapshot-update cancel , чтобы пользователи могли сигнализировать загрузчику, что они хотят обойти этот механизм защиты.
  4. Измените пользовательские инструменты или сценарии перепрошивки, чтобы fastboot snapshot-update cancel выполнялась при перепрошивке всего устройства. Это безопасно, потому что перепрошивка всего устройства удаляет OTA. Инструменты могут обнаруживать эту команду во время выполнения, реализуя fastboot getvar snapshot-update-status . Эта команда помогает различать состояния ошибок.

Пример

struct VirtualAbState {
    uint8_t StructVersion;
    uint8_t MergeStatus;
    uint8_t SourceSlot;
};

bool ShouldPreventUserdataWipe() {
    VirtualAbState state;
    if (!ReadVirtualAbState(&state)) ...
    return state.MergeStatus == MergeStatus::MERGING ||
           (state.MergeStatus == MergeStatus::SNAPSHOTTED &&
            state.SourceSlot != CurrentSlot()));
}

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

Android 11 вносит следующие изменения в протокол быстрой загрузки:

  • getvar snapshot-update-status — возвращает значение, которое HAL управления загрузкой передал загрузчику:
    • Если состояние MERGING , загрузчик должен вернуть merging .
    • Если состояние SNAPSHOTTED , загрузчик должен вернуть snapshotted .
    • В противном случае загрузчик не должен возвращать none .
  • snapshot-update merge — завершает операцию слияния, при необходимости загружаясь в recovery/fastbootd. Эта команда действительна только в том случае, если snapshot-update-status merging и поддерживается только в fastbootd.
  • snapshot-update cancel — Устанавливает статус слияния HAL элемента управления загрузкой в CANCELLED . Эта команда недействительна, когда устройство заблокировано.
  • erase или wipeerase или 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 предоставляет несколько поддерживаемых методов сжатия ( gz , lz4 и none ), которые имеют компромисс между временем установки, использованием пространства COW, временем загрузки и временем объединения моментальных снимков. Опцией по умолчанию, включенной для виртуального ab со сжатием, является gz compression method . (Примечание: относительная производительность между методами сжатия зависит от скорости процессора и пропускной способности хранилища, которая может меняться в зависимости от устройства. Все пакеты OTA, сгенерированные ниже, имеют отключенную постустановку, что немного замедляет время загрузки. Общий размер динамического раздела полного ota без сжатия составляет 4,81 ГБ ).

Инкрементный OTA на Pixel 6 Pro

Время установки без постустановочной фазы Использование пространства COW Время загрузки после OTA Время слияния снимков
гз 24 мин 1,18 ГБ 40,2 сек. 45,5 сек.
лз4 13 мин 1,49 ГБ 37,4 сек. 37,1 сек.
никто 13 мин 2,90 ГБ 37,6 сек. 40,7 сек.

Полный OTA на Pixel 6 Pro

Время установки без постустановочной фазы Использование пространства COW Время загрузки после OTA Время слияния снимков
гз 23 мин 2,79 ГБ 24,9 сек. 41,7 сек.
лз4 12 мин 3,46 ГБ 20,0 сек 25,3 сек.
никто 10 минут 4,85 ГБ 20,6 сек. 29,8 сек.