从 legacy kernel build 迁移到 uwu_kernel
使用 uwuCLI
我们推荐使用 uwuCLI 完成初始转换:
uwu请按照提示选择设备和 kernel migration。
uwuCLI 会读取现有设备配置,并尽可能转换已有的 kernel build 设置。自动生成的配置未必是最终结果。迁移完成后,请您按照以下说明检查 kernel configuration、DTB/DTBO 和 kernel modules 是否符合设备实际情况。
Kernel
Legacy kernel build 通常使用以下变量指定 kernel:
TARGET_KERNEL_SOURCE := kernel/<vendor>/<kernel>
TARGET_KERNEL_ARCH := arm64
BOARD_KERNEL_IMAGE_NAME := Image迁移后,这些信息由 uwu_kernel 模块直接声明:
uwu_kernel {
name: "kernel",
kernel_dir: "kernel/<vendor>/<kernel>",
kernel_arch: "arm64",
image_name: "Image",
}工具链、额外的 Kbuild flags 和其他特殊配置只在设备确实需要时声明。完整属性请参阅 配置参考。
Kernel configuration
Legacy kernel build 可以通过 TARGET_KERNEL_CONFIG、TARGET_KERNEL_ADDITIONAL_FLAGS 等变量指定 kernel configuration 和额外的 build flags。
例如:
TARGET_KERNEL_CONFIG := \
gki_defconfig \
vendor/device.config
TARGET_KERNEL_ADDITIONAL_FLAGS := \
CONFIG_EXAMPLE=y迁移后应直接表达相同的配置关系:
additional_flags: [
"CONFIG_EXAMPLE=y",
],
config: {
defconfig: "gki_defconfig",
fragments: [
"vendor/device.config",
],
},DTB 和 DTBO
常规设备可以直接声明对应输出:
dtb: {
enabled: true,
target: "dtbs",
image_name: "dtb.img",
},
dtbo: {
enabled: true,
target: "dtbs",
image_name: "dtbo.img",
page_size: 4096,
},若要使用 Qualcomm DT merge,请向 dtb 指定 qcom_merge。启用此选项时,dtb.enabled 和 dtbo.enabled 必须同时为 true:
dtb: {
enabled: true,
qcom_merge: true,
target: "dtbs",
image_name: "dtb.img",
},
dtbo: {
enabled: true,
target: "dtbs",
image_name: "dtbo.img",
page_size: 4096,
},Kernel modules
Kernel modules 是迁移时最需要您人工检查的部分。
Legacy kernel build 将 module 的安装位置和 load list 分散在多个 Make 变量和外部列表中,两者之间还存在交叉引用。例如设备可能同时存在:
BOARD_SYSTEM_KERNEL_MODULES_LOAD
BOARD_VENDOR_KERNEL_MODULES_LOAD
BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD
BOOT_KERNEL_MODULES
SYSTEM_KERNEL_MODULESuwu_kernel 不使用这些 legacy 变量。对于每个需要安装 kernel modules 的分区,您必须分别指定:
- install list,即哪些 modules 应安装到该分区;
- load list,即哪些 modules 需要从该分区加载。
例如:
modules: {
enabled: true,
system_dlkm_module_install_list: [
"modules.include.system_dlkm",
],
system_dlkm_module_load_list: [
"modules.load.system_dlkm",
],
vendor_dlkm_module_install_list: [
"modules.include.vendor_dlkm",
],
vendor_dlkm_module_load_list: [
"modules.load.vendor_dlkm",
],
},Install list 描述 这个分区包含什么,load list 描述 需要加载什么。
因此必须满足:
load list ⊆ install listuwu_kernel 会在构建时检查这一关系。如果 load list 中存在未包含在对应 install list 中的 module,构建将失败。uwu_kernel 不会因为一个 module 出现在 load list 中,就自动推断它应该被安装。
这项设计是有意的。最终 module layout 应当能够直接从设备配置中确认,而不需要重新推导规则。
uwuCLI 会解析 legacy kernel module 配置及其引用的静态 module list,并据此生成对应的 install 和 load list 配置。如果现有配置无法被可靠转换,uwuCLI 会告知您。自动转换完成后,您仍应检查各分区的 install 和 load list 是否符合设备实际情况。
自动收集 module dependencies
Install list 不需要手工列出其中 modules 的所有依赖。启用 auto_collect_deps 后,uwu_kernel 会根据 install list 中的 modules 自动收集其依赖,并将这些依赖加入最终的 install list:
modules: {
enabled: true,
auto_collect_deps: true,
vendor_dlkm_module_install_list: [
"modules.include.vendor_dlkm",
],
vendor_dlkm_module_load_list: [
"modules.load.vendor_dlkm",
],
},auto_collect_deps 只补充 install list 所需的 module dependencies,不会根据 load list 推断哪些 modules 应当安装。您仍应明确指定设备需要的 install list 和 load list。
External modules
如果设备使用独立于主 kernel tree 的 external modules,请指定 external module root 和需要构建的 modules:
modules: {
enabled: true,
external_module_root: "kernel/<vendor>/<device>-modules",
external_modules: [
"vendor/example",
],
},默认情况下,uwu_kernel 使用 external module 自身的 build system 构建 module,并向其提供 kernel source 和 output directory 等信息。
如果 external module 是主 kernel Kbuild tree 的一部分,并需要通过 Kbuild 的 M= 方式构建,请在 module 路径后添加 :kbuild:
modules: {
enabled: true,
external_module_root: "kernel/<vendor>/<device>-modules",
external_modules: [
"vendor/example:kbuild",
],
},这等价于通过主 kernel build system 对该目录执行 M=<module> modules 和对应的 modules_install。不要为了保留 legacy kernel build 的形式而为此复制额外的 Make rule。
具体属性和支持的 module 配置请参阅 配置参考。
接入 Android build
定义 uwu_kernel 后,需要让 Android build 使用该模块。
请在设备配置中选择 Soong kernel:
BOARD_USES_SOONG_KERNEL := true
SOONG_KERNEL_MODULE := //device/<vendor>/<device>:kernel并将 kernel 加入产品:
PRODUCT_PACKAGES += kernel其他模块应通过 uwu_kernel 的公开输出引用 kernel 产物。请勿依赖 out/soong/.intermediates 中的具体路径。
可用输出请参阅 输出。
无法自动迁移的配置
部分 legacy 配置表达的不只是 kernel build 参数,因此不能安全地机械转换。
常见情况包括:
- 自定义 DTB/DTBO Makefile;
- 依赖
KERNEL_OUT、DTB_OUT或DTBO_OUT具体路径的脚本; - 平台专用 kernel build wrapper。
遇到这些配置时,应先确认它们最终想得到什么结果,再用 uwu_kernel 表达这个结果。
不要为了逐行复现 legacy Make implementation,而重新在 Soong 中建立同样的隐式规则。
如果某种行为被多个设备共同需要,但当前 uwu_kernel 无法表达,请向 Issue Tracker 提出 Issue。
验证
迁移后首先进行正常构建:
uni至少确认:
- kernel image 可以正常生成;
- 最终
.config与设备预期一致; - DTB/DTBO 可以生成并正常启动;
- kernel modules 安装到了正确的分区;
- modules load list 与实际启动需求一致;
- 设备可以正常启动并使用。
常见问题请参阅 故障排查。