我对内核模块开发的经验很少。尽管如此,我的任务还是维护 Sensoray 626 DAQ 卡的旧驱动程序。我正在使用一个非常简单的 dkms 设置来构建和安装驱动程序,该驱动程序已经运行良好很长时间了。该驱动程序一直在 Ubuntu 22.04 中工作,直到最近我在内核模块构建过程中遇到了以下错误,并且无法找到解决方案。任何帮助表示赞赏。如果需要其他信息,只需询问,我将使用所需信息更新问题。
笔记:我知道 Comedi 有 Sensoray 626 的驱动程序。我不想使用 Comedi 驱动程序。
DKMS 构建日志:
DKMS make.log for s626-1.0.5 for kernel 6.5.0-14-generic (x86_64)
Fri Jan 12 01:17:52 PM PST 2024
make -C /lib/modules/6.5.0-14-generic/build M=/var/lib/dkms/s626/1.0.5/build SUBDIRS=/var/lib/dkms/s626/1.0.5/build
make[1]: Entering directory '/usr/src/linux-headers-6.5.0-14-generic'
warning: the compiler differs from the one used to build the kernel
The kernel was built by: x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
You are using: gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
CC [M] /var/lib/dkms/s626/1.0.5/build/s626drv.o
gcc: error: unrecognized command-line option ‘-ftrivial-auto-var-init=zero’
make[3]: *** [scripts/Makefile.build:251: /var/lib/dkms/s626/1.0.5/build/s626drv.o] Error 1
make[2]: *** [/usr/src/linux-headers-6.5.0-14-generic/Makefile:2037: /var/lib/dkms/s626/1.0.5/build] Error 2
make[1]: *** [Makefile:234: __sub-make] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-6.5.0-14-generic'
make: *** [Makefile:29: all] Error 2
- 发行版:Ubuntu 22.04.3 LTS
- Linux内核版本:6.5.0-14-generic
输出apt list --installed | grep gcc
gcc-11-base/jammy-updates,jammy-security,now 11.4.0-1ubuntu1~22.04 amd64 [installed,automatic]
gcc-11/jammy-updates,jammy-security,now 11.4.0-1ubuntu1~22.04 amd64 [installed,automatic]
gcc-12-base/jammy-updates,jammy-security,now 12.3.0-1ubuntu1~22.04 amd64 [installed,automatic]
gcc-12/jammy-updates,jammy-security,now 12.3.0-1ubuntu1~22.04 amd64 [installed,automatic]
gcc/jammy,now 4:11.2.0-1ubuntu1 amd64 [installed,automatic]
libgcc-11-dev/jammy-updates,jammy-security,now 11.4.0-1ubuntu1~22.04 amd64 [installed,automatic]
libgcc-12-dev/jammy-updates,jammy-security,now 12.3.0-1ubuntu1~22.04 amd64 [installed,automatic]
libgcc-s1/jammy-updates,jammy-security,now 12.3.0-1ubuntu1~22.04 amd64 [installed,automatic]
Makefile(请注意,此 makefile 具有除内核模块之外的其他内容的配方,并且该CC
变量不用于构建内核模块):
###############################################################################
# for kernel modeule level driver:
# Kernel directory
KDIR := /lib/modules/$(shell uname -r)/build
# Module directory
MODDIR := /lib/modules/$(shell uname -r)/kernel/drivers/sensoray
# System values
PWD := $(shell pwd)
KERNEL_24 := $(if $(wildcard $(KDIR)/Rules.make),1,0)
# Target file
obj-m := s626.o
# Source files
ifeq ($(KERNEL_24),0) # > 2.4
s626-objs := s626drv.o
else # <= 2.4
s626-objs := s626drv.o
endif
.PHONY: all clean modules_install
ifeq ($(KERNEL_24),0) # > 2.4
ifeq ($(KERNELRELEASE),)
all:
$(MAKE) -C $(KDIR) M=$(PWD) SUBDIRS=$(PWD)
clean modules_install:
$(MAKE) -C $(KDIR) M=$(PWD) SUBDIRS=$(PWD) $@
endif # KERNELRELEASE
else # <= 2.4
ifneq ($(KERNELRELEASE),)
include $(KDIR)/Rules.make
s626.o: $(s626-objs)
$(Q)$(LD) $(LD_RFLAG) -r -o $@ $(s626-objs)
else
all:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -f *.ko *.o .*.cmd .*.o.flags *.mod.c
endif # KERNELRELEASE
endif # KERNEL_24
ifeq ($(KERNEL_24),1) # <= 2.4
install: s626.o
@if [ -d /lib/modules/$(shell uname -r)/kernel/drivers/sensoray/ ];\
then rm -f /lib/modules/$(shell uname -r)/kernel/drivers/sensoray/s626.*;\
fi
@if [ -d /lib/modules/$(shell uname -r)/extra/ ];\
then rm -f /lib/modules/$(shell uname -r)/extra/s626.*;\
fi
su -c "set -x;./MAKEDEV;mkdir -p $(MODDIR);cp -v s626.o $(MODDIR);depmod -a"
else
install: s626.ko
@if [ -d /lib/modules/$(shell uname -r)/kernel/drivers/sensoray/ ];\
then rm -f /lib/modules/$(shell uname -r)/kernel/drivers/sensoray/s626.*; \
fi
@if [ -d /lib/modules/$(shell uname -r)/extra/ ];\
then rm -f /lib/modules/$(shell uname -r)/extra/s626.*;\
fi
@if [ -d /lib/modules/$(shell uname -r)/kernel/drivers/staging/comedi/drivers ];\
then rm -f /lib/modules/$(shell uname -r)/kernel/drivers/staging/comedi/drivers/s626.*;\
fi
su -c "set -x;./MAKEDEV;mkdir -p $(MODDIR);cp -v s626.ko $(MODDIR);install -m 444 s626.ko $(MODDIR);depmod -a"
endif # KERNEL > 2.4
###############################################################################
# for library and application level:
SRC= # module source tree
CC= # compiler
AR= # library manager
# source path
ifeq ($(strip $(SRC)),)
SRC=.
endif
# the compiler
ifeq ($(strip $(CC)),)
CC=gcc
endif
# the library manager
ifeq ($(strip $(AR)),)
AR=ar
endif
# build the distribution's library
lib: libs626.a
libs626.a: s626core.o s626mod.o
$(AR) cr libs626.a $(SRC)/s626core.o $(SRC)/s626mod.o
# compile the 626 universal core
core: s626core.o
s626core.o: $(SRC)/s626core.c $(SRC)/s626core.h $(SRC)/s626mod.h
$(CC) $(CFLAGS) -c $(SRC)/s626core.c
# build the 626 OS-dependent module
mod: s626mod.o
s626mod.o: $(SRC)/s626mod.c $(SRC)/s626core.h $(SRC)/s626mod.h $(SRC)/s626drv.h $(SRC)/s626.h $(SRC)/s626api.h
$(CC) $(CFLAGS) -c $(SRC)/s626mod.c
# build the distribution's library (you may need to install gcc-multilib package)
lib32: libs626-32.a
libs626-32.a: s626core-32.o s626mod-32.o
$(AR) cr libs626-32.a $(SRC)/s626core-32.o $(SRC)/s626mod-32.o
# compile the 626 universal core
s626core-32.o: $(SRC)/s626core.c $(SRC)/s626core.h $(SRC)/s626mod.h
$(CC) $(CFLAGS) -m32 -c $(SRC)/s626core.c -o $@
# build the 626 OS-dependent module
s626mod-32.o: $(SRC)/s626mod.c $(SRC)/s626core.h $(SRC)/s626mod.h $(SRC)/s626drv.h $(SRC)/s626.h $(SRC)/s626api.h
$(CC) $(CFLAGS) -m32 -c $(SRC)/s626mod.c -o $@
#----------------------------------------------------------------
# Demonstration programs
# type "make demo" to compile, link, and create demo application
demo: libs626.a s626demo.o s626dm2b.o
$(CC) -o s626demo s626demo.o -L$(SRC) -ls626 -lpthread
$(CC) -o s626dm2b s626dm2b.o -L$(SRC) -ls626 -lpthread
s626demo.o: $(SRC)/s626demo.c $(SRC)/s626core.h $(SRC)/s626mod.h $(SRC)/s626drv.h $(SRC)/s626api.h $(SRC)/App626.h
$(CC) $(CFLAGS) -c $(SRC)/s626demo.c
s626dm2b.o: $(SRC)/s626dm2b.c $(SRC)/s626core.h $(SRC)/s626mod.h $(SRC)/s626drv.h $(SRC)/s626api.h $(SRC)/App626.h
$(CC) $(CFLAGS) -c $(SRC)/s626dm2b.c
demo32: libs626-32.a s626demo-32.o s626dm2b-32.o
$(CC) -m32 -o s626demo-32 s626demo-32.o -L$(SRC) -ls626-32 -lpthread
$(CC) -m32 -o s626dm2b-32 s626dm2b-32.o -L$(SRC) -ls626-32 -lpthread
s626demo-32.o: $(SRC)/s626demo.c $(SRC)/s626core.h $(SRC)/s626mod.h $(SRC)/s626drv.h $(SRC)/s626api.h $(SRC)/App626.h
$(CC) $(CFLAGS) -m32 -c $(SRC)/s626demo.c -o $@
s626dm2b-32.o: $(SRC)/s626dm2b.c $(SRC)/s626core.h $(SRC)/s626mod.h $(SRC)/s626drv.h $(SRC)/s626api.h $(SRC)/App626.h
$(CC) $(CFLAGS) -m32 -c $(SRC)/s626dm2b.c -o $@
# for debugging:
# gcc -g -o s626demo s626core.c s626mod.c s626demo.c -lpthread
# gcc -g -o s626dm2b s626core.c s626mod.c s626dm2b.c -lpthread
clnall:
rm -f *.ko *.o .*.cmd .*.o.flags *.mod.c libs626*.a s626demo s626dm2b *.tar.gz s626*-32 Module.symvers modules.order
###############################################################################
# for internal develoment only
#----------------------------------------------------------------
# select files for the distribution tarball
T = $(SRC)/README
T += $(SRC)/COPYING
T += $(SRC)/MAKEDEV
T += $(SRC)/Modules.conf
T += $(SRC)/Makefile
T += $(SRC)/s626drv.h
T += $(SRC)/s626drv.c
T += $(SRC)/s626.h
T += $(SRC)/s626mod.h
T += $(SRC)/s626mod.c
T += $(SRC)/s626core.h
T += $(SRC)/s626core.c
T += $(SRC)/s626api.h
T += $(SRC)/App626.h
T += $(SRC)/libs626.a
T += $(SRC)/s626demo.c
T += $(SRC)/s626dm2b.c
#----------------------------------------------------------------
# build distribution tarball (only for development)
tar:
# tar -Pzcf s626-0.3.tar.gz $(T)
tar -czvf s626-1.0.tar.gz $(T)
DKMS配置文件:
MAKE="'make' KDIR=/lib/modules/${kernelver}/build"
CLEAN="'make' clean"
BUILT_MODULE_NAME=s626
BUILT_MODULE_LOCATION=./
DEST_MODULE_LOCATION=/kernel/drivers/sensoray/
PACKAGE_NAME=s626
PACKAGE_VERSION=1.0.5
AUTOINSTALL=yes
REMAKE_INITRD=yes
答案1
同样的问题。我的系统是Ubuntu 23.10,默认的gcc/g++版本是13。在CUDA 11.8安装过程中,我切换到了gcc/g++版本11。
我曾经update-alternatives
安装过版本选项。
切换回 gcc-13 和 g++-13 解决了这个问题。
答案2
问题似乎在于 Makefile(由原始开发人员编写)设置了CC
make 变量,从而阻止了 DKMS 使用环境变量正确覆盖编译器CC
。这个潜在问题的描述是这个错误报告。
因为在我的例子中,Makefile 仅使用CC
make 变量来构建用户级 API 库(即,它没有在用于构建模块的 Makefile 部分中使用),所以最好的解决方案是安装(到/usr/src/
)一份仅包含处理内核模块的部分的 Makefile,而不是安装完整的 Makefile。
答案3
我将符号链接更改/usr/bin/gcc
为gcc-12
(而不是gcc-11
)
并运行sudo /sbin/vboxconfig
vboxdrv.sh: Stopping VirtualBox services.
vboxdrv.sh: Starting VirtualBox services.
vboxdrv.sh: Building VirtualBox kernel modules.
(使用 Ubuntu 22.04.3 LTS、5.19.17-051917-通用内核)
答案4
向该用户致敬哈坎茨@ 这平行论坛,这是此 gcc 版本问题的有效解决方案。它更改链接以将它们指向 gcc-12:
cd /usr/bin
sudo ln -sf gcc-12 gcc
sudo ln -sf gcc-ar-12 gcc-ar
sudo ln -sf gcc-nm-12 gcc-nm
sudo ln -sf gcc-ranlib-12 gcc-ranlib
sudo rm /usr/lib/parallels-tools
sudo rm /var/lib/parallel-tools
转到挂载目录
cd "/media/YOUR_USER_NAME_HERE/Parallels Tools"
或您拥有的任何挂载目录
最后再次执行:
sudo ./install