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:

Configurando el kernel
Para implementar actualizaciones del sistema A / B:
- Elija la siguiente serie de parches del kernel (si es necesario):
- Si el arranque sin disco de memoria y el uso de "arranque ya que la recuperación", escoja a android-review.googlesource.com/#/c/158491/ .
- Para configurar DM-Verity sin disco RAM, escoja a android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18 .
- 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>"
<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 ) . - Agregue el certificado .X509 que contiene la clave pública al conjunto de claves del sistema:
- Copiar el certificado .X509 formateado en la
.der
formato a la raíz delkernel
directorio. Si el certificado .X509 está formateado como un.pem
archivo, utilice el siguienteopenssl
comando convertir de.pem
a.der
formato:openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
- Construir el
zImage
para incluir el certificado como parte del sistema de anillo de claves. Para verificar, comprobar elprocfs
entrada (requiereKEYS_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). - Reemplazar el espacio con
#
y pasarlo como<public-key-id>
en la línea de comandos del kernel. Por ejemplo, pasar aAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40f
en lugar de<public-key-id>
.
- Copiar el certificado .X509 formateado en la
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 |
/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 |
|
No se puede definir para el objetivo A / B |
|
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 es2
. -
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):
- 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
- 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 .