OTA dla urządzeń A/B bez partycji dynamicznych

Android 10 obsługuje partycje dynamiczne – system partycjonowania przestrzeni użytkownika, który umożliwia tworzenie, zmianę rozmiaru i niszczenie partycji podczas aktualizacji OTA.

Na tej stronie opisano, jak klienci OTA zmieniają rozmiar partycji dynamicznych podczas aktualizacji dla urządzeń A/B, które zostały uruchomione bez obsługi partycji dynamicznych, oraz w jaki sposób klienci OTA uaktualniają się do systemu Android 10.

Tło

Podczas aktualizacji urządzenia A/B w celu obsługi partycji dynamicznych tablica partycji GUID (GPT) na urządzeniu zostaje zachowana, więc na urządzeniu nie ma super partycji. Metadane są przechowywane w system_a i system_b , ale można to dostosować, zmieniając BOARD_SUPER_PARTITION_METADATA_DEVICE .

W każdym z urządzeń blokowych znajdują się dwa sloty 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 odpowiednio w gniazdach A i B. W czasie wykonywania nie ma znaczenia, który slot jest aktualizowany.

Na tej stronie przedziały metadanych nazywane są Metadane S (źródło) i Metadane T (cel). Podobnie partycje są określane jako system_s , vendor_t i tak dalej.

Aby uzyskać więcej informacji na temat konfiguracji systemu kompilacji , zobacz Aktualizowanie urządzeń .

Aby uzyskać więcej informacji na temat przynależności partycji do grup aktualizacji , zobacz Zmiany w konfiguracji płyty dla nowych urządzeń.

Przykładowe metadane na urządzeniu to:

  • Urządzenie bloku fizycznego system_a
    • Metadane 0
      • Grupa foo_a
        • system_a partycji logicznych (dynamicznych)_a
        • Partycja logiczna (dynamiczna) product_services_a
        • Inne partycje zaktualizowane przez Foo
      • bar_a grupowy_a
        • vendor_a partycji logicznej (dynamicznej)_a
        • Partycja logiczna (dynamiczna) product_a
        • Inne partycje zaktualizowane przez Bar
    • Metadane 1 (nieużywane)
  • Urządzenie bloku fizycznego 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
      • Pasek grupowy_b
        • vendor_b partycji logicznej (dynamicznej)_b
        • Partycja logiczna (dynamiczna) product_b
        • Inne partycje zaktualizowane przez Bar

Możesz użyć narzędzia lpdump w obszarze system/extras/partition_tools aby zrzucić metadane na swoje urządzenie. Na przykład:

lpdump --slot 0 /dev/block/by-name/system_a
lpdump --slot 1 /dev/block/by-name/system_b

Dokonaj aktualizacji

Na urządzeniach z systemem Android 9 i starszym klient OTA na urządzeniu nie obsługuje mapowania partycji dynamicznych 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 wiele obrazów odpowiadających rozmiarom urządzeń bloków fizycznych odpowiadających systemowi, dostawcy itd. Te obrazy mają nazwy super_system.img , super_vendor.img i tak dalej. Klient OTA stosuje te obrazy do partycji fizycznych, zamiast stosować obrazy do partycji logicznych (dynamicznych).

Ponieważ klient OTA nie wie, jak mapować partycje dynamiczne, wszystkie kroki po instalacji są automatycznie wyłączane dla tych partycji po wygenerowaniu pakietu aktualizacji. Aby uzyskać więcej informacji, zobacz Konfigurowanie po instalacji .

Przebieg 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 do pracy z partycjami dynamicznymi. Zasięgi partycji źródłowych nigdy nie obejmują docelowych partycji fizycznych.

