Tuesday, March 10, 2015

Cross-compile kernel modules for Raspberry Pi

This is a quick note on how to cross-compile third party kernel modules for Raspberry Pi. The aim is to keep the stock kernel while compiling a module with matching version.

On Raspberry Pi
Update software on the Raspberry Pi

$ sudo apt-get update
$ sudo apt-get upgrade

Also, install rpi-update to upgrade the firmware and kernel. Then reboot.

$ sudo apt-get install rpi-update
$ sudo rpi-update
$ sudo sh -c “sync; sync; shutdown -r now”

Check the version of kernel

$ uname -a
Linux fax1 3.18.9+ #767 PREEMPT Sat Mar 7 21:41:13 GMT 2015 armv6l GNU/Linux

Also, we need to know the configuration used to compile the kernel. Execute the following command to save it to .config. Transfer the file to the cross-compile machine. We will use it later when compiling the kernel.

$ zcat /proc/config.gz > .config

Here the kernel version is 3.18.9. We can now work on a desktop computer for cross-compiling. First we need to compile the kernel source in order to generate the Module.symvers file. We need this file when compiling third-party modules. For the following example, I will be using a Ubuntu x64 machine.

On the cross-compile machine
Create a folder and download the Rapberry Pi kernel source.

$ git clone https://github.com/raspberrypi/linux.git

Check the Makefile and make sure the version is same as the kernel running on your Raspberry Pi.

Create another folder and download the compiler and tools

$ git clone https://github.com/raspberrypi/tools

Set an environment variable KERNEL_SRC to point to the location of the source, e.g.

$ KERNEL_SRC=/home/cho/work/rpi/linux

Set an environment variable CCPREFIX to the prefix of the path of tools, e.g.

$ CCPREFIX=/home/cho/work/rpi-tools/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-

Change directory to the kernel source and clean the tree

$ cd /home/cho/work/rpi/linux
$ make mrproper

Copy the .config file we created earlier on Raspberry Pi to the kernel source directory, e.g.

$ cp ~/download/.config /home/cho/work/rpi/linux

We can start to compile the kernel now. In theory we only needed to build the modules. However, here we build the whole kernel and modules just for fun

$ cd /home/cho/work/rpi/linux
$ ARCH=arm CROSS_COMPILE=${CCPREFIX} make oldconfig

Once it is done, we can go ahead to build our third party modules, e.g.

$ cd /home/cho/work/tsc2007/raspi/tsc2007

Note that you may need to modify the module's Makefile, e.g.
obj-m += tsc2007.o
obj-m += tsc_raspi.o

        make -C /home/cho/work/rpi/linux M=$(PWD) modules

        make -C /home/cho/work/rpi/linux M=$(PWD) clean

Here, the "-C" path is pointing to the root of the kernel source we just built.