Implementar una prueba A/B virtual

Para implementar A/B virtual en un dispositivo nuevo o modernizar un dispositivo lanzado, debes debe realizar cambios en el código específico del dispositivo.

Marcas de compilación

Los dispositivos que usan una A/B virtual se deben configurar como una A/B dispositivo y debe iniciarse con dinámico o particiones.

En el caso de los dispositivos que se lanzan con A/B virtual, configúralos para que hereden esa versión configuración base del dispositivo:

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

Los dispositivos que se lanzan con A/B virtual necesitan solo la mitad del tamaño de la placa para BOARD_SUPER_PARTITION_SIZE porque las ranuras B ya no están en super. Es decir, El valor de BOARD_SUPER_PARTITION_SIZE debe ser mayor o igual que suma(tamaño de grupos de actualización) + carga, que, a su vez, debe ser mayor igual o superior a suma(tamaño de particiones) + carga.

En Android 13 y versiones posteriores, para habilitar las con A/B virtual, heredan la siguiente configuración base:

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

Esto permite instantáneas del espacio del usuario con A/B virtual mientras se usa un no-op de compresión. Luego, puedes configurar el método de compresión en uno de los métodos admitidos, gz, zstd y lz4.

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4

En Android 12, para habilitar las instantáneas comprimidas con A/B virtual, heredan la siguiente configuración base:

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

Compresión XOR

Para los dispositivos que se actualizan a Android 13 y versiones posteriores, la La función de compresión XOR no habilitado de forma predeterminada. Para habilitar la compresión XOR, agrega lo siguiente al archivo .mk.

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

La compresión XOR está habilitada de forma predeterminada para los dispositivos que heredan android_t_baseline.mk

Combinación de espacio del usuario

Para los dispositivos que se actualizan a Android 13 y versiones posteriores, la de combinación de espacio de usuario, como se describe en Device-mapper la superposición de capas no está habilitada de forma predeterminada. Para habilitar la combinación de espacio del usuario, agrega la siguiente línea al .mk del dispositivo. archivo:

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

La combinación de espacio del usuario está habilitada de forma predeterminada en los dispositivos que se lanzan con 13 y versiones posteriores.

HAL del control de inicio

El control de inicio HAL proporciona una interfaz para que los clientes inalámbricos controlen las ranuras de inicio. A/B virtual requiere una actualización de versión secundaria de la HAL del control de inicio porque hay APIs adicionales para garantizar que el bootloader esté protegido durante la instalación o el restablecimiento de la configuración de fábrica. Consulta IBootControl.hal; y types.hal para obtener la versión más reciente de la definición de 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
}

Cambios en fstab

La integridad de la partición de metadatos es esencial para el proceso de inicio, especialmente justo después de que se aplique una actualización OTA. Entonces, la partición de metadatos debe verificarse antes de que first_stage_init lo active. Para garantizar que esto suceda, agrega La marca fs_mgr check de la entrada para /metadata. A continuación, se proporciona un ejemplo:

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

Requisitos del kernel

Para habilitar la captura de instantáneas, establece CONFIG_DM_SNAPSHOT en true.

Para los dispositivos que usan F2FS, incluye la marca f2fs: export FS_NOCOW_FL a user para corregir la fijación de archivos. Incluye el atributo f2fs: compatibilidad fijada con compatibilidad de kernel.

A/B virtual se basa en funciones agregadas en la versión de kernel 4.3: el desbordamiento. bit de estado en los objetivos snapshot y snapshot-merge. Lanzamiento de todos los dispositivos en Android 9 y versiones posteriores ya deberían tener la versión de kernel 4.4 o una posterior.

Para habilitar las instantáneas comprimidas, la versión mínima compatible de kernel es 4.19. Establece CONFIG_DM_USER=m o CONFIG_DM_USER=y. Si usas el primero (un módulo), el módulo debe cargarse en el disco RAM de la primera etapa. Esto se puede lograr Agrega la siguiente línea al archivo Make del dispositivo:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

