This page explains how to rebuild the kernel image for the RPi. There are two possible routes available:

+

# Compile on the Raspberry Pi itself

+

# Cross compile on another Linux system

−

First, you are going to get and build the linux kernel and its modules using a suitable compiler (a "cross-compiler" if you aren't building it on the same hardware you will be running it on) and then you are going to create a kernel image from the uncompressed kernel (Image) to place on the sd, along with the modules you build alongside it.

+

Both of these routes are covered below, however, you are strongly recommended to follow the cross compilation route. The low processing power of the RPi means that a local compile will take many hours.

−

See below for the various guides to get and compile a suitable kernel for your RPi, and then create a kernel.img according to the steps at the end.

+

= Get the kernel source =

+

The kernel source should be downloaded from the [https://github.com/raspberrypi/linux RPI linux section on GitHub]. Although you could just compile the vanilla kernel from [http://www.kernel.org/ Kernel.org], it will not have the necessary drivers and modules for the Broadcom SoC on the RPi. You can however apply patches from the vanilla kernel to the RPi one - be prepared for potential compiler grumbles though!

−

= Raspberry PI kernel compilation =

+

At the time of writing, two branches of interest are available:

+

* '''rpi-3.2.27''' - This is the version of the kernel currently used in Raspbian.

+

* '''rpi-3.6-y''' - This is a development branch based on the current vanilla kernel. It will eventually replace the 3.2 branch.

−

You can compile the kernel on the board itself, but because of the limited resources it will take a lot of time. Alternatively you can crosscompile the kernel on another machine running Linux, Windows or OS X.

Or you can download a tarball from the website using these links: [https://github.com/raspberrypi/linux/archive/rpi-3.2.27.tar.gz rpi-3.2.27] [https://github.com/raspberrypi/linux/archive/rpi-3.6.y.tar.gz rpi-3.6.y]

−

== Compiling on the Raspberry pi itself ==

+

= Get a compiler =

+

Next, you will need to get a version of GCC in order to build the kernel.

−

=== Arch Linux ===

+

== On the RPi ==

−

==== getting the compiler ====

+

=== Raspbian ===

−

You will need GIT to clone the kernel source tree from GitHub, compiler (gcc) and GNU Make:

+

<pre>

−

pacman -S git gcc make

+

apt-get update

+

apt-get -y dist-upgrade

+

apt-get -y install gcc make

+

</pre>

−

(NOTE: git might be omitted if you decide to download sources in compressed format; this is far faster)

+

=== Arch Linux ===

+

<pre>

+

pacman -Syu

+

pacman -S gcc make

+

</pre>

−

==== getting the sources ====

+

== Cross compiling from Linux ==

+

Please note that when cross-compiling, your compiler may not target the correct ARM processor by default. This will at best reduce performance, or worse, compile for a much newer processor resulting in illegal instructions in your code. The pre-built compiler or a custom-built compiler are recommended because of this. (For example, the latest GCC Linaro binary targets armv7-a by default, whereas the RPi requires armv6kz). It is possible to add extra compiler options to the <tt>HOSTCFLAGS</tt> line in <tt>Makefile</tt>. The correct flags are shown on the [[RPi_Software#Compiler|software page]] - note that you may also need to add <tt>-marm</tt> if your compiler produces Thumb code by default.

−

create a directory where you can work on the raspberry pi software. I called mine "raspberrypi". Then clone the git repository.

+

=== Use the provided compiler ===

+

Download the pre-built bmc2708 compiler from the [https://github.com/raspberrypi/tools/tree/master/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi RPI tools section on GitHub].

+

<pre>

+

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

+

</pre>

+

or you can download a tarball from the website using [https://github.com/raspberrypi/tools/archive/master.tar.gz this link].

−

mkdir raspberrypi

+

=== Custom-built Linaro GCC ===

−

cd raspberrypi

+

See [[RPi_Linaro_GCC_Compilation|Linaro GCC Compilation]].

−

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

+

−

(NOTE: git might fail due to memory constraints; in this case creation of swap file might help. Be warned - this takes ages! To omit the revision history and reduce the download, you can add "--depth 1" to the end of the git clone command.)

+

−

Alternatively, download ZIP or TAR.GZ version of the sources from:

+

=== Ubuntu ===

−

https://github.com/raspberrypi/linux/downloads

+

<pre>

−

unpack and enter the extracted directory (this is your kernel directory - its sources to be precise)

+

apt-get install gcc-arm-linux-gnueabi make ncurses-dev

−

+

</pre>

−

==== configuring the kernel ====

+

−

Next, the kernel options are configured. Either copy the cut down Raspberry Pi .config file from the kernel source configs directory:

+

−

cp arch/arm/configs/bcmrpi_cutdown_defconfig .config

+

−

+

−

Or alternatively, to use the configuration from a currently running Raspberry Pi image, connect to the target and extract the .config file. Then copy the resultant .config file into the Linux kernel source root directory:

+

−

zcat /proc/config.gz > .config

+

−

cp .config <path to linux source root directory>

+

−

+

−

If needed - manual/additional configuration:

+

−

make menuconfig

+

−

+

−

==== compile the kernel ====

+

−

make

+

−

+

−

(NOTE: this will take around 6h; You might find GNU Screen useful)

+

−

+

−

==== build kernel.img so your RPi can boot from it ====

+

−

+

−

Finally you need to build a kernel.img for your Pi to boot from. For this, you need the mkimage tool from the raspberrypi github repository:

+

−

+

−

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

+

−

+

−

Alternatively, download 'imagetool-uncompressed.py' and its dependencies from (this takes far less time and resources):

+

−

https://github.com/raspberrypi/tools/tree/master/mkimage

+

−

+

−

Before you can use this script you need Python v2 to be installed:

+

−

pacman -S python2

+

−

+

−

Once all above is set up you should have the following files (checklist):

+

−

* in the kernel folder you compiled a file: linux/arch/arm/boot/Image

+

−

* python2 executable (it should be located by default in /usr/bin/python2)

+

−

* imagetool-uncompressed.py script

+

−

+

−

+

−

If this is a case (you have all the above) convert your kernel image with the script:

+

−

+

−

python2 imagetool-uncompressed.py path/to/linux/arch/arm/boot/Image

+

−

+

−

This will create a file called kernel.img. Transfer this file into /boot directory (make sure the existing kernel.img in /boot directory gets replaced).

+

−

+

−

The last thing is to install kernel modules. To do this navigate to your kernel folder and execute:

+

−

make modules_install

+

−

+

−

This will install all compiled modules into /lib/modules and possibly some additional files into /lib/firmware folders.

Next, the kernel options are configured. Either copy the cut down Raspberry Pi .config file from the kernel source configs directory:

+

−

cp arch/arm/configs/bcmrpi_cutdown_defconfig .config

+

−

+

−

Or alternatively, to use the configuration from a currently running Raspberry Pi image, connect to the target and extract the .config file. Then copy the resultant .config file into the Linux kernel source root directory:

+

−

zcat /proc/config.gz > .config

+

−

cp .config <path to linux source root directory>

+

−

+

−

Configure the kernel with the copied .config file by running oldconfig:

+

−

make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- oldconfig

+

−

+

−

If manual/additional configuration of kernel options are needed run menuconfig:

+

−

make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- menuconfig

+

−

+

−

Then build the kernel:

+

−

make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -k

+

−

+

−

You can use the "-j" flag to improve compilation time. If you have a dual core machine you can use "-j 3", for a quad core machine you can use "-j 6", and so on.

+

−

+

−

If you get the error messages that arm-linux-gnueabi-gcc cannot be found when running make, run the following command:

Crossdev should create a cross-toolchain using the latest stable versions of the required packages. If it fails, you can specify exact versions by removing the "-S" flag and adding the "--b", "--g", "--k" and "--l" flags. On 2012-05-06, <tt>cross -S -v -A gnueabi arm</tt> works just fine.

−

+

−

Build the cross toolchain:

+

−

crossdev -S -v -t arm-unknown-linux-gnueabi

+

−

+

−

theBuell: on 2012-05-06, cross -S -v -A gnueabi arm works just fine

+

−

+

−

This command should create a cross-toolchain using the latest stable versions of the required packages. If it fails, you can specify exact versions by removing the "-S" flag and adding the "--b", "--g", "--k" and "--l" flags. For the exact usage refer to the crossdev manpage. A good starting point for figuring out the right versions are those which are stable for the arm architecture.

+

−

+

−

==== getting the sources ====

+

−

+

−

create a directory where you can work on the raspberry pi software. I called mine "raspberrypi". Then clone the git repository.

+

−

+

−

mkdir raspberrypi

+

−

cd raspberrypi

+

−

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

+

−

cd linux

+

−

+

−

==== compiling ====

+

−

+

−

Next you have to configure the kernel:

+

−

cp arch/arm/configs/bcmrpi_cutdown_defconfig .config

+

−

make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- oldconfig

+

−

+

−

Then building the kernel:

+

−

make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -k

+

−

+

−

You can use the "-j" flag to improve compilation time. If you have a dual core machine you can use "-j 3", for a quad core machine you can use "-j 6", and so on.

+

=== Arch Linux ===

=== Arch Linux ===

+

<pre>

+

yaourt -S arm-linux-gnueabi-gcc

+

</pre>

−

==== getting the compiler ====

+

== Cross compiling from OSX ==

−

You will need GIT to clone the kernel source tree from GitHub:

+

=== Macports ===

−

pacman -S git

+

The Kernel source requires a case-sensitive filesystem. If you do not have a HFS+ Case-sensitive partition that can be used, create a disk image with the appropriate format.

You can use the "-j" flag to improve compilation time. If you have a dual core machine you can use "-j 3", for a quad core machine you can use "-j 6", and so on. (Don't use these for the oldconfig option because it messes up the input and output).

From opensource.apple.com, download and copy [http://opensource.apple.com/source/dtrace/dtrace-48/sys/elf.h?txt elf.h] and [http://opensource.apple.com/source/dtrace/dtrace-48/sys/elftypes.h?txt elftypes.h] to /usr/include

Next, in all cases, you will want to get a working kernel configuration to start from. You can get the one running on the RPi by typing the following (on the RPi):

+

<pre>

+

zcat /proc/config.gz > .config

+

</pre>

+

then copy <tt>.config</tt> into your build directory.

+

+

Alternatively, the default configuration is available in the downloaded kernel source in <tt>arch/arm/configs/bcmrpi_defconfig</tt>. Just copy this to <tt>.config</tt> in the build directory.

+

+

From this point on, if you are cross-compiling, please substitute <tt><your_compiler></tt> with your compiler binary prefix (e.g. <tt>arm-bcm2708hardfp-linux-gnueabi-</tt>) as each compiler will be named slightly differently. If you are building on the RPi, remove <tt>ARCH=arm CROSS_COMPILE=<your_compiler></tt> from each command.

+

+

Ensure that your configuration file is up-to-date:

+

<pre>

+

make ARCH=arm CROSS_COMPILE=<your_compiler> oldconfig

+

</pre>

+

If any configuration options have been added, you will be asked what set each option to. If you don't know the answer, just press enter to accept the default.

+

+

Optionally, if you want to make changes to the configuration, run this next:

+

<pre>

+

make ARCH=arm CROSS_COMPILE=<your_compiler> menuconfig

+

</pre>

−

= Final step: Making the 'kernel.img' for your Pi =

+

Now you are ready to build:

+

<pre>

+

make ARCH=arm CROSS_COMPILE=<your_compiler>

+

</pre>

+

If you are on a multi-core system, you can make the build faster by appending <tt>-j<N></tt> where <tt>N</tt> is the number of cores on your system plus one.

−

Finally you need to build a kernel.img for your Pi to boot from. The next two sections describe how to do this, depending on which firmware/bootloader version you're using.

+

Find something else to get on with while the compilation takes place. On an average PC with the default configuration, this should take about 15 minutes.

−

== Image Generation For Latest Firmware ==

+

= Prepare the image file =

+

Because of the way the memory addresses are arranged in the Broadcom SoC, you will need to prepare the compiled image for use.

−

With the latest firmware (available from https://github.com/raspberrypi/firmware), you no longer need to create an explicit kernel image; you can directly use Image or zImage from the kernel build process as /boot/kernel.img.

+

If you haven't got the tools directory from the Git repo, please do so now:

+

<pre>

+

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

+

</pre>

+

or you can download a tarball from the website using [https://github.com/raspberrypi/tools/archive/master.tar.gz this link].

−

== Image Generation For Older Firmware ==

+

In the tools set, there is a folder called <tt>mkimage</tt>. Enter this directory, then run the following:

For this, you need the mkimage tool from the raspberrypi github repository:

+

This will output a file called <tt>kernel.img</tt>.

−

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

+

= Transfer the build =

+

Copy your new <tt>kernel.img</tt> file into the RPi boot partition, though preferably as a new file (such as <tt>kernel_new.img</tt>) just in case it doesn't work. If you're building on the RPi, just copy the file to <tt>/boot</tt>. If you use a different filename, edit <tt>config.txt</tt> change the kernel line:

+

<pre>

+

kernel=kernel_new.img

+

#kernel=kernel.img

+

</pre>

−

In tools/mkimage, you'll find a python script called 'imagetool-uncompressed.py':

+

Now you need to transfer the modules. In the build directory, run the following (substituting <tt><modules_path></tt> for a folder somewhere (e.g. <tt>~/modules</tt>):

The contents of this directory should then be copied into the RPi root directory. NOTE: If you have rebuilt the new kernel with exactly the same version as the one that's running, you'll need to remove the old modules first. Ideally this should be done offline by mounting the SD card on another system.

−

After building your linux kernel, you'll find the kernel image you require in 'arch/arm/boot/Image' of the linux directory. Convert your kernel image with the script:

+

Your RPi should now be ready to boot the new kernel. However, at this point it's recommended that you update your GPU firmware and libraries. '''This is required if you've just moved from 3.2 to 3.6 as the firmware interface has changed'''.

−

python imagetool-uncompressed.py path/to/linux/arch/arm/boot/Image

+

= Get the firmware =

+

The firmware and boot files should be updated at the same time to ensure that your new kernel works properly. Again, two branches are available:

+

* '''master''' - This is the version of firmware currently used in Raspbian (i.e. it works with the 3.2 kernel).

+

* '''next''' - This is a development branch which provides a newer GPU firmware to work with the updated drivers in the 3.6 kernel.

−

= Transferring The Image To The Raspberry Pi =

+

You can either download the source directly using git:

+

You can download the firmware directly using git. For the master branch:

Or you can download a tarball from the website using these links: [https://github.com/raspberrypi/firmware/archive/master.tar.gz master] [https://github.com/raspberrypi/firmware/archive/next.tar.gz next]

−

Then you have to transfer this img file to the /boot directory and install the compiled modules. Unfortunately the compiled modules are not in a single place, there are two options of installing them.

+

= Transfer the firmware =

+

Firstly, update the required boot files in the RPi <tt>boot</tt> directory with those you've downloaded. These are:

+

* bootcode.bin

+

* fixup.dat

+

* start.elf

−

Boot your RaspberryPi and mount the <code>linux</code> directory over the network using sshfs:

+

Next, you need to copy the VC libraries over. There are two copies of this: one for hard float and one for soft float. To find the correct one, run the following command (substituting the program name for your compiler binary as required):

−

cd /mnt

+

<pre>

−

mkdir linux

+

arm-none-linux-gnueabi-gcc -v 2>&1 | grep hard

−

sshfs <user>@<host>:<path/to/linux> linux

+

</pre>

−

cd linux

+

−

make modules_install

+

−

If that is not an option, you can also install the modules into a temporary folder:

+

If something prints out, and you can see <tt>--with-float=hard</tt>, you need the hard float ones. NOTE: The current version of Raspbian uses hard float.

−

mkdir /tmp/modules

+

−

make ARCH=arm modules_install INSTALL_MOD_PATH=/tmp/modules

+

−

Now you have to copy the contents of that directory to /lib/modules on the SD card.

+

Remove the <tt>/opt/vc</tt> directory from the RPi root, then:

+

* For hard float, copy <tt>vc</tt> from the <tt>hardfp/opt</tt> directory into <tt>/opt</tt> in the RPi root directory

+

* Otherwise copy <tt>vc</tt> from the top-level <tt>opt</tt> directory into <tt>/opt</tt> in the RPi root directory.

−

Once you've done those two steps, you are ready to put the SD card in and try booting your new system!

+

= Test your build =

+

Power cycle your RPi and check the following:

+

* If you have the serial port on the GPIO expander wired up, you should see the kernel booting.

+

* The screen works - the kernel boots and you get a login prompt.

+

* The VC interface is working - if the 'OK' LED flashes regularly eight or so times every few seconds once the OS has booted, it's not. You can also test this by running <tt>vcgencmd measure_temp</tt>. If it prints "VCHI initialization failed", you have the a mismatch between the firmware, the VC libraries, and the kernel driver.

+

* Run <tt>uname -a</tt> and check that your new kernel is the one that's running.

+

* Make sure you don't have any odd error messages during boot that may indicate a module isn't working properly. If you see <tt>missed completion of cmd 18</tt> regarding DMA transfers to the SD card, you can safely ignore it.

Programming - programming languages that might be used on the Raspberry Pi.

Overview

This page explains how to rebuild the kernel image for the RPi. There are two possible routes available:

Compile on the Raspberry Pi itself

Cross compile on another Linux system

Both of these routes are covered below, however, you are strongly recommended to follow the cross compilation route. The low processing power of the RPi means that a local compile will take many hours.

Get the kernel source

The kernel source should be downloaded from the RPI linux section on GitHub. Although you could just compile the vanilla kernel from Kernel.org, it will not have the necessary drivers and modules for the Broadcom SoC on the RPi. You can however apply patches from the vanilla kernel to the RPi one - be prepared for potential compiler grumbles though!

At the time of writing, two branches of interest are available:

rpi-3.2.27 - This is the version of the kernel currently used in Raspbian.

rpi-3.6-y - This is a development branch based on the current vanilla kernel. It will eventually replace the 3.2 branch.

Get a compiler

Next, you will need to get a version of GCC in order to build the kernel.

On the RPi

Raspbian

apt-get update
apt-get -y dist-upgrade
apt-get -y install gcc make

Arch Linux

pacman -Syu
pacman -S gcc make

Cross compiling from Linux

Please note that when cross-compiling, your compiler may not target the correct ARM processor by default. This will at best reduce performance, or worse, compile for a much newer processor resulting in illegal instructions in your code. The pre-built compiler or a custom-built compiler are recommended because of this. (For example, the latest GCC Linaro binary targets armv7-a by default, whereas the RPi requires armv6kz). It is possible to add extra compiler options to the HOSTCFLAGS line in Makefile. The correct flags are shown on the software page - note that you may also need to add -marm if your compiler produces Thumb code by default.

Custom-built Linaro GCC

Ubuntu

apt-get install gcc-arm-linux-gnueabi make ncurses-dev

Gentoo Linux

crossdev -S -v -t arm-unknown-linux-gnueabi

Crossdev should create a cross-toolchain using the latest stable versions of the required packages. If it fails, you can specify exact versions by removing the "-S" flag and adding the "--b", "--g", "--k" and "--l" flags. On 2012-05-06, cross -S -v -A gnueabi arm works just fine.

Arch Linux

yaourt -S arm-linux-gnueabi-gcc

Cross compiling from OSX

Macports

The Kernel source requires a case-sensitive filesystem. If you do not have a HFS+ Case-sensitive partition that can be used, create a disk image with the appropriate format.
Ensure latest Xcode and command line tools are installed from Apple Developer Connection
Install macports

Yagarto

Perform the compilation

Next, in all cases, you will want to get a working kernel configuration to start from. You can get the one running on the RPi by typing the following (on the RPi):

zcat /proc/config.gz > .config

then copy .config into your build directory.

Alternatively, the default configuration is available in the downloaded kernel source in arch/arm/configs/bcmrpi_defconfig. Just copy this to .config in the build directory.

From this point on, if you are cross-compiling, please substitute <your_compiler> with your compiler binary prefix (e.g. arm-bcm2708hardfp-linux-gnueabi-) as each compiler will be named slightly differently. If you are building on the RPi, remove ARCH=arm CROSS_COMPILE=<your_compiler> from each command.

Ensure that your configuration file is up-to-date:

make ARCH=arm CROSS_COMPILE=<your_compiler> oldconfig

If any configuration options have been added, you will be asked what set each option to. If you don't know the answer, just press enter to accept the default.

Optionally, if you want to make changes to the configuration, run this next:

make ARCH=arm CROSS_COMPILE=<your_compiler> menuconfig

Now you are ready to build:

make ARCH=arm CROSS_COMPILE=<your_compiler>

If you are on a multi-core system, you can make the build faster by appending -j<N> where N is the number of cores on your system plus one.

Find something else to get on with while the compilation takes place. On an average PC with the default configuration, this should take about 15 minutes.

Prepare the image file

Because of the way the memory addresses are arranged in the Broadcom SoC, you will need to prepare the compiled image for use.

If you haven't got the tools directory from the Git repo, please do so now:

Transfer the build

Copy your new kernel.img file into the RPi boot partition, though preferably as a new file (such as kernel_new.img) just in case it doesn't work. If you're building on the RPi, just copy the file to /boot. If you use a different filename, edit config.txt change the kernel line:

kernel=kernel_new.img
#kernel=kernel.img

Now you need to transfer the modules. In the build directory, run the following (substituting <modules_path> for a folder somewhere (e.g. ~/modules):

The contents of this directory should then be copied into the RPi root directory. NOTE: If you have rebuilt the new kernel with exactly the same version as the one that's running, you'll need to remove the old modules first. Ideally this should be done offline by mounting the SD card on another system.

Your RPi should now be ready to boot the new kernel. However, at this point it's recommended that you update your GPU firmware and libraries. This is required if you've just moved from 3.2 to 3.6 as the firmware interface has changed.

Get the firmware

The firmware and boot files should be updated at the same time to ensure that your new kernel works properly. Again, two branches are available:

master - This is the version of firmware currently used in Raspbian (i.e. it works with the 3.2 kernel).

next - This is a development branch which provides a newer GPU firmware to work with the updated drivers in the 3.6 kernel.

You can either download the source directly using git:
You can download the firmware directly using git. For the master branch:

Or you can download a tarball from the website using these links: masternext

Transfer the firmware

Firstly, update the required boot files in the RPi boot directory with those you've downloaded. These are:

bootcode.bin

fixup.dat

start.elf

Next, you need to copy the VC libraries over. There are two copies of this: one for hard float and one for soft float. To find the correct one, run the following command (substituting the program name for your compiler binary as required):

arm-none-linux-gnueabi-gcc -v 2>&1 | grep hard

If something prints out, and you can see --with-float=hard, you need the hard float ones. NOTE: The current version of Raspbian uses hard float.

Remove the /opt/vc directory from the RPi root, then:

For hard float, copy vc from the hardfp/opt directory into /opt in the RPi root directory

Otherwise copy vc from the top-level opt directory into /opt in the RPi root directory.

Test your build

Power cycle your RPi and check the following:

If you have the serial port on the GPIO expander wired up, you should see the kernel booting.

The screen works - the kernel boots and you get a login prompt.

The VC interface is working - if the 'OK' LED flashes regularly eight or so times every few seconds once the OS has booted, it's not. You can also test this by running vcgencmd measure_temp. If it prints "VCHI initialization failed", you have the a mismatch between the firmware, the VC libraries, and the kernel driver.

Run uname -a and check that your new kernel is the one that's running.

Make sure you don't have any odd error messages during boot that may indicate a module isn't working properly. If you see missed completion of cmd 18 regarding DMA transfers to the SD card, you can safely ignore it.