Le partitionnement dynamique est implémenté à l'aide du module dm-linear device-mapper du noyau Linux. La super
partition contient des métadonnées répertoriant les noms et les plages de blocs de chaque partition dynamique au sein super
. Lors de la première étape init
, ces métadonnées sont analysées et validées, et des périphériques de bloc virtuels sont créés pour représenter chaque partition dynamique.
Lors de l'application d'un OTA, les partitions dynamiques sont automatiquement créées, redimensionnées ou supprimées selon les besoins. Pour les appareils A/B, il existe deux copies des métadonnées et les modifications sont appliquées uniquement à la copie représentant l'emplacement cible.
Étant donné que les partitions dynamiques sont implémentées dans l'espace utilisateur, les partitions nécessaires au chargeur de démarrage ne peuvent pas être rendues dynamiques. Par exemple, boot
, dtbo
et vbmeta
sont lus par le chargeur de démarrage et doivent donc rester sous forme de partitions physiques.
Chaque partition dynamique peut appartenir à un groupe de mise à jour . Ces groupes limitent l'espace maximum que les partitions de ce groupe peuvent consommer. Par exemple, system
et vendor
peuvent appartenir à un groupe qui restreint la taille totale du 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 lancés avec Android 10 et versions ultérieures. Pour mettre à jour les appareils existants, consultez Mise à niveau des appareils Android .
Modifications des partitions
Pour les appareils lancés avec Android 10, créez une partition appelée super
. La super
partition gère les emplacements A/B en interne, de sorte que les périphériques A/B n'ont pas besoin de partitions super_a
et super_b
séparées. Toutes les partitions AOSP en lecture seule qui ne sont pas utilisées par le chargeur de démarrage doivent être dynamiques et doivent être supprimées de la table de partition GUID (GPT). Les partitions spécifiques au fournisseur ne doivent pas nécessairement être dynamiques et peuvent être placées dans le GPT.
Pour estimer la taille de super
, ajoutez les tailles des partitions supprimées du GPT. Pour les appareils A/B, cela doit inclure la taille des deux emplacements. La figure 1 montre un exemple de table de partition avant et après la conversion en partitions dynamiques.
Les partitions dynamiques prises en charge sont :
- Système
- Fournisseur
- Produit
- Poste système
- ODM
Pour les appareils lancés avec Android 10, l'option de ligne de commande du noyau androidboot.super_partition
doit être vide afin que la commande sysprop ro.boot.super_partition
soit vide.
Alignement des partitions
Le module de mappage de périphériques peut fonctionner moins efficacement si la super
partition n'est pas correctement alignée. La super
partition DOIT être alignée sur la taille minimale de demande d'E/S telle que déterminée par la couche bloc. Par défaut, le système de build (via lpmake
, qui génère l'image de super
partition), suppose qu'un alignement de 1 Mo est suffisant pour chaque partition dynamique. Cependant, les fournisseurs doivent s'assurer que la super
partition est correctement alignée.
Vous pouvez déterminer la taille minimale de requête d'un périphérique bloc en inspectant sysfs
. Par 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 super
partition de la même manière :
# cat /sys/block/sda/sda17/alignment_offset
Le décalage d'alignement DOIT être 0.
Modifications de la configuration de l'appareil
Pour activer le partitionnement dynamique, ajoutez l'indicateur suivant dans device.mk
:
PRODUCT_USE_DYNAMIC_PARTITIONS := true
Modifications de la configuration de la carte
Vous devez définir la taille de la super
partition :
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>
Sur les périphériques A/B, le système de build génère une erreur si la taille totale des images de partition dynamique est supérieure à la moitié de la taille de la super
partition.
Vous pouvez configurer la liste des partitions dynamiques comme suit. Pour les appareils utilisant des groupes de mise à jour, répertoriez les groupes dans la variable BOARD_SUPER_PARTITION_GROUPS
. Chaque nom de groupe a ensuite une variable BOARD_ group _SIZE
et BOARD_ group _PARTITION_LIST
. Pour les appareils A/B, la taille maximale d'un groupe ne doit couvrir qu'un seul emplacement, car les noms de groupe comportent un suffixe d'emplacement en interne.
Voici un exemple de périphérique 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 de périphérique qui place les services système et produits dans group_foo
, et vendor
, 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
- Pour les appareils de lancement Virtual A/B, la somme des tailles maximales de tous les groupes doit être au maximum :
BOARD_SUPER_PARTITION_SIZE
– frais généraux
Voir Implémentation de l'A/B virtuel . - Pour les appareils de 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 modernisés, la somme des tailles maximales de tous les groupes doit être :
BOARD_SUPER_PARTITION_SIZE
– frais généraux - Au moment de la construction, la somme des tailles des images de chaque partition d'un groupe de mise à jour ne doit pas dépasser la taille maximale du groupe.
- Une surcharge est nécessaire dans le calcul pour tenir compte des métadonnées, des alignements, etc. Une surcharge raisonnable est de 4 Mio, mais vous pouvez choisir une surcharge plus importante selon les besoins de l'appareil.
Dimensionner les partitions dynamiques
Avant les partitions dynamiques, les tailles des partitions étaient suraffectées pour garantir qu'elles disposaient de suffisamment d'espace pour les futures mises à jour. La taille réelle a été prise telle quelle et la plupart des partitions en lecture seule disposaient d'une certaine quantité d'espace libre dans leur système de fichiers. Dans les partitions dynamiques, cet espace libre est inutilisable et pourrait être utilisé pour agrandir les partitions lors d'une OTA. Il est essentiel de s'assurer que les partitions ne gaspillent pas d'espace et sont allouées à une taille minimale possible.
Pour les images ext4 en lecture seule, le système de construction alloue automatiquement la taille minimale si aucune taille de partition codée en dur n'est spécifiée. Le système de construction s'adapte à l'image afin que le système de fichiers dispose du moins d'espace inutilisé possible. Cela garantit que l'appareil ne gaspille pas d'espace pouvant être utilisé pour les OTA.
De plus, les images ext4 peuvent être davantage compressées en activant la déduplication au niveau des blocs. Pour activer cela, 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 manières de contrôler la taille de la partition. Vous pouvez spécifier une quantité minimale d'espace libre avec BOARD_ partition IMAGE_PARTITION_RESERVED_SIZE
, ou vous pouvez spécifier BOARD_ partition IMAGE_PARTITION_SIZE
pour forcer les partitions dynamiques à une taille spécifique. Aucune de ces solutions n’est recommandée, sauf si cela est nécessaire.
Par exemple:
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
Cela force le système de fichiers dans product.img
à disposer de 50 Mo d'espace inutilisé.
Modifications du système en tant que racine
Les appareils lancés avec Android 10 ne doivent pas utiliser le système en tant que root.
Les appareils dotés de partitions dynamiques (qu'ils soient lancés avec ou modernisés par des partitions dynamiques) ne doivent pas utiliser le système en tant que racine. Le noyau Linux ne peut pas interpréter la super
partition et ne peut donc pas monter system
lui-même. system
est maintenant monté par init
de première étape, qui réside dans le disque virtuel.
Ne définissez pas BOARD_BUILD_SYSTEM_ROOT_IMAGE
. Dans Android 10, l'indicateur BOARD_BUILD_SYSTEM_ROOT_IMAGE
est uniquement utilisé pour différencier si le système est monté par le noyau ou par l' init
de première étape dans le disque virtuel.
La définition BOARD_BUILD_SYSTEM_ROOT_IMAGE
sur true
provoque une erreur de construction lorsque PRODUCT_USE_DYNAMIC_PARTITIONS
est également true
.
Lorsque BOARD_USES_RECOVERY_AS_BOOT
est défini sur true, l'image de récupération est créée sous le nom boot.img, contenant le disque virtuel de récupération. Auparavant, le chargeur de démarrage utilisait le paramètre de ligne de commande du noyau skip_initramfs
pour décider dans quel mode démarrer. Pour les appareils Android 10, le chargeur de démarrage NE DOIT PAS transmettre skip_initramfs
à la ligne de commande du noyau. Au lieu de cela, le chargeur de démarrage doit transmettre androidboot.force_normal_boot=1
pour ignorer la récupération et démarrer Android normal. Les appareils lancés avec Android 12 ou version ultérieure doivent utiliser bootconfig pour transmettre androidboot.force_normal_boot=1
.
Modifications de la configuration AVB
Lorsque vous utilisez Android Verified Boot 2.0 , si l'appareil n'utilise pas de descripteurs de partition chaînés , aucune modification n'est nécessaire. Toutefois, si vous utilisez des partitions chaînées et que l'une des partitions vérifiées est dynamique, des modifications sont nécessaires.
Voici un exemple de configuration pour un périphérique qui chaîne vbmeta
pour les partitions system
et vendor
.
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 chargeur de démarrage s'attend à trouver un pied de page vbmeta à la fin des partitions system
et vendor
. Étant donné que ces partitions ne sont plus visibles par le chargeur de démarrage (elles résident dans super
), deux modifications sont nécessaires.
- Ajoutez les partitions
vbmeta_system
etvbmeta_vendor
à la table de partition du périphérique. Pour les appareils A/B, ajoutezvbmeta_system_a
,vbmeta_system_b
,vbmeta_vendor_a
etvbmeta_vendor_b
. Si vous ajoutez une ou plusieurs de ces partitions, elles doivent avoir la même taille que la partitionvbmeta
. - Renommez les indicateurs 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 périphérique peut utiliser l'une de ces partitions, les deux ou aucune. Les modifications sont nécessaires uniquement lors du chaînage à une partition logique.
Modifications du chargeur de démarrage AVB
Si le chargeur de démarrage a intégré libavb , incluez les correctifs suivants :
- 818cf56740775446285466eda984acedd4baeac0 — "libavb : interrogez uniquement les GUID de partition lorsque la ligne de commande en a besoin."
- 5abd6bc2578968d24406d834471adfd995a0c2e9 — "Autoriser l'absence de la partition système"
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 — "Le correctif AvbSlotVerifyData->cmdline pourrait être NULL"
Si vous utilisez des partitions chaînées, incluez un correctif supplémentaire :
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb : prise en charge des blobs vbmeta au début de la partition."
Modifications de la ligne de commande du noyau
Un nouveau paramètre, androidboot.boot_devices
, doit être ajouté à la ligne de commande du noyau. Ceci est utilisé par init
pour activer les liens /dev/block/by-name
. Il doit s'agir du composant de chemin de périphérique vers le lien symbolique sous-jacent par nom créé par ueventd
, c'est-à-dire /dev/block/platform/ device-path /by-name/ partition-name
. Les appareils lancés avec Android 12 ou version ultérieure doivent utiliser bootconfig pour transmettre androidboot.boot_devices
à init
.
Par exemple, si le lien symbolique par nom de super partition 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 comme suit :
BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshcVous pouvez ajouter le paramètre bootconfig dans le fichier BoardConfig.mk comme suit :
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc
changements fstab
L'arborescence des périphériques et les superpositions de l'arborescence des périphériques ne doivent pas contenir d'entrées fstab. Utilisez un fichier fstab qui fera partie du disque virtuel.
Des modifications doivent être apportées au fichier fstab pour les partitions logiques :
- Le champ fs_mgr flags doit inclure l'indicateur
logical
et l'indicateurfirst_stage_mount
, introduits dans Android 10, qui indiquent qu'une partition doit être montée dans la première étape. - Une partition peut spécifier
avb= vbmeta partition name
comme indicateurfs_mgr
, puis la partitionvbmeta
spécifiée est initialisée par la première étapeinit
avant de tenter de monter des périphériques. - Le champ
dev
doit être le nom de la partition.
Les entrées fstab suivantes définissent le système, le fournisseur et le produit comme partitions logiques 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
Copiez le fichier fstab dans le disque virtuel de première étape.
Modifications de SELinux
Le périphérique de bloc de super partition doit être marqué avec l'étiquette super_block_device
. Par exemple, si le lien symbolique par nom de super partition 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
démarrage rapide
Le chargeur de démarrage (ou tout outil de flashage non-utilisateur) ne comprend pas les partitions dynamiques, il ne peut donc pas les flasher. Pour résoudre ce problème, les appareils doivent utiliser une implémentation dans l’espace utilisateur du protocole fastboot, appelée fastbootd.
Pour plus d'informations sur la façon d'implémenter fastbootd, consultez Déplacement de Fastboot vers l'espace utilisateur .
remontage de la BAD
Pour les développeurs utilisant des versions eng ou userdebug, adb remount
est extrêmement utile pour une itération rapide. Les partitions dynamiques posent un problème pour adb remount
car il n'y a plus d'espace libre dans chaque système de fichiers. Pour résoudre ce problème, les appareils peuvent activer les superpositions. Tant qu'il y a de l'espace libre dans la super partition, adb remount
crée automatiquement une partition dynamique temporaire et utilise overlayfs pour les écritures. La partition temporaire est nommée scratch
, n'utilisez donc pas ce nom pour d'autres partitions.
Pour plus d'informations sur la façon d'activer overlayfs, consultez le README overlayfs dans AOSP.
Mettre à niveau les appareils Android
Si vous mettez à niveau un appareil vers Android 10 et souhaitez inclure la prise en charge des partitions dynamiques dans l'OTA, vous n'avez pas besoin de modifier la table de partition intégrée. Une configuration supplémentaire est requise.
Modifications de la configuration de l'appareil
Pour moderniser le partitionnement dynamique, ajoutez les indicateurs suivants 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 périphériques de bloc utilisés pour stocker les extensions de partitions dynamiques. Il s'agit de la liste des noms des partitions physiques existantes sur le périphérique. - Définissez
BOARD_SUPER_PARTITION_ partition _DEVICE_SIZE
sur les tailles de chaque périphérique bloc dansBOARD_SUPER_PARTITION_BLOCK_DEVICES
, respectivement. Il s'agit de la liste des tailles des partitions physiques existantes sur le périphérique. Il s'agit généralementBOARD_ partition IMAGE_PARTITION_SIZE
dans les configurations de carte existantes. - Supprimez
BOARD_ partition IMAGE_PARTITION_SIZE
existante pour toutes les partitions deBOARD_SUPER_PARTITION_BLOCK_DEVICES
. - Définissez
BOARD_SUPER_PARTITION_SIZE
sur la somme deBOARD_SUPER_PARTITION_ partition _DEVICE_SIZE
. - Définissez
BOARD_SUPER_PARTITION_METADATA_DEVICE
sur le périphérique de bloc où les métadonnées de partition dynamique sont stockées. Il doit s'agir de l'un desBOARD_SUPER_PARTITION_BLOCK_DEVICES
. Habituellement, cela est défini sursystem
. - Définissez respectivement
BOARD_SUPER_PARTITION_GROUPS
,BOARD_ group _SIZE
etBOARD_ group _PARTITION_LIST
. Voir Modifications de la configuration de la carte sur les nouveaux appareils pour plus de détails.
Par exemple, si l'appareil dispose déjà de partitions système et fournisseur et que vous souhaitez les convertir en partitions dynamiques et ajouter une nouvelle partition produit lors de la mise à jour, définissez cette configuration de carte :
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 de SELinux
Les périphériques de bloc de super partition doivent être marqués avec l'attribut super_block_device_type
. Par exemple, si le périphérique possède déjà des partitions system
et vendor
, vous souhaitez les utiliser comme périphériques de bloc pour stocker des extensions 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
Ensuite, ajoutez la ligne suivante à device.te
:
typeattribute system_block_device super_block_device_type;
Pour d'autres configurations, consultez Implémentation de partitions dynamiques sur de nouveaux appareils .
Pour plus d'informations sur les mises à jour de mise à niveau, consultez OTA pour les appareils A/B sans partitions dynamiques .
Images d'usine
Pour un périphérique lancé avec prise en charge des partitions dynamiques, évitez d'utiliser le démarrage rapide de l'espace utilisateur pour flasher les images d'usine, car le démarrage dans l'espace utilisateur est plus lent que les autres méthodes de flashage.
Pour résoudre ce problème, make dist
crée désormais une image super.img
supplémentaire qui peut être flashée directement sur la super partition. Il regroupe automatiquement le contenu des partitions logiques, ce qui signifie qu'il contient system.img
, vendor.img
, etc., en plus des métadonnées de la super
partition. Cette image peut être flashée directement sur la super
partition sans aucun outil supplémentaire ni utilisation de fastbootd. Après la construction, super.img
est placé dans ${ANDROID_PRODUCT_OUT}
.
Pour les appareils A/B qui se lancent avec des partitions dynamiques, super.img
contient des images dans l'emplacement A. Après avoir flashé directement la super image, marquez l'emplacement A comme amorçable avant de redémarrer l'appareil.
Pour les appareils de mise à niveau, make dist
crée un ensemble d'images super_*.img
qui peuvent être flashées directement sur les partitions physiques correspondantes. Par exemple, make dist
builds super_system.img
et super_vendor.img
lorsque BOARD_SUPER_PARTITION_BLOCK_DEVICES
est le fournisseur du système. Ces images sont placées dans le dossier OTA dans target_files.zip
.
Réglage des périphériques de stockage du mappeur de périphériques
Le partitionnement dynamique prend en charge un certain nombre d'objets de mappage de périphériques non déterministes. Ceux-ci peuvent ne pas tous être instanciés comme prévu, vous devez donc suivre tous les montages et mettre à jour les propriétés Android de toutes les partitions associées avec leurs périphériques de stockage sous-jacents.
Un mécanisme à l'intérieur init
suit les montages et met à jour de manière asynchrone les propriétés Android. Il n'est pas garanti que le temps que cela prendra se situe dans une période spécifique, 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 du périphérique de stockage de base, comme indiqué dans ces exemples :
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 d'étendre les propriétés Android dans le cadre des règles, et les périphériques de stockage peuvent être réglés par la plate-forme selon les besoins avec des 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 démarre lors de la deuxième étape init
, la epoll loop
devient active et les valeurs commencent à se mettre à jour. Cependant, comme les déclencheurs de propriété ne sont actifs qu'à la fin de init
, ils ne peuvent pas être utilisés lors des étapes de démarrage initiales pour gérer root
, system
ou vendor
. Vous pouvez vous attendre à ce que la valeur par défaut read_ahead_kb
du noyau soit suffisante jusqu'à ce que les scripts init.rc
puissent être remplacés dans early-fs
(lorsque divers démons et fonctionnalités démarrent). Par conséquent, Google vous recommande d'utiliser la fonctionnalité on property
, associée à une propriété contrôlée init.rc
comme sys.read_ahead_kb
, pour gérer la synchronisation des opérations et éviter les conditions de concurrence, comme dans ces 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}