構建內核

本頁詳細介紹了為 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

下表列出了通過此方法可用的內核的BRANCH名稱。

設備AOSP 樹中的二進制路徑回購分支
像素折疊(菲利克斯)設備/谷歌/felix-內核android-gs-felix-5.10-android13-qpr3-c
Pixel 平板電腦 (tangorpro)設備/谷歌/tangorpro-內核android-gs-tangorpro-5.10-android13-qpr3
Pixel 7(黑豹)
Pixel 7 Pro(獵豹)
設備/谷歌/pantah-內核android-gs-pantah-5.10-android13-qpr3
Pixel 6a(冠藍鴉)設備/谷歌/bluejay-內核android-gs-bluejay-5.10-android13-qpr3
Pixel 6(黃鶯)
Pixel 6 Pro(烏鴉)
設備/谷歌/raviole-內核android-gs-raviole-5.10-android13-qpr3
Pixel 5a(巴貝)
Pixel 5(紅鰭)
Pixel 4a (5G)(荊棘)
設備/谷歌/紅牛內核android-msm-redbull-4.19-android13-qpr3
Pixel 4a(翻車魚)設備/谷歌/sunfish-內核android-msm-sunfish-4.14-android13-qpr3
像素4(火焰)
Pixel 4 XL(珊瑚色)
設備/谷歌/珊瑚內核android-msm-coral-4.14-android13
Pixel 3a(薩爾戈)
Pixel 3a XL(鰹魚)
設備/谷歌/鰹魚內核android-msm-bonito-4.9-android12L
Pixel 3(藍線)
Pixel 3 XL(交叉線)
設備/谷歌/crosshatch-kernel android-msm-crosshatch-4.9-android12
Pixel 2(白眼魚)
Pixel 2 XL(泰門)
設備/谷歌/wahoo-內核android-msm-wahoo-4.4-android10-qpr3
像素(旗魚)
Pixel XL(馬林魚)
設備/谷歌/marlin-內核android-msm-marlin-3.18-pie-qpr2
海基960設備/linaro/hikey-內核遠基-linaro-android-4.14
遠基-linaro-android-4.19
通用-android12-5.4
通用-android13-5.10
比格犬 x15設備/ti/beagle_x15-內核omap-beagle-x15-android-4.14
omap-beagle-x15-android-4.19
Android通用內核不適用通用-android-4.4
通用-android-4.9
通用-android-4.14
通用-android-4.19
通用-android-4.19-穩定版
通用-android11-5.4
通用-android12-5.4
通用-android12-5.10
通用-android13-5.10
通用-android13-5.15
通用-android14-5.15
通用-android14-6.1
通用 android 主線

構建內核

使用 Bazel (Kleaf) 構建

Android 13 引入了使用Bazel構建內核。

要為 aarch64 架構構建 GKI 內核,請查看不早於 Android 13 的 Android Common Kernel 分支,然後運行以下命令:

tools/bazel build //common:kernel_aarch64_dist

要創建發行版,請運行:

tools/bazel run //common:kernel_aarch64_dist -- --dist_dir=$DIST_DIR

此後,內核二進製文件、模塊和相應的映像位於$DIST_DIR目錄中。如果未指定--dist_dir ,請參閱命令的輸出以了解工件的位置。有關詳細信息,請參閱AOSP 上的文檔

使用 build.sh 進行構建(舊版)

對於 Android 12 或更低版本的分支,或沒有 Kleaf 的分支:

build/build.sh

內核二進製文件、模塊和相應的映像位於out/ BRANCH /dist目錄中。

為虛擬設備構建供應商模塊

Android 13 引入了使用Bazel (Kleaf) 構建內核,取代了build.sh

要構建virtual_device的模塊,請運行:

tools/bazel build //common-modules/virtual-device:virtual_device_x86_64_dist

要創建發行版,請運行:

tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist -- --dist_dir=$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 和模擬器):

BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh

Kleaf 對設備和內核的支持

下表列出了 Kleaf 對各個設備內核的支持。對於未列出的設備,請聯繫設備製造商。

設備回購分支葉子支撐build/build.sh支持
Android通用內核
db845c
虛擬設備(x86_64、arm64)
虛擬設備(i686、arm)
Rockpi4
通用-android-4.4
通用-android-4.9
通用-android-4.14
通用-android-4.19
通用-android-4.19-穩定版
通用-android11-5.4
通用-android12-5.4
通用-android12-5.10
Android通用內核通用-android13-5.10
通用-android13-5.15
✅(官方) 1
Android通用內核通用-android14-5.15
通用-android14-6.1
通用-android15-6.1
通用 android 主線
db845c通用-android13-5.10
db845c通用-android13-5.15 ✅(官方) 1
db845c通用-android14-5.15
通用-android14-6.1
通用-android15-6.1
通用 android 主線
虛擬設備(x86_64、arm64)通用-android13-5.10
通用-android13-5.15
✅(官方) 1 ⚠️(未維護) 2
虛擬設備(x86_64、arm64)通用-android14-5.15
通用-android14-6.1
通用-android15-6.1
通用 android 主線
虛擬設備(i686、arm)通用-android13-5.10
通用-android13-5.15
虛擬設備(i686、arm)通用-android14-5.15
通用-android14-6.1
通用-android15-6.1
通用 android 主線
Rockpi4通用-android13-5.10
通用-android13-5.15
Rockpi4通用-android14-5.15
通用-android14-6.1
通用-android15-6.1
通用 android 主線
海基960遠基-linaro-android-4.14
遠基-linaro-android-4.19
通用-android12-5.4
通用-android13-5.10
fips140模塊通用-android12-5.10
通用-android13-5.10
通用-android13-5.15
fips140模塊通用-android14-5.15

1 “官方”意味著這是構建內核的官方方法,儘管也可能使用替代方法來構建內核。

2 “未維護”意味著使用此方法構建內核應該可以工作,但構建方法沒有經過持續測試。未來可能會停止建設。請改用“官方”方式構建。

運行內核

有多種方法可以運行定制的內核。以下是適合各種開發場景的已知方式。

嵌入到 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 start命令並將目標內核工件作為參數。以下示例命令使用common-android14-6.1內核清單中的 arm64 目標的內核工件。

cvd start \
    -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從初始化構建環境的位置構建配置文件。該位置必須相對於 Repo 根目錄進行定義。默認為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(AOSP 實驗版)及更高版本中,您可以使用 defconfig 片段來自定義內核配置。請參閱有關 defconfig 片段的 Kleaf 文檔

使用構建配置(舊版)進行本地構建的自定義內核配置

在 Android 13 及更低版本中,請參閱以下內容。

如果您需要定期切換內核配置選項(例如,在處理某個功能時),或者如果您需要為開發目的設置選項,則可以通過維護構建配置的本地修改或副本來實現這種靈活性。

將變量POST_DEFCONFIG_CMDS設置為在通常的make defconfig步驟完成後立即評估的語句。由於build.config文件源自構建環境,因此可以將build.config中定義的函數作為 post-defconfig 命令的一部分進行調用。

一個常見的示例是在開發過程中禁用交叉影線內核的鏈接時間優化 (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 樹的內核版本

AOSP 樹包含預構建的內核版本。 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 -- --dist_dir=$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構建工件,並將其用作 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