构建内核

构建内核

本页详细介绍了为 Android 设备构建自定义内核的流程。以下说明会逐步指导您如何选择正确的源代码,构建内核,以及将结果嵌入到根据 Android 开源项目 (AOSP) 构建的系统映像中。

您可以使用 Repo 获取最新的内核源代码;通过在源代码检出的根目录下运行 build/build.sh 可构建这些内核源代码,而无需更多配置。

注意:内核源代码检出的根目录包含 build/build.sh。Android 树仅包含预构建的内核二进制文件。内核树包含内核源代码和用于构建内核的所有工具,包括此脚本。

下载源代码和构建工具

对于最新的内核,可以使用 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 设备下载和编译内核,请参阅构建 Pixel 内核。

注意:您可以在一个 Repo 检出中切换不同的分支。通用内核清单(以及大多数其他清单)定义了要完全克隆(非浅克隆)的内核 git 仓库,这使您能够在这些分支之间快速切换。切换到不同的分支类似于初始化分支;-u 参数是可选的。例如,要从现有的 Repo 检出切换到 common-android-mainline,请运行以下命令:$ repo init -b common-android-mainline && repo sync。

构建内核

使用 Bazel (Kleaf) 构建

注意:如需了解何时可以使用 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 14 及更高版本不支持 build.sh。

对于 Android 12 或更低版本的分支,或者不使用 Kleaf 的分支:

build/build.sh

注意:通用内核是通用的可自定义内核,因此不会定义默认配置。如需了解如何为通用内核指定 build 配置,请参阅自定义内核 build。例如,如需为 aarch64 平台构建 GKI 内核,请运行以下命令:

$ BUILD_CONFIG=common/build.config.gki.aarch64 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 配置:

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 映像 build 中

将 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

使用此方法时,内核实际上并未刷新,因此不会在重新启动时保留。

注意:内核名称因设备而异。要找到内核的正确文件名,请参阅 AOSP 树中的 device/VENDOR/NAME-kernel。

在 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 build 自定义内核 build,请参阅 Kleaf 文档。

注意:通常,Kleaf 构建流程不受环境变量影响,而受命令行选项和 BUILD 定义的影响。

使用 build.sh(旧版)自定义内核 build

对于 build/build.sh,构建流程和结果可能会受环境变量的影响。它们中的大多数是可选的,并且每个内核分支都应该具有适当的默认配置。此处列出了最常用的变量。如需完整(且最新)的列表,请参阅 build/build.sh。

环境变量

说明

示例

BUILD_CONFIG

用于初始化构建环境的 build 配置文件。必须相对于 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

内核 build 的基本输出目录。

OUT_DIR=/path/to/my/out

SKIP_DEFCONFIG

跳过 make defconfig

SKIP_DEFCONFIG=1

SKIP_MRPROPER

跳过 make mrproper

SKIP_MRPROPER=1

本地构建的自定义内核配置

在 Android 14 及更高版本中,您或许可使用 defconfig fragment 自定义内核配置。请参阅关于 defconfig fragment 的 Kleaf 文档。

注意:如需修改 Kleaf 的 LTO 设置,请使用 --lto 命令行选项。

具有 build 配置(旧版)的本地构建的自定义内核配置

在 Android 13 及更低版本中,请参阅以下内容。

如果您需要定期切换内核配置选项(例如在开发某项功能时),或者需要设置一个用于开发的选项,可以通过维护 build 配置的本地修改或副本来实现这种灵活性。

将 POST_DEFCONFIG_CMDS 变量设为一个在常规 make defconfig 步骤完成后立即接受评估的语句。由于 build.config 文件源于构建环境,因此 build.config 中定义的函数可以作为 post-defconfig 命令的一部分进行调用。

一个常见示例是在开发期间针对 crosshatch 内核停用链接时优化 (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 [-- --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 build 中下载 ramdisk-recovery.img build 工件,并将其用作 ramdisk 二进制文件。

当您拥有 ramdisk 二进制文件并将其复制到内核 build 的根目录中的 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//dist/boot.img。

相关推荐

全民水浒攻略大全2024(新手平民最强阵容推荐与升级攻略)
飒飒最新小说作品
365投注入口

飒飒最新小说作品

⌛ 08-21 👁️ 283
Changhong(长虹)曲面电视报价
菠菜365哪个是真的

Changhong(长虹)曲面电视报价

⌛ 08-20 👁️ 2260
嘍的意思,嘍的解释,嘍的拼音,嘍的部首,嘍的笔顺
菠菜365哪个是真的

嘍的意思,嘍的解释,嘍的拼音,嘍的部首,嘍的笔顺

⌛ 08-16 👁️ 3001
软件怎么重启
365投注入口

软件怎么重启

⌛ 08-27 👁️ 7168
地下城厉鬼锁魂套掉落地点
菠菜365哪个是真的

地下城厉鬼锁魂套掉落地点

⌛ 07-15 👁️ 3733