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 (источник) и Метаданные Т (цель). Точно так же разделы называются 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

При создании добавочных 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 в качестве шага после установки и отклоняет обновление.