Inalámbrico para dispositivos A/B sin particiones dinámicas

Android 10 admite particiones dinámicas, un sistema de partición de espacio de usuario que puede crear, cambiar el tamaño y destruir particiones durante las actualizaciones inalámbricas (OTA).

En esta página, se describe cómo los clientes inalámbricos cambian el tamaño de las particiones dinámicas durante una actualización para dispositivos A/B que se lanzaron sin compatibilidad con particiones dinámicas y cómo los clientes inalámbricos actualizan a Android 10.

Segundo plano

Durante la actualización de un dispositivo A/B para admitir particiones dinámicas, se conserva la tabla de particiones GUID (GPT) en el dispositivo, por lo que no hay una partición super en el dispositivo. Los metadatos se almacenan en system_a y system_b, pero esto se puede personalizar si cambias BOARD_SUPER_PARTITION_METADATA_DEVICE.

En cada uno de los dispositivos de almacenamiento en bloque, hay dos ranuras de metadatos. Solo se usa un banquete de metadatos en cada dispositivo de almacenamiento en bloque. Por ejemplo, los metadatos 0 en system_a y los metadatos 1 en system_b corresponden a particiones en los ranuras A y B, respectivamente. En el tiempo de ejecución, no importa qué ranura se actualice.

En esta página, los espacios de metadatos se denominan Metadata S (fuente) y Metadata T (destino). Del mismo modo, las particiones se denominan system_s, vendor_t, y así sucesivamente.

Para obtener más información sobre las configuraciones del sistema de compilación, consulta Cómo actualizar dispositivos.

Para obtener más información sobre cómo las particiones pertenecen a grupos de actualización, consulta Cambios en la configuración de la placa para dispositivos nuevos.

Un ejemplo de metadatos en un dispositivo es el siguiente:

  • Dispositivo de bloques físicos system_a
    • Metadatos 0
      • Grupo foo_a
        • Partición lógica (dinámica) system_a
        • Partición lógica (dinámica) product_services_a
        • Otras particiones actualizadas por Foo
      • Grupo bar_a
        • Partición lógica (dinámica) vendor_a
        • Partición lógica (dinámica) product_a
        • Otras particiones actualizadas por Bar
    • Metadatos 1 (no utilizado)
  • Dispositivo de almacenamiento en bloques físico system_b
    • Metadatos 0 (no se usa)
    • Metadatos 1
      • Grupo foo_b
        • Partición lógica (dinámica) system_b
        • Partición lógica (dinámica) product_services_b
        • Otras particiones actualizadas por Foo
      • Agrupa bar_b
        • Partición lógica (dinámica) vendor_b
        • Partición lógica (dinámica) product_b
        • Otras particiones actualizadas por Bar

Puedes usar la herramienta lpdump en system/extras/partition_tools para volcar los metadatos en tu dispositivo. Por ejemplo:

lpdump --slot 0 /dev/block/by-name/system_a
lpdump --slot 1 /dev/block/by-name/system_b

Actualiza una actualización

En los dispositivos que ejecutan Android 9 y versiones anteriores, el cliente inalámbrico no admite la asignación de particiones dinámicas antes de la actualización. Se crea un conjunto adicional de parches para que la asignación se pueda aplicar directamente a las particiones físicas existentes.

El generador inalámbrico compila el archivo super.img final que incluye el contenido de todas las particiones dinámicas y, luego, divide la imagen en varias imágenes que coinciden con los tamaños de los dispositivos de bloques físicos correspondientes al sistema, al proveedor, etcétera. Estas imágenes se denominan super_system.img, super_vendor.img, etcétera. El cliente OTA aplica estas imágenes a las particiones físicas, en lugar de aplicar las imágenes a las particiones lógicas (dinámicas).

Debido a que el cliente OTA no sabe cómo asignar particiones dinámicas, todos los pasos posteriores a la instalación se inhabilitan automáticamente para estas particiones cuando se genera el paquete de actualización. Para obtener más detalles, consulta Configura después de la instalación para obtener más detalles.

El flujo de actualización es el mismo que en Android 9.

Antes de la actualización, haz lo siguiente:

ro.boot.dynamic_partitions=
ro.boot.dynamic_partitions_retrofit=

Después de la actualización, haz lo siguiente:

ro.boot.dynamic_partitions=true
ro.boot.dynamic_partitions_retrofit=true

Actualizaciones futuras después de la adaptación

Después de la actualización de la retroadaptación, el cliente OTA se actualiza para funcionar con particiones dinámicas. Los límites de las particiones de origen nunca se extienden a las particiones físicas de destino.

Flujo de actualización con un paquete de actualización normal

  1. Inicializa los metadatos de la partición super.
    1. Construye metadatos nuevos M a partir de los metadatos S (metadatos de origen). Por ejemplo, si los metadatos S usan [system_s, vendor_s, product_s] como dispositivos de bloqueo, los metadatos nuevos M usan [system_t, vendor_t, product_t] como dispositivos de bloqueo. Todos los grupos y particiones se descartan en M.
    2. Agrega grupos y particiones de destino según el campo dynamic_partition_metadata en el manifiesto de actualización. El tamaño de cada partición se puede encontrar en new_partition_info.
    3. Escribe M en el campo de metadatos T.
    4. Asigna las particiones agregadas en el asignador de dispositivos como que admiten escritura.
  2. Aplica la actualización en los dispositivos de almacenamiento en bloque.
    1. Si es necesario, asigna las particiones de origen en el asignador de dispositivos como de solo lectura. Esto es necesario para la transferencia, ya que las particiones de origen no se asignan antes de la actualización.
    2. Aplica una actualización completa o delta a todos los dispositivos de almacenamiento en el espacio objetivo.
    3. Activa las particiones para ejecutar la secuencia de comandos posterior a la instalación y, luego, desactiva las particiones.
  3. Desasignar las particiones de destino

