Android 10 obsługuje partycje dynamiczne, czyli system partycjonowania w przestrzeni użytkownika, który umożliwia tworzenie, zmianę rozmiaru i usuwanie partycji podczas aktualizacji bezprzewodowych (OTA).
Na tej stronie opisujemy, jak klienci OTA zmieniają rozmiar partycji dynamicznych podczas aktualizacji urządzeń A/B, które zostały wprowadzone na rynek bez obsługi partycji dynamicznych, oraz jak klienci OTA przeprowadzają aktualizację do Androida 10.
Tło
Podczas aktualizacji urządzenia A/B do obsługi partycji dynamicznych tabela partycji GUID (GPT) na urządzeniu jest zachowywana, więc na urządzeniu nie ma partycji super na urządzeniu. Metadane są przechowywane w
system_a i system_b, ale można to
dostosować, zmieniając BOARD_SUPER_PARTITION_METADATA_DEVICE.
W każdym urządzeniu blokowym znajdują się 2 miejsca na metadane. Używane jest tylko jedno
miejsce na metadane w każdym urządzeniu blokowym. Na przykład metadane 0 w
system_a i metadane 1 w system_b
odpowiadają partycjom w odpowiednio miejscach A i B. Podczas działania nie ma znaczenia, które miejsce jest aktualizowane.
Na tej stronie miejsca na metadane są nazywane metadanymi S
(źródło) i metadanymi T (cel). Podobnie partycje są określane
jako system_s, vendor_t, itd.
Więcej informacji o konfiguracjach systemu kompilacji znajdziesz w artykule Aktualizowanie urządzeń.
Więcej informacji o tym, jak partycje należą do grup aktualizacji, znajdziesz w artykule Zmiany w konfiguracji płyty dla nowych urządzeń.
Przykład metadanych na urządzeniu:
- Fizyczne urządzenie blokowe
system_a- Metadane 0
- Grupa
foo_a- Logiczna (dynamiczna) partycja
system_a - Logiczna (dynamiczna) partycja
product_services_a - Inne partycje aktualizowane przez Foo
- Logiczna (dynamiczna) partycja
- Grupa
bar_a- Logiczna (dynamiczna) partycja
vendor_a - Logiczna (dynamiczna) partycja
product_a - Inne partycje aktualizowane przez Bar
- Logiczna (dynamiczna) partycja
- Grupa
- Metadane 1 (nieużywane)
- Metadane 0
- Fizyczne urządzenie blokowe
system_b- Metadane 0 (nieużywane)
- Metadane 1
- Grupa foo_b
- Logiczna (dynamiczna) partycja
system_b - Logiczna (dynamiczna) partycja
product_services_b - Inne partycje aktualizowane przez Foo
- Logiczna (dynamiczna) partycja
- Grupa bar_b
- Logiczna (dynamiczna) partycja
vendor_b - Logiczna (dynamiczna) partycja
product_b - Inne partycje aktualizowane przez Bar
- Logiczna (dynamiczna) partycja
- Grupa foo_b
Aby zrzucić metadane na urządzeniu, możesz użyć narzędzia lpdump w
system/extras/partition_tools Przykład:
lpdump --slot 0 /dev/block/by-name/system_alpdump --slot 1 /dev/block/by-name/system_b
Dopasowywanie aktualizacji
Na urządzeniach z Androidem 9 i starszym klient OTA na urządzeniu nie obsługuje mapowania partycji dynamicznych przed aktualizacją. Tworzony jest dodatkowy zestaw poprawek, aby mapowanie można było zastosować bezpośrednio do istniejących partycji fizycznych.
Generator OTA tworzy końcowy plik super.img, który
zawiera zawartość wszystkich partycji dynamicznych, a następnie dzieli obraz
na kilka obrazów pasujących do rozmiarów fizycznych urządzeń blokowych
odpowiadających systemowi, dostawcy itp. Te obrazy mają nazwy
super_system.img, super_vendor.img, itd.
Klient OTA stosuje te obrazy do partycji fizycznych, a nie do obrazów partycji logicznych (dynamicznych).
Ponieważ klient OTA nie wie, jak mapować partycje dynamiczne, 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 dopasowaniu
Po aktualizacji dopasowującej klient OTA jest aktualizowany, aby działał z dynamicznymi partycjami. Zakresy partycji źródłowych nigdy nie obejmują docelowych partycji fizycznych.
Proces aktualizacji przy użyciu zwykłego pakietu aktualizacji
- Zainicjuj metadane partycji
super-
Utwórz nowe metadane M na podstawie metadanych S (metadane źródłowe).
Jeśli na przykład metadane S używają [
system_s,vendor_s,product_s] jako urządzeń blokowych, nowe metadane M używają [system_t,vendor_t,product_t] jako urządzeń blokowych. Wszystkie grupy i partycje są odrzucane w M. -
Dodaj grupy i partycje docelowe zgodnie z polem
dynamic_partition_metadataw manifeście aktualizacji. Rozmiar każdej partycji można znaleźć 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 (metadane źródłowe).
Jeśli na przykład metadane S używają [
- Zastosuj aktualizację na urządzeniach blokowych.
- W razie potrzeby zmapuj partycje źródłowe w mapowaniu urządzeń jako tylko do odczytu. Jest to konieczne w przypadku wczytywania z boku, ponieważ partycje źródłowe nie są mapowane przed aktualizacją.
- Zastosuj pełną lub przyrostową aktualizację do wszystkich urządzeń blokowych w miejscu docelowym.
- Zamontuj partycje, aby uruchomić skrypt po instalacji, a następnie odmontuj partycje.
- Odmapuj partycje docelowe.
Proces aktualizacji przy użyciu pakietu aktualizacji dopasowującej
Jeśli pakiet aktualizacji dopasowującej zostanie zastosowany na urządzeniu, które już
obsługuje partycje dynamiczne, klient OTA zastosuje podzielony
super.img bezpośrednio na urządzeniach blokowych. Proces aktualizacji
przepływu jest podobny do aktualizacji dopasowującej. Szczegółowe informacje znajdziesz w artykule
Dopasowywanie aktualizacji.
Załóżmy na przykład, że:
- Miejsce A jest miejscem aktywnym.
-
system_azawiera aktywne metadane w miejscu 0. -
system_a,vendor_a, iproduct_asą używane jako urządzenia blokowe.
Gdy klient OTA otrzyma pakiet aktualizacji dopasowującej, zastosuje
super_system.img na fizycznym system_b,
super_vendor.img na fizycznym vendor_b, i
super_product.img na fizycznym product_b.
Fizyczne urządzenie blokowe system_b zawiera prawidłowe
metadane do mapowania logicznych system_b,
vendor_b i product_b podczas uruchamiania.
Generowanie pakietów aktualizacji
Przyrostowa aktualizacja OTA
Podczas generowania przyrostowych aktualizacji OTA dla urządzeń dopasowujących 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
super.imgplik i wyłącza krok po instalacji. - Jeśli kompilacja podstawowa definiuje zmienne, jest to taka sama aktualizacja jak typowa aktualizacja z partycjami dynamicznymi. Pakiet aktualizacji zawiera obrazy partycji logicznych (dynamicznych). Można włączyć krok po instalacji.
Pełna aktualizacja OTA
Dla urządzeń dopasowujących generowane są 2 pełne pakiety OTA.
-
$(PRODUCT)-ota-retrofit-$(TAG).zipzawsze zawiera podzielony pliksuper.imgi wyłącza krok po instalacji w przypadku aktualizacji dopasowującej.-
Jest generowany z dodatkowym argumentem
--retrofit_dynamic_partitionsdoota_from_target_filesskryptu. - Można go zastosować do wszystkich kompilacji.
-
Jest generowany z dodatkowym argumentem
-
$(PRODUCT)-ota-$(TAG).zipzawiera obrazy logiczne na potrzeby przyszłych aktualizacji.- Stosuj go tylko do kompilacji z włączonymi partycjami dynamicznymi. Szczegółowe informacje o wymuszaniu tego znajdziesz poniżej.
Odrzucanie aktualizacji niedopasowujących w starszych kompilacjach
Zastosuj zwykły pełny pakiet OTA tylko do kompilacji z partycjami dynamicznymi. Jeśli serwer OTA jest nieprawidłowo skonfigurowany i wysyła te pakiety na urządzenia z Androidem 9 lub starszym, urządzenia nie uruchomią się. Klient OTA w Androidzie 9 i starszym nie może odróżnić pakietu OTA dopasowującego od zwykłego pełnego pakietu OTA, więc klient nie odrzuci pełnego pakietu.
Aby uniemożliwić urządzeniu zaakceptowanie pełnego pakietu OTA, możesz wymagać wykonania kroku po instalacji, aby sprawdzić istniejącą konfigurację urządzenia. 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ę.