Implémenter des partitions dynamiques

Le partitionnement dynamique est implémenté à l'aide de l'outil de mappage d'appareils dm-linear dans le noyau Linux. La partition super contient des métadonnées répertoriant les noms et les plages de blocs de chaque partition dynamique dans un rayon de super. Lors de la première phase init, les métadonnées sont analysées et validées, et des appareils de stockage de blocs virtuels sont créés pour représentent chaque partition dynamique.

Lors de l'application d'une OTA, des partitions dynamiques sont automatiquement créées, redimensionnés ou supprimés si nécessaire. Pour les appareils A/B, il existe deux copies les métadonnées. Les modifications ne sont appliquées qu'à la copie représentant emplacement cible.

Étant donné que les partitions dynamiques sont implémentées dans l'espace utilisateur, elles doivent par le bootloader ne peut être rendu dynamique. Par exemple, boot, dtbo et vbmeta sont lus par le bootloader, et et doivent donc rester sous forme de partitions physiques.

Chaque partition dynamique peut appartenir à un groupe de mise à jour. Ces limitent l'espace maximal que les partitions d'un groupe peuvent utiliser. Par exemple, system et vendor peuvent appartenir à un qui limite la taille totale de system et vendor

Implémenter des partitions dynamiques sur les nouveaux appareils

Cette section explique comment implémenter des partitions dynamiques sur les nouveaux appareils avec Android 10 ou version ultérieure. Pour mettre à jour appareils existants, consultez la section Mise à niveau appareils mobiles.

Modifications de partition

Pour les appareils équipés d'Android 10, créez une partition appelée super. super gère les emplacements A/B en interne, de sorte que les périphériques A/B n'ont pas besoin séparer les partitions super_a et super_b. Toutes les partitions AOSP en lecture seule qui ne sont pas utilisées par le bootloader doivent être dynamiques et doivent être supprimées de la table de partition GUID (GPT). Les partitions spécifiques aux fournisseurs n'ont pas besoin d'être dynamiques et peuvent être placées dans le tag GPT.

<ph type="x-smartling-placeholder">

Pour estimer la taille de super, ajoutez les tailles du des partitions en cours de suppression du GPT. Pour les appareils A/B, doit inclure la taille des deux espaces. La Figure 1 illustre un exemple de table de partition avant et après la conversion en table dynamique des partitions.

<ph type="x-smartling-placeholder">
</ph> Disposition de la table de partitionnement <ph type="x-smartling-placeholder">
</ph> Figure 1. Nouvelle disposition de la table de partitionnement physique conversion en partitions dynamiques

Les partitions dynamiques compatibles sont les suivantes:

  • Système
  • Fournisseur
  • Produit
  • Ext. système
  • ODM

Pour les appareils équipés d'Android 10, Option de ligne de commande du noyau androidboot.super_partition doit être vide pour que la commande sysprop Le champ "ro.boot.super_partition" est vide.

Alignement des partitions

Le module de mappage de l'appareil peut être moins efficace si le La partition super n'est pas correctement alignée. La La partition super DOIT être alignée sur les E/S minimales la taille d'une requête telle que déterminée par la couche de bloc. Par défaut, système de compilation (via lpmake, qui génère super), suppose qu'un alignement de 1 Mio est suffisant pour chaque partition dynamique. Toutefois, les fournisseurs doivent vous assurer que la partition super est correctement alignée.

Vous pouvez déterminer la taille de requête minimale d'un appareil de stockage en mode bloc en en inspectant sysfs. Exemple :

# ls -l /dev/block/by-name/super
lrwxrwxrwx 1 root root 16 1970-04-05 01:41 /dev/block/by-name/super -> /dev/block/sda17
# cat /sys/block/sda/queue/minimum_io_size
786432

Vous pouvez vérifier l'alignement de la partition super dans une de la même manière:

# cat /sys/block/sda/sda17/alignment_offset

Le décalage d'alignement DOIT être égal à 0.

Modifications apportées à la configuration de l'appareil

Pour activer le partitionnement dynamique, ajoutez l'option suivante dans device.mk:

PRODUCT_USE_DYNAMIC_PARTITIONS := true

