Android 10 unterstützt dynamische Partitionen, ein Partitionierungssystem für den Nutzerbereich, mit dem Partitionen während OTA-Updates (Over-the-Air) erstellt, in der Größe angepasst und gelöscht werden können.
Auf dieser Seite wird beschrieben, wie OTA-Clients dynamische Partitionen während eines Updates für Nicht-A/B-Geräte anpassen.
Bei Geräten, die keine A/B-Geräte sind, wird das OTA-Update für dynamische Partitionen mit updater im Updatepaket angewendet.
Startgeräte aktualisieren
Dieser Abschnitt gilt für Geräte ohne A/B-Partitionen, die mit Unterstützung für dynamische Partitionen auf den Markt kommen und von Android 10 auf höhere Versionen aktualisiert werden.
Updatepakete generieren
OTA-Aktualisierungspakete werden vom Skript ota_from_target_files generiert, das sich unter build/make/tools/releasetools befindet. Standardmäßig wird mit dem Skript ein Paket generiert, mit dem die Partitionen system und vendor aktualisiert werden. Wenn es zusätzliche dynamische Partitionen wie product, product_services oder odm gibt, müssen ihre Updates im gerätespezifischen Code generiert werden.
Implementieren Sie zum Generieren von Updates 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 würde. Von diesen beiden Funktionen zurückgegebene Partitionen sollten nicht manuell geändert oder an anderer Stelle überprüft werden, z. B. in *_InstallBegin() oder *_InstallEnd().
Beispiel für die Generierung eines Updates:
# 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
Im Hintergrund werden dem Edify-Skript die folgenden Funktionen hinzugefügt:
unmap_partition(name)- Hebt die Zuordnung der Partition auf, falls sie zugeordnet ist. Andernfalls wird nichts unternommen.
- Gibt bei Erfolg den String
tund bei einem Fehler einen leeren String zurück.
map_partition(name)- Weisen Sie der Partition einen Laufwerkbuchstaben zu, falls noch nicht geschehen.
- Gibt bei Erfolg den absoluten Pfad des zugeordneten Blockgeräts zurück, bei Fehler eine leere Zeichenfolge.
update_dynamic_partitions(op_list)- Wendet die angegebene Liste von Vorgängen auf dynamische Partitionsmetadaten an und hebt bei Bedarf die Zuordnung von Partitionen auf.
-
Gibt bei Erfolg
tund bei einem Fehler einen leeren String zurück.
Das Argument op_list für update_dynamic_partitions verweist auf eine Datei im Update-Paket. Jede Zeile in der Datei gibt einen Vorgang an. Wenn ein Vorgang fehlschlägt, gibt update_dynamic_partitions sofort einen leeren String zurück. Die Vorgänge sind:
resize partition-name size- Heben Sie die Zuordnung der Partition auf und passen Sie dann ihre Größe auf size an.
remove partition_name- Heben Sie die Zuordnung der Partition auf und entfernen Sie sie dann.
add partition-name group-name- Fügen Sie der angegebenen Gruppe eine neue Partition hinzu.
- Vorgang abbrechen, wenn die Gruppe oder die Partition bereits vorhanden ist.
move partition-name group-name- Verschieben Sie die Partition in die angegebene Gruppe.
- Vorgang abbrechen, wenn die Gruppe oder Partition nicht vorhanden ist.
-
add_group group-name maximum-size- Fügen Sie eine Gruppe mit dem angegebenen Namen und der angegebenen maximalen Größe hinzu.
- Vorgang abbrechen, wenn die Gruppe bereits vorhanden ist.
- Ein 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 Partitionen in der Gruppe den verfügbaren Speicherplatz auf dem Gerät nicht überschreiten.
-
resize_group group-name maximum-size- Ändert die Größe der Gruppe auf die angegebene maximale Größe.
- Abbrechen, wenn die Gruppe nicht vorhanden ist.
- Ein 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 Partitionen in der Gruppe den verfügbaren Speicherplatz auf dem Gerät nicht überschreiten.
remove_group group-name- Gruppe entfernen
- Vorgang abbrechen, wenn die Gruppe Partitionen enthält.
remove_all_groups- Alle Partitionen aus dem Device Mapper entfernen.
- Entfernen Sie alle Partitionen und Gruppen.
Inkrementelles OTA
Inkrementelle OTA-Updates verwenden die folgende Logik:
- Partitionen verkleinern/löschen/aus der Gruppe verschieben, damit genügend Speicherplatz zum Verkleinern von Gruppen vorhanden ist
- Gruppen verkleinern, damit genügend Platz für das Wachstum von Gruppen vorhanden ist
- Gruppen vergrößern (damit genügend Platz zum Vergrößern/Hinzufügen von Partitionen vorhanden ist)
- Partitionen vergrößern/hinzufügen/in eine neue Gruppe verschieben
update-script wird mit der folgenden 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 Datei op_list 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 groupVollständiges OTA
Vollständige OTA-Updates verwenden die folgende Logik:
- Alle vorhandenen Gruppen und Partitionen löschen
- Gruppen hinzufügen
- Partitionen hinzufügen
update-script wird mit der folgenden Logik generiert:
update_dynamic_partitions(op_list)
for each adding partition:
block_image_update(map_partition(name), …)
Die Datei op_list 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