Disposition des partitions

Dans Android 10, le système de fichiers racine n'est plus inclus dans ramdisk.img et est fusionné dans system.img (c'est-à-dire que system.img est toujours créé comme si BOARD_BUILD_SYSTEM_ROOT_IMAGE était défini). Appareils lancés avec Android 10 :

  • Utilisez une disposition de partition système en tant que racine (automatiquement appliquée par la construction sans option pour modifier le comportement).
  • Doit utiliser un disque virtuel, qui est requis pour dm-linear.
  • Doit définir BOARD_BUILD_SYSTEM_ROOT_IMAGE sur false . Ce paramètre est utilisé uniquement pour différencier les périphériques qui utilisent un disque virtuel et les périphériques qui n'utilisent pas de disque virtuel (et pour monter directement system.img à la place).

La signification d'une configuration système en tant que racine diffère entre Android 9 et Android 10. Dans une configuration système en tant que racine Android 9, BOARD_BUILD_SYSTEM_ROOT_IMAGE est défini sur true , ce qui oblige la build à fusionner le système de fichiers racine dans system.img puis montez system.img en tant que système de fichiers racine (rootfs). Cette configuration est obligatoire pour les appareils lancés avec Android 9, mais est facultative pour les appareils mis à niveau vers Android 9 et pour les appareils exécutant des versions inférieures d'Android. Dans une configuration système en tant que racine Android 10, la build fusionne toujours $TARGET_SYSTEM_OUT et $TARGET_ROOT_OUT dans system.img ; cette configuration est le comportement par défaut pour tous les appareils exécutant Android 10.

Android 10 apporte d'autres modifications pour prendre en charge les partitions dynamiques , un système de partitionnement de l'espace utilisateur qui permet aux mises à jour en direct (OTA) de créer, redimensionner ou détruire des partitions. Dans le cadre de ce changement, le noyau Linux ne peut plus monter la partition système logique sur les appareils exécutant Android 10, cette opération est donc gérée par la première étape d'initialisation.

Les sections suivantes décrivent les exigences du système en tant que racine pour les OTA système uniquement et fournissent des conseils sur la mise à jour des appareils pour utiliser le système en tant que racine (y compris les modifications de la disposition des partitions et les exigences du noyau dm-verity). Pour plus de détails sur les modifications apportées au disque virtuel, consultez Partitions du disque virtuel .

À propos des OTA système uniquement

Les OTA système uniquement, qui permettent aux versions Android de mettre à jour system.img et product.img sans modifier les autres partitions, nécessitent une disposition de partition système en tant que racine. Tous les appareils exécutant Android 10 doivent utiliser une disposition de partition système en tant que racine pour activer les OTA système uniquement.

  • Les périphériques A/B, qui montent la partition system en tant que rootfs, utilisent déjà le système en tant que racine et ne nécessitent aucune modification pour prendre en charge les OTA du système.
  • Les périphériques non-A/B, qui montent la partition system sur /system , doivent être mis à jour pour utiliser une disposition de partition système en tant que racine pour prendre en charge les OTA système.

Pour plus de détails sur les appareils A/B et non-A/B, reportez-vous à Mises à jour du système A/B (transparentes) .

Utilisation de la superposition de fournisseurs

La superposition du fournisseur vous permet de superposer les modifications apportées à la partition vendor au moment du démarrage du périphérique. Une superposition de fournisseur est un ensemble de modules de fournisseur dans la partition product qui sont superposés sur la partition vendor lorsque le périphérique démarre, remplaçant et ajoutant des modules existants.

Lorsque le périphérique démarre, le processus init termine la première étape de montage et lit les propriétés par défaut. Ensuite, il recherche /product/vendor_overlay/<target_vendor_version> et monte chaque sous-répertoire sur son répertoire de partition vendor correspondant, si les conditions suivantes sont remplies :

  • /vendor/<overlay_dir> existe.
  • /product/vendor_overlay/<target_vendor_version>/<overlay_dir> a le même contexte de fichier que /vendor/<overlay_dir> .
  • init est autorisé à monter sur le contexte de fichier de /vendor/<overlay_dir> .

Implémentation de la superposition des fournisseurs

Installez les fichiers de superposition du fournisseur dans /product/vendor_overlay/<target_vendor_version> . Ces fichiers se superposent à la partition vendor au démarrage du périphérique, remplaçant les fichiers du même nom et ajoutant de nouveaux fichiers. La superposition du fournisseur ne peut pas supprimer les fichiers de la partition vendor .

