Raspberry Pi

Raspberry Pi 2 kernel self-compile

This is a process to compile the kernel on Raspberry 2, which is currently working on a Raspberry Pi.

To create Linux environment for ARM architecture, a x86/x86_64 based cross-compile host environment is often used since its speed of compiling. Recently, since faster ARM machines such as Raspberry Pi 2 have been developed, self-compiling on ARM is a reasonable alternative to cross-compiling on x86/x86_64.
As you need a pre-built kernel source, such as USB Wifi driver or you like to change a build option for the kernel, you can complete these tasks only on Raspberry Pi 2. You do not need any other platforms.

The self-compiling process is the same to both Raspbian Wheezy and Jessie.

Required packages

Please install required packages for building kernel.

$ sudo apt-get install bc ncurses-dev

gcc, make, and git are already included. For Wheezy, the version of gcc is 4.6.3, and the version of gcc for Jessie is 4.9.2.

The differences between versions do not affect on the build process of kernel source, but this would affects on the build of kernel sources for external drivers. Since the differences in gcc options and macro, the driver sources due to differences in version of gcc are needed to be modified.

Obtaining kernel source

Moving to the directory of /usr/src, obtain the kernel source with git.

beat@raspberrypi ~ $ cd /usr/src/
beat@raspberrypi /usr/src $ sudo -s

The main part of kernel

root@raspberrypi:/usr/src# git clone --depth 1 -b rpi-4.1.y
Cloning into 'linux'...
remote: Counting objects: 52876, done.
remote: Compressing objects: 100% (50356/50356), done.
remote: Total 52876 (delta 4012), reused 17583 (delta 1851), pack-reused 0
Receiving objects: 100% (52876/52876), 142.62 MiB | 1.96 MiB/s, done.
Resolving deltas: 100% (4012/4012), done.
Checking connectivity... done.
Checking out files: 100% (49946/49946), done.


root@raspberrypi:/usr/src# git clone --depth 1
Cloning into 'firmware'...
remote: Counting objects: 4077, done.
remote: Compressing objects: 100% (2200/2200), done.
remote: Total 4077 (delta 1702), reused 2305 (delta 1576), pack-reused 0
Receiving objects: 100% (4077/4077), 75.59 MiB | 1.21 MiB/s, done.
Resolving deltas: 100% (1702/1702), done.
Checking connectivity... done.
Checking out files: 100% (3777/3777), done.

As of October 15 2015, the kernel version at rpi-4.1.y branch is 4.1.10.

Preparation for the build precess

Please move to the directory where the kernel source is checked out. To load the configs module, obtain config of the kernel, which is currently running. Then, prepare for the build process

root@raspberrypi:/usr/src/linux# cd linux
root@raspberrypi:/usr/src/linux# modprobe configs
root@raspberrypi:/usr/src/linux# zcat /proc/config.gz > .config
root@raspberrypi:/usr/src/linux# cp ../firmware/extra/Module7.symvers Module.symvers

Resulting on config

root@raspberrypi:/usr/src/linux# make oldconfig
scripts/kconfig/conf  --oldconfig Kconfig
# configuration written to .config

Since the version of new config is identical to the version of currently running config, the preparation ends without asking whether to make newly added options effective or not.

Build process

Let's start the build process.
Because CPU of Raspberry Pi 2 has 4 cores, zImage, modules, and dtbs can be built collectively, utilizing the four-parallel execution of 4 cores with -j4 option. However, the four parallel execution consumes a lot of memory it requires to set swap. Without setting swap, a hung will occur in the middle of build process. Therefore, the three kernel sources are built one by one. During the build process, the build time is also measured by time command.


root@raspberrypi:/usr/src/linux# time make zImage 2>&1 | tee make1.log
~~ Skipping ~~
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready

real    76m45.564s
user    76m33.100s
sys     3m42.070s


root@raspberrypi:/usr/src/linux# time make modules 2>&1 | tee make2.log
~~ Skipping ~~
  IHEX    firmware/yam/1200.bin
  IHEX    firmware/yam/9600.bin

real    214m43.233s
user    204m52.790s
sys     10m32.480s


root@raspberrypi:/usr/src/linux# time make dtbs 2>&1 | tee make3.log
~~ 中略 ~~
  DTC     arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dtb
  DTC     arch/arm/boot/dts/bcm2709-rpi-2-b.dtb

real    0m10.528s
user    0m3.110s
sys     0m1.650s


Because these are self-compiled, they can be installed without any modification.


root@raspberrypi:/usr/src/linux# make modules_install
~~ Skipping ~~
  INSTALL /lib/firmware/yam/9600.bin
  DEPMOD  4.1.10-v7+


root@raspberrypi:/usr/src/linux# ls arch/arm/boot/dts/*.dtb
root@raspberrypi:/usr/src/linux# cp arch/arm/boot/dts/*.dtb /boot/
root@raspberrypi:/usr/src/linux# cp arch/arm/boot/dts/overlays/*.dtb /boot/overlays/
root@raspberrypi:/usr/src/linux# cp arch/arm/boot/dts/overlays/README  /boot/overlays/

Raspbian stores two zImages at /boot/ directory. The one zImage (kernel.img) is for Raspberry Pi, and the other zImage (kernel7) is for ARMv7, including Raspberry Pi 2. zImage for Raspberry Pi 2 is replaced with newly build one.

root@raspberrypi:/usr/src/linux# cp /boot/kernel7.img /boot/kernel7.img.old
root@raspberrypi:/usr/src/linux# scripts/mkknlimg arch/arm/boot/zImage /boot/kernel7.img
root@raspberrypi:/usr/src/linux# ./scripts/mkknlimg arch/arm/boot/zImage /boot/kernel7.img
Version: Linux version 4.1.10-v7+ (root@raspberrypi) (gcc version 4.9.2 (Raspbian 4.9.2-10) ) #1 SMP PREEMPT Fri Oct 16 22:21:16 JST 2015
DT: y
283x: n


To boot from the newly built kernel, please reboot the system.

# reboot

To check whether the newly build kernel is working or not, please look at the status. Please apply the command line below. (The other line is its return.)

pi@raspberrypi:~$ uname -a
Linux raspberrypi 4.1.10-v7+ #1 SMP PREEMPT Fri Oct 16 22:21:16 JST 2015 armv7l GNU/Linux

To look at the status, if the new kernel is working, uname -a and local setting at build kernel are changed.

pi@raspberrypi:~$ uname -a
Linux raspberrypi 4.1.10-v7+ #821 SMP PREEMPT Sat Oct 10 00:16:28 BST 2015 armv7l GNU/Linux

Revision History

  • 2016-02-15 This document is initially released

Front page   Edit Freeze Diff Backup Upload Copy Rename Reload   New List of pages Search Recent changes   RSS of recent changes
Last-modified: 2016-02-15 (Mon) 09:22:03 (648d)