Yocto构建多源文件内核模块缺失Device Tree别名问题排查
Zynq-7000多源文件内核模块DT匹配失败解决方法
你的问题核心是多源文件构建时,设备树匹配表(of_device_id)未被正确嵌入模块的.modinfo段,导致内核无法识别DT别名,probe函数无法触发。以下是具体解决步骤:
1. 强制导出设备树匹配表
在定义of_device_id的源文件中,必须添加MODULE_DEVICE_TABLE(of, xxx)宏——这个宏是把匹配表信息写入模块元数据的关键,单源文件时内核编译链可能自动处理,但多源文件时必须显式声明。
示例(假设匹配表定义在my_drv_core.c):
#include <linux/platform_device.h> #include <linux/of_platform.h> // 设备树匹配规则 static const struct of_device_id my_drv_of_match[] = { { .compatible = "xlnx,my-custom-ip" }, // 和DT节点compatible属性完全一致 { /* 哨兵节点,必须添加 */ } }; // 必须添加此宏,否则多源文件编译时匹配表会被丢弃 MODULE_DEVICE_TABLE(of, my_drv_of_match); static struct platform_driver my_drv_driver = { .probe = my_drv_probe, .remove = my_drv_remove, .driver = { .name = "my-custom-driver", .of_match_table = my_drv_of_match, }, }; module_platform_driver(my_drv_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Zynq Custom IP Driver");
2. 正确编写模块Makefile
多源文件构建时,要明确列出所有依赖的目标文件,不能只写最终的.ko文件名。
示例Makefile:
# 最终生成的模块名 obj-m += my_custom_drv.o # 列出所有参与编译的.c文件对应的.o文件,用空格分隔 my_custom_drv-objs := my_drv_core.o my_drv_utils.o my_drv_hw_ops.o # Yocto环境下KERNELDIR会自动指向构建的内核源码,无需手动指定(也可按需覆盖) KERNELDIR ?= ${STAGING_KERNEL_DIR} PWD := $(shell pwd) all: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
3. Yocto附加层配方(.bb)配置
确保配方文件包含所有源文件,并且正确继承module类。
示例my-custom-drv.bb:
SUMMARY = "Zynq-7000 Custom IP Kernel Driver" LICENSE = "GPL-2.0-only" LIC_FILES_CHKSUM = "file://COPYING;md5=eb723b61539feef013de476e68b5c50a" # 列出所有需要的源文件和配置文件 SRC_URI = "file://Makefile \ file://my_drv_core.c \ file://my_drv_utils.c \ file://my_drv_hw_ops.c \ file://COPYING \ " S = "${WORKDIR}" # 继承内核模块构建类 inherit module # 指定要安装的模块 MODULES_INSTALL += "my_custom_drv.ko" # 限定仅在Zynq平台构建 COMPATIBLE_MACHINE = "zynq"
4. 验证模块有效性
构建完成后,在目标板上用modinfo检查模块是否包含DT匹配信息:
modinfo my_custom_drv.ko | grep of_match_table
如果输出类似of_match_table: 0xXXXXXXXX,说明匹配表已正确嵌入;若没有输出,回头检查上述步骤是否遗漏。
常见排查点
- 确保只有一个
platform_driver注册入口,不要在多个源文件中重复定义驱动结构体 - 检查DT节点的
compatible属性和驱动中的字符串完全一致(包括大小写、标点) - 避免手动添加会移除未使用符号的编译选项(如
--gc-sections),内核模块编译默认不会启用此类优化
内容的提问来源于stack exchange,提问作者bLAZ
相关产品推荐
相关产品推荐

