编译CorXtiumCLMX4k.ko内核模块无输出,求助排查原因
问题描述
打包驱动程序时,编译未生成预期的CorXtiumCLMX4k.ko文件,尽管Makefile中已配置:
obj-m := CorXtiumCLMX4k.o CorXtiumCLMX4k-objs := $(GDRV_OBJS) $(TARGETLIB)
同时有疑问:-objs的作用是什么?内核文档提到-y前缀,替换后也未成功。
编译日志
编译过程无报错,但未生成.ko文件,日志如下:
salsera_xtium> make: Entering directory '/build/va8hwnknyg6cgzqydl3gm64j8z0vyq2i-source/DALSA/src/xtium/xtium_cl_mx4/driver/kernel/linux' salsera_xtium> make -C /nix/store/n862ppa5sy8bmnhs801cskcisd6z7fd0-linux-5.4.225-dev/lib/modules/5.4.225/build M=/build/va8hwnknyg6cgzqydl3gm64j8z0vyq2i-source/DALSA/src/xtium/xtium_cl_mx4/driver/kernel/linux IROOT=/build/va8hwnknyg6cgzqydl3gm64j8z0vyq2i-source/DALSA/src/xtium/xtium_cl_mx4/driver/kernel/linux/../../../../.. modules salsera_xtium> make[1]: Entering directory '/nix/store/n862ppa5sy8bmnhs801cskcisd6z7fd0-linux-5.4.225-dev/lib/modules/5.4.225/build' salsera_xtium> CC [M] /build/va8hwnknyg6cgzqydl3gm64j8z0vyq2i-source/DALSA/src/xtium/xtium_cl_mx4/driver/kernel/linux/GDrv_Linux.o salsera_xtium> CC [M] /build/va8hwnknyg6cgzqydl3gm64j8z0vyq2i-source/DALSA/src/xtium/xtium_cl_mx4/driver/kernel/linux/GDrv_LinuxUtil.o salsera_xtium> CC [M] /build/va8hwnknyg6cgzqydl3gm64j8z0vyq2i-source/DALSA/src/xtium/xtium_cl_mx4/driver/kernel/linux/GDrv_Util.o salsera_xtium> CC [M] /build/va8hwnknyg6cgzqydl3gm64j8z0vyq2i-source/DALSA/src/xtium/xtium_cl_mx4/driver/kernel/linux/memmanag.o salsera_xtium> make[1]: Leaving directory '/nix/store/n862ppa5sy8bmnhs801cskcisd6z7fd0-linux-5.4.225-dev/lib/modules/5.4.225/build' salsera_xtium> make: Leaving directory '/build/va8hwnknyg6cgzqydl3gm64j8z0vyq2i-source/DALSA/src/xtium/xtium_cl_mx4/driver/kernel/linux' salsera_xtium> cp: cannot stat '/build/va8hwnknyg6cgzqydl3gm64j8z0vyq2i-source/DALSA/src/xtium/xtium_cl_mx4/driver/kernel/linux/CorXtiumCLMX4k.ko': No such file or directory
注:使用Nix环境,已修正路径,make使用/nix/…/lib而非/lib;编译前已完成其他依赖库的编译。尝试过文档宣称支持的5.4及更高版本内核,问题依旧。
调试信息
- 编译前目录文件列表:
copysources corenv.h CorXtiumCLMX4k26_x86_64_a gdrv.h GDrv_kernel.h GDrv_KernelThread.h GDrv_Linux.c GDrv_LinuxUtil.c GDrv_LinuxUtil.h GDrv_OS.h GDrv_Util.c Makefile sdrv.h sources
- 编译后目录文件列表:
copysources cormgrlibk.c gdrv.h GDrv_KernelThread.h GDrv_LinuxUtil.c GDrv_OS.h Makefile Module.symvers serialk.c corenv.h CorXtiumCLMX4k26_x86_64_a GDrv_kernel.h GDrv_Linux.c GDrv_LinuxUtil.h GDrv_Util.c memmanag.c sdrv.h sources
CorXtiumCLMX4k26_x86_64_a文件信息:
$ file CorXtiumCLMX4k26_x86_64_a CorXtiumCLMX4k26_x86_64_a: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), with debug_info, not stripped $ ldd CorXtiumCLMX4k26_x86_64_a ldd: warning: you do not have execution permission for `./CorXtiumCLMX4k26_x86_64_a' not a dynamic executable
曾尝试将其重命名为CorXtiumCLMX4k.o_shipped,并设置TARGETLIB = CorXtiumCLMX4k.o,仍未成功。
后续构建错误
salsera_xtium> /nix/store/039g378vc3pc3dvi9dzdlrd0i4q93qwf-binutils-2.39/bin/ld: warning: /build/va8hwnknyg6cgzqydl3gm64j8z0vyq2i-source/DALSA/Xtium-CL_MX4/lib/libXtiumCLMX4L_1_0_a has a section extending past end of file salsera_xtium> /nix/store/039g378vc3pc3dvi9dzdlrd0i4q93qwf-binutils-2.39/bin/ld: error: /build/va8hwnknyg6cgzqydl3gm64j8z0vyq2i-source/DALSA/Xtium-CL_MX4/lib/libXtiumCLMX4L_1_0_a: ELF section name out of range
不确定该错误是否因缺少pic编译标志、文件损坏,或是未生成.ko文件导致。
Makefile完整内容
#-----------------------------------------------------------------------------# MAKEFILE# Copyright(C) Teledyne DALSA Inc 2015# All rights reserved.# # Description:# Makefile for distributed version of the CorXtiumCLMX4 kernel module for Linux# #-----------------------------------------------------------------------------# # Determine the kernel version being compiled for.CORKERNEL_MAJOR:=$(shell uname -r | cut -d '.' -f 1)CORKERNEL_MINOR:=$(shell uname -r | cut -d '.' -f 2) # # Kernel version-specific dependencies# (mainly needed for 2.4 kernel support).# ifeq ($(CORKERNEL_MAJOR), 2) ifeq ($(CORKERNEL_MINOR), 6) # 2.6 kernel TARGET_OPTIONS = -DHOSTPC -DPOSIX_HOSTPC -DNEW_CXM_INTERFACE -DEXPORT_SYMTAB #TARGET_OPTIONS = -DHOSTPC -DPOSIX_HOSTPC -DNEW_CXM_INTERFACE -DEXPORT_SYMTAB -DDEBUG_PRINT SAPSRCROOT := $(IROOT)/sapera else # Not 2.6 kernel - not supported (PCIe hardware). $(error $(shell echo "Kernel version must be 2.6 or higher to support PCIe hardware")) endifelse ifeq ($(CORKERNEL_MAJOR), 3) # 2.6 (or higher kernel) TARGET_OPTIONS = -DHOSTPC -DPOSIX_HOSTPC -DNEW_CXM_INTERFACE -DEXPORT_SYMTAB #TARGET_OPTIONS = -DHOSTPC -DPOSIX_HOSTPC -DNEW_CXM_INTERFACE -DEXPORT_SYMTAB -DDEBUG_PRINT SAPSRCROOT := $(IROOT)/saperaendif # # API Version control information to be embedded.# ifndef CORARCH CORARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/x86_64/x86_64/ )endif TARGETNAME = CorXtiumCLMX4kTARGET = $(TARGETNAME).koifeq ($(CORARCH), x86_64) TARGETLIB = $(TARGETNAME)26_x86_64_a CORARCH_OPTIONS= -Dx86_64else TARGETLIB = $(TARGETNAME)26_i386_a CORARCH_OPTIONS= -D__i386__ endif # # Include Path for the kernel module.# I_CORSERIALCOMMON= $(SAPSRCROOT)/driver/corserial/linux/commonCORSERIALDEV= $(SAPSRCROOT)/driver/corserial/linux/kernelCORMGRK= $(SAPSRCROOT)/driver/cormanager/kernelXCELERA_HS_PX8_INC= $(IROOT)/xtium/xtium_cl_mx4/includeCURDIR = $(IROOT)/xtium/xtium_cl_mx4/driver/kernel/linux INC_COMMON_PATH = -I$(CURDIR) -I$(KERNEL_INCLUDEDIR) -I$(CURDIR) -I$(SAPSRCROOT)/include \ -I$(XCELERA_HS_PX8_INC) -I$(CORMGRK) -I$(I_CORSERIALCOMMON) -I$(CORSERIALDEV) DISTINSTALLDIR=$(IROOT)/../Xtium-CL_MX4/binRUNNINGKERNEL=$(shell uname -r)INSTALLDIR= /lib/modules/$(RUNNINGKERNEL)/misc # # Source Path for the kernel module.# # # Object definitions: Specific files for this library.# GDrv objects.GDRV_OBJS = GDrv_Linux.o \ GDrv_LinuxUtil.o \ GDrv_Util.o \ memmanag.o \ cormgrlibk.o \ serialk.o # # 2.6 kernel build section# INC_PATH = -I$(CURDIR) $(INC_COMMON_PATH) CFLAGS_MODULE += $(INC_PATH) $(TARGET_OPTIONS) $(CORKERNEL_CONFIG_OPTIONS) \ $(CORARCH_OPTIONS)EXTRA_CFLAGS += -Wno-parentheses -Wno-missing-braces -Wno-unknown-pragmas \ -Wno-cast-qual -Wno-unused-function -Wno-unused-label # # As of kernel 2.6.28 (and later) - versioned module symbol dependencies need to be specified# explicitly - using absolute paths - to the Module.symvers files for the modules whose# symbols we depend on.# (Actually broken in an early 2.6.28 but later fixed).## Prior to 2.6.28 - the kernel build system and module loader would resolve all symbols automatically# CORKVER := $(shell uname -r | cut -d '.' -f 3)CORKTEMP := 28COMPAREKVER := $(shell echo ${CORKVER}\>=${CORKTEMP} | bc )ifeq ($(COMPAREKVER),1) KBUILD_EXTRA_SYMBOLS= $(CORMGRK)/Module.symvers $(CORSERIALDEV)/Module.symverselse $(shell cat $(CORMGRK)/Module.symvers > $(CURDIR)/Module.symvers) $(shell cat $(CORSERIALDEV)/Module.symvers >> $(CURDIR)/Module.symvers)endif # # 2.6 kernel build section# ifneq ($(KERNELRELEASE),) obj-m := CorXtiumCLMX4k.o CorXtiumCLMX4k-objs := $(GDRV_OBJS) $(TARGETLIB) # # Perform any specific kernel configuration difference checks.# CORKERNEL_INCLUDEDIR = /lib/modules/$(shell uname -r)/build/include ifeq ($(shell $(SAPSRCROOT)/corcfgtest.sh remap_pfn_range $(CORKERNEL_INCLUDEDIR)),1) CORKERNEL_CONFIG_OPTIONS += -DUSE_REMAP_PFN_RANGEendif else KERNELDIR ?= /lib/modules/$(shell uname -r)/buildPWD := $(shell pwd)RES := $(shell ./copysources) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) IROOT=$(PWD)/../../../../.. modules endif all: $(TARGET) clean: -$(RM) $(OBJS) $(GDRV_OBJS) $(TARGET) distinstall: all cp $(TARGET) $(DISTINSTALLDIR)
曾尝试将else ifeq ($(CORKERNEL_MAJOR), 3)改为else以适配5.x内核,问题依旧。
问题分析与解决建议
1. -objs与-y的作用区别
module-name-objs:用于指定复合模块的依赖目标文件列表。当内核模块由多个.o文件链接而成时,通过这个变量告诉内核构建系统,需要将这些目标文件合并成module-name.o,最终编译为module-name.ko,这是2.6及以后内核模块构建的标准写法。-y前缀属于内核Kbuild系统的内置驱动语法,用于将目标文件直接加入内核镜像,和模块构建场景不匹配,替换后无效是正常的。
2. 未生成.ko文件的核心原因
从编译日志和文件列表来看,内核构建系统仅编译了少数文件,未处理cormgrlibk.o、serialk.o等依赖,也未链接生成.ko,核心问题是Makefile的内核版本分支逻辑不兼容5.x内核:
原Makefile仅处理主版本为2或3的情况,5.x主版本为5,会直接跳过TARGET_OPTIONS和SAPSRCROOT的设置,导致GDRV_OBJS中依赖的头文件路径缺失,内核构建系统自动跳过这些文件的编译,最终因缺少必要目标文件无法完成链接。
修复步骤:
修改Makefile中的内核版本判断分支,覆盖所有3及以上版本:
ifeq ($(CORKERNEL_MAJOR), 2) ifeq ($(CORKERNEL_MINOR), 6) # 2.6 kernel TARGET_OPTIONS = -DHOSTPC -DPOSIX_HOSTPC -DNEW_CXM_INTERFACE -DEXPORT_SYMTAB SAPSRCROOT := $(IROOT)/sapera else $(error $(shell echo "Kernel version must be 2.6 or higher to support PCIe hardware")) endif else # 3.x/4.x/5.x及更高内核 TARGET_OPTIONS = -DHOSTPC -DPOSIX_HOSTPC -DNEW_CXM_INTERFACE -DEXPORT_SYMTAB SAPSRCROOT := $(IROOT)/sapera endif
3. 静态目标文件处理建议
CorXtiumCLMX4k26_x86_64_a是 relocatable 格式的目标文件(非静态库),内核构建系统可直接链接,无需重命名为.o_shipped(该命名规则仅适用于内核源码树中的预编译目标文件)。若修改分支后仍有问题,可先确保文件权限可读取:
chmod 644 CorXtiumCLMX4k26_x86_64_a
4. 后续链接错误说明
libXtiumCLMX4L_1_0_a的链接错误属于用户态库构建问题,和内核模块.ko生成无关,但如果该库依赖内核模块导出的符号,需先解决.ko生成问题,再排查库文件损坏或编译参数(如-fPIC)是否符合Nix环境要求。
内容的提问来源于stack exchange,提问作者tobiasBora

