Implementa A/B virtuale

Per implementare il test A/B virtuale su un nuovo dispositivo o per eseguire il retrofit di un dispositivo lanciato, devi apportare modifiche al codice specifico del dispositivo.

Flag di compilazione

I dispositivi che utilizzano A/B virtuali devono essere configurati come dispositivo A/B e devono essere avviati con partizioni dinamiche.

Per i dispositivi che vengono lanciati con A/B virtuale, impostali in modo che erediti la configurazione di base del dispositivo A/B virtuale:

$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)

I dispositivi che vengono lanciati con A/B virtuale richiedono solo la metà delle dimensioni della scheda per BOARD_SUPER_PARTITION_SIZE perché gli slot B non sono più in super. In altre parole, BOARD_SUPER_PARTITION_SIZE deve essere maggiore o uguale a somma(dimensioni dei gruppi di aggiornamento) + overhead, che a sua volta deve essere maggiore o uguale a somma(dimensioni delle partizioni) + overhead.

Per Android 13 e versioni successive, per attivare gli istantanee compresse con Virtual A/B, eredita la seguente configurazione di base:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/vabc_features.mk)

In questo modo vengono attivati gli snapshot nello spazio utente con Virtual A/B utilizzando un metodo di compressione senza operazioni. Puoi quindi configurare il metodo di compressione su uno dei metodi supportati,zstd e lz4. Per Android 15, la compressione può essere ulteriormente personalizzata in base alle esigenze del dispositivo. Per ulteriori informazioni, consulta Ottimizzazione fine della compressione.

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4
PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536

Per Android 12, per attivare gli snapshot compressi con Virtual A/B, eredita la seguente configurazione di base:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)

Compressione XOR

Per i dispositivi che eseguono l'upgrade ad Android 13 e versioni successive, la funzionalità di compressione XOR non è attivata per impostazione predefinita. Per attivare la compressione XOR, aggiungi quanto segue al file .mk del dispositivo.

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true

La compressione XOR è attiva per impostazione predefinita per i dispositivi che ereditano da android_t_baseline.mk.

Unione dello spazio utente

Nella versione moderna di Virtual A/B (Android T e versioni successive), il processo di unione delle istantanee avviene interamente nello spazio utente. Questa modifica è resa possibile da snapuserd e dm-user. Nei dispositivi lanciati con Android 13 e versioni successive, l'unione dello spazio utente è attivata per impostazione predefinita e, per l'upgrade dei dispositivi meno recenti, questa proprietà può essere impostata con quanto segue:

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true

HAL di controllo dell'avvio

L'HAL di controllo dell'avvio fornisce un'interfaccia per i client OTA per controllare gli slot di avvio. A/B virtuale richiede un upgrade della versione secondaria dell'HAL per il controllo di avvio, perché sono necessarie API aggiuntive per garantire che il bootloader sia protetto durante il flashing o il ripristino dei dati di fabbrica. Consulta IBootControl.hal e types.hal per la versione più recente della definizione 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
}

Modifiche a fstab

L'integrità della partizione dei metadati è essenziale per il processo di avvio, soprattutto subito dopo l'applicazione di un aggiornamento OTA. Pertanto, la partizione dei metadati deve essere controllata prima che first_stage_init la monti. Per assicurarti che ciò accada, aggiungi il flag fs_mgrcheck alla voce per /metadata. Di seguito è riportato un esempio:

/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check

Requisiti del kernel

Per attivare gli snapshot, imposta CONFIG_DM_SNAPSHOT su true.

Per i dispositivi che utilizzano F2FS, includi la patch del kernel f2fs: export FS_NOCOW_FL nell'utente per correggere il blocco dei file. Includi anche la patch del kernel f2fs: support aligned file.

La virtualizzazione A/B si basa sulle funzionalità aggiunte nella versione 4.3 del kernel: il bit di stato overflow nei target snapshot e snapshot-merge. Tutti i dispositivi che vengono lanciati con Android 9 e versioni successive dovrebbero già avere il kernel versione 4.4 o successiva.

Per attivare gli snapshot compressi, la versione minima del kernel supportata è 4.19. Imposta CONFIG_DM_USER=m o CONFIG_DM_USER=y. Se utilizzi il primo (un modulo), il modulo deve essere caricato nella ramdisk di primo livello. Per eseguire questa operazione, aggiungere la seguente riga al file Makefile del dispositivo:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

Modifiche agli strumenti Fastboot

