Mises à jour A / B fluides dans Android: comment elles fonctionnent

image



Bonjour. Chez SberDevices, notre équipe est engagée dans le développement de divers matériels et micrologiciels pour eux basés sur AOSP.



À partir d'Android 8 (certains fournisseurs de la version 7.1), le système dispose d'un nouveau mécanisme de mise à jour OTA, le soi-disant. Mises à jour transparentes A / B OTA - mises à jour transparentes. Dans cet article, je décrirai les principes généraux de son fonctionnement, examinerai le mécanisme du point de vue du développeur et le comparerai également avec l'ancienne approche (nous l'appellerons basée sur la récupération) pour appliquer les mises à jour. Tout ce qui suit ne sera vrai que pour l'AOSP pur, puisque l'implémentation spécifique dépend du fournisseur.



OTA basé sur la récupération



Les mises à jour pour Android sont fournies sous la forme d'une archive zip avec des mises à jour basées sur des blocs. À l'époque de KitKat, il s'agissait simplement d'un ensemble de fichiers copiés sur l'appareil par le script inclus. Je ne m'attarderai pas sur ce mode en détail, je décrirai brièvement les principes de base de son fonctionnement:



  • l'archive zip est téléchargée par le système sur l'appareil;
  • le système redémarre en mode de récupération ;
  • vérifier la compatibilité de la mise à jour avec l'appareil, sa signature;
  • si tout va bien, le script de mise à jour de l'archive zip est exécuté ;
  • lors de la mise à jour, l'appareil peut redémarrer plusieurs fois (par exemple, pour mettre à jour l' arborescence des appareils );
  • si tout s'est bien passé, lancez le nouveau firmware.


Quels sont les inconvénients de ce schéma?



  • La nécessité de réserver une quantité suffisante de mémoire interne pour l'archive OTA. La section / cache est utilisée pour cela . Certains fournisseurs utilisent / data , mais c'est rare. En conséquence, l'utilisateur se retrouve avec moins d'espace (oui, les applications peuvent toujours utiliser de l'espace dans la partition / cache , mais avec certaines restrictions).
  • Le redémarrage et l'application de la mise à jour prennent du temps, ce qui peut être critique pour certains types d'appareils, par exemple pour les téléviseurs intelligents.
  • L'interruption du processus de mise à jour peut entraîner une boucle de démarrage .
  • Il n'y a aucun moyen de revenir à l'ancienne version du micrologiciel.


Cet inconvénient vous permet de contourner la méthode de mise à niveau transparente. Voyons voir comment ça fonctionne.



OTA A / B sans couture



Composants et mécanismes clés nécessaires pour mettre en œuvre des mises à jour A / B transparentes :



  • balisage de l'emplacement de la mémoire flash; 
  • interaction avec le chargeur, gestion de l'état des slots ;
  • démon système update_engine ;
  • générer une archive zip avec une mise à jour. Cet aspect ne sera pas pris en compte dans cet article.


Machines à sous



Le principe de base de A / B OTA est le  crénage . Toutes les partitions qui doivent être mises à jour (il peut s'agir de n'importe quelle partition, pas seulement de partition système) doivent être en deux copies ou, sinon, dans des emplacements. La mise en oeuvre prend en charge les applications 2 emplacements, qui sont nommées A et B, respectivement . Le système démarre et fonctionne à partir de l'emplacement actuel, le second n'est utilisé qu'au moment de la mise à jour. Un suffixe avec le nom de l'emplacement est ajouté au nom de la section.



Vous trouverez ci-dessous un tableau comparant les deux options d'organisation des partitions sur un périphérique. Toutes les partitions à fente sont marquées avec l'option de montage  slotselect afin que le système puisse sélectionner le bon logement. Selon l'endroit où ils sont décrits, cela pourrait être fstab

image



ou dts .



Modifications de la table de partition



  • Le cache B / n'est plus nécessaire. Maintenant, la mise à jour peut être enregistrée soit dans / data , soit immédiatement flashée dans un emplacement inactif (plus d'informations ci-dessous). 
  • La section de récupération n'est également plus utilisée. Cependant,  le mode de  récupération  existe toujours, il est nécessaire, par exemple, de réinitialiser l'appareil aux paramètres d'usine (cela peut conduire à une équipe de  secours ). Ou pour le soi-disant. mise à jour manuelle ( sideload ) via adbLe disque de récupération est  maintenant à l'intérieur de la  partition de démarrage , le noyau est partagé.
  • (android/recovery) cmdline ‑ skip_initramfs.


