Aktualizacja OTA na urządzeniach innych niż A/B z partycjami dynamicznymi

Android 10 obsługuje dynamiczne partycje, czyli partycjonowanie przestrzeni użytkownika. który może tworzyć, niszczyć i zmieniać rozmiar partycji podczas aktualizacji OTA.

Na tej stronie dowiesz się, jak klienty OTA zmieniają rozmiar partycji dynamicznych podczas aktualizacji urządzeń innych niż A/B.

W przypadku urządzeń innych niż A/B jest stosowana aktualizacja OTA do partycji dynamicznych za pomocą funkcji updater w pakiecie aktualizacji.

Aktualizowanie urządzeń uruchamiających

Ta sekcja dotyczy urządzeń innych niż A/B, które uruchamiają się z dynamicznymi obsługa partycji; te urządzenia przeszły z Androida od 10 do wyższych wersji.

Generowanie pakietów aktualizacji

Pakiety aktualizacji OTA są generowane przez Skrypt ota_from_target_files znajduje się pod build/make/tools/releasetools Domyślnie skrypt generuje pakiet, który aktualizuje partycje system i vendor. Jeśli masz dodatkowe tagi dynamiczne partycje, takie jak product, product_services lub odm, ich aktualizacje muszą być generowane w zależnie od urządzenia .

Aby generować aktualizacje, w rozszerzonym module Pythona zaimplementuj funkcje FullOTA_GetBlockDifferences() i IncrementalOTA_GetBlockDifferences(). Te dwie opcje funkcje zwracają listę obiektów BlockDifference, każdy z opisem poprawki do aktualizacji, która zostałaby zastosowana partycji danych. Partycje zwracane przez te 2 funkcje nie powinny być zmodyfikowanych ręcznie lub zweryfikowanych w innym miejscu, na przykład w *_InstallBegin() lub *_InstallEnd().

Przykład generowania aktualizacji:

# 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()]

Aktualizowanie procesu

W tle do skryptu edify dodawane są te funkcje:

  • unmap_partition(name)
    • Odmapuj partycję, jeśli jest zamapowana, w przeciwnym razie nic nie rób.
    • Zwracaj ciąg t w przypadku powodzenia lub puste pole w przypadku niepowodzenia.
  • map_partition(name)
    • Zmapuj partycję, jeśli jeszcze nie jest zamapowana.
    • W przypadku powodzenia zwraca ścieżkę bezwzględną zmapowanego urządzenia blokującego, a w przypadku niepowodzenia – pusty ciąg znaków.
  • update_dynamic_partitions(op_list)
    • Zastosuj podaną listę operacji do metadanych partycji dynamicznej, w razie potrzeby niemapować partycji.
    • Zwrot t w przypadku powodzenia lub pusty ciąg znaków w przypadku niepowodzenia.

Argument op_list funkcji update_dynamic_partitions wskazuje plik w pakietu aktualizacji. Każdy wiersz w pliku określa operację. Jeśli tak, operacja się nie udała, update_dynamic_partitions natychmiast zwraca pusty ciąg. Operacje:

  • resize partition-name size
    • Usuń mapowanie partycji, a następnie zmień jej rozmiar na size.
  • remove partition_name
    • Usuń mapowanie partycji, a następnie ją usuń.
  • add partition-name group-name
    • Dodaj nową partycję do określonej grupy.
    • Przerwij, jeśli grupa nie istnieje lub jeśli partycja już istnieje istnieje.
  • move partition-name group-name
    • Przenieś partycję do określonej grupy.
    • Przerwij, jeśli grupa nie istnieje lub partycja nie istnieje.
  • add_group group-name maximum-size
    • Dodaj grupę z podaną nazwą i maksymalną wielkością.
    • Anuluj, jeśli grupa już istnieje.
    • Wartość maximum_size o wartości 0 oznacza, że nie ma limitów rozmiaru. na partycjach w grupie. Wymagane są dodatkowe testy, upewnij się, że partycje w grupie nie przekraczają miejsca na urządzeniu.
  • resize_group group-name maximum-size
    • Zmień rozmiar grupy do podanego maksymalnego rozmiaru.
    • Przerwij, jeśli grupa nie istnieje.
    • Wartość maximum_size o wartości 0 oznacza, że nie ma limitów rozmiaru. na partycjach w grupie. Konieczne są dodatkowe testy, aby mieć pewność, że partycje w grupie nie przekraczają dostępnej przestrzeni na urządzeniu.
  • remove_group group-name
    • usunąć grupę,
    • Przerwij, jeśli w grupie istnieją partycje.
  • remove_all_groups
    • Odmapuj wszystkie partycje z mapera urządzenia.
    • Usuń wszystkie partycje i grupy.

Przyrostowa OTA

Przyrostowe aktualizacje OTA działają w ten sposób:

  1. Zmniejsz partycje/usuń partycje/przenieś partycje poza grupy (tak aby było wystarczająco dużo miejsca na zmniejszenie grup)
  2. Zmniejsz grupy (aby było wystarczająco dużo miejsca na ich powiększenie).
  3. rozwijają grupy (dzięki czemu mamy wystarczającą ilość miejsca, aby się rozwijać/dodawać); partycje)
  4. zwiększać partycje, dodawać partycje lub przenosić partycje do nowej grupy.

Szczegółowo update-script jest generowany według tej logiki:

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), …)

Plik op_list dotyczący Element update_dynamic_partitions jest generowany na jego podstawie logika:

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

Pełna aktualizacja OTA

Pełne aktualizacje OTA działają w ten sposób:

  1. usunąć wszystkie istniejące grupy i partycje.
  2. Dodaj grupy
  3. Dodawanie partycji

Szczegóły dotyczące update-script są generowane zgodnie z tą logiką:

update_dynamic_partitions(op_list)

for each adding partition:
    block_image_update(map_partition(name), …)

Plik op_list dotyczący Element update_dynamic_partitions jest generowany na jego podstawie logika:

remove_all_groups
for each adding group:
    add_group
for each adding partition:
    add
for each adding partition:
    resize