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 y bibliotecas del sistema que tienen código fuente disponible en el Proyecto de código abierto de Android (AOSP). Durante el funcionamiento normal, esta partición se monta como de sólo lectura; su contenido cambia solo durante una actualización OTA.
proveedor
Contiene aplicaciones y bibliotecas del sistema que no tienen código fuente disponible en el Proyecto de código abierto de Android (AOSP). Durante el funcionamiento normal, esta partición se monta como de sólo 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 utilizan este espacio con la expectativa de que los archivos puedan desaparecer en cualquier momento. Algunas instalaciones de paquetes OTA pueden provocar 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, que incluye un kernel y el binario de recuperación especial que lee un paquete y usa su contenido para actualizar las otras particiones.
miscelánea
Pequeña partición utilizada por la recuperación para guardar información sobre lo que está haciendo en caso de que el dispositivo se reinicie mientras se aplica el paquete OTA.

Vida de una actualización OTA

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

  1. El dispositivo realiza un control periódico con los servidores OTA y se le notifica la disponibilidad de una actualización, incluida la URL del paquete de actualización y una cadena de descripción para mostrársela al usuario.
  2. La actualización se descarga 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 inicio.
  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 con 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, del sistema y/o del 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 inicio 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 anteriormente se almacenó 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 actualizar).

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

Paquetes de actualización

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, recovery extrae este binario a /tmp y lo ejecuta, 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 paquete de actualización. Archivo .zip .

Un paquete de actualización puede utilizar 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 programación 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 Dentro de los paquetes OTA .

Migrar desde versiones anteriores

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

función C método C ++
inicio_recuperación_dispositivo() Dispositivo::RecoveryStart()
dispositivo_toggle_display()
dispositivo_reboot_now()
RecuperaciónUI::CheckKey()
(también RecoveryUI::IsKeyPressed())
dispositivo_handle_key() Dispositivo::HandleMenuKey()
dispositivo_realizar_acción() Dispositivo::InvokeMenuItem()
dispositivo_wipe_data() Dispositivo::WipeData()
dispositivo_ui_init() ScreenRecoveryUI::Init()

La conversión de funciones antiguas a métodos nuevos 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.