La taille de page correspond à la granularité avec laquelle un système d'exploitation gère la mémoire. La plupart des processeurs actuels sont compatibles avec une taille de page de 4 Ko. Par conséquent, l'OS Android et les applications ont toujours été conçus et optimisés pour fonctionner avec une taille de page de 4 Ko. Les processeurs ARM sont compatibles avec la taille de page de 16 Ko, et à partir d'Android 15, AOSP permet également de créer Android avec une taille de page de 16 Ko. Cette option utilise de la mémoire supplémentaire, mais améliore les performances du système. À partir d'Android 15, cette option n'est pas activée par défaut, mais elle est disponible en tant qu'option ou mode développeur pour les OEM et les développeurs d'applications afin de se préparer à passer au mode 16 ko partout à l'avenir.
Android 15 et les versions ultérieures permettent de créer Android avec un alignement ELF de 16 Ko, qui fonctionne avec les noyaux de 4 Ko et de 16 Ko à partir de android14-6.1
.
Lorsqu'elle est utilisée avec un noyau de 16 Ko, cette configuration utilise de la mémoire supplémentaire, mais améliore les performances du système.
Définir Android sur 16 ko
Les pages de 16 Ko ne sont compatibles qu'avec les cibles arm64
dotées de kernels de 16 Ko.
Toutefois, il est également possible de simuler un espace utilisateur de 16 Ko sur x86_64
pour Cuttlefish.
Espace du noyau
Pour les cibles arm64
, si vous utilisez Kleaf pour créer votre noyau, --page_size=16k
crée le noyau en mode 16 Ko.
Si vous utilisez directement la configuration du noyau Linux, vous pouvez sélectionner des pages de 16 Ko en définissant CONFIG_ARM64_16K_PAGES
au lieu de CONFIG_ARM64_4K_PAGES
.
Espace utilisateur
Pour activer la prise en charge de la taille de page de 16 Ko dans l'espace utilisateur Android, définissez les options de compilation suivantes sur votre produit :
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
supprime la définitionPAGE_SIZE
et permet aux composants de déterminer la taille de la page au moment de l'exécution.PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
, ce qui garantit que les fichiers ELF de la plate-forme sont créés avec un alignement de 16 Ko. Cette taille plus grande que nécessaire est destinée à la compatibilité future. Avec l'alignement ELF de 16 Ko, le kernel peut prendre en charge les tailles de page de 4 Ko/16 Ko.
Vérifier les indicateurs de compilation
Après avoir sélectionné la cible lunch
, vérifiez que les indicateurs de compilation sont correctement configurés dans l'environnement :
$ source build/envsetup.sh
$ lunch target
$ get_build_var TARGET_MAX_PAGE_SIZE_SUPPORTED
16384
$ get_build_var TARGET_NO_BIONIC_PAGE_SIZE_MACRO
true
Si les deux commandes précédentes renvoient respectivement 16384
et true
, vos indicateurs de compilation sont correctement configurés pour fonctionner avec un noyau de 16 Ko. Toutefois, même si une compilation réussit, il peut toujours y avoir des problèmes d'exécution en raison des différences dans un environnement de 16 Ko.
Programmation du système avec une taille de page de 16 ko
La grande majorité du code sur n'importe quel appareil Android ne traite pas directement de la taille des pages. Toutefois, pour le code qui traite des pages, le comportement d'allocation de mémoire du noyau change. Vous devez en tenir compte pour écrire du code qui est non seulement compatible, mais aussi le plus performant possible et le moins gourmand en ressources possible.
Si vous appelez mmap
sur une région de 1 Ko, 2 Ko ou jusqu'à 4 Ko sur un système de 4 Ko, le système réserve 4 Ko pour implémenter cette opération. En d'autres termes, lorsque vous demandez de la mémoire au noyau, celui-ci doit toujours arrondir la mémoire demandée à la taille de page la plus proche. Par exemple, si vous allouez une région de 5 Ko sur une région de 4 Ko, le noyau alloue 8 Ko.
Sur un noyau de 16 Ko, ces "extrémités" supplémentaires des pages sont plus grandes. Par exemple, toutes ces allocations, de 1 Ko à 5 Ko, alloueraient 16 Ko lorsqu'elles sont utilisées avec un noyau de 16 Ko. Si vous demandez 17 Ko, 32 Ko sont alloués.
Par exemple, sur un système de 4 Ko, il est acceptable d'allouer deux régions anonymes en lecture/écriture de 4 Ko. Toutefois, sur un kernel de 16 Ko, cela entraînerait l'allocation de deux pages, soit 32 Ko. Sur un kernel de 16 Ko, si possible, ces régions peuvent être combinées en une seule page lisible ou inscriptible, de sorte que seuls 16 Ko sont utilisés, ce qui représente un gaspillage de 8 Ko par rapport au cas du kernel de 4 Ko. Pour réduire encore davantage l'utilisation de la mémoire, vous pouvez combiner plus de pages. En fait, sur un système de 16 Ko optimisé au maximum, les pages de 16 Ko nécessitent moins de mémoire que les systèmes de 4 Ko, car la table de pages est quatre fois plus petite pour la même mémoire.
Lorsque vous utilisez mmap
, assurez-vous d'arrondir la taille demandée à la taille de page la plus proche. Cela garantit que la quantité totale de mémoire allouée par le noyau est directement visible par l'espace utilisateur dans les valeurs d'exécution, au lieu d'être demandée de manière implicite et accessible de manière implicite ou accidentelle.
Créer des bibliothèques partagées avec un alignement ELF de 16 ko
Pour créer des bibliothèques partagées qui font partie du projet Android, les paramètres précédents de la section Activer la taille de page de 16 Ko suffisent :
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
Pour créer des bibliothèques partagées qui ne font pas partie du projet Android, vous devez transmettre cet indicateur d'éditeur de liens :
-Wl,-z,max-page-size=16384
Vérifier les binaires et les précompilés pour l'alignement ELF de 16 ko
La meilleure façon de vérifier l'alignement et le comportement d'exécution consiste à effectuer des tests et à exécuter un noyau compilé de 16 Ko. Toutefois, pour détecter certains problèmes plus tôt :
À partir d'Android 16, vous pouvez définir
PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := true
au moment de la compilation. Utilisezignore_max_page_size: true
dansAndroid.bp
etLOCAL_IGNORE_MAX_PAGE_SIZE := true
dansAndroid.mk
pour les ignorer temporairement. Ces paramètres permettent de vérifier tous les composants prédéfinis et de détecter lorsqu'un composant est mis à jour, mais n'est pas aligné sur 16 Ko.Vous pouvez exécuter
atest elf_alignment_test
, qui vérifie l'alignement des fichiers ELF sur l'appareil sur les appareils lancés avec Android 15 et versions ultérieures.