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
- Логический (динамический) раздел
product_services_a
- Другие разделы обновлены пользователем Foo
- Логический (динамический) раздел
- Группа
bar_a
- Логический (динамический) раздел
vendor_a
- Логический (динамический) раздел
product_a
- Другие разделы обновлены Баром
- Логический (динамический) раздел
- Группа
- Метаданные 1 (не используются)
- Метаданные 0
- Физическое блочное устройство
system_b
- Метаданные 0 (не используются)
- Метаданные 1
- Группа foo_b
- Логический (динамический) раздел
system_b
- Логический (динамический) раздел
product_services_b
- Другие разделы обновлены пользователем Foo
- Логический (динамический) раздел
- Группа bar_b
- Логический (динамический) раздел
vendor_b
- Логический (динамический) раздел
product_b
- Другие разделы обновлены Баром
- Логический (динамический) раздел
- Группа foo_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 обновляется для работы с динамическими разделами. Экстенты исходных разделов никогда не перекрывают целевые физические разделы.
Обновление потока с использованием обычного пакета обновлений
- Инициализируйте метаданные
super
.- Создать новые метаданные M из метаданных S (исходных метаданных). Например, если метаданные S используют [
system_s
,vendor_s
,product_s
] в качестве блочных устройств, то новые метаданные M используют [system_t
,vendor_t
,product_t
] в качестве блочных устройств. Все группы и разделы в M удаляются. - Добавьте целевые группы и разделы в соответствии с полем
dynamic_partition_metadata
в манифесте обновления. Размер каждого раздела можно узнать вnew_partition_info
. - Записать M в метаданные T.
- Отобразите добавленные разделы на устройстве сопоставления как доступные для записи.
- Создать новые метаданные M из метаданных S (исходных метаданных). Например, если метаданные S используют [
- Примените обновление на блочных устройствах.
- При необходимости отобразите исходные разделы в средстве сопоставления устройств как доступные только для чтения. Это необходимо для загрузки из сторонних источников, поскольку исходные разделы не отображаются до обновления.
- Применить полное или дельта-обновление ко всем блочным устройствам в целевом слоте.
- Смонтируйте разделы для запуска послеустановочного скрипта, а затем отмонтируйте разделы.
- Отменить сопоставление целевых разделов.
Обновление потока с использованием пакета обновлений для модернизации
Если пакет ретрофитного обновления применяется на устройстве, которое уже поддерживает динамические разделы, 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
Для модернизированных устройств создаются два полных пакета 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
в качестве шага после установки и отклоняет обновление.