Retrofit en dispositivos que se actualizan a Android 11

Cuando actualizas a Android 11, los dispositivos que se iniciaron con particiones dinámicas pueden opcionalmente, adaptar A/B virtual. El proceso de actualización es casi el mismo que el de dispositivos que se lanzan con A/B virtual, con algunas diferencias menores:

  • Ubicación de archivos COW: Para dispositivos de lanzamiento, el cliente inalámbrico usa todo el espacio vacío disponible en la superpartición antes de usar el espacio /data Para los dispositivos adaptados, siempre hay suficiente espacio en la partición para que el archivo COW nunca se cree en /data.

  • Marcas de función durante el tiempo de compilación: Para dispositivos que se adaptan a las versiones A/B virtuales, se configuraron PRODUCT_VIRTUAL_AB_OTA y PRODUCT_VIRTUAL_AB_OTA_RETROFIT a true, como se muestra a continuación:

    (call inherit-product, \
      (SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
    
  • Tamaño de superpartición: Los dispositivos que se lanzan con A/B virtual pueden cortar BOARD_SUPER_PARTITION_SIZE por la mitad porque las ranuras B no están en el super por cada partición. Los dispositivos que se actualizan con la versión A/B virtual conserva la superpartición anterior el tamaño, por lo que BOARD_SUPER_PARTITION_SIZE es mayor o igual que 2 * suma(tamaño de los grupos de actualización) + sobrecarga, que a su vez es mayor o igual que 2 * suma(tamaño de las particiones) + general.

Cambios en el bootloader

Durante el paso de combinación de una actualización, /data contiene la única instancia completa del SO Android Cuando comienza la migración, se activan system, vendor y product particiones estarán incompletas hasta que finalice la copia. Si el dispositivo es el restablecimiento de la configuración de fábrica durante este proceso, ya sea mediante la recuperación del cuadro de diálogo de configuración, el dispositivo no se podría iniciar.

Antes de borrar /data, finaliza la combinación en la recuperación o reversión según lo siguiente: el estado del dispositivo:

  • Si la compilación nueva se inició correctamente antes, finaliza la migración.
  • De lo contrario, revierte a la ranura anterior:
    • Para las particiones dinámicas, vuelve al estado anterior.
    • En el caso de las particiones estáticas, establece la ranura activa en la ranura anterior.

Tanto el bootloader como fastbootd pueden borrar la partición /data si el dispositivo está desbloqueado. Si bien fastbootd puede forzar la finalización de la migración, no lo hace. El bootloader no sabe si hay una combinación o no. progreso, o qué bloques en /data constituyen las particiones del SO. Los dispositivos deben cumplir con los siguientes requisitos: evitar que el usuario, sin saberlo, desactive el dispositivo (bloqueo) al haciendo lo siguiente:

  1. Implementa la HAL del control de inicio para que el bootloader pueda leer el valor establecido con el método setSnapshotMergeStatus()
  2. Si el estado de combinación es MERGING o si el estado de combinación es SNAPSHOTTED y la ranura se cambió a la que se actualizó recientemente. Luego, se solicita la limpieza userdata, metadata, o la partición que almacena el estado de combinación debe ser se rechazan en el bootloader.
  3. Implementa el comando fastboot snapshot-update cancel para que los usuarios puedan al bootloader que quiere omitir este mecanismo de protección.
  4. Se modificaron las herramientas o secuencias de comandos de escritura en la memoria flash personalizadas para emitir fastboot snapshot-update cancel cuando se instala todo el dispositivo. Es seguro emitirlo porque instalar todo el dispositivo elimina el dispositivo inalámbrico. Las herramientas pueden detectar este comando en el tiempo de ejecución implementando fastboot getvar snapshot-update-status. Esta ayuda a diferenciar entre las condiciones de error.

Ejemplo

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

Cambios en las herramientas de fastboot

Android 11 realiza los siguientes cambios en el inicio rápido protocolo:

  • getvar snapshot-update-status: Muestra el valor que controla la HAL que se comunica al bootloader:
    • Si el estado es MERGING, el bootloader debe mostrar merging.
    • Si el estado es SNAPSHOTTED, el bootloader debe mostrar snapshotted.
    • De lo contrario, el bootloader debe mostrar none.
  • snapshot-update merge: Completa una operación de combinación; se inicia en recuperación/fastbootd si es necesario. Este comando es válido solo si snapshot-update-status es merging y solo es compatible con fastbootd.
  • snapshot-update cancel: Establece el estado de combinación de la HAL del control de inicio en CANCELLED Este comando no es válido cuando el dispositivo está bloqueado.
  • erase o wipe: Es un erase o wipe de metadata, userdata o una partición que tenga el estado de combinación de la HAL del control de inicio debería verificar el estado de combinación de instantáneas. Si el estado es MERGING o SNAPSHOTTED, el el dispositivo debería anular la operación.
  • set_active: Es un comando set_active que cambia el espacio activo. debería verificar el estado de combinación de instantáneas. Si el estado es MERGING, el el dispositivo debería anular la operación. El espacio se puede cambiar de forma segura en la SNAPSHOTTED.

Estos cambios están diseñados para evitar que, accidentalmente, no se pueda iniciar un dispositivo pero pueden interrumpir las herramientas automatizadas. Cuando los comandos se usan como por escribir en la memoria flash todas las particiones, como ejecutar fastboot flashall, es se recomienda usar el siguiente flujo:

  1. Consulta getvar snapshot-update-status.
  2. Si es merging o snapshotted, emite snapshot-update cancel.
  3. Continúa con los pasos de escritura en la memoria flash.

Reduce los requisitos de almacenamiento

Los dispositivos que no tienen almacenamiento A/B completo asignado en super y esperan usar /data según sea necesario, se recomienda que uses la asignación de bloques herramienta. La herramienta de asignación de bloques mantiene la coherencia de las asignaciones de bloques y reduce las escrituras innecesarias en la instantánea. Esto se documenta en Reduce Tamaño inalámbrico.

Métodos de compresión OTA

Los paquetes de OTA se pueden ajustar para diferentes métricas de rendimiento. Android proporciona varios métodos de compresión compatibles (gz, lz4, zstd y none) que tienen compensaciones entre el tiempo de instalación, el uso del espacio del COW, el tiempo de inicio y la instantánea momento de la fusión. La opción predeterminada habilitada para el abdomen virtual con compresión es el gz compression method (Nota: El rendimiento relativo entre los métodos de compresión) varía en función de la velocidad de la CPU y la capacidad de procesamiento del almacenamiento, en el dispositivo. Todos los paquetes inalámbricos que se generan a continuación tienen inhabilitada la función PostInstall, ralentizará un poco el tiempo de inicio. Es el tamaño total de partición dinámica de un OTA completa sin compresión es de 4.81 GB).

Actualización inalámbrica incremental en Pixel 6 Pro

Tiempo de instalación sin fase posterior a la instalación Uso del espacio de COW Tiempo posterior al inicio inalámbrico Fecha y hora de combinación de instantáneas
gz 24 min 1.18 GB 40.2 s 45.5 s
LZ4 13 min 1.49 GB 37.4 s 37.1 s
none 13 min 2.90 GB 37.6 s 40.7 s

Actualización inalámbrica completa en el Pixel 6 Pro

Tiempo de instalación sin fase posterior a la instalación Uso del espacio de COW Tiempo posterior al inicio inalámbrico Fecha y hora de combinación de instantáneas
gz 23 min 2.79 GB 24.9 s 41.7 s
LZ4 12 min 3.46 GB 20.0 s 25.3 s
none 10 min 4.85 GB 20.6 s 29.8 s