O tamanho da página é a granularidade em que um SO gerencia a memória. A maioria das CPUs atuais aceita um tamanho de página de 4 KB. Por isso, o SO Android e os apps foram historicamente criados e otimizados para serem executados com um tamanho de página de 4 KB. As CPUs ARM são compatíveis com o tamanho de página maior de 16 KB, e, a partir do Android 15, o AOSP também oferece suporte à criação do Android com um tamanho de página de 16 KB. Essa opção usa mais memória, mas melhora o desempenho do sistema. No Android 15, essa opção não está ativada por padrão, mas está disponível como um modo ou uma opção de desenvolvedor para OEMs e desenvolvedores de apps se prepararem para mudar para o modo de 16 KB em todos os lugares no futuro.
O Android 15 e versões mais recentes oferecem suporte à criação
do Android com um alinhamento ELF de 16 KB, que funciona com kernels de 4 KB e
16 KB a partir do
android14-6.1
.
Quando usada com um kernel de 16 KB, essa configuração usa mais memória, mas melhora o desempenho do sistema.
Definir o Android como 16 KB
As páginas de 16 KB só são compatíveis com destinos arm64
com kernels de 16 KB.
No entanto, também há uma opção para
simular o espaço do usuário de 16 KB em x86_64
para o Cuttlefish.
Espaço do kernel
Para destinos arm64
, se você usar o
Kleaf
para criar o kernel, o --page_size=16k
vai criar o kernel no modo de 16 KB.
Se você estiver usando diretamente a configuração do kernel do Linux, poderá selecionar páginas de 16 KB definindo CONFIG_ARM64_16K_PAGES
em vez de CONFIG_ARM64_4K_PAGES
.
Espaço do usuário
Para ativar o suporte a tamanho de página de 16 KB no espaço do usuário do Android, defina as seguintes opções de build no seu produto:
- O
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
remove a definiçãoPAGE_SIZE
e faz com que os componentes determinem o tamanho da página durante a execução. PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
, que garante que os arquivos ELF da plataforma sejam criados com alinhamento de 16 KB. Esse tamanho maior do que o necessário é para compatibilidade futura. Com o alinhamento ELF de 16 KB, o kernel pode oferecer suporte a tamanhos de página de 4 KB/16 KB.
Verificar flags de build
Depois de selecionar o destino lunch
, verifique se as flags de build estão configuradas corretamente no ambiente:
$ 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
Se os dois comandos anteriores retornarem 16384
e true
, respectivamente, as flags de build
estarão configuradas corretamente para funcionar com um kernel de 16 KB. No entanto, mesmo que um build seja aprovado, ainda podem ocorrer problemas de tempo de execução devido a diferenças em um ambiente de 16 KB.
Programação de sistema com tamanho de página de 16 KB
A grande maioria do código em qualquer dispositivo Android não lida diretamente com o tamanho da página. No entanto, para códigos que lidam com páginas, o comportamento de alocação de memória do kernel muda, e é preciso ter isso em mente para escrever códigos que não sejam apenas compatíveis, mas também tenham o máximo de desempenho e o mínimo de uso de recursos.
Se você chamar mmap
em uma região de 1 KB, 2 KB ou até 4 KB em um sistema de 4 KB, o sistema vai reservar 4 KB para implementar isso. Em outras palavras, ao solicitar memória do kernel, ele sempre precisa arredondar a memória solicitada para o tamanho de página mais próximo. Por exemplo, se você alocar uma região de 5 KB em uma região de 4 KB, o kernel vai alocar 8 KB.
Em um kernel de 16 KB, essas "extremidades finais" extras das páginas são maiores. Por exemplo, todas essas alocações, de 1 KB a 5 KB, alocariam 16 KB quando usadas com um kernel de 16 KB. Se você solicitar 17 KB, ele vai alocar 32 KB.
Por exemplo, em um sistema de 4 KB, é possível alocar duas regiões anônimas de leitura e gravação de 4 KB. No entanto, em um kernel de 16 KB, isso resultaria na alocação de duas páginas ou 32 KB. Em um kernel de 16 KB, se possível, essas regiões podem ser combinadas em uma única página legível ou gravável para que apenas 16 KB sejam usados, desperdiçando 8 KB em comparação com o caso do kernel de 4 KB. Para reduzir ainda mais o uso de memória, mais páginas podem ser combinadas. Na verdade, em um sistema de 16 KB totalmente otimizado, as páginas de 16 KB exigem menos memória do que os sistemas de 4 KB porque a tabela de páginas tem um quarto do tamanho para a mesma memória.
Sempre que usar mmap
, arredonde o tamanho solicitado para o tamanho de página mais próximo. Isso garante que toda a quantidade de memória alocada pelo kernel seja diretamente visível para o espaço do usuário em valores de tempo de execução, em vez de ser solicitada implicitamente e acessível de forma implícita ou acidental.
Criar bibliotecas compartilhadas com alinhamento ELF de 16 KB
Para criar bibliotecas compartilhadas que fazem parte do projeto do Android, as configurações anteriores em Ativar tamanho de página de 16 KB são suficientes:
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
Para criar bibliotecas compartilhadas que não fazem parte do projeto do Android, transmita esta flag do vinculador:
-Wl,-z,max-page-size=16384
Verificar binários e pré-compilados para alinhamento ELF de 16 KB
A melhor maneira de verificar o alinhamento e o comportamento de tempo de execução é testar e executar em um kernel compilado de 16 KB. No entanto, para detectar alguns problemas mais cedo:
A partir do Android 16, é possível definir
PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := true
durante a compilação. Useignore_max_page_size: true
emAndroid.bp
eLOCAL_IGNORE_MAX_PAGE_SIZE := true
emAndroid.mk
para ignorar temporariamente. Essas configurações verificam todos os pré-criados e permitem detectar quando um deles é atualizado, mas não está alinhado a 16 KB.Você pode executar
atest elf_alignment_test
, que verifica o alinhamento de arquivos ELF no dispositivo em dispositivos lançados com Android 15 e versões mais recentes.