在 Beaglebone black/Debian 上编译 Linux 内核模块时 crc8 未定义

在 Beaglebone black/Debian 上编译 Linux 内核模块时 crc8 未定义

我正在尝试在我的 beaglebone black(BBB) 上使用 TI 电池监视器 BQ76PL536 的设备驱动程序。驱动程序代码位于此处:https://github.com/tommessick/bq76pl536

虽然作者已经测试了交叉编译Ubuntu工具链,但我尝试直接在我的BBB上编译内核模块。

我做到了

sudo apt-get install linux-headers-4.4.9-ti-r25

安装相关的内核头文件,然后使用以下命令Makefile

DRIVER = bq76pl536

ifneq ($(KERNELRELEASE),)
    obj-m += $(DRIVER).o
else
    PWD := $(shell pwd)

default:
ifeq ($(strip $(KERNELDIR)),)
    $(error "KERNELDIR is undefined!")
else
    $(MAKE) -C $(KERNELDIR)  M=$(PWD) modules
endif

我定义了KERNELDIR=/lib/modules/4.4.9-ti-r25/build/.我按照此处的说明进行操作:http://derekmolloy.ie/writing-a-linux-kernel-module-part-1-introduction/

我的输出make是:

make
make -C /lib/modules/4.4.9-ti-r25/build/      M=/var/lib/cloud9/bq76_driver/bq76pl536 modules
make[1]: Entering directory '/usr/src/linux-headers-4.4.9-ti-r25'
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: "crc8_populate_msb"   [/var/lib/cloud9/bq76_driver/bq76pl536/bq76pl536.ko] undefined!
WARNING: "crc8" [/var/lib/cloud9/bq76_driver/bq76pl536/bq76pl536.ko] undefined!
make[1]: Leaving directory '/usr/src/linux-headers-4.4.9-ti-r25'

创建 .o、.ko 等文件时。当我尝试使用加载模块时insmod出现错误:

sudo insmod ./bq76pl536.ko 
insmod: ERROR: could not insert module ./bq76pl536.ko: Unknown symbol in module

我的dmesg输出如下

dmesg | tail
[   21.564768] eqep 48304180.eqep: failed to get clock
[   21.605265] c_can_platform 481cc000.can: c_can_platform device registered (regs=fa1cc000, irq=207)
[   21.661309] c_can_platform 481d0000.can: c_can_platform device registered (regs=fa1d0000, irq=208)
[   21.768584] eqep: probe of 48304180.eqep failed with error -2
[161381.366409] bq76pl536: Unknown symbol crc8 (err 0)
[161381.366768] bq76pl536: Unknown symbol crc8_populate_msb (err 0)
[162501.175612] bq76pl536: Unknown symbol crc8 (err 0)
[162501.175973] bq76pl536: Unknown symbol crc8_populate_msb (err 0)

我无法理解此错误的起源 - 编译器无法找到函数:crc8crc8_populate_msb,当它们在 crc8.h 中定义时,可在标头中访问: /linux/crc8.h

答案1

该错误不是来自编译器,而是来自链接器。头文件只包含函数的声明,不包含函数的代码,因此在头文件中声明函数不足以执行它。构建时间连接器警告您尚未找到定义该函数的位置。当您尝试加载模块时,内核会执行最后的链接步骤。在此阶段,加载模块使用的所有函数都必须由正在运行的内核定义。在您的情况下,crc8模块需要但内核未定义,因此无法加载模块。

crc8功能是可选功能,必须通过以下方式启用CONFIG_CRC8(“库例程”下的“CRC8 函数”)在构建时。它可以作为也称为 的模块加载crc8。尝试

modprobe crc8

如果这有效,那么您的安装就有该crc8模块。编译bq76pl536并安装后/lib/modules,运行depmod -a;这会生成一个依赖文件,在此之后正常加载bq76pl536(即使用modprobe bq76pl536,而不是直接使用insmod)也将加载crc8模块。

如果这不起作用,那么您的安装没有该crc8模块,您需要用它重新编译内核。使用 Ubuntu 的打包和配置(除了更改该配置项之外)。请参阅Ubuntu 维基进行演练。由于您已经修改了配置,请确保debian.master/changelog按照 wiki 上的说明添加版本修饰符。然后在新内核下重新启动并bq76pl536针对新内核重新编译模块。

相关内容