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
$ ARCH=arm CROSS_COMPILE=${CCPREFIX} make


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

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

clean:
        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.