Para implementar A/B virtual en un dispositivo nuevo o actualizar un dispositivo lanzado, debe realizar cambios en el código específico del dispositivo.
construir banderas
Los dispositivos que utilizan A/B virtual deben configurarse como dispositivos A/B y deben iniciarse con particiones dinámicas .
Para los dispositivos que se inician con A/B virtual, configúrelos para que hereden la configuración básica del dispositivo A/B virtual:
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)
Los dispositivos que se inician con A/B virtual solo necesitan la mitad del tamaño de placa para BOARD_SUPER_PARTITION_SIZE
porque las ranuras B ya no están en súper. Es decir, BOARD_SUPER_PARTITION_SIZE
debe ser mayor o igual que suma(tamaño de los grupos de actualización) + gastos generales , que, a su vez, debe ser mayor o igual que suma(tamaño de las particiones) + gastos generales .
Para Android 13 y versiones posteriores, para habilitar instantáneas comprimidas con Virtual A/B, herede la siguiente configuración básica:
$(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 de usuario con Virtual A/B mientras se utiliza un método de compresión no operativo. Luego puede configurar el método de compresión en uno de los métodos admitidos, gz
, zstd
y lz4
.
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4
Para Android 12, para habilitar instantáneas comprimidas con Virtual A/B, herede la siguiente configuración básica:
$(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 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, agregue 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
.
Fusión de espacio de usuario
Para los dispositivos que se actualizan a Android 13 y versiones posteriores, el proceso de fusión del espacio de usuario como se describe en Capas del mapeador de dispositivos no está habilitado de forma predeterminada. Para habilitar la combinación de espacios de usuario, agregue la siguiente línea al archivo .mk
del dispositivo:
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
La combinación de espacio de usuario está habilitada de forma predeterminada en dispositivos que se inician con 13 y superiores.
Control de arranque HAL
El HAL de control de arranque proporciona una interfaz para que los clientes OTA controlen las ranuras de arranque. Virtual A/B requiere una actualización de versión menor del control de arranque HAL porque se necesitan API adicionales para garantizar que el cargador de arranque esté protegido durante la actualización/restablecimiento de fábrica. Consulte IBootControl.hal y tipos.hal para obtener la última versión 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 de tabulador
La integridad de la partición de metadatos es esencial para el proceso de arranque, especialmente justo después de aplicar una actualización OTA. Por lo tanto, se debe verificar la partición de metadatos antes de que first_stage_init
la monte. Para garantizar que esto suceda, agregue el indicador 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 núcleo
Para habilitar la creación de instantáneas, establezca CONFIG_DM_SNAPSHOT
en true
.
Para dispositivos que usan F2FS, incluya el indicador f2fs: export FS_NOCOW_FL al parche del kernel del usuario para corregir la fijación de archivos. Incluya también el f2fs: admite el parche del kernel de archivos anclados alineados .
Virtual A/B se basa en características agregadas en la versión 4.3 del kernel: el bit de estado de desbordamiento en la snapshot
y los objetivos snapshot-merge
. Todos los dispositivos que se inician con Android 9 y posteriores ya deberían tener la versión del kernel 4.4 o posterior.
Para habilitar instantáneas comprimidas, la versión mínima del kernel admitida es 4.19. Establezca CONFIG_DM_USER=m
o CONFIG_DM_USER=y
. Si se utiliza el primero (un módulo), el módulo debe cargarse en el disco RAM de la primera etapa. Esto se puede lograr agregando la siguiente línea al Makefile del dispositivo:
BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko
Actualización en dispositivos que se actualizan a Android 11
Al actualizar a Android 11, los dispositivos que se iniciaron con particiones dinámicas pueden, opcionalmente, actualizar A/B virtual. El proceso de actualización es prácticamente el mismo que para los dispositivos que se inician con A/B virtual, con algunas diferencias menores:
Ubicación de los archivos COW : para dispositivos de lanzamiento, el cliente OTA utiliza todo el espacio vacío disponible en la superpartición antes de usar el espacio en
/data
. Para dispositivos modernizados, siempre hay suficiente espacio en la superpartición para que el archivo COW nunca se cree en/data
.Indicadores de funciones en tiempo de compilación : para dispositivos que actualizan A/B virtual, tanto
PRODUCT_VIRTUAL_AB_OTA
comoPRODUCT_VIRTUAL_AB_OTA_RETROFIT
están configurados entrue
, como se muestra a continuación:(call inherit-product, \
(SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
Tamaño de súper partición : los dispositivos que se inician con A/B virtual pueden reducir
BOARD_SUPER_PARTITION_SIZE
a la mitad porque las ranuras B no están en la súper partición. Los dispositivos que actualizan A/B virtual mantienen el tamaño de superpartición anterior, por lo queBOARD_SUPER_PARTITION_SIZE
es mayor o igual a 2 * suma (tamaño de los grupos de actualización) + gastos generales , que a su vez es mayor o igual a 2 * suma (tamaño de las particiones) + gastos generales .
Cambios en el gestor de arranque
Durante el paso de fusión de una actualización, /data
contiene la única instancia completa del sistema operativo Android. Una vez que comienza la migración, las particiones nativas system
, vendor
y product
están incompletas hasta que finaliza la copia. Si el dispositivo se restablece de fábrica durante este proceso, ya sea mediante recuperación o mediante el cuadro de diálogo de configuración del sistema, entonces el dispositivo no podrá iniciarse.
Antes de borrar /data
, finalice la combinación en recuperación o reversión según el estado del dispositivo:
- Si la nueva compilación se inició correctamente antes, finalice la migración.
- De lo contrario, retroceda a la ranura anterior:
- Para particiones dinámicas, retroceda al estado anterior.
- Para particiones estáticas, configure la ranura activa en la ranura anterior.
Tanto el gestor de arranque 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, el gestor de arranque no puede. El gestor de arranque no sabe si hay una fusión en curso o qué bloques en /data
constituyen las particiones del sistema operativo. Los dispositivos deben evitar que el usuario, sin saberlo, deje el dispositivo inoperable (bloqueándolo) haciendo lo siguiente:
- Implemente el control de arranque HAL para que el gestor de arranque pueda leer el valor establecido por el método
setSnapshotMergeStatus()
. - Si el estado de fusión es
MERGING
, o si el estado de fusión esSNAPSHOTTED
y la ranura ha cambiado a la ranura recién actualizada, entonces las solicitudes para borraruserdata
,metadata
o la partición que almacena el estado de fusión deben rechazarse en el gestor de arranque. - Implemente el comando
fastboot snapshot-update cancel
para que los usuarios puedan indicarle al gestor de arranque que desean omitir este mecanismo de protección. - Modifique las herramientas o scripts de actualización personalizados para
fastboot snapshot-update cancel
al actualizar todo el dispositivo. Esto es seguro porque al actualizar todo el dispositivo se elimina la OTA. Las herramientas pueden detectar este comando en tiempo de ejecución implementandofastboot getvar snapshot-update-status
. Este comando ayuda a diferenciar entre 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 arranque rápido
Android 11 realiza los siguientes cambios en el protocolo fastboot:
-
getvar snapshot-update-status
: devuelve el valor que el control de arranque HAL comunicó al gestor de arranque:- Si el estado es
MERGING
, el gestor de arranque debe devolvermerging
. - Si el estado es
SNAPSHOTTED
, el gestor de arranque debe regresarsnapshotted
. - De lo contrario, el gestor de arranque debe devolver
none
.
- Si el estado es
-
snapshot-update merge
: completa una operación de combinación y arranca en recovery/fastbootd si es necesario. Este comando es válido solo sisnapshot-update-status
se estámerging
y solo se admite en fastbootd. -
snapshot-update cancel
: establece el estado de fusión del HAL del 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 fusión para el control de arranque HAL debería verificar el estado de fusión de la instantánea. Si el estado esMERGING
oSNAPSHOTTED
, el dispositivo debería cancelar la operación. -
set_active
: un comandoset_active
que cambia la ranura activa debe verificar el estado de combinación de instantáneas. Si el estado esMERGING
, el dispositivo debería cancelar 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 no pueda arrancar accidentalmente, pero pueden ser perjudiciales para las herramientas automatizadas. Cuando los comandos se utilizan como componente para actualizar todas las particiones, como ejecutar fastboot flashall
, se recomienda utilizar el siguiente flujo:
- Consulta
getvar snapshot-update-status
. - Si
merging
osnapshotted
, emitasnapshot-update cancel
. - Continúe con los pasos intermitentes.
Reducir los requisitos de almacenamiento
Se recomienda encarecidamente que los dispositivos que no tienen almacenamiento A/B completo asignado en super y esperan usar /data
según sea necesario utilicen la herramienta de mapeo de bloques. La herramienta de mapeo de bloques mantiene la asignación de bloques consistente entre compilaciones, lo que reduce las escrituras innecesarias en la instantánea. Esto está documentado en Reducción del tamaño de OTA .
Métodos de compresión OTA
Los paquetes 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 COW, el tiempo de arranque y el tiempo de fusión de instantáneas. La opción predeterminada habilitada para ab virtual con compresión es el gz compression method
. (Nota: el rendimiento relativo entre los métodos de compresión varía según la velocidad de la CPU y el rendimiento del almacenamiento, lo que puede cambiar según el dispositivo. Todos los paquetes OTA generados a continuación tienen PostInstall deshabilitado, lo que ralentizará ligeramente el tiempo de arranque. El tamaño total de la partición dinámica de una OTA completa sin compresión es de 4,81 GB ).
OTA incremental en Pixel 6 Pro
Tiempo de instalación sin fase posterior a la instalación | Uso del espacio de las VACAS | Después del tiempo de arranque OTA | Tiempo de fusión de instantáneas | |
---|---|---|---|---|
gz | 24 minutos | 1,18GB | 40,2 segundos | 45,5 segundos |
lz4 | 13 minutos | 1,49GB | 37,4 seg | 37,1 segundos |
ninguno | 13 minutos | 2,90GB | 37,6 segundos | 40,7 seg |
OTA completa en Pixel 6 Pro
Tiempo de instalación sin fase posterior a la instalación | Uso del espacio de las VACAS | Después del tiempo de arranque OTA | Tiempo de fusión de instantáneas | |
---|---|---|---|---|
gz | 23 minutos | 2,79GB | 24,9 seg | 41,7 seg |
lz4 | 12 minutos | 3,46GB | 20,0 segundos | 25,3 segundos |
ninguno | 10 minutos | 4,85GB | 20,6 segundos | 29,8 seg |