建構核心

本頁詳細說明為 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