Producenci OEM i dostawcy 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 HAL sterowania rozruchem
Programy rozruchowe obsługujące aktualizacje A/B muszą implementować interfejs HAL boot_control
hardware/libhardware/include/hardware/boot_control.h
. Implementacje możesz testować za pomocą narzędzia 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:
-
Wybierz te serie poprawek jądra (w razie potrzeby):
- Jeśli uruchamiasz system bez dysku RAM i używasz opcji „boot as recovery”, 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
.der
do katalogu głównegokernel
. Jeśli certyfikat X .509 jest sformatowany jako plik.pem
, użyj tego poleceniaopenssl
, aby przekonwertować go z formatu.pem
na 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ć,poszukaj wpisuprocfs
(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:#7e4333f9bba00adfe0ede979e28ed1920492b40f
zamiast<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 A/B |
|
Nie można zdefiniować w przypadku kierowania na test A/B |
|
Opcjonalne w przypadku wersji debugowania | PRODUCT_PACKAGES_DEBUG += update_engine_client |
Ustawianie partycji (miejsc)
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 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
itp.): 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 służyła 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 odzyskiwania, który służy do przywracania danych fabrycznych i instalowania pakietów aktualizacji z zewnątrz (stąd nazwa „odzyskiwanie”). 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 odzyskiwania jest niewielki (a większość jego zawartości była już na partycji rozruchowej), więc rozmiar partycji rozruchowej nie zwiększa się.
Fstab
Argument slotselect
musi znajdować się w wierszu partycji poddanych testom A/B. Na 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 montowania /vendor
.
Argumenty przedziału jądra
Obecny sufiks gniazda powinien być przekazywany przez konkretny węzeł drzewa urządzenia (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, nieużywanego obecnie slotu, fastboot też je flashuje. Dostępne opcje:
-
--slot SLOT
. Zastąp domyślne zachowanie 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ą reprezentują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 nieuruchamialne, a w przeciwnym razie „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 elementu docelowego 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 różnicowych dane binarne z bieżącego boksu są używane do generowania danych w nowym boksie. Wszelkie modyfikacje mogą spowodować, że nowe dane przedziału nie przejdą weryfikacji podczas procesu aktualizacji, a tym samym 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
produktu lub urządzenia (w stosownych przypadkach):
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) następujący kod:
-
Dołącz komponenty natywne do kompilacji, aby skrypt kompilacji i pliki binarne zostały skompilowane i uwzględnione w obrazie 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.