Para implementar A/B virtual en un dispositivo nuevo o adaptar un dispositivo lanzado, debes realizar cambios en el código específico del dispositivo.
Marcas de compilación
Los dispositivos que usan A/B virtual deben configurarse como dispositivos A/B y deben iniciarse con particiones dinámicas.
En el caso de los dispositivos que se lanzan con A/B virtual, configúralos para que hereden la configuración base del dispositivo A/B virtual:
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)
Los dispositivos que se lanzan con A/B virtual solo necesitan la mitad del tamaño de la placa para BOARD_SUPER_PARTITION_SIZE
, ya que las ranuras B ya no están en super. Es decir, BOARD_SUPER_PARTITION_SIZE
debe ser mayor o igual que sum(tamaño de los grupos de actualización) + sobrecarga, que, a su vez, debe ser mayor o igual que sum(tamaño de las particiones) + sobrecarga.
En Android 13 y versiones posteriores, para habilitar instantáneas comprimidas con Virtual A/B, hereda 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/vabc_features.mk)
Esto habilita las instantáneas del espacio del usuario con Virtual A/B mientras se usa un método de compresión no operativo. Luego, puedes configurar el método de compresión en uno de los métodos admitidos,zstd
y lz4
. En Android 15, la compresión se puede personalizar aún más para satisfacer las necesidades del dispositivo. Para obtener más información, consulta Ajuste de la compresión.
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4
PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536
En Android 12, para habilitar instantáneas comprimidas con A/B virtual, hereda 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
En el caso de los dispositivos que se actualizan a Android 13 y versiones posteriores, la función de compresión XOR no está habilitada de forma predeterminada. Para habilitar la compresión XOR, agrega lo siguiente al archivo .mk
del dispositivo.
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
La compresión XOR está habilitada de forma predeterminada para los dispositivos que heredan de android_t_baseline.mk
.
Combinación del espacio del usuario
En la versión moderna de Virtual A/B (Android T y versiones posteriores), el proceso de combinación de instantáneas se realiza por completo en el espacio de usuario. Este cambio es posible gracias a snapuserd y dm-user. Los dispositivos que se lanzan con Android 13 y versiones posteriores tienen habilitada la combinación de espacio de usuario de forma predeterminada. En el caso de los dispositivos más antiguos que se actualizan, esta propiedad se puede establecer con lo siguiente:
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
HAL de control de inicio
El HAL de control de arranque proporciona una interfaz para que los clientes de OTA controlen las ranuras de arranque. Virtual A/B requiere una actualización de versión secundaria del HAL de control de arranque porque se necesitan APIs adicionales para garantizar que el cargador de arranque esté protegido durante el restablecimiento de la configuración de fábrica o el proceso de escritura en la memoria flash. 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, en especial, justo después de que se aplica una actualización OTA. Por lo tanto, se debe verificar la partición de metadatos antes de que first_stage_init
la monte. Para asegurarte de que esto suceda, agrega la marca check
fs_mgr a la entrada de /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 creación de instantáneas, establece CONFIG_DM_SNAPSHOT
en true
.
Para los dispositivos que usan F2FS, incluye el parche del kernel f2fs: export FS_NOCOW_FL flag to user para corregir la fijación de archivos. También incluye el parche del kernel f2fs: support aligned pinned file.
Virtual A/B se basa en las funciones agregadas en la versión 4.3 del kernel: el bit de estado overflow en los destinos snapshot
y snapshot-merge
. Todos los dispositivos que se lancen con Android 9 y versiones posteriores ya deberían tener la versión del kernel 4.4 o posterior.
Para habilitar las instantáneas comprimidas, la versión mínima del kernel admitida es la 4.19.
Establece CONFIG_DM_USER=m
o CONFIG_DM_USER=y
. Si usas el primero (un módulo), este debe cargarse en el disco RAM de la primera etapa. Para ello, agrega la siguiente línea al archivo Makefile del dispositivo:
BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko
Cambios en las herramientas de fastboot
Android 11 realiza los siguientes cambios en el protocolo fastboot:
getvar snapshot-update-status
: Devuelve el valor que el HAL de control de arranque comunicó al bootloader:- Si el estado es
MERGING
, el cargador de arranque debe devolvermerging
. - Si el estado es
SNAPSHOTTED
, el cargador de arranque debe devolversnapshotted
. - De lo contrario, el cargador de arranque debe devolver
none
.
- Si el estado es
snapshot-update merge
: Completa una operación de combinación y, si es necesario, inicia el dispositivo en el modo de recuperación o fastbootd. Este comando solo es válido sisnapshot-update-status
esmerging
y solo se admite en fastbootd.snapshot-update cancel
: Establece el estado de combinación del HAL de control de arranque enCANCELLED
. Este comando no es válido cuando el dispositivo está bloqueado.erase
owipe
: Unerase
owipe
demetadata
,userdata
o una partición que contiene el estado de combinación del HAL de control de arranque debe verificar el estado de combinación de la instantánea. Si el estado esMERGING
oSNAPSHOTTED
, el dispositivo debe anular la operación.set_active
: Un comandoset_active
que cambia la ranura activa debe verificar el estado de combinación de la instantánea. Si el estado esMERGING
, el dispositivo debe anular la operación. La ranura se puede cambiar de forma segura en el estadoSNAPSHOTTED
.
Estos cambios están diseñados para evitar que un dispositivo deje de ser iniciable por accidente, pero pueden interrumpir las herramientas automatizadas. Cuando los comandos se usan como un componente de la escritura de todas las particiones, como la ejecución de fastboot flashall
, se recomienda usar el siguiente flujo:
- Consulta
getvar snapshot-update-status
. - Si es
merging
osnapshotted
, emitesnapshot-update cancel
. - Continúa con los pasos de escritura.
Reducir los requisitos de almacenamiento
Se recomienda encarecidamente que los dispositivos que no tienen almacenamiento A/B completo asignado en super y que esperan usar /data
según sea necesario utilicen la herramienta de asignación de bloques. La herramienta de asignación de bloques mantiene la asignación de bloques coherente entre las compilaciones, lo que reduce las escrituras innecesarias en la instantánea. Esto se documenta en Cómo reducir el tamaño de la OTA.
Algoritmos de compresión de OTA
Los paquetes OTA se pueden ajustar para diferentes métricas de rendimiento. Android proporciona varios métodos de compresión compatibles (lz4
, zstd
y none
) que tienen compensaciones entre el tiempo de instalación, el uso de espacio de COW, el tiempo de arranque y el tiempo de combinación de instantáneas. La opción predeterminada habilitada para el ab virtual con compresión es lz4
compression method
.
Ajuste de la compresión
Los algoritmos de compresión se pueden personalizar aún más con dos métodos: (nivel de compresión) (la cantidad de compresión que se logra a expensas de la velocidad) y (factor de compresión) (el tamaño máximo de la ventana comprimible).
El nivel de compresión está disponible para ciertos algoritmos, como zstd
, y cambiar el nivel implica una compensación entre la velocidad y el índice de compresión.
El factor de compresión describe el tamaño máximo de la ventana de compresión que se usa durante la instalación OTA. El valor predeterminado se establece en 64 000, pero se puede anular personalizando el parámetro de compilación PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR
. Se admiten factores de compresión de 4 k, 8 k, 16 k, 32 k, 64 k, 128 k y 256 k.
PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536
Actualización inalámbrica incremental en el Pixel 8 Pro
Tiempo de instalación sin la fase posterior a la instalación | Uso del espacio de COW | Tiempo de inicio posterior a la actualización OTA | Hora de combinación de la instantánea | |
---|---|---|---|---|
lz4 | 18 min 15 s | 2,5 GB | 32.7 s | 98.6 s |
zstd | 24 min 49 s | 2.05 GB | 36.3 s | 133.2 s |
none | 16 min 42 s | 4.76 GB | 28.7 s | 76.6 s |
Actualización inalámbrica completa en el Pixel 8 Pro
Tiempo de instalación sin la fase posterior a la instalación | Uso del espacio de COW | Tiempo de inicio posterior a la actualización OTA | Hora de combinación de la instantánea | |
---|---|---|---|---|
lz4 | 15 min 11 s | 4.16 GB | 17.6 s | 82.2 s |
zstd | 16 min 19 s | 3.46 GB | 21.0 s | 106.3 s |
none | 13 min 33 s | 6.39 GB | 18.5 s | 92.5 s |