La dimensione della pagina è la granularità con cui un sistema operativo gestisce la memoria. La maggior parte delle CPU attuali supporta una dimensione della pagina di 4 kB, pertanto il sistema operativo Android e le app sono stati storicamente creati e ottimizzati per essere eseguiti con una dimensione della pagina di 4 kB. Le CPU ARM supportano la dimensione della pagina più grande di 16 kB e, a partire da Android 15, anche AOSP supporta la creazione di Android con una dimensione della pagina di 16 kB. Questa opzione utilizza memoria aggiuntiva, ma migliora le prestazioni del sistema. A partire da Android 15, questa opzione non è attivata per impostazione predefinita, ma è disponibile come modalità sviluppatore o opzione sviluppatore per OEM e sviluppatori di app per prepararsi al passaggio alla modalità a 16 kB ovunque in futuro.
Android 15 e versioni successive supportano la creazione di
Android con un allineamento ELF di 16 kB, che funziona con i kernel da 4 kB e
16 kB a partire da
android14-6.1.
Se utilizzata con un kernel da 16 kB, questa configurazione utilizza memoria aggiuntiva, ma migliora le prestazioni del sistema.
Imposta Android su 16 kB
Le pagine da 16 kB sono supportate solo su target arm64 con kernel da 16 kB.
Tuttavia, è disponibile anche un'opzione per
simulare lo spazio utente da 16 kB su x86_64 per Cuttlefish.
Spazio kernel
Per i target arm64, se utilizzi
Kleaf
per creare il kernel, --page_size=16k crea il kernel in modalità a 16 kB.
Se utilizzi direttamente la configurazione del kernel Linux, puoi selezionare le pagine da 16 kB impostando CONFIG_ARM64_16K_PAGES anziché CONFIG_ARM64_4K_PAGES.
Per i file binari GKI (Generic Kernel Image) da 16 kB precompilati, i rami supportati e i dettagli di release e respin, consulta Release GKI da 16 kB e build di release GKI.
Spazio utente
Per attivare il supporto della dimensione della pagina di 16 kB nello spazio utente di Android, imposta le seguenti opzioni di build sul tuo prodotto:
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := truerimuove la definizionePAGE_SIZEe fa in modo che i componenti determinino la dimensione della pagina in fase di runtime.PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384, che garantisce che i file ELF della piattaforma vengano creati con un allineamento di 16 kB. Questa dimensione maggiore del necessario è per la compatibilità futura. Con l'allineamento ELF di 16 kB, il kernel può supportare dimensioni della pagina di 4 kB/16 kB.
Verifica i flag di build
Dopo aver selezionato il target lunch, verifica che i flag di build siano configurati correttamente nell'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 i due comandi precedenti restituiscono rispettivamente 16384 e true, i flag di build sono configurati correttamente per funzionare con un kernel da 16 kB. Tuttavia, anche se una build viene eseguita correttamente, potrebbero verificarsi problemi di runtime a causa delle differenze in un ambiente da 16 kB.
Programmazione di sistema con dimensione della pagina di 16 kB
La stragrande maggioranza del codice su qualsiasi dispositivo con Android non gestisce direttamente la dimensione della pagina. Tuttavia, per il codice che gestisce le pagine, il comportamento di allocazione della memoria del kernel cambia e devi tenerlo presente per scrivere codice non solo compatibile, ma anche con prestazioni ottimali e con un consumo minimo di risorse.
Se chiami mmap su una regione di 1 kB, 2 kB o fino a 4 kB su un sistema da 4 kB, il sistema riserva 4 kB per implementarla. In altre parole, quando richiedi memoria al kernel, quest'ultimo deve sempre arrotondare la memoria richiesta alla dimensione della pagina più vicina. Ad esempio, se allochi una regione di 5 kB su una regione di 4 kB, il kernel alloca 8 kB.
Su un kernel da 16 kB, queste "estremità finali" aggiuntive delle pagine sono più grandi. Ad esempio, tutte queste allocazioni, da 1 kB a 5 kB, allocano 16 kB se utilizzate con un kernel da 16 kB. Se richiedi 17 kB, vengono allocati 32 kB.
Ad esempio, su un sistema da 4 kB, è possibile allocare due regioni anonime di lettura/scrittura da 4 kB. Tuttavia, su un kernel da 16 kB, ciò comporterebbe l'allocazione di due pagine o 32 kB. Su un kernel da 16 kB, se possibile, queste regioni possono essere combinate in una singola pagina di lettura o scrittura in modo che vengano utilizzati solo 16 kB, sprecando 8 kB rispetto al caso del kernel da 4 kB. Per ridurre ulteriormente la memoria utilizzata, è possibile combinare più pagine. Infatti, su un sistema da 16 kB ottimizzato al massimo, le pagine da 16 kB richiedono meno memoria rispetto ai sistemi da 4 kB perché la tabella delle pagine è un quarto della dimensione per la stessa memoria.
Ogni volta che utilizzi mmap, assicurati di arrotondare la dimensione richiesta alla dimensione della pagina più vicina. In questo modo, l'intera quantità di memoria allocata dal kernel è direttamente visibile allo spazio utente nei valori di runtime, anziché essere richiesta implicitamente e accessibile implicitamente o accidentalmente.
Crea librerie condivise con allineamento ELF di 16 kB
Per creare librerie condivise che fanno parte del progetto Android, le impostazioni precedenti in Attiva la dimensione della pagina di 16 kB sono sufficienti:
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := truePRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
Per creare librerie condivise che non fanno parte del progetto Android, devi passare questo flag del linker:
-Wl,-z,max-page-size=16384
Verifica i file binari e i precompilati per l'allineamento ELF di 16 kB
Il modo migliore per verificare l'allineamento e il comportamento di runtime è testare ed eseguire su un kernel compilato da 16 kB. Tuttavia, per rilevare alcuni problemi in anticipo:
A partire da Android 16, puoi impostare
PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := truein fase di build. Utilizzaignore_max_page_size: trueinAndroid.bpeLOCAL_IGNORE_MAX_PAGE_SIZE := trueinAndroid.mkper ignorarli temporaneamente. Queste impostazioni verificano tutti i precompilati e ti consentono di rilevare quando uno viene aggiornato ma non è allineato a 16 kB.Puoi eseguire
atest elf_alignment_test, che verifica l'allineamento dei file ELF sul dispositivo sui dispositivi lanciati con Android 15 e versioni successive.