I am trying to use the device driver for a TI battery monitor BQ76PL536 on my beaglebone black(BBB). The driver code is located here: https://github.com/tommessick/bq76pl536 .

Although, the author had tested for a cross-compile Ubuntu toochain, I tried to compile the kernel module directly on my BBB.

I did

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

to install the relevant kernel headers, and then using the following Makefile

DRIVER = bq76pl536

    obj-m += $(DRIVER).o
    PWD := $(shell pwd)

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

and I defined KERNELDIR=/lib/modules/4.4.9-ti-r25/build/ . I am following the instructions as here: http://derekmolloy.ie/writing-a-linux-kernel-module-part-1-introduction/

and my output of make is :

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'

While the .o, .ko etc. files are created. When I try to load the module using insmod I get an error:

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

My dmesg output is as under

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)

I cannot understand the origin of this error - compiler not being able to find functions: crc8 and crc8_populate_msb, when they are defined in crc8.h, which is accessible in the headers: /linux/crc8.h


The error isn't coming from the compiler, it's coming from the linker. Header files only contain the declaration of functions, they don't contain the function's code, so having the function declared in a header isn't sufficient to execute it. The build-time linker warns you that it hasn't found a place where the function is defined. When you try to load the module, the kernel performs the last linking steps. At that stage, all functions used by the loaded module must be defined by the running kernel. In your case, crc8 is required by the module but not defined by the kernel so the module cannot be loaded.

The crc8 function is an optional feature that must be enabled with CONFIG_CRC8 (“CRC8 function” under “Library routines”) at build time. It may be loaded as a module also called crc8. Try

modprobe crc8

If this works then your installation has the crc8 module. After compiling the bq76pl536 and installing it under /lib/modules, run depmod -a; this generates a dependency file and after this loading the bq76pl536 normally (i.e. with modprobe bq76pl536, not directly with insmod) will also load the crc8 module.

If this doesn't work, then your installation doesn't have the crc8 module, and you'll need to recompile a kernel with it. Use Ubuntu's packaging and configuration (except for changing that one configuration item). See the Ubuntu wiki for a walkthrough. Since you've modified the configuration, make sure to add a version modifier in debian.master/changelog as explained on the wiki. Then reboot under the new kernel and recompile the bq76pl536 module against the new kernel.

  • Thank you for your detailed answer. modprobe crc8 gave an error: Module crc8 not found. So I am guessing I will have to take the route two. I will accept your answer soon. If I understood it correctly, then I should plan to cross-compile the debian arm kernel on an Ubuntu x86 with the changed configuration. Aug 16 '16 at 19:23
  • I am accepting your answer but need the slight help with finishing. I am trying for Raspberry Pi as the new kernel installation is much simpler. I will try BBB as well. On Rpi, I made the necessary config changes to the kernel, and built it. Now when I run modprobe crc8, I do not get the error as before, and the crc8 module gets loaded. I compile the bq76pl536 code and it compiles without warning. I did depmod -a. However, modprobe bq76pl536 and modprobe bq76pl536.ko result in module not found error. I also tried insmod, but to no avail. Aug 22 '16 at 3:00
  • Also, I do not know what you mean by "installing it under /lib/modules ". I just ran make in the bq76 directory and then depmod -a. Is there an intermediate step of installation in between ? Aug 22 '16 at 3:01
  • @ChintanPathak modprobe looks for the module file under /lib/modules/$(uname -r). Run sudo make modules_install from the module directory to install it there. Aug 22 '16 at 7:33
  • The Makefile: github.com/tommessick/bq76pl536/blob/master/Makefile for the module doesnt have a rule for target module_install so it throws the error, when I do make modules_install from the bq76pl536 directory where I compiled the module and .ko file is located. Aug 27 '16 at 19:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.