Przepływ aktualizacji przy użyciu zwykłego pakietu aktualizacji

  1. Zainicjuj metadane super partycji.
    1. Skonstruuj nowe metadane M z Metadanych S (metadane źródłowe). Na przykład, jeśli Metadane S używają [ system_s , vendor_s , product_s ] jako urządzeń blokowych, wówczas nowe metadane M używają [ system_t , vendor_t , product_t ] jako urządzeń blokowych. Wszystkie grupy i partycje są odrzucane w M.
    2. Dodaj grupy docelowe i partycje zgodnie z polem dynamic_partition_metadata w manifeście aktualizacji. Rozmiar każdej partycji można znaleźć w new_partition_info .
    3. Zapisz M do Metadanych T.
    4. Zamapuj dodane partycje w programie mapującym urządzenia jako nadające się do zapisu.
  2. Zastosuj aktualizację na urządzeniach blokowych.
    1. Jeśli to konieczne, zamapuj partycje źródłowe w programie mapującym urządzenia jako tylko do odczytu. Jest to konieczne w przypadku ładowania bocznego, ponieważ partycje źródłowe nie są mapowane przed aktualizacją.
    2. Zastosuj aktualizację pełną lub delta do wszystkich urządzeń blokowych w gnieździe docelowym.
    3. Zamontuj partycje, aby uruchomić skrypt poinstalacyjny, a następnie odmontuj partycje.
  3. Odmapuj partycje docelowe.

Przepływ aktualizacji przy użyciu pakietu aktualizacji modernizacyjnej

Jeśli pakiet aktualizacji modernizacyjnej zostanie zastosowany na urządzeniu, które już umożliwia partycje dynamiczne, klient OTA zastosuje podzielony plik super.img bezpośrednio na urządzeniach blokowych. Przebieg aktualizacji jest podobny do aktualizacji modernizacyjnej. Aby uzyskać szczegółowe informacje, zobacz temat Modernizacja aktualizacji .

Załóżmy na przykład, co następuje:

  • Gniazdo A jest aktywnym gniazdem.
  • system_a zawiera aktywne metadane w gnieździe 0.
  • system_a , vendor_a i product_a są używane jako urządzenia blokowe.

Gdy klient OTA otrzyma pakiet aktualizacji modernizacyjnej, stosuje plik 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 poprawne metadane do mapowania logicznego system_b , vendor_b i product_b w czasie rozruchu.

Wygeneruj pakiety aktualizacji

Przyrostowa OTA

Podczas generowania przyrostowych OTA dla urządzeń modernizowanych aktualizacje zależą od tego, czy w wersji podstawowej zdefiniowano PRODUCT_USE_DYNAMIC_PARTITIONS i PRODUCT_RETROFIT_DYNAMIC_PARTITIONS .

  • Jeśli wersja podstawowa nie definiuje zmiennych, jest to aktualizacja doposażająca. Pakiet aktualizacji zawiera podzielony plik super.img i wyłącza krok poinstalacyjny.
  • Jeśli wersja podstawowa definiuje zmienne, jest to to samo, co typowa aktualizacja z partycjami dynamicznymi. Pakiet aktualizacji zawiera obrazy partycji logicznych (dynamicznych). Można włączyć krok po instalacji.

Pełna OTA

Dla urządzeń typu retrofit generowane są dwa pełne pakiety OTA.

  • $(PRODUCT)-ota-retrofit-$(TAG).zip zawsze zawiera podzielony plik super.img i wyłącza krok poinstalacyjny w celu doposażenia.
    • Jest generowany z dodatkowym argumentem --retrofit_dynamic_partitions do skryptu ota_from_target_files .
    • Można go zastosować do wszystkich konstrukcji.
  • $(PRODUCT)-ota-$(TAG).zip zawiera obrazy logiczne do przyszłych aktualizacji.
    • Zastosuj to tylko do kompilacji z włączonymi partycjami dynamicznymi. Poniżej znajdziesz szczegółowe informacje na temat egzekwowania tego.

Odrzuć aktualizację niezmodernizowaną w starych kompilacjach

Zastosuj zwykły pełny pakiet OTA tylko do kompilacji z włączonymi partycjami dynamicznymi. Jeśli serwer OTA jest nieprawidłowo skonfigurowany i przesyła te pakiety do urządzeń z systemem Android 9 lub starszym, urządzenia nie uruchamiają się. Klient OTA na Androidzie 9 i starszym nie potrafi odróżnić retrofitu pakietu OTA od zwykłego pełnego pakietu OTA, więc klient nie odrzuci pełnego pakietu.

Aby uniemożliwić urządzeniu przyjęcie pełnego pakietu OTA, możesz wymagać wykonania kroku po instalacji w celu sprawdzenia istniejącej konfiguracji 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 \

Kiedy zwykły pakiet OTA zostanie zastosowany na urządzeniu bez włączonych partycji dynamicznych, klient OTA uruchamia check_dynamic_partitions jako krok po instalacji i odrzuca aktualizację.