1. Introduction
When we start working Embedded Linux SBC (single board computer) like Beaglebone black, Intel Edison, Raspberry-Pi, etc.. the important thing embedded developers look at is how easily we can do customize the kernel for these board. How easy we can configure the Linux kernel and build for that board. This also helps in setup our development environment for working on
Linux kernel modules and device drivers. This article focus on cross-compiling Linux kernel for Raspberry-Pi board. Initially, we can try building Linux kernel on the Raspberry-Pi itself but this approach takes more time, sometimes 4-5 hours. Having a cross-compiling environment on host Ubuntu gives a lot of flexibility for kernel module and device driver development further.
2. Getting kernel config file from RPi board running with Raspbian OS.
We have Raspberry-Pi running with Raspbian OS. Let us try to do cross-compile kernel for the same board. The best way to get the initial kernel configuration file (.config) is copy from the board running with Raspbian OS. We can use the following commands to get
pi# zcat /proc/config.gz > config_file
if the config.gz file is not found in proc file system then use the following command to get the config.gz file in proc file system.
pi # modprobe configs
3. Setting up the host computer running with Ubuntu OS.
Now we can switch focus to setting up host environment on Ubuntu machine.
Get the tools for Raspberry-Pi from Git repo
c2plabs# git clone https://github.com/raspberrypi/tools c2plabs# cd ~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/ c2plabs# ls // This directory contains bin files of all the tools //arm-linux-gnueabihf-gcc, arm-linux-gnueabihf-cpp, arm-linux-gnueabihf-ld etc... add the path to PATH variable of the system. This can be added to ~/.bashrc file PATH=/home/c2plabs/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:$PATH
Get the Linux source from the git repository.
git clone https://github.com/raspberrypi/linux.git cd linux/
once the Linux kernel is synced completely, copy the config_file extracted from the board as mentioned in step 2, and copy to ~/linux/.config file.
This can be done by using the scp command. For this, both e Raspberry-Pi and host Ubuntu computers are connected to the same Wi-Fi network. Once “.config” file is copied to Linux kernel and toolchain is set to PATH, Linux kernel can be configured using
bash# make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
Above command opens kernel configuration screen by using which we can customize the kernel configuration, then build kernel using
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
After kernel cross-compilation is successful, we need to build all the kernel modules and install to a specific directory using the following command
make modules_install ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=~/rpi/modules/
Above command install kernel modules in~/rpi/modules/
To make kernel image compatible with Raspberry-Pi boot loader use the following command to create kernel.img file which is used by bootloader from SD Card.
bash# cd ~/linux/
bash#./scripts/mkknlimg arch/arm/boot/zImage kernel.img
Latest kernels with version > 5.3+ don’t have mkknlimg
utility to convert kernel image. These kernels can boot zImage creates, so simply use copy (cp) command.
bash# cp arch/arm/boot/zImage kernel.img
Remove the SDcard from Raspberry-Pi and mound on host ubuntu computer to copy the kernel.img created to /boot/ partition of SD card. Copy dtb files from arch/arm/boot/dts/ directory to /boot/ partition of SD card. In general the dtb files are bcm2708-rpi-0-w.dtb, bcm2708-rpi-0-w.dtb, bcm2708-rpi-0-w.dtb etc .. based on Raspberry-Pi board used.
Similarly copy ~/rpi/modules/ directory to the lib directory of /root/ partition of SD card and sync with the file system using sync command.
Now remove the SD Card and boot the Raspberry-Pi with this SD Card. Now Raspberry-Pi boots with the newly compiled kernel image.