本頁詳細說明為 Android 裝置建構自訂核心的程序。這些指示會逐步引導您選取合適的來源、建構核心,以及將結果嵌入從 Android 開放原始碼計畫 (AOSP) 建構的系統映像檔。
下載來源和建構工具
如要使用近期推出的核心,請使用 repo
下載來源、工具鍊和建構指令碼。部分核心 (例如 Pixel 3 核心) 需要多個 Git 存放區的來源,其他核心 (例如通用核心) 則只需要單一來源。使用 repo
方法可確保來源目錄設定正確無誤。
下載適當分支的來源:
mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync
如需可與先前的 `repo init` 指令搭配使用的 Repo 分支 (BRANCH) 清單,請參閱「核心分支及其建構系統」。
如要瞭解如何下載及編譯 Pixel 裝置的 Kernel,請參閱「 建構 Pixel Kernel」。
建構核心
使用 Bazel (Kleaf) 建構
Android 13 導入了使用 Bazel 建構核心的功能。
如要為 aarch64 架構建立 GKI 核心的發行版本,請查看不早於 Android 13 的 Android Common Kernel 分支版本,然後執行下列指令:
tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]
之後,核心二進位檔、模組和對應的映像檔會位於 $DIST_DIR
目錄中。如果未指定 --destdir
,請參閱指令輸出內容,瞭解構件的位置。詳情請參閱 AOSP 說明文件。
使用 build.sh 建構 (舊版)
如果是 Android 12 以下的分支版本,或是沒有 Kleaf 的分支版本:
build/build.sh
核心二進位檔、模組和對應的映像檔位於 out/BRANCH/dist
目錄中。
為虛擬裝置建構供應商模組
Android 13 導入了使用 Bazel (Kleaf) 建構核心的功能,取代 build.sh
。
如要為 virtual_device
的模組建立發布內容,請執行:
tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist [-- --destdir=$DIST_DIR]
如要進一步瞭解如何使用 Bazel 建構 Android 核心,請參閱。Kleaf - Building Android Kernels with Bazel。
如要瞭解 Kleaf 對個別架構的支援情形,請參閱「Kleaf support for devices and kernels」。
使用 build.sh (舊版) 建構虛擬裝置的供應商模組
在 Android 12 中,Cuttlefish 和 Goldfish 會合併,因此共用相同的核心:virtual_device
。如要建構該核心的模組,請使用下列建構設定:
BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh
Android 11 推出通用核心映像檔 (GKI),將核心分成 Google 維護的核心映像檔和供應商維護的模組,並分別建構。
以下範例顯示核心映像檔設定:
BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh
這個範例顯示模組設定 (Cuttlefish 和模擬器):
BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh
執行核心
執行自建核心的方法有很多種。以下是適合各種開發情境的已知方式。
嵌入 Android 映像檔建構作業
將 Image.lz4-dtb
複製到 AOSP 樹狀結構中的相應核心二進位位置,然後重建開機映像檔。
或者,您也可以在使用 make bootimage
(或任何其他可建構開機映像檔的 make
指令列) 時,定義 TARGET_PREBUILT_KERNEL
變數。所有裝置都支援這個變數,因為它是透過 device/common/populate-new-device.sh
設定。例如:
export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb
使用 Fastboot 刷寫及啟動核心
最新裝置都提供啟動載入程式擴充功能,可簡化產生及啟動啟動映像檔的程序。
如要在不刷機的情況下啟動核心,請按照下列步驟操作:
adb reboot bootloader
fastboot boot Image.lz4-dtb
使用這個方法時,系統不會實際刷入核心,且重新啟動後不會保留核心。
在 Cuttlefish 上執行核心
您可以在Cuttlefish 裝置上,以所選架構執行核心。
如要使用特定的一組核心構件啟動 Cuttlefish 裝置,請執行 cvd create
指令,並將目標核心構件做為參數。下列範例指令會使用 common-android14-6.1
核心資訊清單中的 arm64 目標核心構件。
cvd create \
-kernel_path=/$PATH/$TO/common-android14-6.1/out/android14-6.1/dist/Image \
-initramfs_path=/$PATH/$TO/common-android14-6.1/out/android14-6.1/dist/initramfs.img
詳情請參閱「在 Cuttlefish 上開發核心」。
自訂核心建構作業
如要自訂 Kleaf 建構的 Kernel 建構作業,請參閱 Kleaf 說明文件。
使用 build.sh 自訂核心建構作業 (舊版)
對於 build/build.sh
,建構程序和結果可能會受到環境變數影響。其中大多數是選用項目,每個核心分支都應附有適當的預設設定。以下列出最常用的幾種。如需完整 (且最新) 的清單,請參閱 build/build.sh
。
環境變數 | 說明 | 範例 |
---|---|---|
BUILD_CONFIG |
建構設定檔,您可從中初始化建構環境。
位置必須相對於存放區根目錄定義。預設值為 build.config 。常見核心的必要項目。 |
BUILD_CONFIG=common/build.config.gki.aarch64 |
CC |
覆寫要使用的編譯器。改回 build.config 定義的預設編譯器。 |
CC=clang |
DIST_DIR |
核心發布的基礎輸出目錄。 | DIST_DIR=/path/to/my/dist |
OUT_DIR |
核心建構作業的基本輸出目錄。 | OUT_DIR=/path/to/my/out |
SKIP_DEFCONFIG |
略過 make defconfig |
SKIP_DEFCONFIG=1 |
SKIP_MRPROPER |
略過 make mrproper |
SKIP_MRPROPER=1 |
本機建構作業的自訂核心設定
在 Android 14 以上版本中,您可以使用 defconfig 片段自訂核心設定。請參閱 Kleaf 說明文件中的 defconfig 片段。
使用建構設定 (舊版) 為本機建構作業自訂核心設定
如果是 Android 13 以下版本,請參閱下列說明。
如果您需要定期切換核心設定選項 (例如開發功能時),或是需要為開發目的設定選項,可以維護建構設定的本機修改項目或副本,達到所需的彈性。
將變數 POST_DEFCONFIG_CMDS 設為陳述式,在完成一般 make defconfig
步驟後立即評估。由於 build.config
檔案會納入建構環境,因此可以呼叫 build.config
中定義的函式,做為 post-defconfig 指令的一部分。
常見的例子是在開發期間,停用 Crosshatch 核心的連結時間最佳化 (LTO)。雖然 LTO 對於發布的 Kernel 有益,但建構時的負擔可能相當大。以下程式碼片段新增至本機 build.config
時,會在使用 build/build.sh
時持續停用 LTO。
POST_DEFCONFIG_CMDS="check_defconfig && update_debug_config"
function update_debug_config() {
${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \
-d LTO \
-d LTO_CLANG \
-d CFI \
-d CFI_PERMISSIVE \
-d CFI_CLANG
(cd ${OUT_DIR} && \
make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig)
}
找出核心版本
您可以從兩個來源找出要建構的正確版本:AOSP 樹狀結構和系統映像檔。
Android 開放原始碼計畫樹狀結構中的核心版本
Android 開放原始碼計畫樹狀結構包含預先建構的核心版本。git log 會在提交訊息中顯示正確版本:
cd $AOSP/device/VENDOR/NAME
git log --max-count=1
如果 Git 記錄中未列出核心版本,請按照下列說明從系統映像檔取得。
系統映像檔的核心版本
如要判斷系統映像檔中使用的核心版本,請對核心檔案執行下列指令:
file kernel
如為 Image.lz4-dtb
檔案,請執行:
grep -a 'Linux version' Image.lz4-dtb
建構開機映像檔
您可以使用核心建構環境建構開機映像檔。
為搭載 init_boot 的裝置建構開機映像檔
對於具有 init_boot
分割區的裝置,開機映像檔會與核心一起建構。initramfs
圖片未嵌入開機映像檔。
舉例來說,您可以使用 Kleaf 建構 GKI 開機映像檔:
tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]
使用 build/build.sh
(舊版) 時,您可以使用下列指令建構 GKI 開機映像檔:
BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
GKI 開機映像檔位於 $DIST_DIR。
為沒有 init_boot 的裝置建構開機映像檔 (舊版)
如果裝置沒有 init_boot
分割區,您需要 ramdisk 二進位檔,可以下載 GKI 開機映像檔並解壓縮取得。您可以使用相關聯 Android 版本中的任何 GKI 開機映像檔。
tools/mkbootimg/unpack_bootimg.py --boot_img=boot-5.4-gz.img
mv $KERNEL_ROOT/out/ramdisk gki-ramdisk.lz4
目標資料夾是核心樹狀結構的頂層目錄 (目前的工作目錄)。
如果您使用最新的 AOSP 發布分支版本進行開發,可以改為從 ci.android.com 的 aosp_arm64 建構作業下載 ramdisk-recovery.img
建構構件,並將其做為 ramdisk 二進位檔。
取得 ramdisk 二進位檔並複製到核心建構作業的根目錄 gki-ramdisk.lz4
後,即可執行下列指令來產生開機映像檔:
BUILD_BOOT_IMG=1 SKIP_VENDOR_BOOT=1 KERNEL_BINARY=Image GKI_RAMDISK_PREBUILT_BINARY=gki-ramdisk.lz4 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
如果您使用 x86 架構,請將 Image
取代為 bzImage
,並將 aarch64
取代為 x86_64
:
BUILD_BOOT_IMG=1 SKIP_VENDOR_BOOT=1 KERNEL_BINARY=bzImage GKI_RAMDISK_PREBUILT_BINARY=gki-ramdisk.lz4 BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh
該檔案位於構件目錄 $KERNEL_ROOT/out/$KERNEL_VERSION/dist
中。
啟動映像檔位於 out/<kernel branch>/dist/boot.img
。