Um virtuelles A/B auf einem neuen Gerät zu implementieren oder ein eingeführtes Gerät nachzurüsten, müssen Sie Änderungen am gerätespezifischen Code vornehmen.
Flaggen bauen
Geräte, die virtuelles A/B verwenden, müssen als A/B-Gerät konfiguriert sein und mit dynamischen Partitionen starten .
Legen Sie für Geräte, die mit virtuellem A/B gestartet werden, fest, dass sie die Basiskonfiguration des virtuellen A/B-Geräts erben:
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)
Geräte, die mit virtuellem A/B starten, benötigen für BOARD_SUPER_PARTITION_SIZE
nur halb so viel Platinengröße, da sich B-Steckplätze nicht mehr in Super befinden. Das heißt, BOARD_SUPER_PARTITION_SIZE
muss größer oder gleich sum(size of update groups) + overhead sein, was wiederum größer oder gleich sum(size of partitions) + overhead sein muss.
Für Android 13 und höher erben Sie die folgende Basiskonfiguration, um komprimierte Snapshots mit Virtual A/B zu ermöglichen:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/android_t_baseline.mk)
Dies ermöglicht Userspace-Snapshots mit Virtual A/B unter Verwendung einer No-Op-Komprimierungsmethode. Anschließend können Sie die Komprimierungsmethode auf eine der unterstützten Methoden gz
und brotli
konfigurieren.
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := gz
Für Android 12 erben Sie die folgende Basiskonfiguration, um komprimierte Snapshots mit Virtual A/B zu aktivieren:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)
XOR-Komprimierung
Bei Geräten, die auf Android 13 und höher aktualisiert werden, ist die XOR-Komprimierungsfunktion standardmäßig nicht aktiviert. Um die XOR-Komprimierung zu aktivieren, fügen Sie Folgendes zur .mk
Datei des Geräts hinzu.
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
Die XOR-Komprimierung ist standardmäßig für Geräte aktiviert, die von android_t_baseline.mk
erben.
Userspace-Zusammenführung
Für Geräte, die auf Android 13 und höher aktualisiert werden, ist der unter Device-Mapper-Layering beschriebene Userspace-Zusammenführungsprozess nicht standardmäßig aktiviert. Um die Zusammenführung von Userspaces zu aktivieren, fügen Sie der .mk
Datei des Geräts die folgende Zeile hinzu:
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
Die Zusammenführung von Userspaces ist auf Geräten mit Version 13 und höher standardmäßig aktiviert.
Boot-Steuerung HAL
Der Boot-Control-HAL bietet eine Schnittstelle für OTA-Clients zur Steuerung von Boot-Slots. Virtual A/B erfordert ein kleineres Versions-Upgrade der Boot-Control-HAL, da zusätzliche APIs erforderlich sind, um sicherzustellen, dass der Bootloader während des Flashens/Zurücksetzens auf die Werkseinstellungen geschützt ist. Die neueste Version der HAL-Definition finden Sie unter IBootControl.hal undtypes.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
}
Fstab-Änderungen
Die Integrität der Metadatenpartition ist für den Startvorgang von entscheidender Bedeutung, insbesondere direkt nach der Anwendung eines OTA-Updates. Daher muss die Metadatenpartition überprüft werden, bevor first_stage_init
sie bereitstellt. Um sicherzustellen, dass dies geschieht, fügen Sie das Flag check
fs_mgr zum Eintrag für /metadata
hinzu. Nachfolgend finden Sie ein Beispiel:
/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check
Kernel-Anforderungen
Um Snapshotting zu aktivieren, setzen Sie CONFIG_DM_SNAPSHOT
auf true
.
Fügen Sie für Geräte, die F2FS verwenden, das Flag f2fs: export FS_NOCOW_FL in den Benutzer- Kernel-Patch ein, um das Anheften von Dateien zu beheben. Fügen Sie auch den f2fs: support-Kernel-Patch für ausgerichtete angeheftete Dateien hinzu.
Virtual A/B basiert auf Funktionen, die in Kernel-Version 4.3 hinzugefügt wurden: das Überlaufstatusbit in den snapshot
und snapshot-merge
Zielen. Alle Geräte, die mit Android 9 und höher starten, sollten bereits über die Kernel-Version 4.4 oder höher verfügen.
Um komprimierte Snapshots zu ermöglichen, ist die minimal unterstützte Kernelversion 4.19. Legen Sie CONFIG_DM_USER=m
oder CONFIG_DM_USER=y
fest. Wenn ersteres (ein Modul) verwendet wird, muss das Modul in die Ramdisk der ersten Stufe geladen werden. Dies kann durch Hinzufügen der folgenden Zeile zum Geräte-Makefile erreicht werden:
BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko
Nachrüstung bei Geräten, die auf Android 11 aktualisiert werden
Beim Upgrade auf Android 11 können Geräte, die mit dynamischen Partitionen gestartet sind, optional virtuelles A/B nachrüsten. Der Update-Prozess ist größtenteils derselbe wie bei Geräten, die mit Virtual A/B gestartet werden, mit einigen geringfügigen Unterschieden:
Speicherort der COW-Dateien – Für Startgeräte nutzt der OTA-Client den gesamten verfügbaren leeren Speicherplatz in der Superpartition, bevor er Speicherplatz in
/data
verwendet. Bei Nachrüstgeräten ist in der Superpartition immer genügend Platz vorhanden, sodass die COW-Datei nie auf/data
erstellt wird.Build-Time-Feature-Flags – Für Geräte, die virtuelles A/B nachrüsten, werden sowohl
PRODUCT_VIRTUAL_AB_OTA
als auchPRODUCT_VIRTUAL_AB_OTA_RETROFIT
auftrue
gesetzt, wie unten gezeigt:(call inherit-product, \
(SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
Super-Partitionsgröße – Geräte, die mit virtuellem A/B gestartet werden, können
BOARD_SUPER_PARTITION_SIZE
halbieren, da sich B-Steckplätze nicht in der Super-Partition befinden. Geräte, die Virtual A/B nachrüsten, behalten die alte Superpartitionsgröße bei, sodassBOARD_SUPER_PARTITION_SIZE
größer oder gleich 2 * Summe (Größe der Aktualisierungsgruppen) + Overhead ist, was wiederum größer oder gleich 2 * Summe (Größe der Partitionen) ist. + Overhead .
Bootloader-Änderungen
Während des Zusammenführungsschritts eines Updates enthält /data
die einzige vollständige Instanz des Android-Betriebssystems. Sobald die Migration beginnt, sind die nativen system
, vendor
und product
unvollständig, bis die Kopie abgeschlossen ist. Wenn das Gerät während dieses Vorgangs entweder durch Wiederherstellung oder über das Dialogfeld „Systemeinstellungen“ auf die Werkseinstellungen zurückgesetzt wird, kann das Gerät nicht mehr gestartet werden.
Bevor Sie /data
löschen, schließen Sie je nach Gerätestatus die Zusammenführung bei der Wiederherstellung oder beim Rollback ab:
- Wenn der neue Build zuvor erfolgreich gestartet wurde, schließen Sie die Migration ab.
- Ansonsten Rollback zum alten Slot:
- Führen Sie bei dynamischen Partitionen ein Rollback auf den vorherigen Zustand durch.
- Stellen Sie bei statischen Partitionen den aktiven Steckplatz auf den alten Steckplatz ein.
Sowohl der Bootloader als auch fastbootd
können die /data
Partition löschen, wenn das Gerät entsperrt ist. Während fastbootd
den Abschluss der Migration erzwingen kann, ist dies beim Bootloader nicht möglich. Der Bootloader weiß nicht, ob gerade eine Zusammenführung stattfindet oder welche Blöcke in /data
die Betriebssystempartitionen bilden. Geräte müssen verhindern, dass der Benutzer das Gerät unwissentlich funktionsunfähig macht (Bricking), indem er Folgendes tut:
- Implementieren Sie die Boot-Steuerungs-HAL, damit der Bootloader den von der
setSnapshotMergeStatus()
Methode festgelegten Wert lesen kann. - Wenn der Zusammenführungsstatus
MERGING
lautet oder wenn der ZusammenführungsstatusSNAPSHOTTED
lautet und der Steckplatz in den neu aktualisierten Steckplatz geändert wurde, müssen Anforderungen zum Löschenuserdata
,metadata
oder der Partition, die den Zusammenführungsstatus speichert, im Bootloader abgelehnt werden. - Implementieren Sie den Befehl
fastboot snapshot-update cancel
, damit Benutzer dem Bootloader signalisieren können, dass sie diesen Schutzmechanismus umgehen möchten. - Ändern Sie benutzerdefinierte Flash-Tools oder Skripte, um beim Flashen des gesamten Geräts
fastboot snapshot-update cancel
auszulösen. Dies ist sicher, da durch das Flashen des gesamten Geräts der OTA entfernt wird. Tooling kann diesen Befehl zur Laufzeit erkennen, indem esfastboot getvar snapshot-update-status
implementiert. Dieser Befehl hilft bei der Unterscheidung zwischen Fehlerbedingungen.
Beispiel
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()));
}
Änderungen an den Fastboot-Tools
Android 11 nimmt die folgenden Änderungen am Fastboot-Protokoll vor:
-
getvar snapshot-update-status
– Gibt den Wert zurück, den die Boot-Steuerungs-HAL dem Bootloader mitgeteilt hat:- Wenn der Status
MERGING
lautet, muss der Bootloadermerging
zurückgeben. - Wenn der Status
SNAPSHOTTED
ist, muss der Bootloadersnapshotted
zurückgeben. - Andernfalls muss der Bootloader
none
zurückgeben.
- Wenn der Status
-
snapshot-update merge
– Führt einen Zusammenführungsvorgang durch und startet bei Bedarf mit Recovery/Fastbootd. Dieser Befehl ist nur gültig, wennsnapshot-update-status
merging
ist, und wird nur in fastbootd unterstützt. -
snapshot-update cancel
– Setzt den Zusammenführungsstatus der Boot-Steuerungs-HAL aufCANCELLED
. Dieser Befehl ist ungültig, wenn das Gerät gesperrt ist. -
erase
oderwipe
– Einerase
oderwipe
vonmetadata
,userdata
oder einer Partition, die den Zusammenführungsstatus für die Startsteuerung enthält. HAL sollte den Snapshot-Zusammenführungsstatus überprüfen. Wenn der StatusMERGING
oderSNAPSHOTTED
lautet, sollte das Gerät den Vorgang abbrechen. -
set_active
– Einset_active
Befehl, der den aktiven Slot ändert, sollte den Snapshot-Zusammenführungsstatus überprüfen. Wenn der StatusMERGING
lautet, sollte das Gerät den Vorgang abbrechen. Der Steckplatz kann imSNAPSHOTTED
Zustand sicher geändert werden.
Diese Änderungen sollen verhindern, dass ein Gerät versehentlich nicht mehr gestartet werden kann, sie können jedoch zu Störungen bei automatisierten Tools führen. Wenn die Befehle als Komponente zum Flashen aller Partitionen verwendet werden, z. B. beim Ausführen von fastboot flashall
, wird die Verwendung des folgenden Ablaufs empfohlen:
- Fragen Sie
getvar snapshot-update-status
. - Wenn
merging
odersnapshotted
erstellen, geben Siesnapshot-update cancel
aus. - Fahren Sie mit den blinkenden Schritten fort.
Reduzieren Sie den Speicherbedarf
Für Geräte, denen in Super nicht der volle A/B-Speicher zugewiesen ist und die voraussichtlich /data
nach Bedarf verwenden, wird dringend empfohlen, das Block-Mapping-Tool zu verwenden. Das Blockzuordnungstool sorgt dafür, dass die Blockzuordnung zwischen den Builds konsistent bleibt und unnötige Schreibvorgänge in den Snapshot reduziert werden. Dies ist unter „Reduzierung der OTA-Größe“ dokumentiert.
OTA-Komprimierungsmethoden
Ota-Pakete können für verschiedene Leistungsmetriken optimiert werden. Android bietet derzeit einige unterstützte Komprimierungsmethoden ( gz
, lz4
und none
), die Kompromisse zwischen Installationszeit, COW-Speicherplatznutzung, Startzeit und Snapshot-Zusammenführungszeit haben. Die für Virtual AB mit Komprimierung aktivierte Standardoption ist die gz compression method
. (Hinweis: Die relative Leistung zwischen den Komprimierungsmethoden variiert je nach CPU-Geschwindigkeit und Speicherdurchsatz, die sich je nach Gerät ändern können. Bei allen unten generierten OTA-Paketen ist PostInstall deaktiviert, was die Startzeit etwas verlangsamt. Die gesamte dynamische Partitionsgröße eines vollständigen OTA ohne Komprimierung beträgt 4,81 GB ).
Inkrementelles OTA auf Pixel 6 Pro
Installationszeit ohne Nachinstallationsphase | COW-Raumnutzung | Post-OTA-Startzeit | Snapshot-Zusammenführungszeit | |
---|---|---|---|---|
gz | 24 Min | 1,18 GB | 40,2 Sek | 45,5 Sek |
lz4 | 13 Min | 1,49 GB | 37,4 Sek | 37,1 Sek |
keiner | 13 Min | 2,90 GB | 37,6 Sek | 40,7 Sek |
Vollständiges OTA auf Pixel 6 Pro
Installationszeit ohne Nachinstallationsphase | COW-Raumnutzung | Post-OTA-Startzeit | Snapshot-Zusammenführungszeit | |
---|---|---|---|---|
gz | 23 Min | 2,79 GB | 24,9 Sek | 41,7 Sek |
lz4 | 12 Min | 3,46 GB | 20,0 Sek | 25,3 Sek |
keiner | 10 Minuten | 4,85 GB | 20,6 Sek | 29,8 Sek |