Modifications de la configuration de la carte

Vous devez définir la taille de la partition super:

BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

Sur les appareils A/B, le système de compilation génère une erreur si la taille totale des images de partition dynamiques représentent plus de la moitié des super la taille de la partition.

Vous pouvez configurer la liste des partitions dynamiques comme suit. Pour à l'aide des groupes de mise à jour, listez les groupes Variable BOARD_SUPER_PARTITION_GROUPS. Le nom de chaque groupe a ensuite un BOARD_group_SIZE et la variable BOARD_group_PARTITION_LIST. Pour les appareils A/B, la taille maximale d'un groupe ne doit couvrir qu'un seul "slot", car les noms des groupes comportent des suffixes d'emplacement en interne.

Voici un exemple d'appareil qui place toutes les partitions dans un groupe appelé example_dynamic_partitions:

BOARD_SUPER_PARTITION_GROUPS := example_dynamic_partitions
BOARD_EXAMPLE_DYNAMIC_PARTITIONS_SIZE := 6442450944
BOARD_EXAMPLE_DYNAMIC_PARTITIONS_PARTITION_LIST := system vendor product

Voici un exemple d'appareil qui place les services système et produits dans group_foo, vendor et product, et odm dans group_bar:

BOARD_SUPER_PARTITION_GROUPS := group_foo group_bar
BOARD_GROUP_FOO_SIZE := 4831838208
BOARD_GROUP_FOO_PARTITION_LIST := system product_services
BOARD_GROUP_BAR_SIZE := 1610612736
BOARD_GROUP_BAR_PARTITION_LIST := vendor product odm
<ph type="x-smartling-placeholder"> <ph type="x-smartling-placeholder">
  • Pour les appareils virtuels de lancement A/B, la somme des tailles maximales de tous les groupes doit ne doit pas dépasser:
    BOARD_SUPER_PARTITION_SIZE - frais généraux
    Consultez la page Implémenter des tests A/B virtuels.
  • Pour les appareils avec lancement A/B, la somme des tailles maximales de tous les groupes doit être:
    BOARD_SUPER_PARTITION_SIZE / 2 - frais généraux
  • Pour les appareils non-A/B et les appareils A/B ayant été adaptés, la somme des valeurs maximales les tailles de tous les groupes doivent être:
    BOARD_SUPER_PARTITION_SIZE – frais généraux
  • Au moment de la compilation, la somme des tailles des images de chaque partition dans un groupe de mise à jour ne doit pas dépasser la taille maximale du groupe.
  • Les frais généraux sont requis dans le calcul pour tenir compte des métadonnées. les alignements, etc. Une surcharge raisonnable est de 4 Mio, mais peut choisir une surcharge plus importante si nécessaire par l'appareil.

Taille des partitions dynamiques

Avant les partitions dynamiques, les tailles de partition étaient surallouées aux s’assurer qu’ils disposaient de suffisamment de place pour les mises à jour futures. La taille réelle était pris en l'état, et la plupart des partitions en lecture seule disposaient d'une certaine quantité dans leur système de fichiers. Dans les partitions dynamiques, cet espace libre inutilisable et pourrait être utilisé pour augmenter les partitions lors d’une OTA. Il est essentiel de s'assurer que les partitions ne gaspillent pas d'espace et sont est allouée à une taille minimale possible.

Pour les images ext4 en lecture seule, le système de compilation alloue automatiquement la taille minimale si aucune taille de partition codée en dur n'est spécifiée. La système de compilation ajuste l'image afin que le système de fichiers n'ait que possible l'espace inutilisé. Cela garantit que l'appareil ne le gaspille pas pouvant être utilisé pour les agences de voyages en ligne.

Vous pouvez aussi compresser davantage les images ext4 en activant au niveau de la déduplication. Pour l'activer, utilisez la configuration suivante:

BOARD_EXT4_SHARE_DUP_BLOCKS := true

Si l'allocation automatique d'une taille minimale de partition n'est pas souhaitable, il existe deux façons de contrôler la taille de la partition. Vous pouvez spécifier un d'espace libre minimum avec BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE, ou vous pouvez spécifier BOARD_partitionIMAGE_PARTITION_SIZE pour forcer des partitions dynamiques à une taille spécifique. Aucune de ces options n’est recommandé, sauf en cas de nécessité.

