OEM et les fournisseurs SoC qui veulent mettre en œuvre les mises à jour du système A / B doivent assurer leur bootloader met en œuvre la boot_control HAL et transmet les paramètres corrects au niveau du noyau.
Implémentation du contrôle de démarrage HAL
A / B bootloader capable doit mettre en œuvre la boot_control
HAL au hardware/libhardware/include/hardware/boot_control.h
. Vous pouvez tester les implémentations utilisant le system/extras/bootctl
utilitaire et system/extras/tests/bootloader/
.
Vous devez également implémenter la machine à états ci-dessous :

Configuration du noyau
Pour mettre en œuvre les mises à jour du système A/B :
- Choisissez la série de correctifs du noyau suivante (si nécessaire) :
- Si le démarrage sans disque virtuel et en utilisant « boot comme la récupération », cherrypick android-review.googlesource.com/#/c/158491/ .
- Pour mettre en place dm-Verity sans disque virtuel, cherrypick android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18 .
- Assurez -vous des arguments de ligne de commande du noyau contiennent les arguments supplémentaires suivants:
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>
valeur est l'ID de la clé publique utilisée pour vérifier la signature de la table de Verity (pour plus de détails, voir dm-Verity ) . - Ajoutez le certificat .X509 contenant la clé publique au trousseau de clés système :
- Copiez le certificat .X509 formaté dans le
.der
format à la racine dukernel
répertoire. Si le certificat est .X509 formaté comme.pem
fichier, utilisez ce qui suitopenssl
commande pour convertir de.pem
à.der
Format:openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
- Construire le
zImage
pour inclure le certificat dans le cadre du système de porte - clé. Pour vérifier, vérifier l'procfs
entrée (nécessiteKEYS_CONFIG_DEBUG_PROC_KEYS
être activé):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
inclusion réussie du certificat .X509 indique la présence de la clé publique dans le trousseau de clés du système (point culminant indique l'ID de clé publique). - Remplacer l'espace avec
#
et le transmettre comme<public-key-id>
dans la ligne de commande du noyau. Par exemple, passerAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40f
à la place de<public-key-id>
.
- Copiez le certificat .X509 formaté dans le
Définition des variables de construction
Les chargeurs de démarrage compatibles A/B doivent répondre aux critères de variable de construction suivants :
Doit être défini pour la cible A/B |
/device/google/marlin/+/android-7.1.0_r1/device-common.mk . Vous pouvez éventuellement effectuer la post-installation (mais pré-redémarrage) dex2oat étape décrite dans Compiling . |
---|---|
Fortement recommandé pour la cible A/B |
|
Impossible de définir pour la cible A/B |
|
Facultatif pour les versions de débogage | PRODUCT_PACKAGES_DEBUG += update_engine_client |
Paramétrage des partitions (emplacements)
Les appareils A/B n'ont pas besoin de partition de récupération ou de partition de cache, car Android n'utilise plus ces partitions. La partition de données est maintenant utilisée pour le package OTA téléchargé et le code de l'image de récupération se trouve sur la partition de démarrage. Toutes les partitions qui sont A / B-ed devraient être nommés comme suit (slots sont toujours nommés a
, b
, etc.): boot_a
, boot_b
, system_a
, system_b
, vendor_a
, vendor_b
.
Cacher
Pour les mises à jour non A/B, la partition de cache était utilisée pour stocker les packages OTA téléchargés et pour stocker temporairement les blocs lors de l'application des mises à jour. Il n'y a jamais eu de bonne façon de dimensionner la partition de cache : sa taille dépendait des mises à jour que vous vouliez appliquer. Le pire des cas serait une partition de cache aussi grande que l'image système. Avec les mises à jour A/B, il n'est pas nécessaire de stocker des blocs (car vous écrivez toujours sur une partition qui n'est pas actuellement utilisée) et avec le streaming A/B, il n'est pas nécessaire de télécharger l'intégralité du package OTA avant de l'appliquer.
Récupération
Le disque RAM de récupération est maintenant contenue dans le boot.img
fichier. Lorsque vous allez dans la récupération, le bootloader ne peut pas mettre la skip_initramfs
option sur la ligne de commande du noyau.
Pour les mises à jour non A/B, la partition de récupération contient le code utilisé pour appliquer les mises à jour. A mises à jour / B sont appliquées par update_engine
en cours d' exécution dans l'image régulière du système botté. Il existe toujours un mode de récupération utilisé pour implémenter la réinitialisation des données d'usine et le chargement latéral des packages de mise à jour (d'où vient le nom "récupération"). Le code et les données du mode de récupération sont stockés dans la partition de démarrage normale d'un disque virtuel ; pour démarrer dans l'image système, le chargeur de démarrage dit au noyau d'ignorer le disque virtuel (sinon le périphérique démarre en mode de récupération. Le mode de récupération est petit (et une grande partie était déjà sur la partition de démarrage), donc la partition de démarrage n'augmente pas en taille.
Fstab
Le slotselect
argument doit être sur la ligne pour les partitions-ed B A /. Par exemple:
<path-to-block-device>/vendor /vendor ext4 ro wait,verify=<path-to-block-device>/metadata,slotselect
Aucune partition doit être nommé vendor
. Au lieu de cela, la partition vendor_a
ou vendor_b
seront sélectionnés et montés sur le /vendor
point de montage.
Arguments d'emplacement de noyau
Le suffixe emplacement actuel doit être passé soit par un noeud (arbre de dispositif spécifique (DT) /firmware/android/slot_suffix
) ou par la androidboot.slot_suffix
ligne de commande ou noyau argument bootconfig.
Par défaut, fastboot fait clignoter l'emplacement actuel sur un périphérique A/B. Si le package de mise à jour contient également des images pour l'autre emplacement non actuel, fastboot fait également clignoter ces images. Les options disponibles incluent :
-
--slot SLOT
. Remplacez le comportement par défaut et invitez fastboot à flasher l'emplacement qui est transmis en tant qu'argument. -
--set-active [ SLOT ]
. Définissez l'emplacement comme actif. Si aucun argument facultatif n'est spécifié, le slot actuel est défini comme actif. -
fastboot --help
. Obtenez des détails sur les commandes.
Si le bootloader met en œuvre fastboot, il devrait soutenir la commande set_active <slot>
qui définit la fente active en cours à la fente donnée (cela doit également effacer le drapeau pour cet emplacement amorçable et réinitialiser le nombre de nouvelles tentatives de valeurs par défaut). Le chargeur de démarrage doit également prendre en charge les variables suivantes :
-
has-slot:<partition-base-name-without-suffix>
. Renvoie « oui » si la partition donnée prend en charge les emplacements, « non » sinon. -
current-slot
. Renvoie le suffixe d'emplacement qui sera démarré à partir du prochain. -
slot-count
. Renvoie un entier représentant le nombre d'emplacements disponibles. À l' heure actuelle, deux emplacements sont pris en charge si cette valeur est2
. -
slot-successful:<slot-suffix>
. Renvoie « oui » si l'emplacement donné a été marqué comme un démarrage réussi, « non » dans le cas contraire. -
slot-unbootable:<slot-suffix>
. Renvoie « oui » si l'emplacement donné est marqué comme non amorçable, « non » sinon. -
slot-retry-count
. Nombre de tentatives restantes pour tenter de démarrer l'emplacement donné.
Pour voir toutes les variables, exécutez fastboot getvar all
.
Générer des packages OTA
Les outils de paquets OTA suivent les mêmes commandes que les commandes pour les dispositifs non-A / B. Le target_files.zip
fichier doit être généré en définissant les variables de construction pour la cible A / B. Les outils de package OTA identifient et génèrent automatiquement des packages au format du programme de mise à jour A/B.
Exemples:
- Pour générer un plein OTA:
./build/make/tools/releasetools/ota_from_target_files \ dist_output/tardis-target_files.zip \ ota_update.zip
- Pour générer un différentiel 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
Configuration des partitions
Le update_engine
peut mettre à jour une paire quelconque de partitions A / B définies dans le même disque. Une paire de partitions a un préfixe commun (tel que le system
ou boot
) et le suffixe par emplacement (comme _a
). La liste des partitions pour lequel le générateur de charge utile définit une mise à jour est configuré par le AB_OTA_PARTITIONS
faire variable.
Par exemple, si une paire de partitions bootloader_a
et booloader_b
sont inclus ( _a
et _b
sont les suffixes à sous), vous pouvez mettre à jour ces partitions en spécifiant ce qui suit sur la configuration du produit ou du conseil:
AB_OTA_PARTITIONS := \ boot \ system \ bootloader
Toutes les partitions mises à jour par update_engine
ne doivent pas être modifiés par le reste du système. Au cours de mises à jour incrémentielles ou delta, les données binaires de l'emplacement actuel est utilisé pour générer les données dans le nouvel emplacement. Toute modification peut entraîner l'échec de la vérification des nouvelles données d'emplacement pendant le processus de mise à jour, et donc l'échec de la mise à jour.
Configuration de la post-installation
Vous pouvez configurer l'étape de post-installation différemment pour chaque partition mise à jour à l'aide d'un ensemble de paires clé-valeur. Pour exécuter un programme situé à /system/usr/bin/postinst
dans une nouvelle image, le chemin relatif à la racine du système de fichiers dans la partition système.
Par exemple, usr/bin/postinst
est system/usr/bin/postinst
(sinon l' aide d' un disque RAM). En outre, de spécifier le type de système de fichiers pour passer à la mount(2)
appel système. Ajouter ce qui suit au produit ou dispositif .mk
fichiers ( le cas échéant):
AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=usr/bin/postinst \ FILESYSTEM_TYPE_system=ext4
Compilation
Pour des raisons de sécurité, system_server
ne peut pas utiliser juste à temps (JIT) compilation. Cela signifie que vous devez compiler en avance sur les fichiers de temps pour system_server
et ses dépendances au minimum; tout le reste est facultatif.
Pour compiler des applications en arrière-plan, vous devez ajouter les éléments suivants à la configuration de l'appareil du produit (dans le fichier device.mk du produit) :
- Incluez les composants natifs dans la construction pour vous assurer que le script de compilation et les binaires sont compilés et inclus dans l'image système.
# A/B OTA dexopt package PRODUCT_PACKAGES += otapreopt_script
- Connectez le script de compilation à
update_engine
telle que fonctionne comme une étape de post-installation.# 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
Pour savoir comment installer les fichiers preopted dans la deuxième partition du système utilisé, reportez - vous à l' installation du premier démarrage de fichiers DEX_PREOPT .