Actualizaciones del sistema no A/B

En dispositivos Android más antiguos sin particiones A/B, el espacio flash normalmente contiene las siguientes particiones:

bota
Contiene el kernel de Linux y un sistema de archivos raíz mínimo (cargado en un disco RAM). Monta el sistema y otras particiones e inicia el tiempo de ejecución ubicado en la partición del sistema.
sistema
Contiene aplicaciones del sistema y bibliotecas que tienen código fuente disponible en Android Open Source Project (AOSP). Durante el funcionamiento normal, esta partición se monta como de solo lectura; su contenido cambia solo durante una actualización OTA.
vendedor
Contiene aplicaciones y bibliotecas del sistema que no tienen código fuente disponible en Android Open Source Project (AOSP). Durante el funcionamiento normal, esta partición se monta como de solo lectura; su contenido cambia solo durante una actualización OTA.
datos del usuario
Almacena los datos guardados por las aplicaciones instaladas por el usuario, etc. Esta partición normalmente no se ve afectada por el proceso de actualización OTA.
cache
Área de retención temporal utilizada por algunas aplicaciones (el acceso a esta partición requiere permisos especiales de la aplicación) y para el almacenamiento de paquetes de actualización OTA descargados. Otros programas usan este espacio con la expectativa de que los archivos puedan desaparecer en cualquier momento. Algunas instalaciones de paquetes OTA pueden hacer que esta partición se borre por completo. El caché también contiene los registros de actualización de una actualización OTA.
recuperación
Contiene un segundo sistema Linux completo, incluido un kernel y el binario de recuperación especial que lee un paquete y usa su contenido para actualizar las otras particiones.
varios
Diminuta partición utilizada por la recuperación para ocultar información sobre lo que está haciendo en caso de que el dispositivo se reinicie mientras se aplica el paquete OTA.

Vida útil de una actualización OTA

Una actualización OTA típica contiene los siguientes pasos:

  1. El dispositivo realiza comprobaciones periódicas con los servidores OTA y recibe una notificación de la disponibilidad de una actualización, incluida la URL del paquete de actualización y una cadena de descripción para mostrar al usuario.
  2. Las descargas de actualizaciones se realizan en una caché o partición de datos y su firma criptográfica se verifica con los certificados en /system/etc/security/otacerts.zip . Se solicita al usuario que instale la actualización.
  3. El dispositivo se reinicia en modo de recuperación, en el que se inician el kernel y el sistema en la partición de recuperación en lugar del kernel en la partición de arranque.
  4. El binario de recuperación se inicia con init. Encuentra argumentos de línea de comandos en /cache/recovery/command que apuntan al paquete descargado.
  5. La recuperación verifica la firma criptográfica del paquete contra las claves públicas en /res/keys (parte del disco RAM contenido en la partición de recuperación).
  6. Los datos se extraen del paquete y se utilizan para actualizar las particiones de arranque, sistema y/o proveedor según sea necesario. Uno de los archivos nuevos que quedan en la partición del sistema contiene el contenido de la nueva partición de recuperación.
  7. El dispositivo se reinicia normalmente.
    1. La partición de arranque recién actualizada se carga, se monta y comienza a ejecutar archivos binarios en la partición del sistema recién actualizada.
    2. Como parte del inicio normal, el sistema compara el contenido de la partición de recuperación con el contenido deseado (que se almacenó previamente como un archivo en /system ). Son diferentes, por lo que la partición de recuperación se actualiza con el contenido deseado. (En arranques posteriores, la partición de recuperación ya contiene el nuevo contenido, por lo que no es necesario volver a flashear).

¡La actualización del sistema está completa! Los registros de actualización se pueden encontrar en /cache/recovery/last_log. # .

Actualizar paquetes

Un paquete de actualización es un archivo .zip que contiene el binario ejecutable META-INF/com/google/android/update-binary . Después de verificar la firma en el paquete, la recovery extrae este binario a /tmp y ejecuta el binario, pasando los siguientes argumentos:

  • Actualice el número de versión de la API binaria . Si los argumentos pasados ​​al binario de actualización cambian, este número aumenta.
  • Descriptor de archivo de la canalización de comandos . El programa de actualización puede usar esta canalización para enviar comandos al binario de recuperación, principalmente para cambios en la interfaz de usuario, como indicar el progreso al usuario.
  • Nombre de archivo del archivo .zip del paquete de actualización .

Un paquete de actualización puede usar cualquier binario vinculado estáticamente como binario de actualización. Las herramientas de construcción de paquetes OTA utilizan el programa de actualización ( bootable/recovery/updater ), que proporciona un lenguaje de secuencias de comandos simple que puede realizar muchas tareas de instalación. Puede sustituir cualquier otro binario que se ejecute en el dispositivo.

Para obtener detalles sobre el binario del actualizador, la sintaxis de edify y las funciones integradas, consulte Inside OTA Packages .

Migración desde versiones anteriores

Al migrar desde la versión Android 2.3/3.0/4.0, el cambio principal es la conversión de toda la funcionalidad específica del dispositivo de un conjunto de funciones C con nombres predefinidos a objetos C++. La siguiente tabla enumera las funciones antiguas y los métodos nuevos que tienen un propósito más o menos equivalente:

función C método C++
dispositivo_recuperación_inicio() Dispositivo::InicioRecuperación()
dispositivo_alternar_pantalla()
dispositivo_reiniciar_ahora()
RecuperaciónUI::CheckKey()
(también RecoveryUI::IsKeyPressed())
dispositivo_manejador_clave() Dispositivo::HandleMenuKey()
dispositivo_realizar_acción() Dispositivo::InvokeMenuItem()
dispositivo_borrar_datos() Dispositivo::WipeData()
dispositivo_ui_init() ScreenRecoveryUI::Init()

La conversión de funciones antiguas a nuevos métodos debería ser razonablemente sencilla. No olvide agregar la nueva función make_device() para crear y devolver una instancia de su nueva subclase de dispositivo.