Exemple :

BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800

Cela oblige le système de fichiers de product.img à avoir 50 Mio d'espace inutilisé

<ph type="x-smartling-placeholder">

Modifications du système en tant que racine

Les appareils équipés d'Android 10 ne doivent pas utilisez le système en tant que racine.

Appareils dotés de partitions dynamiques (lancement ou adaptation partitions dynamiques) ne doivent pas utiliser le système en tant que racine. Le noyau Linux ne peut pas interpréter la partition super et ne peut donc pas installer system. system est maintenant installé par init de premier étage, qui se trouve dans le ramdisk.

Ne définissez pas BOARD_BUILD_SYSTEM_ROOT_IMAGE. Dans Android 10, le L'option BOARD_BUILD_SYSTEM_ROOT_IMAGE n'est utilisée que pour de différencier si le système est installé par le noyau ou par init de premier étage en ramdisk.

Définir BOARD_BUILD_SYSTEM_ROOT_IMAGE sur true une erreur de compilation PRODUCT_USE_DYNAMIC_PARTITIONS est également true.

Lorsque BOARD_USES_RECOVERY_AS_BOOT est défini sur "true", est créée sous le nom boot.img, qui contient l'image "ramdisk". Auparavant, le bootloader utilisait le noyau skip_initramfs. paramètre de ligne de commande pour décider dans quel mode démarrer. Pour Appareils Android 10, le bootloader NE DOIT PAS réussir skip_initramfs à la ligne de commande du noyau. Au lieu de cela, le bootloader doit transmettre androidboot.force_normal_boot=1 pour ignorer la récupération et démarrer un appareil Android normal. Appareils équipés d'Android 12 ou une version ultérieure doivent utiliser bootconfig pour transmettre androidboot.force_normal_boot=1.

Modifications de la configuration AVB

<ph type="x-smartling-placeholder">

Si vous utilisez Android Démarrage validé 2.0, si l'appareil n'utilise pas de partitions en chaîne de description, aucun changement n'est nécessaire. Si vous utilisez des chaînes des partitions, mais l'une des partitions validées est dynamique alors des changements sont nécessaires.

Voici un exemple de configuration pour un appareil vbmeta pour system et vendor partitions.

BOARD_AVB_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048
BOARD_AVB_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION := 1

BOARD_AVB_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_VENDOR_ALGORITHM := SHA256_RSA2048
BOARD_AVB_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_VENDOR_ROLLBACK_INDEX_LOCATION := 1

Avec cette configuration, le bootloader s'attend à trouver un vbmeta pied de page à la fin des system et vendor partitions. Comme ces partitions ne sont plus visibles par le bootloader (ils se trouvent dans super), deux des changements sont nécessaires.

  • Ajouter vbmeta_system et vbmeta_vendor des partitions à la table de partitionnement de l'appareil. Pour les appareils A/B, ajoutez vbmeta_system_a, vbmeta_system_b vbmeta_vendor_a et vbmeta_vendor_b. Si lorsque vous ajoutez une ou plusieurs de ces partitions, elles doivent avoir la même taille en tant que partition vbmeta.
  • Renommez les options de configuration en ajoutant VBMETA_ et Spécifiez à quelles partitions le chaînage s'étend:
    BOARD_AVB_VBMETA_SYSTEM := system
    BOARD_AVB_VBMETA_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
    BOARD_AVB_VBMETA_SYSTEM_ALGORITHM := SHA256_RSA2048
    BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
    BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 1
    
    BOARD_AVB_VBMETA_VENDOR := vendor
    BOARD_AVB_VBMETA_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
    BOARD_AVB_VBMETA_VENDOR_ALGORITHM := SHA256_RSA2048
    BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
    BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION := 1
    

Un appareil peut utiliser l'une de ces partitions, les deux ou aucune de ces partitions. Modifications ne sont nécessaires que lors du chaînage à une partition logique.

Modifications du bootloader AVB

Si le bootloader intègre libavb, incluent les correctifs suivants:

