OTA для устройств не-A/B с динамическими разделами

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) используется следующая логика:

  1. Сжимать разделы/удалять разделы/перемещать разделы за пределы группы (чтобы освободить достаточно места для сжатия групп).
  2. Сократите группы (чтобы осталось достаточно места для расширения групп).
  3. Расширяйте группы (чтобы у нас было достаточно места для расширения/добавления разделов).
  4. Увеличение размера разделов/добавление разделов/перемещение разделов в новую группу

Подробнее, 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) используют следующую логику:

  1. Удалите все существующие группы и разделы.
  2. Добавить группы
  3. Добавить разделы

Подробнее, 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