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 A/B, które zostały wprowadzone na rynek bez obsługi partycji dynamicznych, oraz jak klienci OTA przeprowadzają uaktualnienie do Androida 10.
Tło
Podczas aktualizacji urządzenia A/B w celu obsługi partycji dynamicznych tabela partycji GUID (GPT) na urządzeniu jest zachowywana, więc na urządzeniu nie ma partycji super
. Metadane są przechowywane w lokalizacjach system_a
i system_b
, ale można to dostosować, zmieniając wartość BOARD_SUPER_PARTITION_METADATA_DEVICE
.
Na każdym urządzeniu blokowym znajdują się 2 miejsca na metadane. W każdym urządzeniu blokowym używane jest tylko 1 miejsce na metadane. Na przykład metadane 0 w system_a
i metadane 1 w system_b
odpowiadają odpowiednio partycjom w gniazdach A i B. W czasie działania nie ma znaczenia, które miejsce na reklamę jest aktualizowane.
Na tej stronie gniazda metadanych są nazywane Metadata S (źródło) i Metadata T (miejsce docelowe). Podobnie partycje są oznaczane jako system_s
, vendor_t
itd.
Więcej informacji o konfiguracjach systemu kompilacji znajdziesz w sekcji Uaktualnianie urządzeń.
Więcej informacji o tym, do jakich grup aktualizacji należą partycje, znajdziesz w sekcji Zmiany w konfiguracji płyty w przypadku nowych urządzeń.
Przykład metadanych na urządzeniu:
- Fizyczne urządzenie blokowe
system_a
- Metadane 0
- Grupa
foo_a
- Partycja logiczna (dynamiczna)
system_a
- Partycja logiczna (dynamiczna)
product_services_a
- Inne partycje zaktualizowane przez Foo
- Partycja logiczna (dynamiczna)
- Grupa
bar_a
- Partycja logiczna (dynamiczna)
vendor_a
- Partycja logiczna (dynamiczna)
product_a
- Inne partycje zaktualizowane przez Bar
- Partycja logiczna (dynamiczna)
- Grupa
- Metadane 1 (nieużywane)
- Metadane 0
- Fizyczne urządzenie blokowe
system_b
- Metadane 0 (nieużywane)
- Metadane 1
- Grupa foo_b
- Partycja logiczna (dynamiczna)
system_b
- Partycja logiczna (dynamiczna)
product_services_b
- Inne partycje zaktualizowane przez Foo
- Partycja logiczna (dynamiczna)
- Group bar_b
- Partycja logiczna (dynamiczna)
vendor_b
- Partycja logiczna (dynamiczna)
product_b
- Inne partycje zaktualizowane przez Bar
- Partycja logiczna (dynamiczna)
- Grupa foo_b
Możesz użyć narzędzia lpdump
w sekcji system/extras/partition_tools
, aby zrzucić metadane na urządzenie. Na przykład:
lpdump --slot 0 /dev/block/by-name/system_a
lpdump --slot 1 /dev/block/by-name/system_b
Dostosowywanie aktualizacji
Na urządzeniach z Androidem 9 i starszym klient OTA nie obsługuje mapowania dynamicznych partycji przed aktualizacją. Tworzony jest dodatkowy zestaw poprawek, dzięki czemu mapowanie można zastosować bezpośrednio do istniejących partycji fizycznych.
Generator OTA tworzy ostateczny plik super.img
, który zawiera zawartość wszystkich partycji dynamicznych, a następnie dzieli obraz na kilka obrazów o rozmiarach odpowiadających rozmiarom fizycznych urządzeń blokowych odpowiadających systemowi, dostawcy itp. Obrazy te noszą nazwy super_system.img
, super_vendor.img
itd.
Klient OTA stosuje te obrazy do partycji fizycznych, a nie do partycji logicznych (dynamicznych).
Klient OTA nie wie, jak mapować partycje dynamiczne, więc wszystkie kroki po instalacji są automatycznie wyłączane w przypadku tych partycji podczas generowania pakietu aktualizacji. Więcej informacji znajdziesz w artykule Konfigurowanie po instalacji.
Proces aktualizacji jest taki sam jak w Androidzie 9.
Przed aktualizacją:
ro.boot.dynamic_partitions= ro.boot.dynamic_partitions_retrofit=
Po aktualizacji:
ro.boot.dynamic_partitions=true ro.boot.dynamic_partitions_retrofit=true
Przyszłe aktualizacje po modernizacji
Po aktualizacji modernizacyjnej klient OTA jest aktualizowany, aby działać z partycjami dynamicznymi. Zakresy partycji źródłowych nigdy nie obejmują docelowych partycji fizycznych.
Aktualizowanie przepływu za pomocą zwykłego pakietu aktualizacji
- Zainicjuj metadane partycji
super
.-
Utwórz nowe metadane M na podstawie metadanych S (metadanych źródłowych).
Jeśli na przykład metadane S używają [
system_s
,vendor_s
,product_s
] jako urządzeń blokowych, to nowe metadane M używają [system_t
,vendor_t
,product_t
] jako urządzeń blokowych. W przypadku M wszystkie grupy i partycje są odrzucane. -
Dodaj grupy docelowe i podziały zgodnie z polem
dynamic_partition_metadata
w pliku manifestu aktualizacji. Rozmiar każdej partycji znajdziesz wnew_partition_info
. - Zapisz M w metadanych T.
- Zmapuj dodane partycje w mapowaniu urządzeń jako zapisywalne.
-
Utwórz nowe metadane M na podstawie metadanych S (metadanych źródłowych).
Jeśli na przykład metadane S używają [
- Zastosuj aktualizację na urządzeniach blokujących.
- W razie potrzeby zmapuj partycje źródłowe na mapowaniu urządzenia jako tylko do odczytu. Jest to konieczne w przypadku wczytywania z zewnątrz, ponieważ partycje źródłowe nie są mapowane przed aktualizacją.
- Zastosuj pełną lub przyrostową aktualizację do wszystkich urządzeń blokowych w docelowym slocie.
- Zamontuj partycje, aby uruchomić skrypt poinstalacyjny, a następnie odmontuj partycje.
- Odłącz partycje docelowe.
Aktualizowanie przepływu za pomocą pakietu aktualizacji wstecznej
Jeśli pakiet aktualizacji zostanie zastosowany na urządzeniu, które już obsługuje partycje dynamiczne, klient OTA zastosuje plik super.img
na urządzeniach blokowych bezpośrednio. Proces aktualizacji jest podobny do aktualizacji modernizacyjnej. Więcej informacji znajdziesz w artykule Dostosowywanie aktualizacji.
Załóżmy na przykład, że:
- Slot A jest aktywny.
-
system_a
zawiera aktywne metadane w slocie 0. -
system_a
,vendor_a
iproduct_a
są używane jako urządzenia blokujące.
Gdy klient OTA otrzyma pakiet aktualizacji, zastosuje super_system.img
na urządzeniu system_b
, super_vendor.img
na urządzeniu vendor_b
i super_product.img
na urządzeniu product_b
.
Fizyczne urządzenie blokowe system_b
zawiera prawidłowe metadane, które umożliwiają zmapowanie logicznych urządzeń system_b
, vendor_b
i product_b
podczas uruchamiania.
Generowanie pakietów aktualizacji
Przyrostowa OTA
Podczas generowania przyrostowych aktualizacji OTA dla urządzeń modernizowanych aktualizacje zależą od tego, czy kompilacja podstawowa definiuje PRODUCT_USE_DYNAMIC_PARTITIONS
i PRODUCT_RETROFIT_DYNAMIC_PARTITIONS
.
-
Jeśli kompilacja podstawowa nie definiuje zmiennych, jest to aktualizacja dopasowująca. Pakiet aktualizacji zawiera podzielony plik
super.img
i wyłącza krok po instalacji. - Jeśli kompilacja podstawowa definiuje zmienne, jest to takie samo jak typowa aktualizacja z partycjami dynamicznymi. Pakiet aktualizacji zawiera obrazy partycji logicznych (dynamicznych). Można włączyć etap po instalacji.
Pełna aktualizacja OTA
W przypadku urządzeń modernizowanych generowane są 2 pełne pakiety OTA.
-
$(PRODUCT)-ota-retrofit-$(TAG).zip
zawsze zawiera podzielonysuper.img
i wyłącza krok po instalacji w przypadku aktualizacji.-
Jest on generowany z dodatkowym argumentem
--retrofit_dynamic_partitions
do skryptuota_from_target_files
. - Można ją zastosować do wszystkich wersji.
-
Jest on generowany z dodatkowym argumentem
-
$(PRODUCT)-ota-$(TAG).zip
zawiera logiczne obrazy na potrzeby przyszłych aktualizacji.- Stosuj to tylko w przypadku kompilacji z włączonymi partycjami dynamicznymi. Szczegółowe informacje o egzekwowaniu tych zasad znajdziesz poniżej.
Odrzucanie aktualizacji bez dopasowania w przypadku starszych kompilacji
Zastosuj zwykły pełny pakiet OTA tylko w przypadku kompilacji z włączonymi partycjami dynamicznymi. Jeśli serwer OTA jest nieprawidłowo skonfigurowany i przesyła te pakiety na urządzenia z Androidem 9 lub starszym, urządzenia nie uruchomią się. Klient OTA na Androidzie 9 i starszych wersjach nie potrafi odróżnić pakietu OTA z modernizacją od zwykłego pełnego pakietu OTA, więc nie odrzuci pełnego pakietu.
Aby uniemożliwić urządzeniu zaakceptowanie pełnego pakietu OTA, możesz wymagać wykonania po instalacji czynności sprawdzającej istniejącą konfigurację urządzenia. Na przykład:
device/device_name/dynamic_partitions/check_dynamic_partitions
#!/system/bin/sh DP_PROPERTY_NAME="ro.boot.dynamic_partitions" DP_RETROFIT_PROPERTY_NAME="ro.boot.dynamic_partitions_retrofit" DP_PROPERTY=$(getprop ${DP_PROPERTY_NAME}) DP_RETROFIT_PROPERTY=$(getprop ${DP_RETROFIT_PROPERTY_NAME}) if [ "${DP_PROPERTY}" != "true" ] || [ "${DP_RETROFIT_PROPERTY}" != "true" ] ; then echo "Error: applied non-retrofit update on build without dynamic" \ "partitions." echo "${DP_PROPERTY_NAME}=${DP_PROPERTY}" echo "${DP_RETROFIT_PROPERTY_NAME}=${DP_RETROFIT_PROPERTY}" exit 1 fi
device/device_name/dynamic_partitions/Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE:= check_dynamic_partitions LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := EXECUTABLES LOCAL_SRC_FILES := check_dynamic_partitions LOCAL_PRODUCT_MODULE := true include $(BUILD_PREBUILT)
device/device_name/device.mk
PRODUCT_PACKAGES += check_dynamic_partitions # OPTIONAL=false so that the error in check_dynamic_partitions will be # propagated to OTA client. AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_product=true \ POSTINSTALL_PATH_product=bin/check_dynamic_partitions \ FILESYSTEM_TYPE_product=ext4 \ POSTINSTALL_OPTIONAL_product=false \
Gdy zwykły pakiet OTA zostanie zastosowany na urządzeniu bez włączonych partycji dynamicznych, klient OTA uruchomi check_dynamic_partitions
jako krok po instalacji i odrzuci aktualizację.