OTA для устройств A/B без динамических разделов

Android 10 поддерживает динамические разделы — систему разбиения пользовательского пространства, которая может создавать, изменять размер и удалять разделы во время обновлений по беспроводной сети (OTA).

На этой странице описывается, как клиенты OTA изменяют размер динамических разделов во время обновления для устройств A/B, запущенных без поддержки динамических разделов, и как клиенты OTA обновляются до Android 10.

Фон

Во время обновления устройства A/B для поддержки динамических разделов таблица разделов GUID (GPT) на устройстве сохраняется, поэтому на устройстве нет super . Метаданные хранятся в system_a и system_b , но это можно настроить, изменив BOARD_SUPER_PARTITION_METADATA_DEVICE .

В каждом из блочных устройств есть два слота метаданных. Используется только один слот метаданных в каждом блочном устройстве. Например, Metadata 0 в system_a и Metadata 1 в system_b соответствуют разделам в слотах A и B соответственно. Во время выполнения неважно, какой слот обновляется.

На этой странице слоты метаданных называются Metadata S (источник) и Metadata T (цель). Аналогично, разделы называются system_s , vendor_t и т. д.

Дополнительную информацию о конфигурациях системы сборки см. в разделе Обновление устройств .

Дополнительную информацию о принадлежности разделов к группам обновлений см. в разделе Изменения конфигурации платы для новых устройств.

Пример метаданных на устройстве:

  • Физическое блочное устройство system_a
    • Метаданные 0
      • Группа foo_a
        • Логический (динамический) раздел system_a
        • Логический (динамический) раздел product_services_a
        • Другие разделы обновлены Foo
      • Группа bar_a
        • Логический (динамический) раздел vendor_a
        • Логический (динамический) раздел product_a
        • Другие разделы обновлены пользователем Bar
    • Метаданные 1 (не используются)
  • Физическое блочное устройство system_b
    • Метаданные 0 (не используются)
    • Метаданные 1
      • Группа foo_b
        • Логический (динамический) раздел system_b
        • Логический (динамический) раздел product_services_b
        • Другие разделы обновлены Foo
      • Группа bar_b
        • Логический (динамический) раздел vendor_b
        • Логический (динамический) раздел product_b
        • Другие разделы обновлены пользователем Bar

Вы можете использовать инструмент lpdump в system/extras/partition_tools для дампа метаданных на вашем устройстве. Например:

lpdump --slot 0 /dev/block/by-name/system_a
lpdump --slot 1 /dev/block/by-name/system_b

Модернизация обновления

На устройствах с Android 9 и ниже клиент OTA на устройстве не поддерживает отображение динамических разделов до обновления. Создается дополнительный набор исправлений, чтобы отображение можно было применить непосредственно к существующим физическим разделам.

Генератор OTA создает окончательный файл super.img , содержащий содержимое всех динамических разделов, затем разбивает образ на несколько образов, соответствующих размерам физических блочных устройств, соответствующих системе, поставщику и т. д. Эти образы называются super_system.img , super_vendor.img и т. д. Клиент OTA применяет эти образы к физическим разделам, а не к логическим (динамическим) разделам.

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

Процесс обновления такой же, как в Android 9.

До обновления:

ro.boot.dynamic_partitions=
ro.boot.dynamic_partitions_retrofit=

После обновления:

ro.boot.dynamic_partitions=true
ro.boot.dynamic_partitions_retrofit=true

Будущие обновления после модернизации

После обновления Retrofit клиент OTA обновляется для работы с динамическими разделами. Экстенты для исходных разделов никогда не охватывают целевые физические разделы.

Поток обновления с использованием обычного пакета обновлений

  1. Инициализируйте метаданные super .
    1. Построить новые метаданные M из метаданных S (исходные метаданные). Например, если метаданные S используют [ system_s , vendor_s , product_s ] в качестве блочных устройств, то новые метаданные M используют [ system_t , vendor_t , product_t ] в качестве блочных устройств. Все группы и разделы отбрасываются в M.
    2. Добавьте целевые группы и разделы в соответствии с полем dynamic_partition_metadata в манифесте обновления. Размер каждого раздела можно найти в new_partition_info .
    3. Записать M в метаданные T.
    4. Отобразите добавленные разделы на устройстве сопоставления как доступные для записи.
  2. Примените обновление на блочных устройствах.
    1. При необходимости отобразите исходные разделы на устройстве-картографе как только для чтения. Это необходимо для загрузки извне, поскольку исходные разделы не отображаются до обновления.
    2. Применить полное или дельта-обновление ко всем блочным устройствам в целевом слоте.
    3. Смонтируйте разделы для запуска послеустановочного скрипта, а затем размонтируйте разделы.
  3. Отмените сопоставление целевых разделов.

