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 соответственно. Во время выполнения не имеет значения, какой слот обновляется.

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

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

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

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

  • Физическое блочное устройство system_a
    • Метаданные 0
      • Группа foo_a
        • Логическая (динамическая) system_a разделов_a
        • Логический (динамический) раздел product_services_a
        • Другие разделы обновлены пользователем Foo.
      • Группа bar_a
        • Логический (динамический) раздел vendor_a
        • Логическое (динамическое) разделение product_a
        • Другие разделы обновлены Баром.
    • Метаданные 1 (не используются)
  • Физическое блочное устройство system_b
    • Метаданные 0 (не используются)
    • Метаданные 1
      • Группа foo_b
        • Логическая (динамическая) system_b разделения_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. Отмените сопоставление целевых разделов.

Обновление процесса с помощью пакета обновления Retrofit.

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

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

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

Когда OTA-клиент получает пакет обновления Retrofit, он применяет 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

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