Les fichiers de superposition du fournisseur doivent avoir le même contexte de fichier que les fichiers cibles qu'ils remplacent dans la partition vendor . Par défaut, les fichiers du répertoire /product/vendor_overlay/<target_vendor_version> ont le contexte vendor_file . S'il existe des incohérences de contexte de fichier entre les fichiers de superposition du fournisseur et les fichiers qu'ils remplacent, spécifiez-le dans la stratégie spécifique au périphérique. Le contexte du fichier est défini au niveau du répertoire. Si le contexte de fichier d'un répertoire de superposition de fournisseur ne correspond pas au répertoire cible et que le contexte de fichier correct n'est pas spécifié dans la stratégie spécifique au périphérique, ce répertoire de superposition de fournisseur n'est pas superposé au répertoire cible.

Pour utiliser la superposition du fournisseur, le noyau doit activer OverlayFS en définissant CONFIG_OVERLAY_FS=y . De plus, le noyau doit être fusionné à partir du noyau commun 4.4 ou version ultérieure, ou corrigé avec "overlayfs: override_creds=off option bypass creator_cred" .

Exemple de mise en œuvre de la superposition de fournisseurs

Cette procédure illustre l'implémentation d'une superposition de fournisseur qui recouvre les répertoires /vendor/lib/* , /vendor/etc/* et /vendor/app/* .

  1. Ajoutez des fichiers de fournisseur prédéfinis dans device/<vendor>/<target>/vendor_overlay/<target_vendor_version>/ :

    device/google/device/vendor_overlay/28/lib/libfoo.so
    device/google/device/vendor_overlay/28/lib/libbar.so
    device/google/device/vendor_overlay/28/etc/baz.xml
    device/google/device/vendor_overlay/28/app/qux.apk
    
  2. Installez les fichiers du fournisseur prédéfinis dans product/vendor_overlay dans device/google/device/device.mk :

    PRODUCT_COPY_FILES += \
        $(call find-copy-subdir-files,*,device/google/device/vendor_overlay,$(TARGET_COPY_OUT_PRODUCT)/vendor_overlay)
    
  3. Définissez des contextes de fichiers si les fichiers de partition vendor cible ont des contextes autres que vendor_file . Étant donné que /vendor/lib/* utilise le contexte vendor_file , cet exemple n'inclut pas ce répertoire.

    Ajoutez ce qui suit à device/google/device-sepolicy/private/file_contexts :

    /(product|system/product)/vendor_overlay/[0-9]+/etc(/.*)?   u:object_r:vendor_configs_file:s0
    /(product|system/product)/vendor_overlay/[0-9]+/app(/.*)?   u:object_r:vendor_app_file:s0
    
  4. Autorisez le processus init à monter la superposition du fournisseur sur des contextes de fichiers autres que vendor_file . Étant donné que le processus init est déjà autorisé à monter sur le contexte vendor_file , cet exemple ne définit pas la stratégie pour vendor_file .

    Ajoutez ce qui suit à device/google/device-sepolicy/public/init.te :

    allow init vendor_configs_file:dir mounton;
    allow init vendor_app_file:dir mounton;
    

Validation de la superposition des fournisseurs

Pour valider la configuration de superposition du fournisseur, ajoutez des fichiers dans /product/vendor_overlay/<target_vendor_version>/<overlay_dir> et vérifiez si les fichiers sont superposés sur les fichiers dans /vendor/<overlay_dir> .

Pour les builds userdebug , il existe un module de test pour Atest :

$ atest -v fs_mgr_vendor_overlay_test

Mise à jour vers le système en tant que root

Pour mettre à jour les périphériques non A/B afin d'utiliser le système en tant que racine, vous devez mettre à jour le schéma de partitionnement pour boot.img et system.img , configurer dm-verity et supprimer toutes les dépendances de démarrage sur les dossiers racine spécifiques au périphérique.

Mise à jour des partitions

Contrairement aux périphériques A/B qui réutilisent /boot comme partition de récupération , les périphériques non-A/B doivent garder la partition /recovery séparée car ils n'ont pas de partition d'emplacement de secours (par exemple, de boot_a à boot_b ). Si /recovery est supprimé sur un périphérique non-A/B et rendu similaire au schéma A/B, le mode de récupération pourrait être interrompu lors d'un échec de mise à jour de la partition /boot . Pour cette raison, la partition /recovery doit être une partition distincte de /boot pour les appareils non-A/B, ce qui implique que l'image de récupération continuera à être mise à jour de manière différée (c'est-à-dire de la même manière que sur les appareils exécutant Android). 8.1.0 ou version antérieure).

Le tableau suivant répertorie les différences de partition d'image pour les appareils non-A/B avant et après Android 9.

Image Disque Ram (avant 9) Système en tant que root (après 9)
boot.img Contient un noyau et un ramdisk.img :
ramdisk.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/ (mount point)
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
Contient uniquement un noyau de démarrage normal.
recovery.img Contient un noyau de récupération et un ramdisk.img de récupération.
system.img Contient les éléments suivants :
system.img
  -/
    - bin/
    - etc
    - vendor -> /vendor
    - ...
Contient le contenu fusionné de system.img et ramdisk.img d'origine :
system.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/
      - bin/
      - etc/
      - vendor -> /vendor
      - ...
    - vendor/ (mount point)
    - odm/ (mount point)
    ...

Les partitions elles-mêmes ne changent pas ; le disque virtuel et le système en tant que racine utilisent le schéma de partition suivant :

  • /boot
  • /system
  • /system
  • /recovery
  • /vendor , etc.

Configuration de DM-Verity

Dans le système en tant que racine, le noyau doit monter system.img sous / (point de montage) avec dm-verity . AOSP prend en charge les implémentations dm-verity suivantes pour system.img .

vboot 1.0

Pour vboot 1.0 , le noyau doit analyser les métadonnées spécifiques à Android sur /system , puis les convertir en paramètres dm-verity pour configurer dm-verity (nécessite ces correctifs du noyau ). L'exemple suivant montre les paramètres liés à dm-verity pour le système en tant que racine dans la ligne de commande du noyau :

ro root=/dev/dm-0 rootwait skip_initramfs init=/init
dm="system none ro,0 1 android-verity /dev/sda34"
veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f

vboot 2.0

Pour vboot 2.0 ( AVB ), le chargeur de démarrage doit intégrer external/avb/libavb , qui analyse ensuite le descripteur hashtree pour /system , le convertit en dm-verity params et transmet enfin les paramètres au noyau via la ligne de commande du noyau. (Les descripteurs Hashtree de /system peuvent se trouver sur /vbmeta ou sur /system lui-même.)

vboot 2.0 nécessite les correctifs de noyau suivants :

L'exemple suivant montre les paramètres liés à dm-verity pour le système en tant que racine dans la ligne de commande du noyau :

ro root=/dev/dm-0 rootwait  skip_initramfs init=/init

dm="1 vroot none ro 1,0 5159992 verity 1
PARTUUID=00000016-0000-0000-0000-000000000000
PARTUUID=00000016-0000-0000-0000-000000000000 4096 4096 644999 644999
sha1 d80b4a8be3b58a8ab86fad1b498640892d4843a2
8d08feed2f55c418fb63447fec0d32b1b107e42c 10 restart_on_corruption
ignore_zero_blocks use_fec_from_device
PARTUUID=00000016-0000-0000-0000-000000000000 fec_roots 2 fec_blocks
650080 fec_start 650080"

Utilisation de dossiers racine spécifiques à l'appareil

Avec le système en tant que racine, après le flashage de l'image système générique (GSI) sur l'appareil (et avant d'exécuter les tests Vendor Test Suite ), tous les dossiers racine spécifiques à l'appareil ajoutés avec BOARD_ROOT_EXTRA_FOLDERS disparaissent car tout le contenu du répertoire racine a été remplacé. par le système en tant que racine GSI. La suppression de ces dossiers peut empêcher le démarrage du périphérique s'il existe une dépendance aux dossiers racine spécifiques au périphérique (par exemple, ils sont utilisés comme points de montage).

Pour éviter ce problème, n'utilisez pas BOARD_ROOT_EXTRA_FOLDERS pour ajouter des dossiers racine spécifiques à l'appareil. Si vous devez spécifier des points de montage spécifiques au périphérique, utilisez /mnt/vendor/<mount point> (ajouté dans ces listes de modifications ). Ces points de montage spécifiques au fournisseur peuvent être directement spécifiés à la fois dans l'arborescence des périphériques fstab (pour le montage de première étape) et dans le fichier /vendor/etc/fstab.{ro.hardware} sans configuration supplémentaire (car fs_mgr les crée sous /mnt/vendor/* automatiquement).