Developer Blog

16/10/2016 by Magnus Carlsson

Building CANlib (linuxcan) on Raspberry Pi

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.

$ 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

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 Module71.symvers is used for RaspberryPi 4B.

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 support@kvaser.com.

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.