我正在尝试在我的 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)
我无法理解此错误的起源 - 编译器无法找到函数:crc8
和crc8_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
针对新内核重新编译模块。