Los OEM y proveedores de SoC que quieran implementar actualizaciones del sistema A/B deben asegurarse de que su bootloader implementa la HAL de boot_control y pasa los parámetros correctos al kernel.
Implementa la HAL del control de inicio
Los bootloaders compatibles con A/B deben implementar la HAL de boot_control
en
hardware/libhardware/include/hardware/boot_control.h
Puedes probar las implementaciones
system/extras/bootctl
utilidad y
system/extras/tests/bootloader/
También debes implementar la máquina de estados que se muestra a continuación:
Cómo configurar el kernel
Para implementar actualizaciones del sistema A/B, haz lo siguiente:
-
Selecciona los siguientes parches de kernel (si es necesario):
- Si se inicia sin ramdisk y usas la opción “boot as recovery” (iniciar como recuperación), elige android-review.googlesource.com/#/c/158491/.
- Para configurar dm-verity sin ramdisk, usa cherrypick android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18.
-
Asegúrate de que los argumentos de la línea de comandos del kernel contengan los siguientes argumentos adicionales:
... donde el valorskip_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>
es el ID de la clave pública que se usa para verificarás la firma de la tabla de verity (para obtener más información, consulta dm-verity). -
Agrega el certificado .X509 que contiene la clave pública al llavero de claves del sistema:
-
Copia el certificado .X509 con formato
.der
en la raíz del archivokernel
. Si el certificado .X509 tiene el formato.pem
, usa el siguiente comandoopenssl
para convertir desde Formato.pem
a.der
:openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
-
Compila el
zImage
para incluir el certificado como parte del llavero de claves del sistema. Para verificarlo,comprueba la entradaprocfs
(requiereKEYS_CONFIG_DEBUG_PROC_KEYS
que se habilitarán): La inclusión correcta del certificado .X509 indica la presencia de la clave pública. en el llavero de claves del sistema (el punto destacado denota el ID de la clave pública)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
-
Reemplaza el espacio por
#
y pásalo como<public-key-id>
en la línea de comandos del kernel. Por ejemplo, pasaAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40f
en lugar de<public-key-id>
-
Copia el certificado .X509 con formato
Cómo establecer variables de compilación
Los bootloaders compatibles con A/B deben cumplir con los siguientes criterios de variables de compilación:
Se debe definir para el objetivo A/B. |
/device/google/marlin/+/android-7.1.0_r1/device-common.mk De manera opcional, puedes realizar el paso de dex2oat posterior a la instalación (pero antes del reinicio) que se describe en
Compilación.
|
---|---|
Muy recomendado para objetivos A/B |
|
No se puede definir para la orientación A/B |
|
Opcional para las compilaciones de depuración | PRODUCT_PACKAGES_DEBUG += update_engine_client |
Cómo configurar particiones (ranuras)
Los dispositivos A/B no necesitan una partición de recuperación ni una partición de caché porque Android ya no usa
estas particiones. La partición de datos ahora se usa para el paquete inalámbrico descargado, y la
el código de imagen de recuperación
está en la partición de inicio. Todas las particiones que sean A/B-ed deben tener un nombre
de la siguiente manera (las ranuras siempre se denominan a
, b
, etc.): boot_a
,
boot_b
, system_a
, system_b
y vendor_a
,
vendor_b
Caché
En el caso de las actualizaciones que no son A/B, la partición de caché se utilizó para almacenar los paquetes inalámbricos descargados y para bloquear temporalmente los bloqueos durante la aplicación de actualizaciones Nunca hubo un buen tamaño de la caché partición: el tamaño necesario para depender de las actualizaciones que deseaba aplicar. Lo peor sería una partición de caché del tamaño de la imagen del sistema. Con las actualizaciones A/B, no es necesario para almacenar bloques (porque siempre escribes en una partición que no está en uso) y con la transmisión A/B, no es necesario descargar todo el paquete inalámbrico antes de aplicarlo.
Recuperación
El disco RAM de recuperación ahora se encuentra en el archivo boot.img
. Al entrar en
la recuperación, el bootloader no puede colocar la opción skip_initramfs
en
la línea de comandos del kernel.
En el caso de las actualizaciones que no son A/B, la partición de recuperación contiene el código que se usa para aplicar las actualizaciones. A/B
update_engine
aplica las actualizaciones que se ejecutan en la imagen del sistema iniciada normal.
Aún se usa un modo de recuperación para implementar el restablecimiento de la configuración de fábrica y la transferencia de actualizaciones
paquetes (de donde provino el nombre "recuperación"). El código y los datos del Modo de recuperación [Recovery mode]
se almacena en la partición de inicio normal en un disco RAM; para iniciar en la imagen del sistema,
El bootloader le indica al kernel que omita el ramdisk (de lo contrario, el dispositivo se iniciará en el modo de recuperación).
. El modo de recuperación es pequeño (y gran parte ya estaba en la partición de inicio), por lo que
no aumenta de tamaño.
fstab
El argumento slotselect
debe estar en la línea de la dirección A/B.
y particiones. Por ejemplo:
<path-to-block-device>/vendor /vendor ext4 ro wait,verify=<path-to-block-device>/metadata,slotselect
Ninguna partición debe llamarse vendor
. En su lugar, particiona vendor_a
o
Se seleccionará vendor_b
y se activará en el punto de activación /vendor
.
Argumentos de la ranura del kernel
El sufijo de ranura actual debe pasarse por un nodo del árbol de dispositivos (DT) específico
(/firmware/android/slot_suffix
) o a través de la
Línea de comandos del kernel de androidboot.slot_suffix
o argumento bootconfig.
De forma predeterminada, fastboot escribe en la memoria flash de la ranura actual de un dispositivo A/B. Si el paquete de actualización también contiene imágenes para la otra ranura no actual, fastboot también instala esas imágenes. Entre las opciones disponibles, se incluyen las siguientes:
-
--slot SLOT
. Anula el comportamiento predeterminado y solicita a fastboot que escriba en la memoria flash la ranura que se pasa como un argumento. -
--set-active [SLOT]
. Configura el horario disponible como activo. Si no hay un argumento opcional se especifica, la ranura actual se establece como activa. fastboot --help
Obtén información detallada sobre los comandos.
Si el bootloader implementa fastboot, debería admitir el comando.
set_active <slot>
, que establece el espacio activo actual en el espacio determinado (este
También debes borrar la marca de que no se puede iniciar para esa ranura y restablecer el recuento de reintentos a la configuración predeterminada.
de salida). El bootloader también debe admitir las siguientes variables:
-
has-slot:<partition-base-name-without-suffix>
. Devuelve “sí” si el valor especificado partición admite ranuras; de lo contrario, “no”. current-slot
Muestra el sufijo de la ranura que se iniciará a partir del siguiente elemento.-
slot-count
. Muestra un número entero que representa la cantidad de ranuras disponibles. Actualmente, se admiten dos ranuras, por lo que este valor es2
. -
slot-successful:<slot-suffix>
. Muestra "yes". si el espacio proporcionado se ha marcado como iniciado correctamente, "no" de lo contrario. -
slot-unbootable:<slot-suffix>
. Devuelve "yes" si el espacio proporcionado está marcado como imposible de arrancar, "no" de lo contrario. -
slot-retry-count:<slot-suffix>
. Cantidad de reintentos restantes para intentar iniciar la ranura en cuestión.
Para ver todas las variables, ejecuta
fastboot getvar all
Cómo generar paquetes inalámbricos
Las herramientas de paquetes inalámbricos siguen los mismos comandos que
para dispositivos que no son A/B. El archivo target_files.zip
debe generarse
definir las variables de compilación para el destino A/B. Las herramientas de paquetes OTA identifican automáticamente
y generar paquetes en el formato para el actualizador A/B.
Ejemplos:
-
Para generar una OTA completa:
./build/make/tools/releasetools/ota_from_target_files \ dist_output/tardis-target_files.zip \ ota_update.zip
-
Para generar una actualización inalámbrica incremental, haz lo siguiente:
./build/make/tools/releasetools/ota_from_target_files \ -i PREVIOUS-tardis-target_files.zip \ dist_output/tardis-target_files.zip \ incremental_ota_update.zip
Configura particiones
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 cuales
generator define que una actualización se configura mediante la variable make AB_OTA_PARTITIONS
.
Por ejemplo, si un par de particiones bootloader_a
y
Se incluyen booloader_b
(_a
y _b
son el espacio
sufijos), puedes actualizar estas particiones especificando lo siguiente en el producto o la placa
actual:
AB_OTA_PARTITIONS := \ boot \ system \ bootloader
El resto de las particiones no deben modificar las particiones actualizadas por update_engine
en un sistema de archivos. Durante las actualizaciones incrementales o delta, los datos binarios de la ranura actual se
que se usa para generar los datos en la nueva ranura. Cualquier modificación puede hacer que los nuevos datos de la ranura
falla la verificación durante el proceso de actualización y, por lo tanto, falla la actualización.
Configurar posterior a la instalación
Puedes configurar el paso posterior a la instalación de manera diferente para cada partición actualizada con un conjunto de
pares clave-valor. Para ejecutar un programa ubicado en /system/usr/bin/postinst
en una nueva zona
especifica la ruta de acceso relacionada con 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 es así)
con un disco RAM). Además, especifica el tipo de sistema de archivos que se pasará al
Llamada del sistema mount(2)
. Agregue la siguiente información al producto o dispositivo
Archivos .mk
(si corresponde):
AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=usr/bin/postinst \ FILESYSTEM_TYPE_system=ext4
Compilar apps
Las apps se pueden compilar en segundo plano antes del reinicio con la nueva imagen del sistema. Para compilar apps en segundo plano, agrega lo siguiente a la configuración del dispositivo del producto (en el device.mk del producto):
-
Incluye los componentes nativos en la compilación para garantizar que la secuencia de comandos y los objetos binarios de la compilación se
compilarse y, luego, incluirse en la imagen del sistema.
# A/B OTA dexopt package PRODUCT_PACKAGES += otapreopt_script
-
Conecta la secuencia de comandos de compilación a
update_engine
de modo que se ejecute 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
Si necesitas ayuda para instalar los archivos preoptados en la segunda partición del sistema sin usar, consulta Primera instalación de inicio de archivos DEX_PREOPT.