À première vue, il semble qu'un tel schéma ne soit pas optimal, car il est nécessaire d'allouer deux fois plus d'espace au système. Mais nous nous sommes débarrassés de  / cache , ce qui signifie que nous avons déjà économisé beaucoup de mémoire. Ainsi, le système prendra un peu plus que l'option de récupération .



Le principal avantage des mises à jour A / B est la possibilité de  diffuser le firmware. C'est elle qui assure des mises à jour fluides et transparentes pour l'utilisateur: pour mettre à jour l'appareil, il suffit de redémarrer dans un nouveau slot. Dans ce mode, il n'est pas nécessaire de télécharger l'archive zip à l'avance, occupant de l'espace dans / data . Au lieu de cela, le système écrit immédiatement des blocs de données à partir d'un fichier spécialement préparé ( payload, voir ci-dessous) dans chaque section d'un emplacement inactif. Du point de vue de la mise en œuvre, cela ne fait aucune différence que nous téléchargions la mise à jour à l'avance ou que nous la diffusions immédiatement sur l'emplacement.



Les emplacements ont les états suivants:



  • actif - emplacement actif, le système en sera chargé au prochain redémarrage;
  • amorçable - la mise à jour a été flashée avec succès dans l'emplacement, a été validée, les sommes de hachage correspondent, etc.
  • réussi - le système a pu démarrer avec succès dans le nouvel emplacement;
  • non amorçable - l'emplacement est endommagé. Le système marque toujours l'emplacement comme non amorçable avant de démarrer le processus de mise à niveau.


Les deux emplacements peuvent être  amorçables  et  réussis , mais un seul est actif .



L'algorithme du bootloader lors du choix d'un slot:

image

  • Le chargeur de démarrage détecte qu'il existe un ou plusieurs  emplacements de démarrage .
  • L'emplacement actif (ou l'emplacement avec la priorité la plus élevée) est sélectionné parmi eux.
  • Si le système démarre correctement, l'emplacement est marqué comme  réussi  et  actif .
  • Sinon, l'emplacement est marqué comme non amorçable et le système redémarre.




Modification des états des logements pendant la mise à jour:

image



Prérequis pour Seamless A / B.



boot_control



Pour prendre en charge les mises à jour A / B, le fournisseur doit implémenter une interface HAL spéciale - boot_control . Il vous permet de changer les états des slots et d'obtenir des informations à leur sujet. Pour le travail externe (par exemple, via adb shell ), l'utilitaire est utilisé - bootctl . L'interface est utilisée comme moyen de communication entre le système d'exploitation et le chargeur de démarrage.



update_engine



Le composant principal de l' ensemble du circuit A / B. Gère le téléchargement, la diffusion en continu des mises à jour, la vérification des signatures, etc. Modifie les états des emplacements via boot_control . Vous permet de contrôler le processus de mise à jour de l'appareil: pause, reprise, annulation.

Le composant est arrivé à Android à partir de ChromeOS, où il est utilisé depuis un certain temps. AOSP maintient update_engine en tant qu'assemblage statique de chargement latéral . C'est ce qui est utilisé dans la récupération , car ce mode ne prend pas en charge la liaison dynamique.



Le processus de ce composant peut être divisé en les étapes suivantes:



  • chargement de la mise à jour dans l'emplacement. Vous pouvez télécharger les deux à partir d'un package précédemment téléchargé avec une mise à jour, ou directement sur Internet via http / https. Lors du téléchargement, la signature est vérifiée, la clé publique est déjà sur l'appareil (/system/etc/update_engine/update-payload-key.pub.pem);
  • vérification de la mise à jour téléchargée et comparaison des sommes de hachage;
  • exécution de scripts post-installation


Structure du Service Pack:



