Producenci OEM i dostawcy układów SOC, którzy chcą wdrożyć aktualizacje systemu A/B, muszą zadbać o to, aby program rozruchowy implementował HAL boot_control i przekazywał do jądra odpowiednie parametry.
Implementowanie interfejsu HAL sterowania rozruchem
Programy rozruchowe obsługujące aktualizacje A/B muszą implementować interfejs HAL boot_controlhardware/libhardware/include/hardware/boot_control.h. Implementacje możesz testować za pomocą narzędzi system/extras/bootctl i system/extras/tests/bootloader/.
Musisz też wdrożyć automat stanowy pokazany poniżej:
Konfigurowanie jądra
Aby wdrożyć aktualizacje systemu A/B:
-
W razie potrzeby wybierz te serie poprawek jądra:
- Jeśli uruchamiasz urządzenie bez dysku RAM i używasz opcji „Uruchom jako tryb odzyskiwania”, wybierz zmianę android-review.googlesource.com/#/c/158491/.
- Aby skonfigurować dm-verity bez ramdysku, wybierz zmiany z android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18.
-
Sprawdź, czy argumenty wiersza poleceń jądra zawierają te dodatkowe argumenty:
... gdzie wartośćskip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 android-verity <public-key-id> <path-to-system-partition>"<public-key-id>to identyfikator klucza publicznego użytego do zweryfikowania podpisu tabeli weryfikacji (szczegółowe informacje znajdziesz w artykule dm-verity). -
Dodaj certyfikat X .509 zawierający klucz publiczny do pęku kluczy systemu:
-
Skopiuj certyfikat .X509 sformatowany w formacie
.derdo katalogu głównegokernel. Jeśli certyfikat X .509 jest sformatowany jako plik.pem, użyj tego poleceniaopenssl, aby przekonwertować go z formatu.pemna format.der:openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
-
Skonstruuj
zImage, aby uwzględnić certyfikat w pęku kluczy systemu. Aby to sprawdzić,otwórz wpisprocfs(wymaga włączeniaKEYS_CONFIG_DEBUG_PROC_KEYS): Pomyślne dodanie certyfikatu X .509 oznacza obecność klucza publicznego w pęku kluczy systemu (podświetlenie oznacza identyfikator klucza publicznego).angler:/# cat /proc/keys 1c8a217e I------ 1 perm 1f010000 0 0 asymmetri Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f [] 2d454e3e I------ 1 perm 1f030000 0 0 keyring .system_keyring: 1/4
-
Zastąp spację znakiem
#i przekaż ją jako<public-key-id>w wierszu poleceń jądra. Na przykład przekażAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40fzamiast<public-key-id>.
-
Skopiuj certyfikat .X509 sformatowany w formacie
Ustawianie zmiennych kompilacji
Programy rozruchowe obsługujące aktualizacje A/B muszą spełniać te kryteria zmiennych kompilacji:
| Musisz zdefiniować cel testu A/B |
/device/google/marlin/+/android-7.1.0_r1/device-common.mk. Opcjonalnie możesz wykonać krok dex2oat po instalacji (ale przed ponownym uruchomieniem) opisany w sekcji Kompilowanie.
|
|---|---|
| Zdecydowanie zalecane w przypadku celu testu A/B |
|
| Nie można zdefiniować na potrzeby kierowania A/B |
|
| Opcjonalne w przypadku wersji debugowania | PRODUCT_PACKAGES_DEBUG += update_engine_client |
Ustawianie partycji (slotów)
Urządzenia A/B nie potrzebują partycji odzyskiwania ani partycji pamięci podręcznej, ponieważ Android nie używa już tych partycji. Partycja danych jest teraz używana w przypadku pobranego pakietu OTA, a kod obrazu przywracania systemu znajduje się na partycji rozruchowej. Wszystkie partycje, które są testowane A/B, powinny mieć nazwy w tym formacie (sloty zawsze mają nazwy a, b itd.): boot_a,
boot_b, system_a, system_b, vendor_a,
vendor_b.
Pamięć podręczna
W przypadku aktualizacji innych niż A/B partycja pamięci podręcznej była używana do przechowywania pobranych pakietów OTA i tymczasowego przechowywania bloków podczas stosowania aktualizacji. Nie było dobrego sposobu na określenie rozmiaru partycji pamięci podręcznej: jej wielkość zależała od tego, jakie aktualizacje chcesz zastosować. Najgorszym przypadkiem byłaby partycja pamięci podręcznej tak duża jak obraz systemu. W przypadku aktualizacji A/B nie trzeba zapisywać bloków (ponieważ zawsze zapisujesz dane w partycji, która nie jest obecnie używana), a w przypadku aktualizacji A/B strumieniowych nie trzeba pobierać całego pakietu OTA przed jego zastosowaniem.
Odzyskiwanie
Dysk RAM odzyskiwania jest teraz zawarty w pliku boot.img. Podczas przechodzenia do trybu odzyskiwania program rozruchowy nie może umieścić opcji skip_initramfs w wierszu poleceń jądra.
W przypadku aktualizacji innych niż A/B partycja odzyskiwania zawiera kod używany do stosowania aktualizacji. Aktualizacje A/B są stosowane przez update_engine działający w regularnym obrazie systemu.
Nadal istnieje tryb przywracania (Recovery Mode), który służy do przywracania danych fabrycznych i instalowania pakietów aktualizacji z nieoficjalnych źródeł (stąd nazwa „przywracanie”). Kod i dane trybu odzyskiwania są przechowywane w zwykłej partycji rozruchowej w ramdysku. Aby uruchomić obraz systemu, program rozruchowy informuje jądro, aby pominęło ramdysk (w przeciwnym razie urządzenie uruchomi się w trybie odzyskiwania). Tryb przywracania (Recovery Mode) jest niewielki (a większość jego zawartości znajdowała się już na partycji rozruchowej), więc rozmiar partycji rozruchowej nie zwiększa się.
Fstab
Argument slotselect musi znajdować się w wierszu w przypadku partycji poddanych testom A/B. Przykład:
<path-to-block-device>/vendor /vendor ext4 ro wait,verify=<path-to-block-device>/metadata,slotselect
Żadna partycja nie powinna mieć nazwy vendor. Zamiast tego zostanie wybrana i zamontowana partycja vendor_a lub vendor_b w punkcie podłączania /vendor.
Argumenty przedziału jądra
Obecny sufiks gniazda powinien być przekazywany przez konkretny węzeł drzewa urządzeń (DT) (/firmware/android/slot_suffix) lub przez androidboot.slot_suffix wiersz poleceń jądra lub argument bootconfig.
Domyślnie fastboot flashuje bieżące gniazdo na urządzeniu A/B. Jeśli pakiet aktualizacji zawiera też obrazy dla drugiego, nieaktualnego slotu, fastboot też je flashuje. Dostępne opcje:
-
--slot SLOT. Zastąp domyślne działanie i poproś fastboot o flashowanie gniazda przekazanego jako argument. -
--set-active [SLOT]. Ustaw slot jako aktywny. Jeśli nie podasz żadnego argumentu opcjonalnego, bieżący slot zostanie ustawiony jako aktywny. fastboot --help. Uzyskaj szczegółowe informacje o poleceniach.
Jeśli program rozruchowy implementuje fastboot, powinien obsługiwać polecenie
set_active <slot>, które ustawia bieżący aktywny slot na podany slot (musi ono również wyczyścić flagę unbootable dla tego slotu i zresetować liczbę ponownych prób do wartości domyślnych). Program rozruchowy powinien też obsługiwać te zmienne:
-
has-slot:<partition-base-name-without-suffix>. Zwraca „yes”, jeśli podana partycja obsługuje boksy, a w przeciwnym razie „no”. current-slot. Zwraca sufiks gniazda, z którego nastąpi następne uruchomienie.-
slot-count. Zwraca liczbę całkowitą określającą liczbę dostępnych miejsc. Obecnie obsługiwane są 2 miejsca, więc ta wartość to2. -
slot-successful:<slot-suffix>. Zwraca „yes”, jeśli dany slot został oznaczony jako uruchomiony, a w przeciwnym razie „no”. -
slot-unbootable:<slot-suffix>. Zwraca „yes”, jeśli dane gniazdo jest oznaczone jako niebootowalne, a w przeciwnym razie zwraca „no”. -
slot-retry-count:<slot-suffix>. Liczba pozostałych ponownych prób uruchomienia danego gniazda.
Aby wyświetlić wszystkie zmienne, uruchom polecenie
fastboot getvar all.
Generowanie pakietów OTA
Narzędzia pakietu OTA używają tych samych poleceń co polecenia w przypadku urządzeń innych niż A/B. Plik target_files.zip musi zostać wygenerowany przez zdefiniowanie zmiennych kompilacji dla celu testu A/B. Narzędzia pakietu OTA automatycznie identyfikują i generują pakiety w formacie aktualizatora A/B.
Przykłady:
-
Aby wygenerować pełną aktualizację OTA:
./build/make/tools/releasetools/ota_from_target_files \ dist_output/tardis-target_files.zip \ ota_update.zip -
Aby wygenerować przyrostową aktualizację OTA:
./build/make/tools/releasetools/ota_from_target_files \ -i PREVIOUS-tardis-target_files.zip \ dist_output/tardis-target_files.zip \ incremental_ota_update.zip
Konfigurowanie partycji
update_engine może aktualizować dowolną parę partycji A/B zdefiniowanych na tym samym dysku.
Para partycji ma wspólny prefiks (np. system lub boot) i sufiks dla każdego gniazda (np. _a). Listę partycji, dla których generator ładunku definiuje aktualizację, konfiguruje zmienna AB_OTA_PARTITIONS make.
Jeśli na przykład uwzględniono parę partycji bootloader_a i booloader_b (_a i _b to sufiksy slotów), możesz zaktualizować te partycje, określając w konfiguracji produktu lub płyty:
AB_OTA_PARTITIONS := \ boot \ system \ bootloader
Wszystkie partycje zaktualizowane przez update_engine nie mogą być modyfikowane przez pozostałą część systemu. Podczas aktualizacji przyrostowych lub delta dane binarne z bieżącego boksu są używane do generowania danych w nowym boksie. Wszelkie modyfikacje mogą spowodować, że nowe dane o miejscu reklamowym nie przejdą weryfikacji podczas procesu aktualizacji, a w konsekwencji aktualizacja się nie powiedzie.
Konfigurowanie po instalacji
Możesz skonfigurować krok po instalacji dla każdej zaktualizowanej partycji w inny sposób, używając zestawu par klucz-wartość. Aby uruchomić program znajdujący się w lokalizacji /system/usr/bin/postinst w nowym obrazie, podaj ścieżkę względną do katalogu głównego systemu plików na partycji systemowej.
Na przykład usr/bin/postinst to system/usr/bin/postinst (jeśli nie używasz dysku RAM). Dodatkowo określ typ systemu plików, który ma zostać przekazany do wywołania systemowego mount(2). Dodaj do plików .mk dotyczących produktu lub urządzenia (w stosownych przypadkach) te informacje:
AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=usr/bin/postinst \ FILESYSTEM_TYPE_system=ext4
Kompilowanie aplikacji
Aplikacje można skompilować w tle przed ponownym uruchomieniem z nowym obrazem systemu. Aby kompilować aplikacje w tle, dodaj do konfiguracji urządzenia produktu (w pliku device.mk produktu) ten kod:
-
Dołącz komponenty natywne do kompilacji, aby skrypt kompilacji i pliki binarne zostały skompilowane i dołączone do obrazu systemu.
# A/B OTA dexopt package PRODUCT_PACKAGES += otapreopt_script
-
Połącz skrypt kompilacji z
update_engine, aby był uruchamiany jako krok po instalacji.# A/B OTA dexopt update_engine hookup AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=system/bin/otapreopt_script \ FILESYSTEM_TYPE_system=ext4 \ POSTINSTALL_OPTIONAL_system=true
Aby uzyskać pomoc dotyczącą instalowania wstępnie zoptymalizowanych plików na nieużywanej drugiej partycji systemowej, zapoznaj się z sekcją Instalacja plików DEX_PREOPT podczas pierwszego uruchomienia.