Обновление потока с использованием пакета обновлений для модернизации

Если пакет обновления Retrofit применяется на устройстве, которое уже поддерживает динамические разделы, клиент OTA применяет файл split super.img на блочных устройствах напрямую. Поток обновления аналогичен обновлению Retrofit. Подробности см. в разделе Retrofitting an update .

Например, предположим следующее:

  • Слот A — активный слот.
  • system_a содержит активные метаданные в слоте 0.
  • system_a , vendor_a и product_a используются как блочные устройства.

Когда клиент OTA получает пакет обновления для модернизации, он применяет super_system.img к физической system_b , super_vendor.img к физической vendor_b и super_product.img к физической product_b . Физическое блочное устройство system_b содержит правильные метаданные для сопоставления логических system_b , vendor_b и product_b во время загрузки.

Генерация пакетов обновлений

Инкрементный OTA

При создании инкрементных OTA для модернизированных устройств обновления зависят от того, определены ли в базовой сборке PRODUCT_USE_DYNAMIC_PARTITIONS и PRODUCT_RETROFIT_DYNAMIC_PARTITIONS .

  • Если базовая сборка не определяет переменные, это обновление ретрофитинга. Пакет обновления содержит разделенный файл super.img и отключает шаг после установки.
  • Если базовая сборка определяет переменные, это то же самое, что и типичное обновление с динамическими разделами. Пакет обновления содержит образы для логических (динамических) разделов. Можно включить этап после установки.

Полное ОТА

Для модернизированных устройств создаются два полных пакета OTA.

  • $(PRODUCT)-ota-retrofit-$(TAG).zip всегда содержит разделенный super.img и отключает этап послеустановки для обновления ретрофита.
    • Он генерируется с помощью дополнительного аргумента --retrofit_dynamic_partitions для скрипта ota_from_target_files .
    • Его можно применять ко всем сборкам.
  • $(PRODUCT)-ota-$(TAG).zip содержит логические образы для будущих обновлений.
    • Применяйте это только к сборкам с включенными динамическими разделами. Подробности о применении этого см. ниже.

Отклонить немодернизированное обновление для старых сборок

Применяйте обычный полный пакет OTA только к сборкам с включенными динамическими разделами. Если сервер OTA настроен неправильно и отправляет эти пакеты на устройства под управлением Android 9 или ниже, устройства не загружаются. Клиент OTA на Android 9 и ниже не может отличить пакет Retrofit OTA от обычного полного пакета OTA, поэтому клиент не отклонит полный пакет.

Чтобы устройство не приняло полный пакет OTA, вы можете потребовать послеустановочный шаг для проверки существующей конфигурации устройства. Например:

device/ device_name /dynamic_partitions/check_dynamic_partitions

#!/system/bin/sh
DP_PROPERTY_NAME="ro.boot.dynamic_partitions"
DP_RETROFIT_PROPERTY_NAME="ro.boot.dynamic_partitions_retrofit"

DP_PROPERTY=$(getprop ${DP_PROPERTY_NAME})
DP_RETROFIT_PROPERTY=$(getprop ${DP_RETROFIT_PROPERTY_NAME})

if [ "${DP_PROPERTY}" != "true" ] || [ "${DP_RETROFIT_PROPERTY}" != "true" ] ; then
    echo "Error: applied non-retrofit update on build without dynamic" \
         "partitions."
    echo "${DP_PROPERTY_NAME}=${DP_PROPERTY}"
    echo "${DP_RETROFIT_PROPERTY_NAME}=${DP_RETROFIT_PROPERTY}"
    exit 1
fi

device/ device_name /dynamic_partitions/Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= check_dynamic_partitions
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_SRC_FILES := check_dynamic_partitions
LOCAL_PRODUCT_MODULE := true
include $(BUILD_PREBUILT)

device/ device_name /device.mk

PRODUCT_PACKAGES += check_dynamic_partitions

# OPTIONAL=false so that the error in check_dynamic_partitions will be
# propagated to OTA client.
AB_OTA_POSTINSTALL_CONFIG += \
    RUN_POSTINSTALL_product=true \
    POSTINSTALL_PATH_product=bin/check_dynamic_partitions \
    FILESYSTEM_TYPE_product=ext4 \
    POSTINSTALL_OPTIONAL_product=false \

Когда обычный пакет OTA применяется на устройстве без включенных динамических разделов, клиент OTA запускает check_dynamic_partitions в качестве шага после установки и отклоняет обновление.