建構核心

本頁詳細說明為 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 通用核心分支版本不低於 Android 13 然後執行下列指令:

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 複製至 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 版本的核心版本,請參閱 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

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)
}

找出核心版本

您可以透過 Android 開放原始碼計畫樹狀結構,從下列兩個來源找出要建構的正確版本。 以及系統映像檔

來自 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