Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Implementación de actualizaciones A / B

OEM y SoC vendedores que quieren aplicar las actualizaciones del sistema A / B deben asegurar que sus implementos del gestor de arranque del boot_control HAL y pasa los parámetros correctos para el kernel.

Implementación del control de arranque HAL

A / B gestores de arranque con capacidad deben implementar la boot_control HAL en hardware/libhardware/include/hardware/boot_control.h . Puede probar las implementaciones utilizando el system/extras/bootctl utilidad y system/extras/tests/bootloader/ .

También debe implementar la máquina de estado que se muestra a continuación:

Máquina de estado de la figura 1. Bootloader

Configurando el kernel

Para implementar actualizaciones del sistema A / B:

  1. Elija la siguiente serie de parches del kernel (si es necesario):
  2. Asegúrese de argumentos de línea de órdenes en el núcleo contienen los siguientes argumentos adicionales:
    skip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 android-verity <public-key-id> <path-to-system-partition>"
    ... donde el <public-key-id> valor es el ID de la clave pública utilizada para verificar la firma de tabla de verdad (para más detalles, véase dm-Verity ) .
  3. Agregue el certificado .X509 que contiene la clave pública al conjunto de claves del sistema:
    1. Copiar el certificado .X509 formateado en la .der formato a la raíz del kernel directorio. Si el certificado .X509 está formateado como un .pem archivo, utilice el siguiente openssl comando convertir de .pem a .der formato:
      openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
    2. Construir el zImage para incluir el certificado como parte del sistema de anillo de claves. Para verificar, comprobar el procfs entrada (requiere KEYS_CONFIG_DEBUG_PROC_KEYS esté habilitado):
      angler:/# cat /proc/keys
      
      1c8a217e I------     1 perm 1f010000     0     0 asymmetri
      Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f []
      2d454e3e I------     1 perm 1f030000     0     0 keyring
      .system_keyring: 1/4
      La inclusión exitosa del certificado .X509 indica la presencia de la clave pública en el sistema de anillo de claves (resaltar indica el ID de clave pública).
    3. Reemplazar el espacio con # y pasarlo como <public-key-id> en la línea de comandos del kernel. Por ejemplo, pasar a Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f en lugar de <public-key-id> .

Establecer variables de compilación

Los cargadores de arranque compatibles con A / B deben cumplir los siguientes criterios de variables de compilación:

Debe definir para el objetivo A / B
  • AB_OTA_UPDATER := true
  • AB_OTA_PARTITIONS := \
    boot \
    system \
    vendor
    y otras particiones actualizados a través update_engine (radio, cargador de arranque, etc.)
  • PRODUCT_PACKAGES += \
    update_engine \
    update_verifier
Para un ejemplo, consulte /device/google/marlin/+/android-7.1.0_r1/device-common.mk . Opcionalmente, puede realizar la post-instalación (pero pre-reinicio) dex2oat paso describe en Compilar .
Muy recomendado para objetivo A / B
  • Definir TARGET_NO_RECOVERY := true
  • Definir BOARD_USES_RECOVERY_AS_BOOT := true
  • No defina BOARD_RECOVERYIMAGE_PARTITION_SIZE
No se puede definir para el objetivo A / B
  • BOARD_CACHEIMAGE_PARTITION_SIZE
  • BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
Opcional para compilaciones de depuración PRODUCT_PACKAGES_DEBUG += update_engine_client

Configuración de particiones (ranuras)

Los dispositivos A / B no necesitan una partición de recuperación o una partición de caché porque Android ya no usa estas particiones. La partición de datos ahora se usa para el paquete OTA descargado y el código de imagen de recuperación está en la partición de arranque. Todas las particiones que son A / B-ed deben ser nombrados como sigue (las ranuras siempre se nombran a , b , etc.): boot_a , boot_b , system_a , system_b , vendor_a , vendor_b .

Cache

