本頁詳細說明為 Android 裝置建構自訂核心的程序。這些操作說明會引導您完成選取正確來源、建構核心,以及將結果嵌入由 Android 開放原始碼計畫 (AOSP) 建構的系統映像檔的程序。
您可以使用 Repo 取得較新的核心來源;只要從來源檢出的根目錄執行 build/build.sh
,即可不必進一步設定就建構核心。
下載來源和建構工具
如要使用近期的核心,請使用 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` 指令使用的存放區分支 (BRANCH) 清單,請參閱 核心分支和其建構系統。
如要進一步瞭解如何下載及編譯 Pixel 裝置的核心,請參閱「 建構 Pixel 核心」。
建構核心
使用 Bazel (Kleaf) 進行建構
Android 13 推出了使用 Bazel 建構核心的功能。
如要為 aarch64 架構建立 GKI 核心的發行版本,請檢查 Android 13 以上的 Android 通用核心分支,然後執行下列指令:
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 - 使用 Bazel 建構 Android 核心。
如要進一步瞭解個別架構的 Kleaf 支援,請參閱「裝置和核心的 Kleaf 支援」。
使用 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 和 Emulator):
BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh
執行核心
您可以透過多種方式執行自訂核心。以下是適合各種開發情境的已知方法。
嵌入 Android 映像檔建構作業
將 Image.lz4-dtb
複製到 Android 開放原始碼計畫樹狀結構中的對應核心二進位檔位置,然後重新建構開機映像檔。
或者,您也可以在使用 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 建構的核心版本,請參閱 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
中定義的函式。
常見的例子是在開發期間,為交叉格式核心停用連結時間最佳化 (LTO)。雖然 LTO 對已發布的核心有益,但建構期間的額外負擔可能會相當大。以下程式碼片段會新增至本機 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 樹狀結構和系統映像檔。
來自 AOSP 樹狀結構的核心版本
Android 開放原始碼計畫樹狀結構包含預先建構的核心版本。Git 記錄會在修訂版本訊息中顯示正確的版本:
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 main 進行開發,可以改為從 ci.android.com 的 aosp_arm64 版本下載 ramdisk-recovery.img
建構成果物,並將其用於 RAM 磁碟二進位檔。
當您取得 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
。