Skip to content
This repository has been archived by the owner on Aug 29, 2020. It is now read-only.
skelliam edited this page Mar 28, 2015 · 27 revisions

Discontinued
2015-02-11
I haven't got the time to maintain this anymore. If anyone want's to pick it up, please do.
It doesn't work with the Pi2 kernel.

rpi-source installs the kernel source used to build rpi-update kernels and the kernel on the Raspian image.
This makes it possible to build loadable kernel modules.
It is not possible to build modules that depend on missing parts that need to be built into the kernel proper (bool in Kconfig).

The script uses sudo internally when self-updating and when making the links /lib/modules/$(uname -r)/{build,source}

Note: rpi-source is supported from Linux version 3.10.37 (when Module.symvers appeared in the repo)

Examples on how to build various modules

Install

sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source && sudo chmod +x /usr/bin/rpi-source && /usr/bin/rpi-source -q --tag-update

Run

rpi-source

gcc version check

ERROR:
gcc version check: mismatch between gcc (4.6.3) and /proc/version (4.7.2)
Skip this check with --skip-gcc

rpi-source complains if the major.minor version of gcc differs from the one used to build the kernel.

Version used to build the kernel

$ cat /proc/version
Linux version 3.10.32+ (pi@raspi2) (gcc version 4.7.1 20120402 (prerelease) (crosstool-NG 1.15.2) ) #2 PREEMPT Fri Mar 7 01:33:27 CET 2014

Current gcc version

$ gcc --version | grep gcc
gcc (Debian 4.6.3-14+rpi1) 4.6.3

Install gcc 4.8

The latest kernels are built with gcc 4.8

Check if gcc 4.8.3 or higher is available:

sudo apt-get install gcc-4.8 g++-4.8

Note: If you don't use version 4.8.3 or higher, make prepare_modules will likely fail with this error:

#error Your compiler is too buggy; it is known to miscompile kernels

(bug filed here)

Before continuing with adding the jessie source to apt-get, read this, where the author demonstrates a nice way of prioritizing the wheezy repo over the jessie repo. People have discussed having issues after the jessie souce is added. FYI. (You can also upgrade the entire system to jessie, see this.)

To get gcc 4.8.3 or higher, add jessie (testing) source:

sudo nano /etc/apt/sources.list.d/jessie.list

Add this line:

deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi

Fetch package lists:

sudo apt-get update

Install 4.8

sudo apt-get install -y gcc-4.8 g++-4.8

# Package configuration
# Configuring libc6:armhf
# Restart services during package upgrades without asking?
# <Yes>

Setup gcc versions

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 20
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 50
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.6 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50

Current gcc version

$ gcc --version
gcc (Raspbian 4.8.3-5) 4.8.3

gcc version can be changed with:

sudo update-alternatives --config gcc

Slightly different method: http://somewideopenspace.wordpress.com/2014/02/28/gcc-4-8-on-raspberry-pi-wheezy/

Install gcc 4.7

Older kernels are built with 4.7

Install 4.7

$ sudo apt-get install gcc-4.7 g++-4.7

$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.6
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.7 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.7

Choose 4.7

$ sudo update-alternatives --config gcc
There are 2 choices for the alternative gcc (providing /usr/bin/gcc).

  Selection    Path              Priority   Status
------------------------------------------------------------
* 0            /usr/bin/gcc-4.6   60        auto mode
  1            /usr/bin/gcc-4.6   60        manual mode
  2            /usr/bin/gcc-4.7   40        manual mode

Press enter to keep the current choice[*], or type selection number: 2
update-alternatives: using /usr/bin/gcc-4.7 to provide /usr/bin/gcc (gcc) in manual mode

Current gcc version

$ gcc --version | grep gcc
gcc (Debian 4.7.2-5+rpi1) 4.7.2

link

ncurses-devel

This library is needed when running 'make menuconfig'

 *** ncurses-devel is NOT installed. Needed by 'make menuconfig'. On Debian: apt-get install ncurses-dev

Install prerequisites

$ sudo apt-get install libncurses5-dev

Misc

make prepare

Always run 'make prepare' after changing the kernel config

Show kernel config diff between current and previous config

$ scripts/diffconfig
 ENC28J60 n -> m
+ENC28J60_WRITEVERIFY n

Show config diff against the running kernel

$ cd linux
$ zcat /proc/config.gz > .config.running
$ scripts/diffconfig .config.running .config

~/linux/Module.symvers

Module.symvers contains all the symbols the kernel and modules has exported, and was made during the kernel build process. This file is used later to find needed symbols when building modules. If it was missing (or empty) during building of a module, you might get a not very helpful error message when loading the module. But dmesg will help:

$ sudo modprobe elo
ERROR: could not insert 'elo': Exec format error
$ dmesg |tail -n 1
[19988.002342] elo: no symbol version for module_layout

But if we build a module that exports a symbol, and another module we build needs that symbol, we get warnings.
The build system can't find that symbol in ~/linux/Module.symvers.
We need to tell the build system where this symbol is. This can be done with KBUILD_EXTRA_SYMBOLS pointing to the needed Module.symvers in the build directory of the exporting module.
See mcp2515a for an example.

I had a situation after building several modules that loading the module failed with some format error. It turned out that ~/linux/Module.symvers had changed somehow.
If that happens, there is a backup file Module.symvers.backup. The timestamps will differ if it has changed.

Kernel taint

The kernel can be tainted in various ways. One of them is loading an out-of-tree module.

$ cat /proc/sys/kernel/tainted
4096

From https://www.kernel.org/doc/Documentation/sysctl/kernel.txt

4096 - An out-of-tree module has been loaded.
Clone this wiki locally