2009-01-01 00:00:00 .....          360          360  META-INF/com/android/metadata
2009-01-01 00:00:00 .....          107          107  care_map.txt
2009-01-01 00:00:00 .....    384690699    384690699  payload.bin
2009-01-01 00:00:00 .....          154          154  payload_properties.txt
2009-01-01 00:00:00 .....         1675          943  META-INF/com/android/otacert


  • care_map.txt - utilisé par update_verifier (voir ci-dessous);
  • payload_properties.txt - contient des hachages et des tailles de données dans la charge utile ;
  • payload.bin - package de mise à jour, contient des blocs de toutes les sections, métadonnées , signature.


update_engine_client



Client de gestion du démon update_engine . Peut être appelé directement par le fournisseur pour appliquer la mise à jour.



update_verifier



Utilitaire pour vérifier l'intégrité du système au premier démarrage (emplacement avec le drapeau  actif , mais pas encore  réussi ). Le contrôle d'intégrité est implémenté à l'aide du module noyau dm-verity . Si la vérification réussit, l'utilitaire marque l'emplacement actuel comme  réussi . Sinon, le système redémarrera dans l'ancien emplacement. Seuls les blocs spécifiés dans le fichier care_map.txt sont vérifiés .



UpdateEngineApi



Il existe une API Java pour la mise en œuvre des services de mise à jour des fournisseurs . Il existe également un exemple d' une telle implémentation de service.



Regardons un exemple de mise à jour A / B dans AOSP. Pour ce faire, éditez le Makefile de la plateforme cible:



#  A/B
AB_OTA_UPDATER := true
#    :
AB_OTA_PARTITIONS := boot system vendor
#  
PRODUCT_PACKAGES := update_engine update_engine_client update_verifier
#  recovery
TARGET_NO_RECOVERY := true
#,       cache:
#BOARD_CACHEIMAGE_PARTITION_SIZE := ...
#BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ...


Après avoir appelé make otapackage, nous obtenons une archive zip avec la mise à jour. Sous cette forme, il est déjà adapté au mode sideload . Nous pouvons redémarrer dans la récupération et appeler adb sideload ota.zip . Cette méthode est pratique pour le débogage.



L'application d'une mise à jour à partir d'un système de production est généralement spécifique au fournisseur. Le moyen le plus simple est de télécharger payload.bin sur un serveur http et d'appeler directement update_engine_client .



Exemple d'appel:



update_engine_client \
--payload=http://path/to/payload.bin \
--update \
--headers=" \
FILE_HASH=ozGgyQEddkI5Zax+Wbjo6I/PCR8PEZka9gGd0nWa+oY= \
FILE_SIZE=282344983 \
METADATA_HASH=GLIKfE6KRwylWMHsNadG/Q8iy5f786WTatvMdBlpOPg= \
METADATA_SIZE=26723"


Le contenu du fichier payload_properties.txt est passé au paramètre headers . Dans logcat, vous pouvez voir la progression de la mise à jour. Si vous passez le commutateur --follow , la progression sera dupliquée dans stdout .



Conclusion



Les avantages du nouveau mécanisme de mise à jour sont évidents:



  • la mise à jour du système s'effectue en arrière-plan sans interrompre le travail de l'utilisateur. Oui, vous aurez toujours besoin d'un redémarrage (vers un nouvel emplacement), mais ce sera  beaucoup  plus rapide que le redémarrage en cours de récupération pour appliquer la mise à jour;
  • la probabilité d'une boucle de démarrage est minimisée (personne n'est à l'abri des erreurs de mise en œuvre). Le processus de mise à jour peut être interrompu, cela n'affectera en aucun cas le slot actif;
  • il devient possible de revenir à la version précédente du micrologiciel. Même si pour une raison quelconque la mise à jour a échoué, le système retournera simplement à l'ancienne version;
  • grâce au streaming, l'appareil se mettra à jour plus rapidement;
  • selon l'implémentation, vous pouvez exclure complètement l'utilisateur du processus de mise à jour.


Parmi les inconvénients, je soulignerais deux points:



  • A / B OTA devient dépendant de la disposition actuelle du disque, car la mise à jour se produit pendant que le système est en cours d'exécution. Autrement dit, il devient impossible de lancer la mise à jour avec les partitions modifiées;
  • la complexité relative de la mise en œuvre.


Et pourtant, à mon avis, les avantages l'emportent. À propos, dans notre appareil récemment annoncé , nous utilisons des mises à jour A / B OTA.



All Articles