Si vous utilisez des partitions en chaîne, incluez un correctif supplémentaire:

  • 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: Prise en charge des blobs vbmeta au début de la partition." <ph type="x-smartling-placeholder">

Modifications de la ligne de commande du noyau

Un nouveau paramètre, androidboot.boot_devices, doit être ajouté. à la ligne de commande du noyau. Il est utilisé par init pour activer les liens symboliques /dev/block/by-name. Il doit s'agir du chemin d'accès de l'appareil au lien symbolique sous-jacent créé par ueventd, c'est-à-dire : /dev/block/platform/device-path/by-name/partition-name Les appareils équipés d'Android 12 ou version ultérieure doivent utiliser bootconfig pour transmettre androidboot.boot_devices à init.

Par exemple, si le lien symbolique de super-partition par nom est /dev/block/platform/soc/100000.ufshc/by-name/super, vous pouvez ajouter le paramètre de ligne de commande dans le fichier BoardConfig.mk en tant que ce qui suit:

BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
Vous pouvez ajouter le paramètre bootconfig dans le fichier BoardConfig.mk comme suit:
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc

modifications du fichier fstab

Les superpositions dans les arborescences d'appareils et d'appareils ne doivent pas contenir de fstab les entrées correspondantes. Utilisez un fichier fstab qui fera partie de ramdisk.

Vous devez modifier le fichier fstab pour les partitions logiques:

  • Le champ des options fs_mgr doit inclure l'option logical. et l'option first_stage_mount, introduite dans Android 10, qui indique qu'une partition doit être installé dans la première étape.
  • Une partition peut spécifier avb=vbmeta partition name en tant que L'option fs_mgr, puis la valeur vbmeta spécifiée est initialisée par la première étape init avant d'installer des périphériques.
  • Le champ dev doit correspondre au nom de la partition.

Les entrées fstab suivantes définissent le système, le fournisseur et le produit comme logiques les partitions en suivant les règles ci-dessus.

#<dev>  <mnt_point> <type>  <mnt_flags options> <fs_mgr_flags>
system   /system     ext4    ro,barrier=1        wait,slotselect,avb=vbmeta,logical,first_stage_mount
vendor   /vendor     ext4    ro,barrier=1        wait,slotselect,avb,logical,first_stage_mount
product  /product    ext4    ro,barrier=1        wait,slotselect,avb,logical,first_stage_mount
<ph type="x-smartling-placeholder">

Copiez le fichier fstab dans le ramdisk de la première étape.

Modifications apportées à SELinux

Le périphérique de bloc de superpartition doit être marqué avec l’étiquette super_block_device Par exemple, si le lien symbolique de super-partition par nom est /dev/block/platform/soc/100000.ufshc/by-name/super, Ajoutez la ligne suivante à file_contexts:

/dev/block/platform/soc/10000\.ufshc/by-name/super   u:object_r:super_block_device:s0

fastbootd

Le bootloader (ou tout outil de flash hors espace utilisateur) ne comprend pas des partitions dynamiques, et ne peut donc pas les flasher. Pour résoudre ce problème, les appareils doit utiliser une implémentation d'espace utilisateur du protocole fastboot, appelée fastbootd.

Pour en savoir plus sur l'implémentation de fastbootd, consultez Déplacer Fastboot vers un espace utilisateur.

réinstaller adb

Pour les développeurs qui utilisent des versions eng ou userdebug, adb remount est extrêmement utile pour une itération rapide. Les partitions dynamiques présentent problème pour adb remount, car l'offre n'est plus sans frais dans chaque système de fichiers. Pour résoudre ce problème, les appareils peuvent activer superfs. Tant qu'il y a de l'espace libre dans la super partition, adb remount crée automatiquement une création dynamique temporaire et utilise des superpositions pour les écritures. La partition temporaire est nommé scratch. Vous ne devez donc pas l'utiliser pour d'autres des partitions.

Pour plus d'informations sur l'activation des superpositions, consultez la section overlayfs README dans AOSP.

Mettre à niveau les appareils Android

Si vous passez à Android 10 sur un appareil si vous souhaitez inclure les partitions dynamiques dans l'OTA, vous n'avez pas besoin de modifier la table de partition intégrée. Certaines configurations supplémentaires sont obligatoire.

