Building kernel for RPi2 with bluetooth_6lowpan for Raspbian

Building kernel for RPi2 with bluetooth_6lowpan

In this guide, you will have two choices:

  • Cross-compilation build

  • Native build

Choose the one that fits your needs. Cross-compilation is the fastest choice.

Dependencies:

In addition to the already installed tools in Raspbian, you'll need

  • Git
  • kernel-package

These can be installed using apt:

sudo apt-get install git kernel-package -y

“kernel-package” is needed for generating the .deb package, and git is used to fetch the repository from Raspberry Pi’s github account. We'll fetch the default branch, which holds 3.18.11 at the time of writing this blog post.

Obtaining the kernel

Open a terminal and maneuver to a clean directory, I made a directory ~/raspbian.

Now we need to clone the kernel:

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

Grab a coffee. This will take a while.

Option 1: Cross-compilation on x86/x64

The easiest option is to grab the toolchain from RaspberryPi. Go into a clean directory and clone:

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

Now we’ll have to define this path for easier building. For building on x86 (32-bit) environment:

export CCPREFIX=/path/to/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-

For building on x64 (64-bit) environment:

export CCPREFIX=/path/to/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-

Go to the kernel directory that you just cloned. We’ll have to ensure that the directory is cleaned

hkn@hkn-VirtualBox:~/raspbian/kernel/linux$ make mrproper

Set the default configuration to bcm2709, which is the chipset for Raspberry Pi 2

hkn@hkn-VirtualBox:~/raspbian/kernel/linux$ ARCH=arm CROSS_COMPILE=${CCPREFIX}
 make bcm2709_defconfig

Now we’ll start compiling

hkn@hkn-VirtualBox:~/raspbian/kernel/linux$ ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=${MODULES_TEMP} make –j5

hkn@hkn-VirtualBox:~/raspbian/kernel/linux$ ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=${MODULES_TEMP} make –j5 modules

On multi-core CPUs, you can utilize the cores via the “-j” operation. On my PC, I have 4 cores, therefore I add “-j 5” to the above command to speed things up. You should set the number to “NUM_OF_CPU_CORES + 1” to ensure that your cores are working full-time.  

Option 2: Native build

It’s recommended to have 10 GB free space on your Raspberry for kernel compilation.

The steps here are very similar to the section about cross-compilation, just that we remove a couple of defines.

First we need to ensure that you have your build essentials in order:

pi@raspberry:~/$ sudo apt-get install build-essential –y

Set the default configuration to bcm2709, which is the chipset for Raspberry Pi 2

pi@raspberry:~/raspbian/kernel/linux$ make bcm2709_defconfig

Now we’ll start compiling

pi@raspberry:~/raspbian/kernel/linux$ make –j5 && make –j5 modules

Generate .deb packages

For cross-compilation approach:

hkn@hkn-VirtualBox:~/raspbian/kernel/linux$ CONCURRENCY_LEVEL=5 DEB_HOST_ARCH=armhf fakeroot make-kpkg --append-to-version –name_of_your_choice --revision `date +%Y%m%d%H%M%S` --ARCH=arm --cross-compile ${CCPREFIX} kernel_image kernel_headers

CONCURRENCY_LEVEL sets the number of jobs. I used 5 since I have four CPU cores.

You will see warnings similar to this when generating the .deb files:

dpkg-architecture: warning: specified GNU system type arm-linux-gnu does not match gcc system type x86_64-linux-gnu, try setting a correct CC environment variable

Don’t worry; this is normal when cross-compiling, and actually reassuring that we did compile the kernel for ARM architecture.

For native build approach:

pi@raspberry:~/raspbian/kernel/linux$ CONCURRENCY_LEVEL=5 DEB_HOST_ARCH=armhf fakeroot make-kpkg --append-to-version –name_of_your_choice --revision `date +%Y%m%d%H%M%S` --initrd kernel_image kernel_headers

