Implementa A/B virtuale

Per implementare la funzionalità A/B virtuale su un nuovo dispositivo o per adattare di nuovo un dispositivo avviato, devono apportare modifiche al codice specifico del dispositivo.

Flag per build

I dispositivi che utilizzano A/B virtuali devono essere configurati come A/B dispositivo e devono essere lanciati con dinamico partizioni di memoria.

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

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

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

Per Android 13 e versioni successive, per attivare i formati compressi snapshot con A/B virtuale, ereditano la configurazione di base seguente:

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

Consente di creare snapshot dello spazio utente con A/B virtuale, utilizzando una di compressione. Puoi quindi configurare il metodo di compressione in uno dei metodi supportati, gz, zstd e lz4.

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4

Per Android 12, per abilitare gli snapshot compressi con A/B virtuale, 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 è sono abilitate per impostazione predefinita. Per attivare la compressione XOR, aggiungi quanto segue al file .mk.

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

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

Unione dello spazio utente

Per i dispositivi che eseguono l'upgrade ad Android 13 e versioni successive, processo di unione dello spazio utente come descritto in Device-Mapper la sovrapposizione di immagini non sia abilitata predefinito. Per attivare l'unione dello spazio utente, aggiungi la seguente riga all'elemento .mk del dispositivo file:

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

L'unione dello spazio utente è abilitata per impostazione predefinita sui dispositivi che vengono avviati con 13 e successive.

HAL per il controllo dell'avvio

Il controllo dell'avvio HAL Offre un'interfaccia per consentire ai client OTA di controllare gli slot di avvio. A/B virtuale richiede un upgrade della versione secondaria dell'HAL per il controllo di avvio, poiché le API aggiuntive necessari per garantire che il bootloader sia protetto durante il flashing o il ripristino dei dati di fabbrica. Consulta IBootControl.hal e types.hal per ottenere l'ultima versione della definizione dell'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 FStab

L'integrità della partizione dei metadati è essenziale per il processo di avvio, in particolare subito dopo l'applicazione di un aggiornamento OTA. Quindi, la partizione dei metadati deve da controllare prima che first_stage_init lo installi. Per assicurarti che ciò accada, aggiungi il parametro check flag fs_mgr per la voce per /metadata. Di seguito viene fornita una esempio:

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

Requisiti del kernel

Per attivare lo snapshot, imposta CONFIG_DM_SNAPSHOT su true.

Per i dispositivi che utilizzano F2FS, includi il flag f2fs: esporta il flag FS_NOCOW_FL in utente per correggere il blocco dei file. Includi f2fs: supporto allineato fissato del kernel.

A/B virtuale si basa su funzionalità aggiunte nella versione 4.3 del kernel: l'overflow bit di stato nei target snapshot e snapshot-merge. Lancio di tutti i dispositivi con Android 9 e successivi dovrebbero già avere il kernel versione 4.4 o successiva.

Per abilitare gli snapshot compressi, la versione minima del kernel supportata è la 4.19. Imposta CONFIG_DM_USER=m o CONFIG_DM_USER=y. Se utilizzi il primo (un modulo), il modulo deve essere caricato nel ramdisk di prima fase. Questo può essere ottenuto aggiungendo la seguente riga al Makefile del dispositivo:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

Retrofit sui dispositivi che eseguono l'upgrade ad Android 11

