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

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 it has entered backports:

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

If not, 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.

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