OTA für Nicht-A/B-Geräte mit dynamischen Partitionen

Android 10 unterstützt dynamische Partitionen , ein Userspace-Partitionierungssystem, das bei Over-the-Air-Updates (OTA) Partitionen erstellen, in der Größe ändern und zerstören kann.

Auf dieser Seite wird beschrieben, wie OTA-Clients die Größe dynamischer Partitionen während eines Updates für Nicht-A/B-Geräte ändern.

Bei Nicht-A/B-Geräten wird das OTA-Update für dynamische Partitionen mithilfe des updater im Update-Paket angewendet.

Startgeräte aktualisieren

Dieser Abschnitt gilt für Nicht-A/B-Geräte, die mit Unterstützung dynamischer Partitionen gestartet werden; Diese Geräte werden von Android 10 auf höhere Versionen aktualisiert.

Generieren Sie Update-Pakete

OTA-Updatepakete werden vom Skript ota_from_target_files generiert, das sich unter build/make/tools/releasetools befindet. Standardmäßig generiert das Skript ein Paket, das die system und vendor aktualisiert. Wenn zusätzliche dynamische Partitionen wie product , product_services “ oder „ odm vorhanden sind, müssen deren Aktualisierungen in gerätespezifischem Code generiert werden.

Um Aktualisierungen zu generieren, implementieren Sie im erweiterten Python-Modul FullOTA_GetBlockDifferences() und IncrementalOTA_GetBlockDifferences() . Diese beiden Funktionen geben eine Liste von BlockDifference Objekten zurück, die jeweils den Update-Patch beschreiben, der auf eine Partition angewendet werden würde. Von diesen beiden Funktionen zurückgegebene Partitionen sollten nicht manuell geändert oder an anderer Stelle überprüft werden, beispielsweise in *_InstallBegin() oder *_InstallEnd() .

Beispiel einer Update-Generierung:

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

Aktualisierungsablauf

Hinter den Kulissen werden dem edify-Skript folgende Funktionen hinzugefügt:

  • unmap_partition(name)
    • Heben Sie die Zuordnung der Partition auf, falls sie zugeordnet ist, andernfalls unternehmen Sie nichts.
    • Gibt bei Erfolg die Zeichenfolge t oder bei einem Fehler eine leere Zeichenfolge zurück.
  • map_partition(name)
    • Ordnen Sie die Partition zu, falls noch nicht geschehen.
    • Gibt bei Erfolg den absoluten Pfad des zugeordneten Blockgeräts oder bei Fehler eine leere Zeichenfolge zurück.
  • update_dynamic_partitions(op_list)
    • Wenden Sie die angegebene Operationsliste auf dynamische Partitionsmetadaten an und heben Sie bei Bedarf die Partitionszuordnung auf.
    • Gibt t bei Erfolg zurück, oder eine leere Zeichenfolge bei Fehler.

Das Argument op_list für update_dynamic_partitions verweist auf eine Datei im Update-Paket. Jede Zeile in der Datei gibt eine Operation an. Wenn ein Vorgang fehlschlägt, gibt update_dynamic_partitions sofort eine leere Zeichenfolge zurück. Die Operationen sind:

  • resize partition-name size
    • Heben Sie die Zuordnung der Partition auf und ändern Sie die Größe auf size .
  • remove partition_name
    • Heben Sie die Zuordnung der Partition auf und entfernen Sie sie.
  • add partition-name group-name
    • Fügen Sie der angegebenen Gruppe eine neue Partition hinzu.
    • Abbruch, wenn die Gruppe nicht existiert oder die Partition bereits existiert.
  • move partition-name group-name
    • Verschieben Sie die Partition in die angegebene Gruppe.
    • Abbruch, wenn die Gruppe nicht existiert oder die Partition nicht existiert.
  • add_group group-name maximum-size
    • Fügen Sie eine Gruppe mit dem angegebenen Namen und der maximalen Größe hinzu.
    • Abbruch, wenn die Gruppe bereits existiert.
    • Eine maximum_size von 0 bedeutet, dass es keine Größenbeschränkungen für Partitionen in der Gruppe gibt. Es sind zusätzliche Tests erforderlich, um sicherzustellen, dass die Partitionen in der Gruppe den verfügbaren Speicherplatz auf dem Gerät nicht überschreiten.
  • resize_group group-name maximum-size
    • Ändern Sie die Größe der Gruppe auf die angegebene maximale Größe.
    • Abbruch, wenn die Gruppe nicht existiert.
    • Eine maximum_size von 0 bedeutet, dass es keine Größenbeschränkungen für Partitionen in der Gruppe gibt. Es sind zusätzliche Tests erforderlich, um sicherzustellen, dass die Partitionen in der Gruppe den verfügbaren Speicherplatz auf dem Gerät nicht überschreiten.
  • remove_group group-name
    • Eine Gruppe entfernen.
    • Abbruch, wenn Partitionen in der Gruppe vorhanden sind.
  • remove_all_groups
    • Heben Sie die Zuordnung aller Partitionen zum Geräte-Mapper auf.
    • Entfernen Sie alle Partitionen und Gruppen.

Inkrementeller OTA

Inkrementelle OTA-Updates verwenden die folgende Logik:

  1. Partitionen verkleinern/Partitionen löschen/Partitionen aus der Gruppe verschieben (damit genügend Platz zum Verkleinern von Gruppen vorhanden ist)
  2. Gruppen verkleinern (damit genügend Platz für die Erweiterung von Gruppen vorhanden ist)
  3. Gruppen vergrößern (damit wir genügend Platz zum Erweitern/Hinzufügen von Partitionen haben)
  4. Partitionen vergrößern/Partitionen hinzufügen/Partitionen in eine neue Gruppe verschieben

Im Detail wird update-script mit dieser Logik generiert:

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

Die op_list Datei für update_dynamic_partitions wird mit dieser Logik generiert:

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

Vollständiger OTA

Vollständige OTA-Updates verwenden die folgende Logik:

  1. Löschen Sie alle vorhandenen Gruppen und Partitionen
  2. Gruppen hinzufügen
  3. Partitionen hinzufügen

Im Detail wird update-script mit dieser Logik generiert:

update_dynamic_partitions(op_list)

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

Die op_list Datei für update_dynamic_partitions wird mit dieser Logik generiert:

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