Taille de page : 16 Ko

La taille de page correspond à la granularité à laquelle un système d'exploitation gère la mémoire. La plupart des processeurs d'aujourd'hui 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 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. Depuis 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 développeurs afin que les OEM et les développeurs d'applications puissent se préparer à passer au mode 16 ko partout à l'avenir.

Android 15 et versions ultérieures prennent en charge la compilation d'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 l'espace utilisateur Android sur 16 ko

Les pages de 16 ko ne sont compatibles qu'avec les cibles arm64 avec des noyaux de 16 ko. Toutefois, il est également possible de simuler un espace utilisateur de 16 ko sur x86_64 pour Cuttlefish.

Pour les cibles arm64, si vous utilisez Kleaf pour créer votre kernel, --page_size=16k le crée 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.

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éfinition PAGE_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, qui garantit que les fichiers ELF de la plate-forme sont compilés avec un alignement de 16 Ko. Cette taille supérieure à la 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 configurés correctement pour fonctionner avec un noyau de 16 ko. Toutefois, même si une compilation réussit, des problèmes d'exécution peuvent toujours se produire en raison des 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 un appareil Android ne gère pas directement la taille de la page. Toutefois, pour le code qui traite des pages, le comportement d'allocation de mémoire du noyau change. Vous devez garder cela à l'esprit pour écrire du code qui n'est pas seulement compatible, mais aussi performant au maximum et peu gourmand en ressources.

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 l'implémenter. En d'autres termes, lorsque vous demandez de la mémoire au noyau, le noyau 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 importantes. 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, vous pouvez 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 ou 32 ko. Sur un kernel de 16 Ko, si possible, ces régions peuvent être combinées en une seule page en lecture ou en écriture afin que seuls 16 Ko soient utilisés, ce qui gaspille 8 Ko par rapport au 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 de pages est un quart de la taille pour la même mémoire.

Chaque fois que vous utilisez mmap, assurez-vous d'arrondir la taille que vous demandez à la taille de page la plus proche. Cela garantit que la totalité de la 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 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 de Activer la taille de page de 16 ko sont suffisants:

  • 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 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

Le meilleur moyen de vérifier l'alignement et le comportement d'exécution consiste à tester et à exécuter sur un noyau compilé de 16 ko. Toutefois, pour détecter certains problèmes plus tôt:

  • À partir d'Android 16 (AOSP expérimental), vous pouvez définir PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := true au moment de la compilation. Utilisez ignore_max_page_size: true dans Android.bp et LOCAL_IGNORE_MAX_PAGE_SIZE := true dans Android.mk pour 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_test, qui vérifie l'alignement des fichiers ELF sur l'appareil sur les appareils lancés avec Android 15 ou version ultérieure.