Android 10 поддерживает динамические разделы — систему разбиения пользовательского пространства, которая может создавать, изменять размер и удалять разделы во время беспроводных обновлений (OTA).
На этой странице описывается, как клиенты OTA изменяют размер динамических разделов во время обновления для устройств, отличных от A/B.
Для устройств, отличных от A/B, обновление OTA для динамических разделов применяется с помощью updater внутри пакета обновления.
Обновление пусковых устройств
Этот раздел относится к устройствам, отличным от A/B, которые запускаются с поддержкой динамических разделов; эти устройства обновляются с Android 10 до более поздних версий.
Генерация пакетов обновлений
Пакеты обновлений OTA генерируются скриптом ota_from_target_files , расположенным в папке build/make/tools/releasetools . По умолчанию скрипт генерирует пакет, обновляющий разделы system и vendor . При наличии дополнительных динамических разделов, таких как product , product_services или odm , их обновления должны быть сгенерированы в коде, специфичном для устройства .
Для генерации обновлений в расширенном модуле Python реализуйте функции FullOTA_GetBlockDifferences() и IncrementalOTA_GetBlockDifferences() . Эти две функции возвращают список объектов BlockDifference , каждый из которых описывает патч обновления, который будет применён к разделу. Разделы, возвращаемые этими двумя функциями, не следует изменять вручную или проверять где-либо ещё, например, в *_InstallBegin() или *_InstallEnd() .
Пример генерации обновления:
# device/yoyodyne/tardis/releasetools.py import os from common import BlockDifference, EmptyImage, GetUserImage # The joined list of user image partitions of source and target builds. # - Items should be added to the list if new dynamic partitions are added. # - Items should not be removed from the list even if dynamic partitions are # deleted. When generating an incremental OTA package, this script needs to # know that an image is present in source build but not in target build. USERIMAGE_PARTITIONS = [ "product", "odm", ] def GetUserImages(input_tmp, input_zip): return {partition: GetUserImage(partition, input_tmp, input_zip) for partition in USERIMAGE_PARTITIONS if os.path.exists(os.path.join(input_tmp, "IMAGES", partition + ".img"))} def FullOTA_GetBlockDifferences(info): images = GetUserImages(info.input_tmp, info.input_zip) return [BlockDifference(partition, image) for partition, image in images.items()] def IncrementalOTA_GetBlockDifferences(info): source_images = GetUserImages(info.source_tmp, info.source_zip) target_images = GetUserImages(info.target_tmp, info.target_zip) # Use EmptyImage() as a placeholder for partitions that will be deleted. for partition in source_images: target_images.setdefault(partition, EmptyImage()) # Use source_images.get() because new partitions are not in source_images. return [BlockDifference(partition, target_image, source_images.get(partition)) for partition, target_image in target_images.items()]
Поток обновления
За кулисами в скрипт edify добавляются следующие функции:
-
unmap_partition(name)- Отменить сопоставление раздела, если оно сопоставлено, в противном случае ничего не делать.
- Возвращает строку
tв случае успеха или пустую строку в случае неудачи.
-
map_partition(name)- Подключите раздел, если он еще не подключен.
- Возвращает абсолютный путь к сопоставленному блочному устройству в случае успеха или пустую строку в случае ошибки.
-
update_dynamic_partitions(op_list)- Применить заданный список операций к динамическим метаданным разделов, при необходимости отменив сопоставление разделов.
- Возвращает
tв случае успеха или пустую строку в случае ошибки.
Аргумент op_list функции update_dynamic_partitions указывает на файл в пакете обновления. Каждая строка файла определяет операцию. Если какая-либо операция завершается неудачей, update_dynamic_partitions немедленно возвращает пустую строку. Доступны следующие операции:
-
resize partition-name size- Отмените отображение раздела, затем измените его размер до size .
-
remove partition_name- Отмените отображение раздела, затем удалите его.
-
add partition-name group-name- Добавить новый раздел в указанную группу.
- Прервать, если группа не существует или раздел уже существует.
-
move partition-name group-name- Переместить раздел в указанную группу.
- Прервать, если группа или раздел не существует.
-
add_group group-name maximum-size- Добавьте группу с указанным именем и максимальным размером.
- Прервать, если группа уже существует.
- Значение maximum_size , равное 0, означает, что размер разделов в группе не ограничен. Необходимо дополнительное тестирование, чтобы убедиться, что разделы в группе не превышают доступное пространство на устройстве.
-
resize_group group-name maximum-size- Измените размер группы до заданного максимального размера.
- Прервать, если группа не существует.
- Значение maximum_size , равное 0, означает, что размер разделов в группе не ограничен. Необходимо дополнительное тестирование, чтобы убедиться, что разделы в группе не превышают доступное пространство на устройстве.
-
remove_group group-name- Удалить группу.
- Прервать, если в группе есть разделы.
-
remove_all_groups- Отменить сопоставление всех разделов с помощью средства сопоставления устройств.
- Удалить все разделы и группы.
Инкрементный OTA
Инкрементные обновления OTA используют следующую логику:
- Сжать разделы/удалить разделы/переместить разделы из группы (чтобы было достаточно места для сжатия групп)
- Сократить группы (чтобы было достаточно места для увеличения групп)
- Увеличивать группы (чтобы было достаточно места для увеличения/добавления разделов)
- Увеличить разделы/добавить разделы/переместить разделы в новую группу
Более подробно, update-script генерируется по следующей логике:
for each shrinking partition:
block_image_update(map_partition(name), …)
update_dynamic_partitions(op_list)
for each growing / adding partition:
block_image_update(map_partition(name), …) Файл op_list для update_dynamic_partitions генерируется по следующей логике:
for each deleting partition:
remove
for each partition that changes groups:
move to "default"
for each shrinking partition:
resize
for each shrinking / removing group:
resize_group / remove_group
for each growing / adding group:
resize_group / add_group
for each adding partition:
add
for each growing / adding partition:
resize
for each partition that changes groups:
move to target groupПолный OTA
Полные обновления OTA используют следующую логику:
- Удалить все существующие группы и разделы
- Добавить группы
- Добавить разделы
Более подробно, update-script генерируется по следующей логике:
update_dynamic_partitions(op_list)
for each adding partition:
block_image_update(map_partition(name), …) Файл op_list для update_dynamic_partitions генерируется по следующей логике:
remove_all_groups
for each adding group:
add_group
for each adding partition:
add
for each adding partition:
resize