Android 10 obsługuje partycje dynamiczne, czyli system partycjonowania przestrzeni użytkownika, który może tworzyć, zmieniać rozmiar i usuwać partycje podczas aktualizacji bezprzewodowych (OTA).
Na tej stronie opisujemy, jak klienci OTA zmieniają rozmiar partycji dynamicznych podczas aktualizacji na urządzeniach innych niż A/B.
W przypadku urządzeń innych niż A/B aktualizacja OTA partycji dynamicznych jest stosowana za pomocą pliku updater w pakiecie aktualizacji.
Aktualizowanie urządzeń wprowadzanych na rynek
Ta sekcja dotyczy urządzeń innych niż A/B, które są wprowadzane na rynek z obsługą partycji dynamicznych. Te urządzenia są aktualizowane z Androida 10 do nowszych wersji.
Generowanie pakietów aktualizacji
Pakiety aktualizacji OTA są generowane przez skrypt ota_from_target_files znajdujący się w folderze build/make/tools/releasetools. Domyślnie skrypt generuje pakiet, który aktualizuje partycje system i vendor. Jeśli istnieją dodatkowe partycje dynamiczne, takie jak product, product_services lub odm, ich aktualizacje muszą być generowane w kodzie specyficznym dla urządzenia.
Aby generować aktualizacje, w rozszerzonym module Pythona zaimplementuj FullOTA_GetBlockDifferences() i IncrementalOTA_GetBlockDifferences(). Te 2 funkcje zwracają listę obiektów BlockDifference, z których każdy opisuje poprawkę aktualizacji, która zostanie zastosowana do partycji. Partycji zwracanych przez te 2 funkcje nie należy modyfikować ręcznie ani weryfikować w innych miejscach, np. 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 przepływu
W skrypcie edify dodawane są te funkcje:
unmap_partition(name)- Usuń mapowanie partycji, jeśli jest zmapowana, w przeciwnym razie nie rób nic.
- W przypadku powodzenia zwraca ciąg znaków
t, a w przypadku niepowodzenia – pusty ciąg znaków.
map_partition(name)- Zmapuj partycję, jeśli nie jest jeszcze zmapowana.
- Zwraca bezwzględną ścieżkę zamapowanego urządzenia blokowego w przypadku powodzenia lub pusty ciąg znaków w przypadku niepowodzenia.
update_dynamic_partitions(op_list)- Zastosuj podaną listę operacji do metadanych partycji dynamicznej, w razie potrzeby usuwając mapowanie partycji.
-
W przypadku powodzenia zwraca
t, a w przypadku niepowodzenia – pusty ciąg znaków.
Argument op_list do
update_dynamic_partitions wskazuje plik w
pakiecie aktualizacji. Każdy wiersz w pliku określa operację. Jeśli jakakolwiek operacja zakończy się niepowodzeniem, funkcja update_dynamic_partitions natychmiast zwraca pusty ciąg. Dostępne są te operacje:
resize partition-name size- Odłącz partycję, a następnie zmień jej rozmiar na size.
remove partition_name- Odłącz partycję, a następnie ją usuń.
add partition-name group-name- Dodaj nowy podział do określonej grupy.
- Przerwij, jeśli grupa nie istnieje lub partycja już istnieje.
move partition-name group-name- Przenieś partycję do określonej grupy.
- Przerwij, jeśli grupa lub partycja nie istnieje.
-
add_group group-name maximum-size- Dodaj grupę o podanej nazwie i maksymalnym rozmiarze.
- Przerwij, jeśli grupa już istnieje.
- Wartość maximum_size równa 0 oznacza, że w grupie nie ma ograniczeń rozmiaru partycji. Konieczne są dodatkowe testy, aby upewnić się, że partycje w grupie nie przekraczają dostępnego 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 równa 0 oznacza, że w grupie nie ma ograniczeń rozmiaru partycji. Konieczne są dodatkowe testy, aby upewnić się, że partycje w grupie nie przekraczają dostępnego miejsca na urządzeniu.
remove_group group-name- Usuń grupę.
- Przerwij, jeśli w grupie są partycje.
remove_all_groups- Odłącz wszystkie partycje od mapowania urządzeń.
- Usuń wszystkie partycje i grupy.
Przyrostowa OTA
Przyrostowe aktualizacje OTA działają według tej logiki:
- Zmniejszanie partycji, usuwanie partycji lub przenoszenie partycji poza grupę (aby było wystarczająco dużo miejsca na zmniejszenie grup)
- Zmniejszanie grup (aby było wystarczająco dużo miejsca na ich powiększenie)
- powiększać grupy (aby mieć wystarczająco dużo miejsca na powiększanie i dodawanie partycji);
- Zwiększanie rozmiaru partycji, dodawanie partycji i przenoszenie partycji do nowej grupy
W szczegółach wartość update-script jest generowana zgodnie z tą logiką:
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 dla update_dynamic_partitions jest generowany zgodnie z tą logiką:
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 groupPełna aktualizacja OTA
Pełne aktualizacje OTA korzystają z tej logiki:
- Usuń wszystkie istniejące grupy i partycje.
- Dodaj grupy
- Dodawanie partycji
W szczegółach wartość update-script jest generowana zgodnie z tą logiką:
update_dynamic_partitions(op_list)
for each adding partition:
block_image_update(map_partition(name), …)
Plik op_list dla update_dynamic_partitions jest generowany zgodnie z tą logiką:
remove_all_groups
for each adding group:
add_group
for each adding partition:
add
for each adding partition:
resize