16 KB 頁面大小

頁面大小是作業系統管理記憶體的細微程度。目前大多數 CPU 都支援 4 KB 分頁大小,因此 Android 作業系統和應用程式在建構和最佳化時,一向以 4 KB 分頁大小為基準。ARM CPU 支援較大的 16 KB 分頁大小,且自 Android 15 起,AOSP 也支援建構 16 KB 分頁大小的 Android。這個選項會使用額外記憶體,但可提升系統效能。自 Android 15 起,系統預設不會啟用這個選項,但 OEM 和應用程式開發人員可以透過開發人員模式或開發人員選項,為日後全面切換至 16 KB 模式做好準備。

Android 15 以上版本支援使用 16 KB ELF 對齊建構 Android,並可與 android14-6.1 以上版本的 4 KB 和 16 KB 核心搭配使用。搭配 16 KB 核心使用時,這項設定會使用額外記憶體,但可提升系統效能。

將 Android 設為 16 KB

16 KB 分頁僅支援搭載 16 KB 核心的 arm64 目標。不過,您也可以選擇在 x86_64 上模擬 16 KB 使用者空間,以便使用 Cuttlefish。

核心空間

如果是 arm64 目標,使用 Kleaf 建構核心時,--page_size=16k 會以 16 KB 模式建構核心。如果您直接使用 Linux 核心設定,可以設定 CONFIG_ARM64_16K_PAGES (而非 CONFIG_ARM64_4K_PAGES),選取 16 KB 頁面。

如要瞭解預先建構的 16 KB 通用核心映像檔 (GKI) 二進位檔、支援的分支版本,以及發布和重製 (respin) 的詳細資料,請參閱「16 KB GKI 版本」和「GKI 發布子版本」。

使用者空間

如要在 Android 使用者空間中啟用 16 KB 分頁大小支援,請在產品上設定下列建構選項:

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true 會移除 PAGE_SIZE 定義,並讓元件在執行階段決定頁面大小。
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384,確保平台 ELF 檔案是以 16 KB 對齊方式建構。這個大小超出實際需求,是為了確保日後相容性。採用 16 KB ELF 對齊方式後,核心可支援 4 KB/16 KB 頁面大小。

驗證建構旗標

選取 lunch 目標後,請確認環境中的建構旗標設定正確:

$ 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

如果前兩個指令分別傳回 16384 和 true,表示建構標記設定正確,可搭配 16 KB 核心運作。不過,即使建構作業通過,16 KB 環境的差異仍可能導致執行階段問題。

16 KB 分頁大小系統程式設計

在任何 Android 裝置上,絕大多數的程式碼都不會直接處理頁面大小。不過,如果是處理網頁的程式碼,核心的記憶體配置行為會有所不同,因此您必須留意這一點,才能編寫出不僅相容,而且效能最高、資源密集度最低的程式碼。

如果您在 4 KB 系統上,對 1 KB、2 KB 或最多 4 KB 的區域呼叫 mmap,系統會保留 4 KB 來實作。換句話說,向核心要求記憶體時,核心一律會將要求的記憶體四捨五入至最接近的分頁大小。舉例來說,如果您在 4 KB 區域分配 5 KB 區域,核心會分配 8 KB。

在 16 KB 核心上,這些額外的「尾端」頁面會更大。舉例來說,如果搭配 16 KB 核心使用,從 1 KB 到 5 KB 的所有配置都會配置 16 KB。如果您要求 17 KB,系統會分配 32 KB。

舉例來說,在 4 KB 系統上,可以分配兩個 4 KB 讀寫匿名區域。不過,在 16 KB 核心上,這會導致分配兩個頁面或 32 KB。在 16 KB 核心上,如果可以,這些區域可以合併為單一可讀取或寫入的頁面,因此只會使用 16 KB,與 4 KB 核心案例相比,浪費了 8 KB。如要進一步減少記憶體用量,可以合併更多頁面。事實上,在經過最佳化的 16 KB 系統上,16 KB 分頁所需的記憶體比 4 KB 系統少,因為分頁表的大小是相同記憶體的四分之一。

使用 mmap 時,請務必將要求的大小四捨五入至最接近的頁面大小。這可確保核心分配的記憶體總量,會直接顯示在使用者空間的執行階段值中,而不是隱含要求,以及隱含或意外存取。

建構 ELF 對齊方式為 16 KB 的共用程式庫

如要建構屬於 Android 專案的共用程式庫,只要使用「啟用 16 KB 分頁大小」一節中的設定即可:

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384

如要建構不屬於 Android 專案的共用程式庫,您必須傳遞以下連結器旗標:

-Wl,-z,max-page-size=16384

確認二進位檔和預先建構的項目是否支援 16 KB ELF 對齊

如要驗證對齊方式和執行階段行為,最好的方法是在 16 KB 編譯核心上測試及執行。不過,如要提早發現某些問題,請採取下列做法:

  • 從 Android 16 開始,您可以在建構時設定 PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := true。在 Android.bp 中使用 ignore_max_page_size: true,以及在 Android.mk 中使用 LOCAL_IGNORE_MAX_PAGE_SIZE := true,即可暫時忽略這些項目。這些設定會驗證所有預建項目,並在偵測到更新項目未對齊 16 KB 時通知您。

  • 您可以執行 atest elf_alignment_test,驗證搭載 Android 15 以上版本的裝置上,裝置端 ELF 檔案的對齊方式。