A number of projects I’m currently working on and some that I haven’t even started yet, require me to compile my own kernel. The reason I need to do this is to be able to build various code in to a live running kernel, or make various modules available for hardware/applications I need or will need in the future.
A few reasons why you may require a custom built kernel:
-Hardware support for particular hardware you are using
-Support for USB drives, USB devices, Wifi, etc…
-Support for kernel features (special networking features, software features, etc…)
-Built support for booting off different rootfs devices (NFS, iSCSI, USB devices)
The list goes on and on, but you have the idea. And chances are if you came to this page, you already have your reason, you’re just trying to figure out how. Well it’s pretty easy on Fedora 17 ARM on your Raspberry Pi. Keep in mind you can use a cross-compiler and build the kernel on your desktop x86 machine and move it over, but I preferred to actually build the kernel on my Raspberry Pi.
1) First let’s grab all the packages we need. We will issue a yum command to make sure we have the compilers, libraries, and other stuff we will need. We will also install “screen” so that we can hide the terminal session where we are compiling so you don’t need to leave your ssh session open.
yum install gcc gcc-c++ gcc-gfortran glib libtool gtk+ gtk+extra gtk2 git ncurses-devel kernel-headers screen
This will install everything and any dependencies that are required.
2) Let’s start a screen session. A screen session is a terminal session you can attach/detach on demand. Think of it as a terminal that you can keep open even in the back ground. You can start it in a ssh session, close your ssh session, and then connect back to the screen session later when you ssh back in.
screen -S kernelcompile
This starts a session called kernelcompile. At any time you can detach the session by pressing Ctrl+A then pressing the “D” button. To re-attach, simply issue “screen -r”.
3) Download the kernel sources (with the Raspberry Pi patches built in). You can grab a copy off of the snapshot off the github Raspberry Pi kernel repo.
mv rpi-patches kernel.tar.gz
tar zxvf kernel.tar.gz
This will download the sources as a file called rpi-patches, and we just rename it then untar it.
4) In my case, it resulted in a folder called “raspberrypi-linux-f679f05″. Here we change directory in to the kernel source, and setup the default kernel config options. And then run “make menuconfig” to bring up the script to allow us to configure our kernel. This is where you choose your options as to what you want to build in to the kernel, and what you want to build as kernel modules that can be loaded after the kernel is booted.
cp arch/arm/configs/bcmrpi_defconfig .config
IMPORTANT: You need to append a version on to the kernel version number, so that you don’t screw your current existing modules up (since there’s a chance if you didn’t edit this, they would be overwritten, or your build would fail when building your modules. You can do this in “make menuconfig” under General Setup. Or you can edit your .config file:
Look for “CONFIG_LOCALVERSION”. In my case, mine is set to: CONFIG_LOCALVERSION=”.001″ this will put a .001 at the end of the kernels versions tring, and also after the module version number. Example: /lib/modules/3.1.9.001
After you are done with menuconfig, simply exit out of “make menuconfig” and save your config.
5) Now it’s time to start the compiling process. Typing “make” will compile the kernel, and typing “make modules_install” will build the modules and install them to the “/lib/modules” directory.
If the building completed then you have successfully built a linux kernel for the Raspberry Pi and also built/installed the modules that come along with it… We aren’t done yet though. We issue a cd.. to get out of the kernel source directory and back in to the directory that holds it.
6) Next we need to download the Raspberry Pi tools which will contain a python application called “imagetool-uncompressed.py”.
mv master tools.zip
We have downloaded the tools, and unzipped them. It might be an idea to issue a “ls” to note the name of the directory it created.
7) No we need to enter the tools directory. In my case the directory was called “raspberrypi-tools-772201f” but it will be different for you. After we will build the image.
python2 imagetool-uncompressed.py /path/to/kernel/source/raspberrypi-linux-f679f05/arch/arm/boot/Image
Note, you will have to also change the directory after the imagetool command to directory where you built your kernel. Once this runs, you will be left with a kernel.img file inside of the directory you are currently in. First we will back up the existing kernel, then copy the new kernel to your /boot/ directory.
IMPORTANT: Once you overwrite your existing kernel, if your kernel build was bad, or you don’t have what’s needed to boot, your kernel MAY not boot. This will cause you to restore your old kernel which I am NOT going in to in this blog post!
mv /boot/kernel.img /boot/kernel.img.bak
cp kernel.img /boot/
Above, we have changed the name of your current kernel and added a .bak to the end. Then we copied the new kernel made to the boot directory.
Now you can simply reboot your Raspberry Pi, and BAM, with luck you’ll be running your own kernel.
PS. If you ever want to back this kernel up, all you need to do is copy kernel.img (in /boot/) to a safe place, and make a copy of your /lib/modules/kernelversion (in my case /lib/modules/3.1.9.001) directory. If you ever re-image your Pi and want to use the kernel you just built, you can copy the kernel.img and the modules directory to the new image and you are good to go! Might also be worth while to make a backup of your kernel sources and imagetool if you need it again!