El tamaño de página es la granularidad con la que un SO administra la memoria. La mayoría de las CPU actuales admiten un tamaño de página de 4 KB, por lo que el SO Android y las apps se han creado y optimizado históricamente para ejecutarse con un tamaño de página de 4 KB. Las CPU de ARM admiten el tamaño de página más grande de 16 KB y, a partir de Android 15, el AOSP también admite la compilación de Android con un tamaño de página de 16 KB. Esta opción usa memoria adicional, pero mejora el rendimiento del sistema. A partir de Android 15, esta opción no está habilitada de forma predeterminada, pero está disponible como modo para desarrolladores o como opción para desarrolladores para que los OEM y los desarrolladores de apps se preparen para cambiar al modo de 16 KB en el futuro.
Android 15 y versiones posteriores admiten la compilación de Android con una alineación ELF de 16 KB, que funciona con kernels de 4 KB y 16 KB a partir de android14-6.1
.
Cuando se usa con un kernel de 16 KB, esta configuración usa memoria adicional, pero mejora el rendimiento del sistema.
Cómo configurar Android en 16 KB
Las páginas de 16 KB solo se admiten en destinos arm64
con kernels de 16 KB.
Sin embargo, también existe la opción de simular un espacio de usuario de 16 KB en x86_64
para Cuttlefish.
Espacio del kernel
Para los destinos arm64
, si usas Kleaf para compilar tu kernel, --page_size=16k
compila el kernel en modo de 16 KB.
Si usas directamente la configuración del kernel de Linux, puedes seleccionar páginas de 16 KB configurando CONFIG_ARM64_16K_PAGES
en lugar de CONFIG_ARM64_4K_PAGES
.
Espacio del usuario
Para habilitar la compatibilidad con el tamaño de página de 16 KB en el espacio del usuario de Android, establece las siguientes opciones de compilación en tu producto:
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
quita la definición dePAGE_SIZE
y hace que los componentes determinen el tamaño de la página en el tiempo de ejecución.PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
, que garantiza que los archivos ELF de la plataforma se compilen con una alineación de 16 KB. Este tamaño más grande de lo necesario es para la compatibilidad futura. Con la alineación ELF de 16 KB, el kernel puede admitir tamaños de página de 4 KB/16 KB.
Verifica las marcas de compilación
Después de seleccionar el destino lunch
, verifica que las marcas de compilación estén configuradas correctamente en el entorno:
$ 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 los dos comandos anteriores devuelven 16384
y true
, respectivamente, tus marcas de compilación están configuradas correctamente para funcionar con un kernel de 16 KB. Sin embargo, incluso si una compilación se aprueba, es posible que sigan existiendo problemas de tiempo de ejecución debido a las diferencias en un entorno de 16 KB.
Programación del sistema de tamaño de página de 16 KB
La gran mayoría del código en cualquier dispositivo con Android no se ocupa directamente del tamaño de la página. Sin embargo, para el código que se ocupa de las páginas, el comportamiento de asignación de memoria del kernel cambia, y debes tener esto en cuenta para escribir código que no solo sea compatible, sino también lo más eficiente posible y que consuma la menor cantidad de recursos.
Si llamas a mmap
en una región de 1 KB, 2 KB o hasta 4 KB en un sistema de 4 KB, el sistema reserva 4 KB para implementar esto. En otras palabras, cuando se solicita memoria al kernel, este siempre debe redondear la memoria solicitada al tamaño de página más cercano. Por ejemplo, si asignas una región de 5 KB en una región de 4 KB, el kernel asigna 8 KB.
En un kernel de 16 KB, estos "extremos finales" adicionales de las páginas son más grandes. Por ejemplo, todas estas asignaciones, de 1 KB a 5 KB, asignarían 16 KB cuando se usaran con un kernel de 16 KB. Si solicitas 17 KB, se asignan 32 KB.
Por ejemplo, en un sistema de 4 KB, está bien asignar dos regiones anónimas de lectura y escritura de 4 KB. Sin embargo, en un kernel de 16 KB, esto generaría la asignación de dos páginas o 32 KB. En un kernel de 16 KB, si es posible, estas regiones se pueden combinar en una sola página de lectura o escritura para que solo se usen 16 KB, lo que desperdicia 8 KB en comparación con el caso del kernel de 4 KB. Para reducir aún más el uso de memoria, se pueden combinar más páginas. De hecho, en un sistema de 16 KB optimizado al máximo, las páginas de 16 KB requieren menos memoria que los sistemas de 4 KB, ya que la tabla de páginas es un cuarto del tamaño para la misma memoria.
Siempre que uses mmap
, asegúrate de redondear el tamaño que solicitas al tamaño de página más cercano. Esto garantiza que la cantidad total de memoria que asigna el kernel sea directamente visible para el espacio del usuario en los valores de tiempo de ejecución, en lugar de solicitarse de forma implícita y ser accesible de forma implícita o accidental.
Compila bibliotecas compartidas con una alineación de ELF de 16 KB
Para compilar bibliotecas compartidas que forman parte del proyecto de Android, son suficientes los parámetros de configuración anteriores en Habilitar tamaño de página de 16 KB:
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
Para compilar bibliotecas compartidas que no forman parte de un proyecto de Android, debes pasar esta marca del vinculador:
-Wl,-z,max-page-size=16384
Verifica los archivos binarios y los elementos prediseñados para la alineación de ELF de 16 KB
La mejor manera de verificar la alineación y el comportamiento del tiempo de ejecución es probar y ejecutar en un kernel compilado de 16 KB. Sin embargo, para detectar algunos problemas antes, haz lo siguiente:
A partir de Android 16, puedes establecer
PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := true
en el momento de la compilación. Usaignore_max_page_size: true
enAndroid.bp
yLOCAL_IGNORE_MAX_PAGE_SIZE := true
enAndroid.mk
para ignorarlos temporalmente. Estos parámetros de configuración verifican todas las versiones precompiladas y te permiten detectar cuándo se actualiza una, pero no está alineada en 16 KB.Puedes ejecutar
atest elf_alignment_test
, que verifica la alineación de los archivos ELF en el dispositivo en los dispositivos que se lanzan con Android 15 y versiones posteriores.