Para las actualizaciones que no son A / B, la partición de caché se utilizó para almacenar paquetes OTA descargados y para almacenar bloques temporalmente mientras se aplicaban las actualizaciones. Nunca hubo una buena manera de ajustar el tamaño de la partición de la caché: qué tan grande debía depender de las actualizaciones que deseaba aplicar. El peor de los casos sería una partición de caché del tamaño de la imagen del sistema. Con las actualizaciones A / B no hay necesidad de guardar bloques (porque siempre está escribiendo en una partición que no se usa actualmente) y con la transmisión A / B no es necesario descargar todo el paquete OTA antes de aplicarlo.

Recuperación

El disco RAM de recuperación está contenida en el boot.img archivo. Al entrar en la recuperación, el gestor de arranque no puede poner el skip_initramfs opción en la línea de comandos del kernel.

Para las actualizaciones que no son A / B, la partición de recuperación contiene el código utilizado para aplicar las actualizaciones. A actualizaciones / B son aplicados por update_engine correr la imagen del sistema bota regular en. Todavía hay un modo de recuperación que se utiliza para implementar el restablecimiento de datos de fábrica y la transferencia de paquetes de actualización (que es de donde proviene el nombre "recuperación"). El código y los datos para el modo de recuperación se almacenan en la partición de arranque normal en un disco RAM; para arrancar en la imagen del sistema, el cargador de arranque le dice al kernel que omita el disco ram (de lo contrario, el dispositivo arranca en modo de recuperación. El modo de recuperación es pequeño (y gran parte de él ya estaba en la partición de arranque), por lo que la partición de arranque no aumenta en tamaño.

Fstab

El slotselect argumento debe estar en la línea para las particiones A / B-ed. Por ejemplo:

<path-to-block-device>/vendor  /vendor  ext4  ro
wait,verify=<path-to-block-device>/metadata,slotselect

No hay una partición debe ser nombrado vendor . En lugar de ello, la partición vendor_a o vendor_b serán seleccionados y montados en el /vendor punto de montaje.

Argumentos de la ranura del kernel

El sufijo ranura actual se debe pasar ya sea a través de un nodo del árbol de dispositivo específico (DT) ( /firmware/android/slot_suffix ) o a través de la androidboot.slot_suffix línea de comandos del núcleo o argumento bootconfig.

De forma predeterminada, fastboot muestra la ranura actual en un dispositivo A / B. Si el paquete de actualización también contiene imágenes para la otra ranura no actual, fastboot también muestra esas imágenes. Las opciones disponibles incluyen:

  • --slot SLOT . Anule el comportamiento predeterminado y solicite a fastboot que actualice la ranura que se pasa como argumento.
  • --set-active [ SLOT ] . Establezca la ranura como activa. Si no se especifica ningún argumento opcional, la ranura actual se establece como activa.
  • fastboot --help . Obtenga detalles sobre los comandos.

Si el fastboot implementos del gestor de arranque, debería apoyar el comando set_active <slot> que establece la corriente de ranura activa a la ranura dada (esto también se deben borrar el indicador que no arranca de esa ranura y restablecer el número de reintentos a valores por defecto). El cargador de arranque también debe admitir las siguientes variables:

  • has-slot:<partition-base-name-without-suffix> . Devuelve "sí" si la partición dada admite ranuras, "no" en caso contrario.
  • current-slot . Devuelve el sufijo de la ranura que se iniciará a partir de la siguiente.
  • slot-count . Devuelve un número entero que representa el número de espacios disponibles. En la actualidad, dos ranuras son compatibles por lo que este valor es 2 .
  • slot-successful:<slot-suffix> . Devuelve "sí" si la ranura dada ha sido marcada como arrancando exitosamente, "no" en caso contrario.
  • slot-unbootable:<slot-suffix> . Devuelve "sí" si la ranura dada está marcada como no arrancable, "no" en caso contrario.
  • slot-retry-count . Número de reintentos restantes para intentar iniciar la ranura dada.

Para ver todas las variables, ejecutar fastboot getvar all .

Generando paquetes OTA

Las herramientas de paquetes OTA siguen los mismos comandos que los comandos para dispositivos que no son A / B. El target_files.zip archivo debe ser generado mediante la definición de las variables de construcción para el objetivo A / B. Las herramientas de paquetes OTA identifican y generan automáticamente paquetes en el formato del actualizador A / B.

Ejemplos:

  • Para generar una OTA completo:
    ./build/make/tools/releasetools/ota_from_target_files \
        dist_output/tardis-target_files.zip \
        ota_update.zip
    
  • Para generar un incremento OTA:
    ./build/make/tools/releasetools/ota_from_target_files \
        -i PREVIOUS-tardis-target_files.zip \
        dist_output/tardis-target_files.zip \
        incremental_ota_update.zip
    

Configurar particiones

El update_engine puede actualizar cualquier par de particiones A / B definidas en el mismo disco. Un par de particiones tiene un prefijo común (como system o boot ) y el sufijo por ranura (como _a ). La lista de particiones para las que el generador de carga útil define una actualización está configurado por los AB_OTA_PARTITIONS hacer variable.

Por ejemplo, si un par de particiones bootloader_a y booloader_b están incluidos ( _a y _b son los sufijos de ranura), puede actualizar estas particiones especificando los siguientes en la configuración del producto o la junta:

AB_OTA_PARTITIONS := \
  boot \
  system \
  bootloader

Todas las particiones actualizados por update_engine no deben ser modificados por el resto del sistema. Durante las actualizaciones incrementales o delta, los datos binarios de la ranura de corriente se utiliza para generar los datos en la nueva ranura. Cualquier modificación puede hacer que los datos de la nueva ranura no se verifiquen durante el proceso de actualización y, por lo tanto, la actualización no se realice.

Configurar la postinstalación

Puede configurar el paso posterior a la instalación de forma diferente para cada partición actualizada mediante un conjunto de pares clave-valor. Para ejecutar un programa ubicado en /system/usr/bin/postinst en una nueva imagen, especifique la ruta relativa a la raíz del sistema de archivos en la partición del sistema.

Por ejemplo, usr/bin/postinst es system/usr/bin/postinst (si no se utiliza un disco RAM). Además, especificar el tipo de sistema de archivos para pasar al mount(2) llamada al sistema. Añadir lo siguiente a los productos o dispositivos .mk archivos (si procede):

AB_OTA_POSTINSTALL_CONFIG += \
  RUN_POSTINSTALL_system=true \
  POSTINSTALL_PATH_system=usr/bin/postinst \
  FILESYSTEM_TYPE_system=ext4

Compilando

Por razones de seguridad, system_server no puede utilizar just-in-time (JIT) compilación. Esto significa que debe compilar por delante de los archivos de tiempo para ODEX system_server y sus dependencias como mínimo; cualquier otra cosa es opcional.

Para compilar aplicaciones en segundo plano, debe agregar lo siguiente a la configuración del dispositivo del producto (en el dispositivo device.mk del producto):

  1. Incluya los componentes nativos en la compilación para garantizar que el script de compilación y los binarios se compilen e incluyan en la imagen del sistema.
      # A/B OTA dexopt package
      PRODUCT_PACKAGES += otapreopt_script
    
  2. Conectar el script de compilación a update_engine tal que se ejecuta como un paso posterior a la instalación.
      # A/B OTA dexopt update_engine hookup
      AB_OTA_POSTINSTALL_CONFIG += \
        RUN_POSTINSTALL_system=true \
        POSTINSTALL_PATH_system=system/bin/otapreopt_script \
        FILESYSTEM_TYPE_system=ext4 \
        POSTINSTALL_OPTIONAL_system=true
    

Para obtener ayuda para la instalación de los archivos preopted en la segunda partición del sistema no utilizados, se refieren a la instalación En primer arranque de archivos DEX_PREOPT .