Modifications apportées à la configuration de l'appareil

Pour adapter le partitionnement dynamique, ajoutez les options suivantes dans device.mk:

PRODUCT_USE_DYNAMIC_PARTITIONS := true
PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true

Modifications de la configuration de la carte

Vous devez définir les variables de tableau suivantes:

  • Définissez BOARD_SUPER_PARTITION_BLOCK_DEVICES sur la liste des appareils de stockage en mode bloc utilisés. pour stocker des fragments de partitions dynamiques. Il s'agit de la liste des noms des appareils des partitions sur le périphérique.
  • Définir BOARD_SUPER_PARTITION_partition_DEVICE_SIZE sur les tailles de chaque appareil en mode bloc dans BOARD_SUPER_PARTITION_BLOCK_DEVICES, respectivement. Il s'agit de la liste des tailles des partitions physiques existantes sur l'appareil. C'est généralement BOARD_partitionIMAGE_PARTITION_SIZE dans le tableau existant de configuration.
  • Ne plus définir les BOARD_partitionIMAGE_PARTITION_SIZE existants pour tous partitions dans BOARD_SUPER_PARTITION_BLOCK_DEVICES.
  • Définissez BOARD_SUPER_PARTITION_SIZE sur la somme de BOARD_SUPER_PARTITION_partition_DEVICE_SIZE
  • Définissez BOARD_SUPER_PARTITION_METADATA_DEVICE sur l'appareil de stockage en mode bloc où les métadonnées de partition dynamique sont stockées. Il doit s'agir de BOARD_SUPER_PARTITION_BLOCK_DEVICES En général, il est défini sur system
  • Définir BOARD_SUPER_PARTITION_GROUPS, BOARD_group_SIZE BOARD_group_PARTITION_LIST, respectivement. Voir Modifications de la configuration de la carte sur les nouveaux appareils pour en savoir plus.

Par exemple, si l'appareil dispose déjà de partitions système et de fournisseurs, et que vous souhaitez convertir vers des partitions dynamiques et ajouter une nouvelle partition de produits lors de la mise à jour, définissez la configuration de la carte suivante:

BOARD_SUPER_PARTITION_BLOCK_DEVICES := system vendor
BOARD_SUPER_PARTITION_METADATA_DEVICE := system

# Rename BOARD_SYSTEMIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE.
BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE := <size-in-bytes>

# Rename BOARD_VENDORIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE
BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE := <size-in-bytes>

# This is BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE + BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

# Configuration for dynamic partitions. For example:
BOARD_SUPER_PARTITION_GROUPS := group_foo
BOARD_GROUP_FOO_SIZE := <size-in-bytes>
BOARD_GROUP_FOO_PARTITION_LIST := system vendor product

Modifications apportées à SELinux

Les périphériques de bloc de superpartition doivent être marqués avec l'attribut super_block_device_type Par exemple, si l'appareil a déjà partitions system et vendor, vous souhaitez les utiliser comme bloc appareils pour stocker des étendues de partitions dynamiques, et leurs liens symboliques par nom sont marqués comme system_block_device:

/dev/block/platform/soc/10000\.ufshc/by-name/system   u:object_r:system_block_device:s0
/dev/block/platform/soc/10000\.ufshc/by-name/vendor   u:object_r:system_block_device:s0

Ajoutez ensuite la ligne suivante à device.te:

typeattribute system_block_device super_block_device_type;

Pour les autres configurations, reportez-vous à la section Implémentation les partitions dynamiques sur les nouveaux appareils.

Pour en savoir plus sur les mises à jour de rétrofit, consultez OTA pour les appareils A/B sans flux dynamique Partitions.

Images d'usine

Pour un appareil qui prend en charge les partitions dynamiques, évitez d'utiliser l'espace utilisateur fastboot vers les images d'usine flash, car le démarrage vers l'espace utilisateur est plus lentement que les autres méthodes de clignotement.

