Introduction
For me, it was the requirement to add a LCD panel to my Raspberry Pi. This was a Sain Smart LCD.
After some searching I decided to use fbtft as the driver for accessing this LCD. For this solution, I had to build a kernel module.
In this post, I describe the single steps to build a kernel and/or integrate a new module into the kernel.
For the integration of the Sain Smart module see me post Add Sain Smart LCD to Raspberry Pi
Requirements
We assume here:
- Raspbian (I used 2014-09-09-wheezy-raspbian)
- Ubuntu as the development host (I used 14.04 64 bit)
- Linaro cross toolchain (see Cross compiling under Raspbian with Linaro toolchain)
Since I was careful to provide a description not too specific for the exact versions I used, it should be at least helpful even if you are using other versions.
Needed Kernel parts
Since the last time I built a Linux kernel was many years ago, I asked myself first what I need to integrate a kernel module. There are some suggestions that use the kernel header files only and not the complete kernel sources. I tried this too, but there were too many problems, so I did not follow this route.
We need the complete kernel sources. This is easy in a normal Linux distro, but not in Raspbian. There is no ready kernel source package to download.
Prepare kernel sources
If you just download from https:/github.com/raspberrypi/linux, you get the latest and newest kernel sources. Problem: this does not match the other components on Raspbian, like firmware.
So, we download the matching kernel sources.
On the Raspberry:
zcat /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz |head
→
raspberrypi-firmware (1.20140908-1) unstable; urgency=low * firmware as of 53d1ae311226b5c -- <asb@asbradbury.org> Mon, 08 Sep 2014 19:23:42 +0000 raspberrypi-firmware (1.20140830-1) unstable; urgency=low * firmware as of 1bb122bcd82bcd3
We need the first line with * firmware as of xxxxx
The xxxxx
is our firmware hash.
♦ Now go to https://raw.github.com/raspberrypi/firmware/xxxxx/extra/git_hash
In our case, this is:
https://raw.github.com/raspberrypi/firmware/53d1ae311226b5c/extra/git_hash
→
94a382fed1a5ec303eef9e1f3439df8f759ba60c
♦ Now download from https://github.com/raspberrypi/linux/archive/xxxxx.tar.gz
where xxxxx is the long hex string.
In our case, this is:
https://github.com/raspberrypi/linux/archive/94a382fed1a5ec303eef9e1f3439df8f759ba60c.tar.gz
♦ Unpack and rename:
tar xzf linux-94a382fed1a5ec303eef9e1f3439df8f759ba60c.tar.gz mv linux-94a382fed1a5ec303eef9e1f3439df8f759ba60c linux
Now we need to create a config file of the current Raspbian kernel.
On the Raspberry Pi:
zcat /proc/config.gz > .config
♦ Now copy this file into the kernel sources (the directory “linux”)
Build kernel
♦ cd into the kernel source dir (“linux”)
export LOCALVERSION=+ make ARCH=arm CROSS_COMPILE=/home/user/linaro/bin/arm-linux-gnueabihf- -j4 make ARCH=arm CROSS_COMPILE=/home/user/linaro/bin/arm-linux-gnueabihf- INSTALL_MOD_PATH=/home/user/rpi_modules modules_install
Hint:
The 4 in –j4 is the thread count during the compile. Adjust to your needs.
After successful compile, we have a new kernel image: arch/arm/boot/zImage
♦ Copy this file to the /boot
partition of the Raspi
♦ To activate the new kernel, edit /boot/config.txt
and append this line:
kernel=zImage
To see if our new kernel is active, we can check with uname -a
Linux raspberrypi 3.12.28+ #1 PREEMPT Sun Nov 9 15:49:01 CET 2014 armv6l GNU/Linux
The newly created kernel modules are in /home/user/rpi_modules
Normally, we should copy this into /lib/modules on the Raspberry Pi. Since we use the same kernel and the same configuration, we can omit this in most cases.
There are other modules installed than the files in /home/user/rpi_modules
We have to examine this for every single work we do and decide, which files we copy.
Build drivers
See my blog entry Add Sain Smart LCD to Raspberry Pi for an example of how to build and integrate a kernel module.