Aby zaimplementować wirtualne A/B na nowym urządzeniu lub zmodernizować uruchomione urządzenie, należy wprowadzić zmiany w kodzie specyficznym dla urządzenia.
Buduj flagi
Urządzenia korzystające z wirtualnego A/B muszą być skonfigurowane jako urządzenia A/B i muszą być uruchamiane z partycjami dynamicznymi .
W przypadku urządzeń uruchamianych z wirtualnym A/B ustaw je tak, aby dziedziczyły podstawową konfigurację wirtualnego urządzenia A/B:
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)
Urządzenia uruchamiane z wirtualnym A/B potrzebują tylko połowy rozmiaru płytki dla BOARD_SUPER_PARTITION_SIZE
, ponieważ gniazda B nie są już w super. Oznacza to, że BOARD_SUPER_PARTITION_SIZE
musi być większe lub równe suma(rozmiar grup aktualizacji) + narzut , która z kolei musi być większa lub równa suma(rozmiar partycji) + narzut .
Aby włączyć skompresowane migawki w systemie Android 13 i nowszych wersjach za pomocą funkcji Virtual A/B, odziedzicz następującą konfigurację podstawową:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/android_t_baseline.mk)
Umożliwia to tworzenie migawek przestrzeni użytkownika za pomocą wirtualnego A/B przy użyciu metody kompresji bez operacji. Następnie możesz skonfigurować metodę kompresji na jedną z obsługiwanych metod, gz
i brotli
.
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := gz
Aby włączyć skompresowane migawki w systemie Android 12 za pomocą funkcji Virtual A/B, odziedzicz następującą konfigurację podstawową:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)
Kompresja XOR
W przypadku urządzeń z systemem Android 13 lub nowszym funkcja kompresji XOR nie jest domyślnie włączona. Aby włączyć kompresję XOR, dodaj następujący fragment do pliku .mk
urządzenia.
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
Kompresja XOR jest domyślnie włączona dla urządzeń dziedziczących z android_t_baseline.mk
.
Scalanie przestrzeni użytkownika
W przypadku urządzeń uaktualnionych do wersji Android 13 lub nowszej proces scalania przestrzeni użytkownika opisany w sekcji Warstwy mapowania urządzeń nie jest domyślnie włączony. Aby włączyć scalanie przestrzeni użytkownika, dodaj następujący wiersz do pliku .mk
urządzenia:
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
Scalanie przestrzeni użytkownika jest domyślnie włączone na urządzeniach uruchamianych w wersji 13 i nowszej.
Kontrola rozruchu HAL
Kontrola rozruchu HAL zapewnia interfejs dla klientów OTA do kontrolowania gniazd rozruchowych. Virtual A/B wymaga niewielkiej aktualizacji wersji HAL kontroli rozruchu, ponieważ potrzebne są dodatkowe interfejsy API, aby zapewnić ochronę programu ładującego podczas flashowania/resetowania do ustawień fabrycznych. Zobacz pliki IBootControl.hal i type.hal , aby zapoznać się z najnowszą wersją definicji HAL.
// hardware/interfaces/boot/1.1/types.hal
enum MergeStatus : uint8_t {
NONE, UNKNOWN, SNAPSHOTTED, MERGING, CANCELLED };
// hardware/interfaces/boot/1.1/IBootControl.hal
package android.hardware.boot@1.1;
interface IBootControl extends @1.0::IBootControl {
setSnapshotMergeStatus(MergeStatus status)
generates (bool success);
getSnapshotMergeStatus()
generates (MergeStatus status);
}
// Recommended implementation
Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus v) {
// Write value to persistent storage
// e.g. misc partition (using libbootloader_message)
// bootloader rejects wipe when status is SNAPSHOTTED
// or MERGING
}
Zmiany w Fstabie
Integralność partycji metadanych ma kluczowe znaczenie dla procesu rozruchu, zwłaszcza zaraz po zastosowaniu aktualizacji OTA. Zatem partycję metadanych należy sprawdzić przed zamontowaniem jej w first_stage_init
. Aby mieć pewność, że tak się stanie, dodaj flagę check
fs_mgr do wpisu /metadata
. Poniżej przedstawiono przykład:
/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check
Wymagania jądra
Aby włączyć tworzenie migawek, ustaw CONFIG_DM_SNAPSHOT
na true
.
W przypadku urządzeń używających F2FS dołącz flagę f2fs: eksport FS_NOCOW_FL do łatki jądra użytkownika, aby naprawić przypinanie plików. Dołącz także łatkę jądra f2fs: support dostosowaną do przypiętych plików .
Wirtualny A/B opiera się na funkcjach dodanych w wersji jądra 4.3: bitu stanu przepełnienia w obiektach snapshot
i snapshot-merge
. Wszystkie urządzenia uruchamiane z systemem Android 9 i nowszym powinny już mieć jądro w wersji 4.4 lub nowszej.
Aby włączyć skompresowane migawki, minimalna obsługiwana wersja jądra to 4.19. Ustaw CONFIG_DM_USER=m
lub CONFIG_DM_USER=y
. Jeśli używasz pierwszego (modułu), moduł musi zostać załadowany do ramdysku pierwszego stopnia. Można to osiągnąć dodając następujący wiersz do pliku Makefile urządzenia:
BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko
Dostosuj na urządzeniach aktualizujących się do Androida 11
Podczas aktualizacji do systemu Android 11 urządzenia uruchomione z partycjami dynamicznymi mogą opcjonalnie doposażyć wirtualne A/B. Proces aktualizacji jest w większości taki sam, jak w przypadku urządzeń uruchamianych za pomocą wirtualnego A/B, z pewnymi drobnymi różnicami:
Lokalizacja plików COW — w przypadku urządzeń uruchamiających klient OTA wykorzystuje całe dostępne puste miejsce na super partycji przed użyciem miejsca w
/data
. W przypadku urządzeń modernizowanych na super partycji zawsze jest wystarczająco dużo miejsca, aby plik COW nigdy nie był tworzony na/data
.Flagi funkcji w czasie kompilacji — w przypadku urządzeń doposażających wirtualne A/B zarówno
PRODUCT_VIRTUAL_AB_OTA
, jak iPRODUCT_VIRTUAL_AB_OTA_RETROFIT
są ustawione natrue
, jak pokazano poniżej:(call inherit-product, \
(SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
Rozmiar super partycji — urządzenia uruchamiane z wirtualną partycją A/B mogą zmniejszyć
BOARD_SUPER_PARTITION_SIZE
o połowę, ponieważ gniazda B nie znajdują się w super partycji. Urządzenia doposażające wirtualne A/B zachowują stary rozmiar super partycji, więcBOARD_SUPER_PARTITION_SIZE
jest większy lub równy 2 * suma (rozmiar grup aktualizacji) + narzut , który z kolei jest większy lub równy 2 * suma (rozmiar partycji) + nad głową .
Zmiany w bootloaderze
Na etapie łączenia aktualizacji /data
przechowuje jedyną całą instancję systemu operacyjnego Android. Po rozpoczęciu migracji partycje system
macierzystego, vendor
i product
będą niekompletne do czasu zakończenia kopiowania. Jeśli w trakcie tego procesu urządzenie zostanie przywrócone do ustawień fabrycznych (w drodze odzyskiwania lub w oknie dialogowym Ustawienia systemu), uruchomienie urządzenia będzie niemożliwe.
Przed usunięciem /data
zakończ scalanie w procesie odzyskiwania lub przywracania w zależności od stanu urządzenia:
- Jeśli nowa kompilacja została wcześniej pomyślnie uruchomiona, zakończ migrację.
- W przeciwnym razie przywróć stare gniazdo:
- W przypadku partycji dynamicznych przywróć poprzedni stan.
- W przypadku partycji statycznych ustaw aktywne gniazdo na stare.
Zarówno bootloader, jak i fastbootd
mogą usunąć partycję /data
jeśli urządzenie jest odblokowane. Podczas gdy fastbootd
może wymusić zakończenie migracji, program ładujący nie może. Program ładujący nie wie, czy trwa scalanie ani jakie bloki w /data
stanowią partycje systemu operacyjnego. Urządzenia muszą uniemożliwiać użytkownikowi nieświadome spowodowanie niesprawności urządzenia (zamurowanie), wykonując następujące czynności:
- Zaimplementuj kontrolę rozruchu HAL, aby program ładujący mógł odczytać wartość ustawioną przez metodę
setSnapshotMergeStatus()
. - Jeśli status scalania to
MERGING
lub jeśli status scalania toSNAPSHOTTED
, a gniazdo zmieniło się na nowo zaktualizowane gniazdo, wówczas żądania wyczyszczeniauserdata
,metadata
lub partycji przechowującej status scalania muszą zostać odrzucone w programie ładującym. - Zaimplementuj polecenie
fastboot snapshot-update cancel
, aby użytkownicy mogli zasygnalizować programowi ładującemu, że chcą ominąć ten mechanizm ochronny. - Zmodyfikuj niestandardowe narzędzia lub skrypty do flashowania, aby
fastboot snapshot-update cancel
podczas flashowania całego urządzenia. Można to bezpiecznie wydać, ponieważ flashowanie całego urządzenia usuwa OTA. Narzędzia mogą wykryć to polecenie w czasie wykonywania, implementującfastboot getvar snapshot-update-status
. To polecenie pomaga rozróżnić warunki błędu.
Przykład
struct VirtualAbState {
uint8_t StructVersion;
uint8_t MergeStatus;
uint8_t SourceSlot;
};
bool ShouldPreventUserdataWipe() {
VirtualAbState state;
if (!ReadVirtualAbState(&state)) ...
return state.MergeStatus == MergeStatus::MERGING ||
(state.MergeStatus == MergeStatus::SNAPSHOTTED &&
state.SourceSlot != CurrentSlot()));
}
Zmiany w narzędziach Fastboot
Android 11 wprowadza następujące zmiany w protokole fastboot:
-
getvar snapshot-update-status
— Zwraca wartość, którą kontrola rozruchu HAL przekazała programowi ładującemu:- Jeśli stan to
MERGING
, program ładujący musi zwrócićmerging
. - Jeśli stan to
SNAPSHOTTED
, program ładujący musi zwrócićsnapshotted
. - W przeciwnym razie program ładujący musi zwrócić
none
.
- Jeśli stan to
-
snapshot-update merge
— kończy operację scalania, w razie potrzeby uruchamiając system recovery/fastbootd. To polecenie jest prawidłowe tylko wtedy, gdysnapshot-update-status
jestmerging
i jest obsługiwany tylko w trybie fastbootd. -
snapshot-update cancel
— Ustawia status scalania HAL kontroli rozruchu naCANCELLED
. To polecenie jest nieprawidłowe, gdy urządzenie jest zablokowane. -
erase
lubwipe
—erase
lubwipe
metadata
,userdata
lub partycji przechowującej status scalania dla kontroli rozruchu HAL powinno sprawdzić stan scalania migawki. Jeżeli status toMERGING
lubSNAPSHOTTED
, urządzenie powinno przerwać operację. -
set_active
— Polecenieset_active
zmieniające aktywne gniazdo powinno sprawdzać stan scalania migawek. Jeżeli status toMERGING
, urządzenie powinno przerwać operację. Slot można bezpiecznie zmienić w stanieSNAPSHOTTED
.
Zmiany te mają na celu zapobieganie przypadkowemu uniemożliwieniu uruchomienia urządzenia, ale mogą zakłócać działanie zautomatyzowanych narzędzi. Gdy polecenia są używane jako element flashowania wszystkich partycji, na przykład podczas uruchamiania fastboot flashall
, zaleca się użycie następującego przepływu:
- Zapytanie
getvar snapshot-update-status
. - W przypadku
merging
lubsnapshotted
wydajsnapshot-update cancel
. - Kontynuuj migające kroki.
Zmniejsz wymagania dotyczące przechowywania
W przypadku urządzeń, które nie mają pełnej pamięci A/B przydzielonej w super i które spodziewają się użycia /data
w razie potrzeby, zdecydowanie zaleca się korzystanie z narzędzia do mapowania bloków. Narzędzie do mapowania bloków utrzymuje spójność alokacji bloków pomiędzy kompilacjami, redukując niepotrzebne zapisy w migawce. Jest to udokumentowane w sekcji Zmniejszanie rozmiaru OTA .
Metody kompresji OTA
Pakiety Ota można dostroić pod kątem różnych wskaźników wydajności. Android obecnie udostępnia kilka obsługiwanych metod kompresji ( gz
, lz4
i none
), które wymagają kompromisów między czasem instalacji, wykorzystaniem przestrzeni COW, czasem uruchamiania i czasem scalania migawek. Domyślną opcją włączoną dla wirtualnego ab z kompresją jest gz compression method
. (Uwaga: względna wydajność pomiędzy metodami kompresji różni się w zależności od szybkości procesora i przepustowości pamięci, która może się zmieniać w zależności od urządzenia. Wszystkie wygenerowane poniżej pakiety OTA mają wyłączoną opcję PostInstall, co nieznacznie spowalnia czas uruchamiania. Całkowity rozmiar partycji dynamicznej pełnego OT bez kompresji wynosi 4,81 GB ).
Przyrostowe OTA na Pixelu 6 Pro
Czas instalacji bez fazy poinstalacyjnej | Wykorzystanie przestrzeni COW | Opublikuj czas rozruchu OTA | Czas scalania migawki | |
---|---|---|---|---|
gz | 24 minuty | 1,18 GB | 40,2 sek | 45,5 sek |
lz4 | 13 minut | 1,49 GB | 37,4 sek | 37,1 sek |
nic | 13 minut | 2,90 GB | 37,6 sek | 40,7 sek |
Pełna OTA na Pixelu 6 Pro
Czas instalacji bez fazy poinstalacyjnej | Wykorzystanie przestrzeni KRÓW | Opublikuj czas rozruchu OTA | Czas scalania migawki | |
---|---|---|---|---|
gz | 23 minuty | 2,79 GB | 24,9 sek | 41,7 sek |
lz4 | 12 minut | 3,46 GB | 20,0 sek | 25,3 sek |
nic | 10 minut | 4,85 GB | 20,6 sek | 29,8 sek |