OTA para dispositivos A/B sin particiones dinámicas

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

Esta página describe cómo los clientes OTA 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 OTA se actualizan a Android 10.

Fondo

Durante una 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 super en el dispositivo. Los metadatos se almacenan en system_a y system_b , pero esto se puede personalizar cambiando BOARD_SUPER_PARTITION_METADATA_DEVICE .

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

En esta página, los espacios de metadatos se denominan Metadatos S (fuente) y Metadatos T (destino). De manera similar, las particiones se conocen como system_s , vendor_t , etc.

Para obtener más información acerca de las configuraciones del sistema de compilación , consulte Actualización de dispositivos .

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

Un ejemplo de metadatos en un dispositivo es:

  • Dispositivo de bloque físico system_a
    • Metadatos 0
      • Grupo foo_a
        • Sistema de 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 bloque físico system_b
    • Metadatos 0 (no utilizado)
    • 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
      • Grupo bar_b
        • Partición lógica (dinámica) vendor_b
        • Partición lógica (dinámica) product_b
        • Otras particiones actualizadas por Bar

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

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

Adaptación de una actualización

En los dispositivos que ejecutan Android 9 y versiones anteriores, el cliente OTA del dispositivo 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 OTA construye el archivo super.img final que contiene el contenido de todas las particiones dinámicas, luego divide la imagen en múltiples imágenes que coinciden con los tamaños de los dispositivos de bloque físico correspondientes al sistema, proveedor, etc. Estas imágenes se denominan super_system.img , super_vendor.img , etc. 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 deshabilitan automáticamente para estas particiones cuando se genera el paquete de actualización. Consulte Configuración posterior a 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:

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

Después de la actualización:

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

Actualizaciones futuras después de la actualización

Después de la actualización de actualización, el cliente OTA se actualiza para trabajar con particiones dinámicas. Las extensiones de las particiones de origen nunca abarcan las particiones físicas de destino.

Flujo de actualización usando un paquete de actualización regular

  1. Inicialice los metadatos de la super .
    1. Construya nuevos metadatos M a partir de Metadatos S (metadatos de origen). Por ejemplo, si los metadatos S usan [ system_s , vendor_s , product_s ] como dispositivos de bloque, entonces los nuevos metadatos M usan [ system_t , vendor_t , product_t ] como dispositivos de bloque. Todos los grupos y particiones se descartan en M.
    2. Agregue grupos de destino y particiones 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. Escriba M en metadatos T.
    4. Asigne las particiones añadidas en el mapeador de dispositivos como escribibles.
  2. Aplicar la actualización en los dispositivos de bloque.
    1. Si es necesario, asigne las particiones de origen en el asignador de dispositivos como de solo lectura. Esto es necesario para la instalación de prueba porque las particiones de origen no se asignan antes de la actualización.
    2. Aplique una actualización completa o delta a todos los dispositivos de bloque en la ranura de destino.
    3. Monte las particiones para ejecutar el script posterior a la instalación y luego desmonte las particiones.
  3. Desasignar las particiones de destino.

Flujo de actualización mediante un paquete de actualización de actualización

Si el paquete de actualización de actualización se aplica en un dispositivo que ya habilita particiones dinámicas, el cliente OTA aplica el archivo super.img dividido en dispositivos de bloque directamente. El flujo de actualización es similar a una actualización de actualización. Consulte Adaptación de una actualización para obtener más información.

Por ejemplo, suponga lo siguiente:

  • La ranura A es la ranura activa.
  • system_a contiene los metadatos activos en la ranura 0.
  • system_a , vendor_a y product_a se utilizan como dispositivos de bloque.

Cuando el cliente OTA recibe un paquete de actualización de actualización, aplica super_system.img en el system_b , super_vendor.img en el vendor_b y super_product.img en el producto product_b . El dispositivo de bloque físico system_b contiene los metadatos correctos para asignar el system_b lógico, el vendor_b y el product_b en el momento del arranque.

Generación de paquetes de actualización

OTA incrementales

Al generar OTA incrementales para dispositivos actualizados, las actualizaciones dependen de si la compilación base define o no PRODUCT_USE_DYNAMIC_PARTITIONS y PRODUCT_RETROFIT_DYNAMIC_PARTITIONS .

  • Si la compilación base no define las variables, se trata de una actualización de actualización. El paquete de actualización contiene el archivo super.img dividido y deshabilita 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 las particiones lógicas (dinámicas). El paso posterior a la instalación se puede habilitar.

OTA completo

Se generan dos paquetes OTA completos para dispositivos retrofit.

  • $(PRODUCT)-ota-retrofit-$(TAG).zip siempre contiene super.img dividido y deshabilita el paso posterior a la instalación para la actualización de actualización.
    • Se genera con un argumento adicional --retrofit_dynamic_partitions al script ota_from_target_files .
    • Se puede aplicar a todas las construcciones.
  • $(PRODUCT)-ota-$(TAG).zip contiene imágenes lógicas para futuras actualizaciones.
    • Aplique esto solo a compilaciones con particiones dinámicas habilitadas. Vea los detalles a continuación sobre cómo hacer cumplir esto.

Rechazo de actualizaciones no actualizadas en compilaciones antiguas

Aplique el paquete OTA completo regular solo a compilaciones con particiones dinámicas habilitadas. Si el servidor OTA está configurado incorrectamente y envía estos paquetes a dispositivos que ejecutan Android 9 o inferior, los dispositivos no se iniciarán. El cliente OTA en Android 9 y versiones anteriores no puede distinguir la diferencia entre un paquete OTA actualizado 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, puede requerir un paso posterior a la instalación para verificar la configuración del dispositivo existente. 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 el paquete OTA regular se aplica en un dispositivo sin particiones dinámicas habilitadas, el cliente OTA ejecuta check_dynamic_partitions como un paso posterior a la instalación y rechaza la actualización.