Aby wdrożyć funkcję wirtualnego A/B na nowym urządzeniu lub zmodernizować urządzenie, należy: musi wprowadzić zmiany w kodzie urządzenia.
Flagi kompilacji
Urządzenia korzystające z wirtualnego testu A/B muszą być skonfigurowane jako poziom A/B. urządzenia i musi uruchomić się za pomocą dynamiczny .
W przypadku urządzeń uruchamianych za pomocą wirtualnego A/B skonfiguruj je tak, aby dziedziczyły wirtualne środowisko A/B podstawowej konfiguracji urządzenia:
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)
Urządzenia uruchamiane z użyciem technologii A/B potrzebują tylko o połowę mniejszego rozmiaru planszy
BOARD_SUPER_PARTITION_SIZE
, ponieważ przedziały B nie są już w trybie Super. To znaczy,
Wartość BOARD_SUPER_PARTITION_SIZE
nie może być mniejsza niż
sum(size of update groups) + narzut, który z kolei musi być większy
co najmniej suma(rozmiar partycji) + narzut.
W przypadku Androida 13 lub nowszego, aby włączyć skompresowane zrzuty z funkcją wirtualnego A/B dziedziczą 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 zrzutów przestrzeni użytkownika z użyciem wirtualnych testów A/B przy jednoczesnym korzystaniu z środowiska bezobsługowego
metody kompresji. Następnie możesz skonfigurować metodę kompresji jedną z
obsługiwane metody: gz
, zstd
i lz4
.
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4
W Androidzie 12: aby włączyć skompresowane zrzuty dysku za pomocą Wirtualne A/B – dziedziczenie tej konfiguracji podstawowej:
$(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 Androidem 13 lub nowszym parametr
Funkcja kompresji XOR nie jest
domyślnie włączone. Aby włączyć kompresję XOR, dodaj ten kod do
.mk
.
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
Kompresja XOR jest domyślnie włączona w przypadku urządzeń dziedziczących dane z
android_t_baseline.mk
Scalanie przestrzeni użytkownika
W przypadku urządzeń z Androidem 13 lub nowszym parametr
proces scalania przestrzeni użytkownika opisany w artykule Device-mapper
nakładania warstw nie jest włączone przez
wartość domyślną. Aby włączyć scalanie przestrzeni użytkownika, dodaj ten wiersz do pola .mk
urządzenia
plik:
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
Scalanie przestrzeni użytkownika jest domyślnie włączone na urządzeniach uruchamianych z 13 lub więcej.
HAL do sterowania rozruchem
Element sterujący uruchamiania HAL udostępnia interfejs klientów OTA do sterowania przedziałami rozruchowymi. Wirtualne A/B wymaga uaktualnienia HAL do wersji podrzędnej, ponieważ dodatkowe interfejsy API są wymagane, by program rozruchowy był chroniony podczas flashowania lub przywracania ustawień fabrycznych. Zobacz IBootControl.hal oraz types.hal aby uzyskać 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 Fstab
Integralność partycji metadanych jest kluczowa dla procesu rozruchu,
zwłaszcza zaraz po aktualizacji OTA. Partycja metadanych musi więc
zostanie sprawdzone, zanim first_stage_init
go zamontuje. Aby tak się stało, dodaj parametr
check
– flaga fs_mgr do wpisu dotyczącego /metadata
. Poniżej znajdziesz
przykład:
/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check
Wymagania jądra systemu
Aby włączyć tworzenie zrzutów, ustaw CONFIG_DM_SNAPSHOT
na true
.
W przypadku urządzeń korzystających z F2FS uwzględnij flagę f2fs: export FS_NOCOW_FL do poprawki jądra użytkownika. Uwzględnij atrybut f2fs: support aligns (przypięta) file.
Wirtualne A/B bazuje na funkcjach dodanych w jądrze w wersji 4.3: overflow.
bit stanu w celach snapshot
i snapshot-merge
. Uruchamiam wszystkie urządzenia
w Androidzie 9 lub nowszym powinno już być jądro w wersji 4.4 lub nowszej.
Aby można było włączyć skompresowane zrzuty, minimalna obsługiwana wersja jądra to 4.19.
Ustaw CONFIG_DM_USER=m
lub CONFIG_DM_USER=y
. Jeśli korzystasz z poprzedniej wersji (modułu),
moduł musi być załadowany na dysku RAM pierwszego etapu. Jest to możliwe dzięki
dodając ten wiersz do pliku Makefile na urządzeniu:
BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko
Odświeżanie na urządzeniach z Androidem 11
Po zaktualizowaniu Androida do wersji 11 urządzenia z uruchomionymi partycjami dynamicznymi mogą opcjonalnie zmodernizować wirtualne testy A/B. Proces aktualizacji wygląda prawie tak samo jak w przypadku urządzeń z funkcją wirtualnego A/B, z kilkoma niewielkimi różnicami:
Lokalizacja plików COW – w przypadku urządzeń po uruchomieniu klient OTA używa całego wolnego miejsca na superpartycji przed użyciem spacji w
/data
W przypadku zmodernizowanych urządzeń w panelu Super partycji, dzięki czemu plik COW nigdy nie zostanie utworzony w/data
.Flagi funkcji podczas kompilacji – w przypadku urządzeń ze zmodyfikowanymi wirtualnymi A/B: zarówno
PRODUCT_VIRTUAL_AB_OTA
, jak iPRODUCT_VIRTUAL_AB_OTA_RETROFIT
są ustawione dotrue
w następujący sposób:(call inherit-product, \
(SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
Superparty rozmiar – na urządzeniach uruchamianych z funkcją wirtualnego A/B można wycinać
BOARD_SUPER_PARTITION_SIZE
na pół, ponieważ przedziały B nie znajdują się w superczacie partycji danych. Urządzenia aktualizujące wirtualną partycję A/B zachowują starą superpartycję rozmiar, 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) + .
Zmiany programu rozruchowego
Na etapie scalania aktualizacji /data
przechowuje jedyne całe wystąpienie instancji
System operacyjny Android. Po rozpoczęciu migracji system
, vendor
i
Partycje (product
) są niepełne, dopóki kopiowanie nie zostanie ukończone. Jeśli urządzenie jest
zresetowany w trakcie tego procesu do ustawień fabrycznych, przy użyciu procedury odzyskiwania lub
ustawień, nie będzie można uruchomić urządzenia.
Przed wykasowaniem danych /data
dokończ scalanie w ramach przywracania lub wycofywanie, w zależności od
stan urządzenia:
- Jeśli nowa kompilacja uruchomiła się wcześniej, dokończ migrację.
- W przeciwnym razie wróć do starego przedziału:
- W przypadku partycji dynamicznych przywróć poprzedni stan.
- W przypadku partycji statycznych ustaw aktywny przedział na stary.
Zarówno program rozruchowy, jak i fastbootd
mogą wymazać partycję /data
, jeśli
urządzenie jest odblokowane. Parametr fastbootd
może wymusić migrację, ale adres
programu rozruchowego nie może. Program rozruchowy nie wie, czy trwa scalanie
lub jakie bloki w /data
tworzą partycje systemu operacyjnego. Urządzenia muszą
zapobiec nieświadomemu dezaktualizacji urządzenia (cegły) przez
wykonując te czynności:
- Wdróż kod HAL elementu sterującego rozruchem, aby program rozruchowy mógł odczytywać ustawioną wartość
za pomocą metody
setSnapshotMergeStatus()
. - Jeśli stan scalania to
MERGING
lubSNAPSHOTTED
a boks zmienił się na zaktualizowany, a następnie pojawi się prośba o wyczyszczenie pamięci.userdata
,metadata
lub partycja, w której jest przechowywany stan scalania, musi mieć wartość odrzucone w programie rozruchowym. - Wdróż polecenie
fastboot snapshot-update cancel
, aby użytkownicy mogli zasygnalizować programowi rozruchowemu, że chce ominąć ten mechanizm zabezpieczający. - Zmodyfikuj niestandardowe narzędzia lub skrypty do flashowania, aby w przypadku całego urządzenia włączały kod
fastboot snapshot-update cancel
. Jest to bezpieczne, ponieważ aktualizacja całego urządzenia powoduje usunięcie OTA. Narzędzia mogą wykryć to polecenie w czasie działania, implementując interfejsfastboot getvar snapshot-update-status
. Ten ułatwia rozróżnianie warunków 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 Tool
Android 11 wprowadza te zmiany w szybkim rozruchu protokół:
getvar snapshot-update-status
– zwraca wartość ustawienia rozruchu. element sterujący HAL przekazywany do programu rozruchowego:- Jeśli stan to
MERGING
, program rozruchowy musi zwrócić wartośćmerging
. - Jeśli stan to
SNAPSHOTTED
, program rozruchowy musi zwrócić wartośćsnapshotted
. - W przeciwnym razie program rozruchowy musi zwracać wartość
none
.
- Jeśli stan to
snapshot-update merge
– wykonuje operację scalania, uruchamia się w razie potrzeby przy użyciu systemu odzyskiwania/szybkiego rozruchu. To polecenie jest prawidłowe tylko wtedy, gdy Komponentsnapshot-update-status
tomerging
i jest obsługiwany tylko w trybie szybkiego rozruchu.snapshot-update cancel
– ustawia stan scalania elementu sterującego rozruchem naCANCELLED
To polecenie jest nieprawidłowe, gdy urządzenie jest zablokowane.erase
lubwipe
–erase
lubwipe
o wartościmetadata
,userdata
lub partycja ze stanem scalania dla HAL kontroli rozruchu powinna sprawdzić oraz stan scalania zrzutów. Jeśli stan toMERGING
lubSNAPSHOTTED
, parametr powinno przerwać operację.set_active
– polecenieset_active
, które zmienia aktywny przedział powinien sprawdzić stan scalania zrzutów. Jeśli stan toMERGING
, powinno przerwać operację. Przedział można bezpiecznie zmienić wSNAPSHOTTED
stan.
Te zmiany mają na celu zapobieganie przypadkowemu odłączeniu urządzenia od rozruchu.
ale mogą też zakłócać pracę zautomatyzowanych narzędzi. Gdy te polecenia są używane jako
Flashowanie wszystkich partycji, np. uruchamianie programu fastboot flashall
,
zalecamy użycie tego procesu:
- Zapytanie
getvar snapshot-update-status
. - Jeśli
merging
lubsnapshotted
, wydaniesnapshot-update cancel
. - Kontynuuj miganie ekranu.
Zmniejszanie wymagań dotyczących miejsca na dane
Urządzenia, które nie mają pełnej pamięci A/B przydzielonej w trybie Super i oczekują
do użycia w razie potrzeby funkcji /data
, zdecydowanie zalecamy użycie mapowania bloków
. Narzędzie do mapowania bloków dba o spójność przydziału bloków między kompilacjami,
z myślą o ograniczeniu niepotrzebnych zapisów do zrzutu. Zostało to opisane w sekcji Zmniejszanie
rozmiar OTA.
Metody kompresji OTA
Pakiety OTA można dostroić pod kątem różnych wskaźników wydajności. Android zapewnia
kilka obsługiwanych metod kompresji (gz
, lz4
, zstd
i none
), które
między czasem instalacji, wykorzystaniem przestrzeni COW, czasem uruchamiania i zrzutem ekranu.
czas scalania. Domyślna opcja włączona dla wirtualnego panelu ab z kompresją to
gz compression method
(Uwaga: względna wydajność różnych metod kompresji
różni się w zależności od szybkości procesora i przepustowości pamięci masowej, które mogą się zmieniać w zależności
na urządzeniu. Wszystkie wygenerowane poniżej pakiety OTA mają wyłączoną opcję PostInstall, która
może nieco spowolnić uruchamianie. Całkowity rozmiar partycji dynamicznej
pełna wersja OTA bez kompresji wynosi 4,81 GB).
Przyrostowa aktualizacja OTA na Pixelu 6 Pro
Czas instalacji bez etapu po instalacji | Wykorzystanie miejsca na dane w COW | Czas po uruchomieniu OTA | Czas scalenia zrzutu | |
---|---|---|---|---|
GZ | 24 min | 1,18 GB | 40,2 s | 45,5 s |
LZ4 | 13 min | 1,49 GB | 37,4 s | 37,1 s |
brak | 13 min | 2,90 GB | 37,6 s | 40,7 s |
Pełna aktualizacja OTA w telefonie Pixel 6 Pro
Czas instalacji bez etapu po instalacji | Korzystanie z przestrzeni COW | Czas po uruchomieniu OTA | Czas scalenia zrzutu | |
---|---|---|---|---|
GZ | 23 min | 2,79 GB | 24,9 s | 41,7 s |
LZ4 | 12 min | 3,46 GB | 20,0 s | 25,3 s |
brak | 10 min | 4,85 GB | 20,6 s | 29,8 s |