Pour résoudre ce problème, make dist crée désormais une couche supplémentaire Image super.img qui peut être flashée directement sur le bouton Super partition. Elle regroupe automatiquement le contenu des partitions, ce qui signifie qu'elle contient system.img, vendor.img, etc., en plus de super métadonnées de partition. Cette image peut être flashée directement sur la partition super sans outil supplémentaire ni utilisation fastbootd. Après la compilation, super.img est placé dans ${ANDROID_PRODUCT_OUT}

Pour les appareils A/B lancés avec des partitions dynamiques, super.img contient des images dans l'emplacement A. Après avoir flashé, directement sur l'image, marquez l'emplacement A comme amorçable avant de redémarrer appareil.

Pour les appareils rétrofit, make dist crée un ensemble de super_*.img images qui peuvent être flashées directement sur des partitions physiques correspondantes. Exemple : make dist construit super_system.img et super_vendor.img lorsque BOARD_SUPER_PARTITION_BLOCK_DEVICES est le système fournisseur. Ces images sont placées dans le dossier OTA dans target_files.zip

Réglage de l'appareil de stockage du mappeur d'appareil

Le partitionnement dynamique est compatible avec un certain nombre d'outils de mappage d'appareils non déterministes. d'objets. Il est possible que ces éléments ne soient pas tous instanciés comme prévu, vous devez donc les suivre et de mettre à jour les propriétés Android de toutes les partitions associées leurs périphériques de stockage sous-jacents.

Un mécanisme dans init suit les installations et de manière asynchrone met à jour les propriétés Android. Le temps nécessaire à cette opération n'est pas garanti se situent dans une période précise. Vous devez donc prévoir suffisamment de temps pour que tous les déclencheurs on property réagissent. Les propriétés sont dev.mnt.blk.<partition> où "<partition>" est "root", system, data ou vendor, par exemple. Chaque propriété est associée au nom de base de l'appareil de stockage, comme illustré dans les exemples suivants:

taimen:/ % getprop | grep dev.mnt.blk
[dev.mnt.blk.data]: [sda]
[dev.mnt.blk.firmware]: [sde]
[dev.mnt.blk.metadata]: [sde]
[dev.mnt.blk.persist]: [sda]
[dev.mnt.blk.root]: [dm-0]
[dev.mnt.blk.vendor]: [dm-1]

blueline:/ $ getprop | grep dev.mnt.blk
[dev.mnt.blk.data]: [dm-4]
[dev.mnt.blk.metadata]: [sda]
[dev.mnt.blk.mnt.scratch]: [sda]
[dev.mnt.blk.mnt.vendor.persist]: [sdf]
[dev.mnt.blk.product]: [dm-2]
[dev.mnt.blk.root]: [dm-0]
[dev.mnt.blk.system_ext]: [dm-3]
[dev.mnt.blk.vendor]: [dm-1]
[dev.mnt.blk.vendor.firmware_mnt]: [sda]

Le langage init.rc permet aux propriétés Android d'être étendu conformément aux règles, et les périphériques de stockage peuvent être réglés par la plate-forme au besoin, à l'aide de commandes comme celles-ci:

write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb 128
write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb 128

Une fois que le traitement des commandes a commencé à l'étape init, epoll loop devient actif et les valeurs commencent à être mises à jour. Toutefois, Comme les déclencheurs de propriété ne sont pas actifs avant la fin du init, ils ne peut pas être utilisée lors des étapes de démarrage initiales pour gérer root. system ou vendor. Attendez-vous à ce que la valeur par défaut du noyau (read_ahead_kb) est suffisante jusqu'à ce que le Les scripts init.rc peuvent être remplacés dans early-fs (lorsque plusieurs daemons et installations démarrent). Par conséquent, Google recommande que vous utilisez la fonctionnalité on property, associée à propriété contrôlée par init.rc comme sys.read_ahead_kb, pour gérer la planification des opérations et éviter les conditions de concurrence, exemples:

on property:dev.mnt.blk.root=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.system=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.system}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.vendor=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.vendor}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.product=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.system_ext}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.oem=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.oem}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.data=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on early-fs:
    setprop sys.read_ahead_kb ${ro.read_ahead_kb.boot:-2048}

on property:sys.boot_completed=1
   setprop sys.read_ahead_kb ${ro.read_ahead_kb.bootcomplete:-128}