Cómo actualizar el flujo con un paquete de actualización de Retrofit

Si el paquete de actualización de retroadaptación se aplica en un dispositivo que ya habilita particiones dinámicas, el cliente OTA aplica el archivo super.img dividido directamente en los dispositivos de almacenamiento en bloque. El flujo de actualización es similar al de una actualización de retroadaptación. Para obtener más información, consulta Cómo adaptar una actualización.

Por ejemplo, supongamos lo siguiente:

  • El zócalo A es el activo.
  • system_a contiene los metadatos activos en la ranura 0.
  • system_a, vendor_a y product_a se usan como dispositivos de almacenamiento en bloques.

Cuando el cliente inalámbrico recibe un paquete de actualización de Retrofit, aplica super_system.img en el system_b físico, super_vendor.img en el vendor_b físico y super_product.img en el product_b físico. El dispositivo de almacenamiento en bloques físico system_b contiene los metadatos correctos para asignar los system_b, vendor_b y product_b lógicos en el momento del inicio.

Genera paquetes de actualización

OTA incremental

Cuando se generan OTA incrementales para dispositivos de reacondicionamiento, las actualizaciones dependen de si la compilación base define PRODUCT_USE_DYNAMIC_PARTITIONS y PRODUCT_RETROFIT_DYNAMIC_PARTITIONS.

  • Si la compilación base no define las variables, esta es una actualización de retroadaptación. El paquete de actualización contiene el archivo super.img dividido y inhabilita el paso posterior a la instalación.
  • Si la compilación base define las variables, esto es lo mismo que una actualización típica con particiones dinámicas. El paquete de actualización contiene las imágenes para particiones lógicas (dinámicas). Se puede habilitar el paso posterior a la instalación.

OTA completa

Se generan dos paquetes inalámbricos completos para los dispositivos de reconversión.

  • $(PRODUCT)-ota-retrofit-$(TAG).zip siempre contiene la división super.img y inhabilita el paso posterior a la instalación para la actualización de retroadaptación.
    • Se genera con un argumento adicional --retrofit_dynamic_partitions a la secuencia de comandos ota_from_target_files.
    • Se puede aplicar a todas las compilaciones.
  • $(PRODUCT)-ota-$(TAG).zip contiene imágenes lógicas para actualizaciones futuras.
    • Aplica esto solo a las compilaciones con particiones dinámicas habilitadas. Consulta los detalles a continuación para aplicar esta medida.

Rechaza la actualización no retrocompatible en compilaciones anteriores

Aplica el paquete inalámbrico completo normal solo a las compilaciones con particiones dinámicas habilitadas. Si el servidor OTA se configura de forma incorrecta y envía estos paquetes a dispositivos que ejecutan Android 9 o versiones anteriores, los dispositivos no se inician. El cliente OTA en Android 9 y versiones anteriores no puede distinguir entre un paquete OTA de retrocompatibilidad y un paquete OTA completo normal, por lo que el cliente no rechazará el paquete completo.

Para evitar que el dispositivo acepte el paquete OTA completo, puedes requerir un paso posterior a la instalación para verificar la configuración existente del dispositivo. Por ejemplo:

device/device_name/dynamic_partitions/check_dynamic_partitions

#!/system/bin/sh
DP_PROPERTY_NAME="ro.boot.dynamic_partitions"
DP_RETROFIT_PROPERTY_NAME="ro.boot.dynamic_partitions_retrofit"

DP_PROPERTY=$(getprop ${DP_PROPERTY_NAME})
DP_RETROFIT_PROPERTY=$(getprop ${DP_RETROFIT_PROPERTY_NAME})

if [ "${DP_PROPERTY}" != "true" ] || [ "${DP_RETROFIT_PROPERTY}" != "true" ] ; then
    echo "Error: applied non-retrofit update on build without dynamic" \
         "partitions."
    echo "${DP_PROPERTY_NAME}=${DP_PROPERTY}"
    echo "${DP_RETROFIT_PROPERTY_NAME}=${DP_RETROFIT_PROPERTY}"
    exit 1
fi

device/device_name/dynamic_partitions/Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= check_dynamic_partitions
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_SRC_FILES := check_dynamic_partitions
LOCAL_PRODUCT_MODULE := true
include $(BUILD_PREBUILT)

device/device_name/device.mk

PRODUCT_PACKAGES += check_dynamic_partitions

# OPTIONAL=false so that the error in check_dynamic_partitions will be
# propagated to OTA client.
AB_OTA_POSTINSTALL_CONFIG += \
    RUN_POSTINSTALL_product=true \
    POSTINSTALL_PATH_product=bin/check_dynamic_partitions \
    FILESYSTEM_TYPE_product=ext4 \
    POSTINSTALL_OPTIONAL_product=false \

Cuando se aplica el paquete OTA normal en un dispositivo sin particiones dinámicas habilitadas, el cliente OTA ejecuta check_dynamic_partitions como paso posterior a la instalación y rechaza la actualización.