Pour implémenter un A/B virtuel sur un nouvel appareil ou pour moderniser un appareil lancé, vous devez apporter des modifications au code spécifique à l'appareil.
Construire des drapeaux
Les appareils qui utilisent A/B virtuel doivent être configurés en tant qu'appareils A/B et doivent être lancés avec des partitions dynamiques .
Pour les appareils lancés avec A/B virtuel, configurez-les pour qu'ils héritent de la configuration de base de l'appareil A/B virtuel :
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)
Les appareils lancés avec A/B virtuel n'ont besoin que de la moitié de la taille de la carte pour BOARD_SUPER_PARTITION_SIZE
car les emplacements B ne sont plus en super. Autrement dit, BOARD_SUPER_PARTITION_SIZE
doit être supérieur ou égal à sum(size of update groups) + overhead , qui, à son tour, doit être supérieur ou égal à sum(size of partitions) + overhead .
Pour Android 13 et versions ultérieures, pour activer les instantanés compressés avec Virtual A/B, héritez de la configuration de base suivante :
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/android_t_baseline.mk)
Cela permet des instantanés de l'espace utilisateur avec Virtual A/B tout en utilisant une méthode de compression sans opération. Vous pouvez ensuite configurer la méthode de compression sur l'une des méthodes prises en charge, gz
et brotli
.
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := gz
Pour Android 12, pour activer les instantanés compressés avec Virtual A/B, héritez de la configuration de base suivante :
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)
Compression XOR
Pour les appareils mis à niveau vers Android 13 et versions ultérieures, la fonction de compression XOR n'est pas activée par défaut. Pour activer la compression XOR, ajoutez ce qui suit au fichier .mk
du périphérique.
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
La compression XOR est activée par défaut pour les appareils qui héritent de android_t_baseline.mk
.
Fusion de l'espace utilisateur
Pour les appareils mis à niveau vers Android 13 et versions ultérieures, le processus de fusion de l'espace utilisateur tel que décrit dans la superposition Device-mapper n'est pas activé par défaut. Pour activer la fusion de l'espace utilisateur, ajoutez la ligne suivante au fichier .mk
de l'appareil :
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
La fusion de l'espace utilisateur est activée par défaut sur les appareils lancés avec 13 et versions ultérieures.
Contrôle de démarrage HAL
Le contrôle de démarrage HAL fournit une interface permettant aux clients OTA de contrôler les emplacements de démarrage. Virtual A/B nécessite une mise à niveau de version mineure de la HAL de contrôle de démarrage car des API supplémentaires sont nécessaires pour garantir que le chargeur de démarrage est protégé pendant le clignotement/la réinitialisation d'usine. Voir IBootControl.hal et types.hal pour la dernière version de la définition HAL.
// hardware/interfaces/boot/1.1/types.hal
enum MergeStatus : uint8_t {
NONE, UNKNOWN, SNAPSHOTTED, MERGING, CANCELLED };
// hardware/interfaces/boot/1.1/IBootControl.hal
package android.hardware.boot@1.1;
interface IBootControl extends @1.0::IBootControl {
setSnapshotMergeStatus(MergeStatus status)
generates (bool success);
getSnapshotMergeStatus()
generates (MergeStatus status);
}
// Recommended implementation
Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus v) {
// Write value to persistent storage
// e.g. misc partition (using libbootloader_message)
// bootloader rejects wipe when status is SNAPSHOTTED
// or MERGING
}
Changements Fstab
L'intégrité de la partition de métadonnées est essentielle au processus de démarrage, en particulier juste après l'application d'une mise à jour OTA. Ainsi, la partition de métadonnées doit être vérifiée avant que first_stage_init
ne la monte. Pour vous en assurer, ajoutez l'indicateur check
fs_mgr à l'entrée pour /metadata
. Ce qui suit en donne un exemple :
/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check
Exigences du noyau
Pour activer la création d'instantanés, définissez CONFIG_DM_SNAPSHOT
sur true
.
Pour les appareils utilisant F2FS, incluez l' indicateur f2fs: export FS_NOCOW_FL vers le correctif du noyau utilisateur pour corriger l'épinglage de fichiers. Incluez le f2fs : prend également en charge le correctif de noyau de fichier épinglé aligné .
Virtual A/B s'appuie sur des fonctionnalités ajoutées dans la version 4.3 du noyau : le bit d'état de débordement dans les cibles d' snapshot
et snapshot-merge
. Tous les appareils lancés avec Android 9 et versions ultérieures doivent déjà disposer de la version 4.4 ou ultérieure du noyau.
Pour activer les instantanés compressés, la version minimale du noyau prise en charge est 4.19. Définissez CONFIG_DM_USER=m
ou CONFIG_DM_USER=y
. Si vous utilisez le premier (un module), le module doit être chargé dans le disque virtuel du premier étage. Ceci peut être réalisé en ajoutant la ligne suivante au Makefile de l'appareil :
BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko
Mise à niveau sur les appareils passant à Android 11
Lors de la mise à niveau vers Android 11, les appareils lancés avec des partitions dynamiques peuvent éventuellement moderniser A/B virtuel. Le processus de mise à jour est essentiellement le même que pour les appareils lancés avec A/B virtuel, avec quelques différences mineures :
Emplacement des fichiers COW — Pour les périphériques de lancement, le client OTA utilise tout l'espace vide disponible dans la super partition avant d'utiliser l'espace dans
/data
. Pour les appareils modernisés, il y a toujours suffisamment d'espace dans la super partition pour que le fichier COW ne soit jamais créé sur/data
.Indicateurs de fonctionnalité au moment de la construction — Pour les appareils modernisant A/B virtuel,
PRODUCT_VIRTUAL_AB_OTA
etPRODUCT_VIRTUAL_AB_OTA_RETROFIT
sont définis surtrue
, comme indiqué ci-dessous :(call inherit-product, \
(SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
Taille de la super partition — Les périphériques lancés avec A/B virtuel peuvent réduire de moitié
BOARD_SUPER_PARTITION_SIZE
car les emplacements B ne se trouvent pas dans la super partition. Les appareils modernisant A/B virtuel conservent l'ancienne taille de super partition, doncBOARD_SUPER_PARTITION_SIZE
est supérieur ou égal à 2 * sum(taille des groupes de mise à jour) + surcharge , qui à son tour est supérieure ou égale à 2 * sum(taille des partitions) + frais généraux .
Modifications du chargeur de démarrage
Lors de l'étape de fusion d'une mise à jour, /data
contient la seule instance complète du système d'exploitation Android. Une fois la migration démarrée, les partitions natives du system
, du vendor
et product
sont incomplètes tant que la copie n'est pas terminée. Si l'appareil est réinitialisé aux paramètres d'usine pendant ce processus, soit par récupération, soit via la boîte de dialogue Paramètres système, l'appareil ne pourra pas démarrer.
Avant d'effacer /data
, terminez la fusion dans recovery ou rollback selon l'état de l'appareil :
- Si la nouvelle version a démarré avec succès avant, terminez la migration.
- Sinon, revenez à l'ancien emplacement :
- Pour les partitions dynamiques, revenez à l'état précédent.
- Pour les partitions statiques, définissez l'emplacement actif sur l'ancien emplacement.
Le bootloader et le fastbootd
peuvent effacer la partition /data
si le périphérique est déverrouillé. Alors que fastbootd
peut forcer la migration à se terminer, le chargeur de démarrage ne le peut pas. Le chargeur de démarrage ne sait pas si une fusion est en cours ou non, ni quels blocs dans /data
constituent les partitions du système d'exploitation. Les appareils doivent empêcher l'utilisateur de rendre l'appareil inutilisable (briquetage) sans le savoir en procédant comme suit :
- Implémentez le contrôle de démarrage HAL afin que le chargeur de démarrage puisse lire la valeur définie par la méthode
setSnapshotMergeStatus()
. - Si l'état de la fusion est
MERGING
, ou si l'état de la fusion estSNAPSHOTTED
et que l'emplacement a été remplacé par l'emplacement nouvellement mis à jour, les demandes d'effacement des donnéesuserdata
,metadata
ou de la partition stockant l'état de la fusion doivent être rejetées dans le chargeur de démarrage. - Implémentez la commande
fastboot snapshot-update cancel
afin que les utilisateurs puissent signaler au chargeur de démarrage qu'ils souhaitent contourner ce mécanisme de protection. - Modifiez les outils ou les scripts de flashage personnalisés pour émettre
fastboot snapshot-update cancel
démarrage rapide lors du flashage de l'ensemble du périphérique. Ceci est sûr à émettre car le fait de clignoter l'ensemble de l'appareil supprime l'OTA. Les outils peuvent détecter cette commande au moment de l'exécution en implémentantfastboot getvar snapshot-update-status
. Cette commande permet de différencier les conditions d'erreur.
Exemple
struct VirtualAbState {
uint8_t StructVersion;
uint8_t MergeStatus;
uint8_t SourceSlot;
};
bool ShouldPreventUserdataWipe() {
VirtualAbState state;
if (!ReadVirtualAbState(&state)) ...
return state.MergeStatus == MergeStatus::MERGING ||
(state.MergeStatus == MergeStatus::SNAPSHOTTED &&
state.SourceSlot != CurrentSlot()));
}
Modifications de l'outillage Fastboot
Android 11 apporte les modifications suivantes au protocole fastboot :
-
getvar snapshot-update-status
— Renvoie la valeur que la HAL de contrôle de démarrage a communiquée au chargeur de démarrage :- Si l'état est
MERGING
, le bootloader doit retournermerging
. - Si l'état est
SNAPSHOTTED
, le chargeur de démarrage doit renvoyersnapshotted
. - Sinon, le chargeur de démarrage doit renvoyer
none
.
- Si l'état est
-
snapshot-update merge
— Termine une opération de fusion, en démarrant sur recovery/fastbootd si nécessaire. Cette commande n'est valide que sisnapshot-update-status
merging
et n'est prise en charge que dans fastbootd. -
snapshot-update cancel
— Définit le statut de fusion de HAL de contrôle de démarrage surCANCELLED
. Cette commande n'est pas valide lorsque l'appareil est verrouillé. -
erase
ouwipe
— Unerase
ou unwipe
desmetadata
, des donnéesuserdata
ou d'une partition contenant l'état de fusion pour le contrôle de démarrage HAL doit vérifier l'état de fusion de l'instantané. Si l'état estMERGING
ouSNAPSHOTTED
, l'appareil doit abandonner l'opération. -
set_active
— Une commandeset_active
qui modifie l'emplacement actif doit vérifier l'état de fusion de l'instantané. Si l'état estMERGING
, l'appareil doit abandonner l'opération. L'emplacement peut être modifié en toute sécurité dans l'étatSNAPSHOTTED
.
Ces modifications sont conçues pour éviter de rendre accidentellement un appareil impossible à démarrer, mais elles peuvent perturber les outils automatisés. Lorsque les commandes sont utilisées comme composant de flashage de toutes les partitions, comme l'exécution de fastboot flashall
, il est recommandé d'utiliser le flux suivant :
-
getvar snapshot-update-status
. - S'il s'agit d'une
merging
ou d'unsnapshotted
, émettezsnapshot-update cancel
. - Procéder aux étapes clignotantes.
Réduction des besoins de stockage
Il est fortement recommandé d'utiliser l'outil de mappage de blocs pour les appareils qui ne disposent pas d'un stockage A/B complet alloué dans super et qui prévoient d'utiliser /data
si nécessaire. L'outil de mappage de blocs assure la cohérence de l'allocation des blocs entre les builds, réduisant ainsi les écritures inutiles sur l'instantané. Ceci est documenté sous Réduction de la taille OTA .