Building CANlib (linuxcan) on Raspberry Pi

  • October 18, 2016
  • Magnus Carlsson

When compiling CANlib (linuxcan) on any Linux computer, you need to make sure that you are using the correct version of kernel header files. For example, on Ubuntu you can issue the command:

sudo apt install linux-headers-$(uname -r)

A Linux header package is currently not available on Raspbian so instead you have to do some digging. It’s not hard once you know what to look for so let us begin.


Install required packages

Using apt we first install the `bc’ package which is required to be able to execute `make prepare’ on the kernel.

$ sudo apt update
$ sudo apt install bc

# For Raspbian Buster or later also do
$ sudo apt install bison
$ sudo apt install flex
$ sudo apt install libssl-dev

Edit 2019-09-26: If you are running on Raspbian Buster or later, you also need to install bison and flex before compiling.

Edit 2019-12-16: libssl-dev was missing for Raspbian Buster or later.


Find correct version of Linux headers

Through some delicate digging, we will now find out what version of Linux headers were used in the build of the Raspbian OS that is running on our Raspberry Pi. We start by finding which revision of firmware that is in the target system by executing the following command:

$ export RPI_FW_REV=$(zcat /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz | sed -n '/.*firmware as of [0-9a-fA-F]\+/ {s/.*firmware as of \([0-9a-fA-F]\+\)/\1/;p;q}')

The environment variable `RPI_FW_REV’ should now contain the revision (git_hash) of [https://github.com/raspberrypi/firmware] that is used in our system.

$ echo $RPI_FW_REV
3b98f7433649e13cf08f54f509d11491c99c4c0b

Using the firmware revision, we can now find out which revision of Linux kernel that is used in the system by executing the following command:

$ export RPI_LINUX_REV=$(wget https://raw.github.com/raspberrypi/firmware/$RPI_FW_REV/extra/git_hash --quiet -O -)

The environment variable `RPI_LINUX_REV’ should now contain the revision (git_hash) of [https://github.com/raspberrypi/linux] that is used in the system.

$ echo $RPI_LINUX_REV
233755da0e7903fccb41f0b8c14e1da5244b69ec

Fetch and build Linux Headers

Now that we know the revision of the Linux headers used, we can download and extract the kernel source tree by executing:

$ mkdir ~/linuxcan
$ cd ~/linuxcan
$ wget https://github.com/raspberrypi/linux/archive/$RPI_LINUX_REV.zip -O linux-$RPI_LINUX_REV.zip
$ unzip linux-$RPI_LINUX_REV.zip

From the repository containing the pre-compiled binaries, we also fetch the ‘Module.symvers’ (or ‘Module7.symvers’ for RaspberryPi 2 and 3) which contains a list of all exported symbols from the kernel build.

Update 2022-03-09: The exact name of the ‘Module.symvers’ source file is kernel dependent. For example, on a Raspberry Pi Compute Module 4 the command ‘uname -r’ gives us:

[email protected]model4:~ $ uname -r
5.10.92-v8

This means that we are running kernel version 5.10.92, and variant v8, which is, at the time of writing, the latest stable version for Raspberry Pi Compute Module 4. The ‘v8’ also indicates that we need to download ‘Module8.symvers’.

If you get a suffix of ‘+’, e.g. 5.10.92-v8+ it means that you are not running on a stable kernel. Most probably you got there by running ‘rpi-update’ which performs a firmware and kernel update. Once the firmware, bootloader, kernel, and libraries are stable, they are made available via ‘apt-get upgrade’, so the general advice is to only run ‘rpi-update’ if you have a specific need to be on the leading edge of firmware and kernel updates.

$ cd linux-$RPI_LINUX_REV

# For RaspberryPi Model B and B+
$ wget https://raw.github.com/raspberrypi/firmware/$RPI_FW_REV/extra/Module.symvers

# For RaspberryPi 2, 3 and 3B+
$ wget https://raw.github.com/raspberrypi/firmware/$RPI_FW_REV/extra/Module7.symvers -O Module.symvers

# For RaspberryPi 4B
$ wget https://raw.github.com/raspberrypi/firmware/$RPI_FW_REV/extra/Module7l.symvers -O Module.symvers

# For RaspberryPi Compute Module 4
$ wget https://raw.github.com/raspberrypi/firmware/$RPI_FW_REV/extra/Module8.symvers -O Module.symvers

Edit 2016-11-04: Updated that Module7.symvers is used for RaspberryPi 2 and 3.
Edit 2018-11-30: Updated that Module7.symvers is also used for RaspberryPi 3B+.
Edit 2019-09-26: Updated that Module7l.symvers is used for RaspberryPi 4B.
Edit 2022-03-09: Updated that Module8.symvers is used for RaspberryPi Compute Module 4.

Now we can setup kernel configuration and build the headers.

$ sudo modprobe configs
$ zcat /proc/config.gz > .config
$ make prepare
$ make modules_prepare

The two `make’ commands took about three minutes to execute on our Raspberry Pi Model B.


Fetch and configure linuxcan

Get and extract the Kvaser Linux driver and SDK from Kvaser web site:

$ cd ~/linuxcan
$ wget --content-disposition "https://www.kvaser.com/downloads-kvaser/?utm_source=software&utm_ean=7330130980754&utm_status=latest"
$ tar xvzf linuxcan.tar.gz
$ cd ~/linuxcan/linuxcan

Edit 2018-11-30: Updated command to get latest version. Original command was wget https://www.kvaser.com/software/7330130980754/V5_17_0/linuxcan.tar.gz.

In version 5.17 of linuxcan, we can set the environment variable `KV_NO_PCI’ to 1 in order to avoid building the PCI based drivers. The variable `KDIR’ should contain the path to the kernel source directory:

$ export KV_NO_PCI=1
$ export KDIR=/home/pi/linuxcan/linux-$RPI_LINUX_REV

Build and install linuxcan

The last step is to build and install linuxcan. The `-E’ argument to `sudo’ will preserve the environment variables. In our case we need the environment variables `KDIR’ and `KV_NO_PCI’.

$ make
$ sudo -E make install

Versions used

The Raspberry Pi Model B is using the following versions

   OS            Rasbian 8.0 with kernel 4.4.11+              
   firmware.git  rev 3b98f7433649e13cf08f54f509d11491c99c4c0b 
   linux.git     rev 233755da0e7903fccb41f0b8c14e1da5244b69ec 

Bug reports, contributions, suggestions for improvements, and similar things are much appreciated and can be sent by e-mail to [email protected].

Tags: wget

Author Image

Magnus Carlsson

Magnus Carlsson is a Software Developer for Kvaser AB and has developed firmware and software for Kvaser products since 2007. He has also written a number of articles for Kvaser’s Developer Blog dealing with the popular Python language.