The .deb files will be placed in the parent directory. Write “ls ../*.deb” and you should have two files:

../linux-headers-*.deb
../linux-image-*.deb

Installing the kernel on your Raspberry Pi 2

If you cross-compiled, you’ll need to transfer your kernel header and kernel image to the Pi. This can be done via scp for instance.

scp linux-header*.deb linux-image*.deb pi@pi-ip:~

This will transfer the files to your home directory.

Now login to your raspberry pi and update your system, and install the new kernel:

sudo dpkg –i linux-header*.deb linux-image*.deb

The kernel is now installed, but we need to specify in our boot settings that it should use this new kernel.

pi@raspberry ~ $ cd /boot
pi@raspberry /boot $ ls | grep vmlinuz
vmlinuz-3.18.11-rpi2-v7+

Here we found the name of our new kernel image. For simplicity, we will make a symbolic link (shortcut) to ‘vmlinuz’:

pi@raspberry /boot $ sudo ln –s vmlinuz-3.18.11-rpi2-v7+ vmlinuz

Now we specify the kernel and append it to config.txt:

pi@raspberry /boot $ sudo sh –c ‘echo “kernel=vmlinuz” >> config.txt’

Reboot and enjoy a fresh new kernel with the bluetooth_6lowpan module.

  • Hello Hakon

    I tried the cross-compiling the kernel for my raspberry pi 2 on my Ubuntu 14.04. I followed your guide and found a problem when doing "Generate .deb packages". It appeared a problem which was caused by a bug of My version of ubuntu.And fixed it by downloading this package .

    However, the debian files I have created had the same problem with Zou. So now I need to take hours to do the native build.

  • Hi Zou and Håkon,

    I followed Zou's instructions to build a new kernel on my Raspberry Pi 2.

    First, I did not need the build-essential and git packages. They were already installed on 2015-05-05-raspbian-wheezy.img.

    Second, make –j 5 && make –j 5 modules gave an error, saying make does not know how to make target -j5 (this was bizarre, because man page says -j is an option. Further, I tried --jobs=5 and it did go thru, but only 1 job at a time. So, it is still building (2+ hours, now)

    Any comments?

    --Rasit

  • Hi Zou,

    I'm glad to hear that the guide was useful! Regarding the dependency to libc6 when cross-compiling; This is something I also saw when running Ubuntu 15.04-AMD64, but I did a force install to verify that the kernel booted properly on the RPi2. The problem seems to be that Ubuntu 15.04 seems to set a dependency to the systems libc instead of the crosscompiled targets libc when it's creating the debian packet using make-kpkg.

    I also did a successful deb-generation on Ubuntu 14.10, and figured it was a 15.04-issue (at the time of writing the blog, 15.04 was still in beta), but it might also be that the "make-kpkg" is called incorrectly from my side.

    It's an annoying issue, but it's not due to cross-compiling, but rather the generation of the .deb files.

    I haven't been able to get around this in 15.04 (yet).

    Cheers, Håkon

  • Hi Hakon,

    Thanks for the great guide. I managed to get a RPi2 then tried the steps. My setup is Raspbian 2015-02-16 on R.Pi 2 Model B, with a 16G microSD.

    For the cross-compilation, I build the Raspbian kernel on my Ubuntu 15.4 laptop. But the kernel has a dependency on libc6 (>= 2.14), while the Raspbian host has 2.13-38+rpi2+deb7u8, so cannot install the debian package.

    For the native build, it works. Major steps that I did

    Get git, bc and kernel-package

    sudo apt-get install git bc kernel-package -y

    Clone the kernel (3.18.12 at the time that I fetched)

    git clone github.com/.../linux.git

    Get build essential

    sudo apt-get install build-essential –y

    Set default configuration

    make bcm2709_defconfig

    Compile

    make –j 5 && make –j 5 modules

    Dedian package

    CONCURRENCY_LEVEL=5 DEB_HOST_ARCH=armhf fakeroot make-kpkg --revision date +%Y%m%d --initrd kernel_image kernel_headers

    I successfuly created two debian files of

    linux-headers-3.18.12-v7+_20150501_armhf.deb and linux-image-3.18.12-v7+_20150501_armhf.deb

    This image has dependency on libc6 (>= 2.13-28), which is all fine. After install it, bluetooth_6lowpan is present.

    BR, zou