While normally not possible on embedded platforms, it is possible to build kernels on your Raspberry Pi with its luxurious root file system. Despite this, cross-compiling on desktop systems is often preferred for faster compile times. This chapter examines the procedure for building your Raspbian kernel outside of the Pi.
It is assumed that you have the cross-compiler tools and environment ready. Either the tool set built in Chapter
20 or an installed prebuilt tool chain will do. In this chapter, I assume that the
cross-compiler prefix is as follows (ending in a hyphen):
/opt/x−tools/arm–unknown−linux–gnueabi/bin/*
Substitute as appropriate, if your tools are installed differently.
The kernel can be built natively on a Pi, with the Raspberry Pi 3 B+ being perhaps the best choice as this is being written. The steps for native builds are also provided in this chapter, since the procedure is very similar to the cross builds.
Host Environment Tools
If these tools and library are not yet installed, install them now:
$ sudo apt-get install git bc
$ sudo apt-get install libncurses5-dev
Kernel Source Code
Fetch the kernel
source code, using git unless you’ve chosen an alternate way:
$ cd ~/xrpi/devel/staging
$ git clone $depth=1 https://github.com/raspberrypi/linux
$ cd ./linux
Be sure to add the $depth=1 option to the git command to avoid a horribly long download. This avoids downloading history you’re not likely to care about.
Fix inputbox.c
Once again, we run into the backspace
character support issue. If you care about this, apply the following simple fix:
$ nano scripts/kconfig/lxdialog/inputbox.c
Around line 128, locate the line:
and add a
case statement below it:
and then save it from your editor.
make mrproper
In theory, this
step shouldn’t be necessary. But the kernel developers want you to do it anyway, in case something was accidentally left out of place. Be warned that this step also removes the
.config file (copy it to a backup file if you need to).
$ cd ~/xrpi/devel/staging/linux
$ make mrproper
Makefile for Pi 1/Zero/Zero W
When
cross-compiling, edit the
Makefile:
$ cd ~/xrpi/devel/staging/linux
$ nano Makefile
and then add the following two lines to the top of the file:
ARCH=arm
CROSS_COMPILE=arm-unknown-linux-gnueabi-
The
CROSS_COMPILE value shown may differ from yours depending upon the content of your /opt/x-tools directory. List it to verify:
$ ls /opt/x-tools
arm-unknown-linux-gnueabi bin lib share
The value for the macro should exactly agree with the name listed, with one trailing hyphen added to the end of it.
Config for Pi 1/Zero/Zero W
Once the Makefile has been edited, apply the following change to your PATH variable (and again if you have logged out and logged in again):
$ PATH="/opt/x-tools/arm-unknown-linux-gnueabi/bin:$PATH"
Before building your kernel, you need a configuration. The downloaded kernel source does not include your Pi’s kernel settings. To generate a suitable default configuration, perform the following to create a file named
.config:
Once the default configuration file has been generated, you can customize it further using:
Makefile for Pi 2/3/3+/Compute Module 3
If you’re cross-compiling from a non-Raspberry Pi platform, add the following two lines to the
Makefile instead:
ARCH=arm
CROSS_COMPILE=arm-unknown-linux-gnueabi-
Config for Pi 2/3/3+/Compute Module 3
Adjust the
PATH variable:
$ PATH="/opt/x-tools/arm-unknown-linux-gnueabi/bin:$PATH"
And then generate a default configuration followed by customization:
$ make bcm2709_defconfig
$ make menuconfig
zImage modules dtbs
Now that the configuration has been established, start the build process. If you hadn’t planned on making configuration changes, you might still be prompted with some configuration questions. To proceed without configuration changes, simply press Enter to accept the existing value for the parameter.
You can build these
components individually, or all at once in order using:
$ make zImage modules dtbs
The build process takes a fair chunk of time. On an older 32-bit single core Devuan Linux instance, this step took 2 hours and 15 minutes.
Native Install Kernel Image
When building the kernel on a Raspberry Pi 3 B+ or similar, you can install the new kernel with the following
steps into your /boot partition:
$ sudo make modules_install
$ sudo cp arch/arm/boot/dts/*.dtb /boot/
$ sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/
$ sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/
The last step depends upon the type of Pi involved. Use the following building for Pi 1/Zero/Zero W:
$ sudo cp arch/arm/boot/zImage /boot/kernel.img
For the Pi 2/3/3+/Compute Module 3, use the following instead:
$ sudo cp arch/arm/boot/zImage /boot/kernel7.img
The difference is just the name of the kernel—kernel.img or kernel7.img.
Cross Install
When installing a cross-compiled kernel, you need to get the kernel and related files into the
SD card. In the procedure to follow, I assume that you have the SD card mounted on your cross-compile host file system. To figure out where your SD card is under Linux, this is one way using
lsblk:
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 149.1G 0 disk
|─sda1 8:1 0 147.3G 0 part /
|─sda2 8:2 0 1K 0 part
|─sda5 8:5 0 1.8G 0 part [SWAP]
sdb 8:16 1 7.2G 0 disk
|─sdb1 8:17 1 43.2M 0 part
|─sdb2 8:18 1 7.2G 0 part
sr0 11:0 1 1024M 0 rom
Another command
blkid provides more information but must be run as root:
$ sudo blkid
/dev/sda1: UUID="51d355c1-2fe1-4f0e-aaae-01d526bb27b5"
TYPE="ext4" PARTUUID="61c63d91-01"
/dev/sda5: UUID="83a322e3-11fe-4a25-bd6c-b877ab0321f9"
TYPE="swap" PARTUUID="61c63d91-05"
/dev/sdb1: LABEL="boot" UUID="6228-7918"
TYPE="vfat" PARTUUID="f8dea240-01"
/dev/sdb2: LABEL="rootfs" UUID="6bfc8851-cf63-4362-abf1-045dda421aad"
TYPE="ext4" PARTUUID="f8dea240-02"
From the above, it is evident that /dev/sdb1 holds the /boot partition of the inserted
SD card. Mount that and the “rootfs” somewhere, for example:
# mkdir /mnt/boot
# mkdir /mnt/root
# mount /dev/sdb1 /mnt/boot
# mount /dev/sdb2 /mnt/root
With your SD card mounted, you can change out your kernel. It is recommended that you rename the original
kernel.img file in case you want to reinstate it later.
# cd /mnt/boot
# mv kernel.img kernel.was
Cross Modules Install
Once the original kernel is safely renamed on the SD card, you can copy the new kernel onto the SD card’s
/boot partition. Back to your normal userid, perform:
$ cd ~/xrpi/devel/staging/linux
$ sudo make INSTALL_MOD_PATH=/mnt/root modules_install
This will install the compiled modules into the mounted root file system. Note how the parameter
INSTALL_MOD_PATH
specifies where the file system is.
Cross Kernel Files Install
For the smaller Pi’s, use the following:
$ sudo cp arch/arm/boot/zImage /mnt/boot/kernel.img
For the larger Pis, use kernel7.img for the target file name instead:
$ sudo cp arch/arm/boot/zImage /mnt/boot/kernel7.img
Followed by the following copies:
$ sudo cp arch/arm/boot/dts/*.dtb /mnt/boot/
$ sudo cp arch/arm/boot/dts/overlays/*.dtb* /mnt/boot/overlays/
$ sudo cp arch/arm/boot/dts/overlays/README /mnt/boot/overlays/
Now you can safely unmount the SD card file systems:
$ sudo unmount /mnt/boot
$ sudo unmount /mnt/root
The Smoke Test
With all the hard work done, we can now insert the SD card into the
target
Pi and boot! After inserting the card into the Pi Zero (host named pizero), it was booted up and I logged in to run
dmesg. The second line confirms that we were up on the new cross-compiled kernel:
[ 0.000000] Linux version 4.14.56+ (wwg@devuan)
(gcc version 6.3.1 20170109 (crosstool-NG crosstool-ng-1.23.0))
#1 Tue Jul 17 23:09:49 EDT 2018
Boot Failure
If you see the initial colored flash screen remain on the console, this indicates that the kernel.img file failed to load/start.
Summary
There are several steps in this chapter, but many are related to the differences in the Pi models. Once you distill the steps needed for the target platform, the procedure is straightforward. Having the ability to build new kernels for your Pi means that you can enable and disable components and subsystems of your choice. Even more exciting is the possibility of writing new kernel modules to fully leverage your system.