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 используют следующую логику:
- Сжать разделы/удалить разделы/переместить разделы из группы (чтобы было достаточно места для сжатия групп)
- Сжимать группы (чтобы было достаточно места для расширения групп)
- Расширить группы (чтобы у нас было достаточно места для увеличения/добавления разделов)
- Увеличить разделы/добавить разделы/переместить разделы в новую группу
Подробно, 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