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
, их обновления должны быть сгенерированы в device-specific code .
Для генерации обновлений в расширенном модуле 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 используют следующую логику:
- Удалить все существующие группы и разделы
- Добавить группы
- Добавить разделы
Более подробно, 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