Android 11 apporta le seguenti modifiche al protocollo fastboot:

  • getvar snapshot-update-status: restituisce il valore che l'HAL del controllo di avvio ha comunicato al bootloader:
    • Se lo stato è MERGING, il bootloader deve restituire merging.
    • Se lo stato è SNAPSHOTTED, il bootloader deve restituire snapshotted.
    • In caso contrario, il bootloader deve restituire none.
  • snapshot-update merge: completa un'operazione di unione, avviando il riavvio in recovery/fastbootd, se necessario. Questo comando è valido solo se snapshot-update-status è merging ed è supportato solo in fastbootd.
  • snapshot-update cancel: imposta lo stato di unione dell'HAL di controllo dell'avvio su CANCELLED. Questo comando non è valido quando il dispositivo è bloccato.
  • erase o wipe: un elemento erase o wipe di metadata, userdata o una partizione con lo stato di unione per il controllo di avvio HAL deve controllare lo stato di unione degli snapshot. Se lo stato è MERGING o SNAPSHOTTED, il dispositivo dovrebbe interrompere l'operazione.
  • set_active: un comando set_active che modifica lo slot attivo deve controllare lo stato dell'unione degli snapshot. Se lo stato è MERGING, il dispositivo deve interrompere l'operazione. Lo slot può essere modificato in sicurezza nello stato SNAPSHOTTED.

Queste modifiche sono progettate per impedire l'avvio accidentale di un dispositivo, ma possono causare interruzioni degli strumenti automatici. Quando i comandi vengono utilizzati come componente del flashing di tutte le partizioni, ad esempio l'esecuzione di fastboot flashall, ti consigliamo di utilizzare il flusso seguente:

  1. Query getvar snapshot-update-status.
  2. Se merging o snapshotted, emetti snapshot-update cancel.
  3. Procedi con i passaggi per il flashing.

Riduci i requisiti di archiviazione

Per i dispositivi che non dispongono di spazio di archiviazione A/B completo allocato in super e che prevedono di utilizzare /data, se necessario, è vivamente consigliato di utilizzare lo strumento di mappatura dei blocchi. Lo strumento di mappatura dei blocchi mantiene l'allocazione dei blocchi coerente tra le build, riducendo le scritture non necessarie nello snapshot. come indicato nella sezione Ridurre le dimensioni OTA.

Algoritmi di compressione OTA

I pacchetti OTA possono essere ottimizzati per metriche sul rendimento diverse. Android fornisce diversi metodi di compressione supportati (lz4, zstd e none) che presentano compromessi tra tempo di installazione, utilizzo dello spazio COW, tempo di avvio e tempo di unione degli snapshot. L'opzione predefinita attivata per l'ab virtuale con compressione è lz4 compression method.

Ottimizzazione della compressione

Gli algoritmi di compressione possono essere ulteriormente personalizzati tramite due metodi: (livello di compressione) (la quantità di compressione ottenuta a spese della velocità) e (fattore di compressione) (le dimensioni massime della finestra comprimibile). Il livello di compressione è disponibile per alcuni algoritmi come zstd e la modifica del livello comporta un compromesso tra velocità e rapporto di compressione. Il fattore di compressione descrive le dimensioni massime della finestra di compressione utilizzata durante l'installazione OTA. Il valore predefinito è 64 KB, ma può essere sostituito personalizzando il parametro di compilazione PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR. Fattori di compressione supportati: 4k, 8k, 16k, 32k, 64k, 128k e 256k.

PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536

Aggiornamento OTA incrementale su Pixel 8 Pro

Tempo di installazione senza fase di postinstallazione Utilizzo spazio COW Pubblica ora di avvio OTA Ora dell'unione degli snapshot
LZ4 18 min 15 sec 2,5 GB 32,7 sec 98,6 sec
zstd 24 min 49s 2,05 GB 36,3 sec 133,2 sec
nessuno 16 min 42 sec 4,76 GB 28,7 sec 76,6 sec

Aggiornamento OTA completo su Pixel 8 Pro

Ora di installazione senza fase di post-installazione Utilizzo spazio COW Pubblica ora di avvio OTA Ora dell'unione degli snapshot
lz4 15 min 11 sec 4,16 GB 17,6 sec 82,2 sec
zstd 16 min 19 sec 3,46 GB 21,0 sec 106,3 sec
nessuno 13 min 33s 6,39 GB 18,5 sec 92,5 sec