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 .

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

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

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

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

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

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

Вы можете использовать инструмент 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

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

После дооснащения клиента 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. Отмените сопоставление целевых разделов.

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

Если пакет обновленного обновления применяется на устройстве, которое уже поддерживает динамические разделы, клиент OTA применяет разделенный файл super.img непосредственно на блочных устройствах. Процесс обновления аналогичен обновлению дооснащения. Подробности см. в разделе «Модернизация обновления» .

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

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