Quando esegui l'upgrade ad Android 11, i dispositivi avviati con partizioni dinamiche possono: A/B virtuale (facoltativo) La procedura di aggiornamento è per lo più la stessa utilizzata per dispositivi che vengono lanciati con A/B virtuale, con alcune piccole differenze:

  • Posizione dei file COW: per i dispositivi di avvio, il client OTA utilizza tutti gli spazi vuoti disponibili nella superpartizione prima di utilizzare lo spazio /data. Per i dispositivi in retrofit, c'è sempre spazio a sufficienza nel in modo che il file COW non venga mai creato il giorno /data.

  • Flag delle funzionalità in fase di creazione: per i dispositivi che eseguono l'adattamento di A/B virtuali, sia PRODUCT_VIRTUAL_AB_OTA sia PRODUCT_VIRTUAL_AB_OTA_RETROFIT sono impostati a true, come illustrato di seguito:

    (call inherit-product, \
      (SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
    
  • Dimensioni super partizione: i dispositivi che si avviano con A/B virtuale possono tagliare BOARD_SUPER_PARTITION_SIZE a metà perché gli slot B non sono nella zona super della partizione di testo. Il retrofitting dei dispositivi A/B virtuale mantiene la vecchia super partizione dimensione, quindi BOARD_SUPER_PARTITION_SIZE è maggiore o uguale a 2 * somma(dimensione dei gruppi di aggiornamento) + overhead, che a sua volta è maggiore o uguale a 2 * somma(dimensione delle partizioni) + dall'alto.

Modifiche del bootloader

Durante la fase di unione di un aggiornamento, /data contiene l'unica istanza intera Sistema operativo Android. Una volta avviata la migrazione, system, vendor e product partizioni sono incomplete fino al termine della copia. Se il dispositivo è ripristinare i dati di fabbrica durante questa procedura, tramite il ripristino o tramite i impostazioni, il dispositivo non si avvia.

Prima di cancellare /data, completa l'unione in ripristino o rollback a seconda lo stato del dispositivo:

  • Se la nuova build si è avviata prima correttamente, completa la migrazione.
  • In caso contrario, esegui il rollback allo slot precedente:
    • Per le partizioni dinamiche, esegui il rollback allo stato precedente.
    • Per le partizioni statiche, imposta lo slot attivo sullo slot precedente.

Sia il bootloader sia fastbootd possono cancellare la partizione /data se il dispositivo è sbloccato. Sebbene fastbootd possa forzare il completamento della migrazione, e bootloader. Il bootloader non sa se è in corso un'unione l'avanzamento o quali blocchi in /data costituiscono le partizioni del sistema operativo. I dispositivi devono Impedire all'utente di rendere inconsapevolmente inutilizzabile il dispositivo (bricking) nel seguente modo:

  1. Implementare l'HAL del controllo di avvio in modo che il bootloader possa leggere il set di valori con il metodo setSnapshotMergeStatus().
  2. Se lo stato dell'unione è MERGING o se lo stato dell'unione è SNAPSHOTTED e lo slot è stato modificato, quindi richiede la cancellazione userdata, metadata o la partizione in cui è archiviato lo stato di unione deve essere viene rifiutato nel bootloader.
  3. Implementa il comando fastboot snapshot-update cancel in modo che gli utenti possano segnale al bootloader che vuole bypassare questo meccanismo di protezione.
  4. Modifica gli strumenti o gli script di flashing personalizzati in modo che restituiscano fastboot snapshot-update cancel durante il flashing dell'intero dispositivo. Questo è un problema di sicurezza perché Il flashing dell'intero dispositivo rimuove l'aggiornamento OTA. Gli strumenti sono in grado di rilevare questo comando in fase di runtime implementando fastboot getvar snapshot-update-status. Questo aiuta a distinguere le condizioni di errore.

Esempio

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()));
}

Modifiche agli strumenti Fastboot

Android 11 apporta le seguenti modifiche a fastboot protocollo:

  • getvar snapshot-update-status: restituisce il valore che l'avvio controllo HAL 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 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 del controllo di avvio HAL su CANCELLED. Questo comando non è valido quando il dispositivo è bloccato.
  • erase o wipe: un valore erase o wipe di metadata, userdata oppure una partizione con lo stato di unione per il controllo di avvio HAL deve controllare lo stato dell'unione degli snapshot. Se lo stato è MERGING o SNAPSHOTTED, lo stato 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 dovrebbe interrompere l'operazione. L'area può essere modificata in sicurezza SNAPSHOTTED.

Queste modifiche sono pensate per impedire l'avvio accidentale di un dispositivo, ma possono rovinare gli strumenti automatizzati. Quando i comandi vengono utilizzati come del flashing di tutte le partizioni, come l'esecuzione di fastboot flashall, ti consigliamo di utilizzare il seguente flusso:

  1. Query su getvar snapshot-update-status.
  2. Se merging o snapshotted, emetti snapshot-update cancel.
  3. Continua con i passaggi lampeggianti.
di Gemini Advanced.

Riduci i requisiti di archiviazione

I dispositivi che non hanno spazio di archiviazione A/B completo allocato in Super e che si aspettano per usare /data in base alle esigenze, ti consigliamo vivamente di usare la mappatura a blocchi lo strumento a riga di comando gcloud. Lo strumento di mappatura a blocchi mantiene l'allocazione dei blocchi coerente tra le build per ridurre le scritture non necessarie sullo snapshot. come documentato nella sezione Riduzione Dimensioni OTA.

Metodi di compressione OTA

I pacchetti OTA possono essere ottimizzati per diverse metriche sulle prestazioni. Android offre diversi metodi di compressione supportati (gz, lz4, zstd e none) che presentano dei compromessi tra tempo di installazione, utilizzo dello spazio COW, tempo di avvio e snapshot ora di unione. L'opzione predefinita abilitata per gli addominali virtuali con compressione è l'opzione gz compression method. Nota: le prestazioni relative tra i metodi di compressione varia a seconda della velocità della CPU e della velocità effettiva di archiviazione, che può cambiare a seconda sul dispositivo. Tutti i pacchetti OTA generati di seguito hanno la funzione PostInstall disabilitata, che rallenterà leggermente i tempi di avvio. La dimensione totale della partizione dinamica di un l'ottava completa senza compressione è di 4,81 GB).

OTA incrementale su Pixel 6 Pro

Ora di installazione senza fase di post-installazione Utilizzo dello spazio COW Pubblica ora di avvio OTA Ora di unione snapshot
gz 24 min 1,18 GB 40,2 sec 45,5 sec
LZ4 13 min 1,49 GB 37,4 sec 37,1 sec
nessuno 13 min 2,90 GB 37,6 sec 40,7 sec

OTA completa su Pixel 6 Pro

Ora di installazione senza fase di post-installazione Utilizzo dello spazio COW Pubblica ora di avvio OTA Ora di unione snapshot
gz 23 min 2,79 GB 24,9 sec 41,7 sec
LZ4 12 min 3,46 GB 20 sec 25,3 sec
nessuno 10 min 4,85 GB 20,6 sec 29,8 sec