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 une taille de page plus importante de 16 Ko. À partir d'Android 15, AOSP est également compatible avec la création d'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 que mode développeur ou option 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 versions ultérieures sont compatibles avec la création d'
Android avec un alignement ELF de 16 Ko, qui fonctionne avec les kernels de 4 Ko et
16 Ko à partir de
android14-6.1.
Lorsqu'elle est utilisée avec un kernel 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 avec des kernels de 16 Ko.
Toutefois, il est également possible de
simuler un espace utilisateur de 16 Ko sur x86_64 pour Cuttlefish.
Espace du kernel
Pour les cibles arm64, si vous utilisez
Kleaf
pour créer votre kernel, --page_size=16k crée le kernel en mode 16 Ko.
Si vous utilisez directement la configuration du kernel Linux, vous pouvez sélectionner des pages de 16 Ko en définissant CONFIG_ARM64_16K_PAGES au lieu de CONFIG_ARM64_4K_PAGES.
Pour en savoir plus sur les binaires d'image de kernel générique (GKI) précompilés de 16 Ko, les branches compatibles, les versions et les détails de respin, consultez Versions GKI de 16 Ko et Builds de version GKI.
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 := truesupprime la définitionPAGE_SIZEet permet aux composants de déterminer la taille de la page au moment de l'exécution.PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384qui garantit que les fichiers ELF de la plate-forme sont créés avec un alignement de 16 Ko. Cette taille supérieure à celle nécessaire est destinée à la compatibilité future. Avec un alignement ELF de 16 Ko, le kernel peut prendre en charge les tailles de page de 4 Ko/16 Ko.
Vérifier les flags de compilation
Après avoir sélectionné la cible lunch, vérifiez que les flags 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 flags de compilation sont correctement configurés pour fonctionner avec un kernel de 16 Ko. Toutefois, même si une compilation réussit, il peut toujours y avoir des problèmes d'exécution en raison de différences dans un environnement de 16 Ko.
Programmation 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 de la page. Toutefois, pour le code qui traite des pages, le comportement d'allocation de mémoire du kernel change. Vous devez en tenir compte pour écrire du code qui est non seulement compatible, mais aussi le plus performant possible et qui consomme le moins de 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 kernel, 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 kernel alloue 8 Ko.
Sur un kernel 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 kernel 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 de 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 afin que seuls 16 Ko soient utilisés, ce qui gaspille 8 Ko par rapport au cas du kernel de 4 Ko. Pour réduire encore plus l'utilisation de la mémoire, vous pouvez combiner davantage 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 des pages est quatre fois plus petite pour la même mémoire.
Chaque fois que 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 kernel est directement visible pour l'espace utilisateur dans les valeurs d'exécution, au lieu d'être demandée implicitement et accessible implicitement ou accidentellement.
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 dans Activer la taille de page de 16 Ko suffisent :
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := truePRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
Pour créer des bibliothèques partagées qui ne font pas partie du projet Android, vous devez transmettre ce flag de l'é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 à tester et à exécuter sur un kernel 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 := trueau moment de la compilation. Utilisezignore_max_page_size: truedansAndroid.bpetLOCAL_IGNORE_MAX_PAGE_SIZE := truedansAndroid.mkpour les ignorer temporairement. Ces paramètres vérifient tous les précompilés et vous permettent de détecter quand l'un d'eux est mis à jour, mais n'est pas aligné sur 16 Ko.Vous pouvez exécuter
atest elf_alignment_testqui vérifie l'alignement des fichiers ELF sur l'appareil sur les appareils lancés avec Android 15 et versions ultérieures.