How to cross compile linux kernel for Raspberry Pi on Ubuntu
Here is notes on how to cross compile linux kernel for Raspbian image of Raspberry Pi on Ubuntu 14.04.
An important note: Once you install your custom kernel, there is a chance of getting it overwritten when you update Firmware through rpi-update command. To avoid it you can always run this following way so that Firmware update will happen skipping the Kernel update.
RPi # SKIP_KERNEL=1 rpi-update
1. Install the git and build tools:
$ sudo apt-get install git-core gcc-4.7-arm-linux-gnueabi
$ sudo apt-get install libncurses5-dev
2. Ensure that the above mentioned ARM build tool as default ARM build tool by making a symbolic link.
$ sudo ln -s /usr/bin/arm-linux-gnueabi-gcc-4.7 /usr/bin/arm-linux-gnueabi-gcc
3. Get the source code for linux kernel and other tools to make image.
$ mkdir raspberrypi
$ cd raspberrypi
$ git clone https://github.com/raspberrypi/tools.git
$ git clone https://github.com/raspberrypi/linux.git
Note: To get a specific version (branch) of kernel, use “-b <branch>”
$ git clone -b rpi-3.19.y https://github.com/raspberrypi/linux.git
4. Get Firmware Hash Value
You need to get Firmware hash value to go to next step (it is referred as <your_git_hash_here> in next step). Many documents direct me to get this value through /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz file. But I did not find such file (in turn missing raspberrypi-bootloader package) in my RPi system. Eventually this file should help you to get right build firmware build hash and corresponding git hash value from http://raw.github.com/raspberrypi/firmware/<fw-hash>/extra/git_hash. Since it is missing, I found a shortcut. That is run “rpi-update” in RPi and then look for /root/.rpi-firmware/git_hash file for this value. For my case of version of kernel is 4.1.5+, the hash value is 592503752b6951972f161f04280683c5af38d173. So command for me was
“git checkout 592503752b6951972f161f04280683c5af38d173”.
$ cd linux
$ git checkout <your_git_hash_here>
$ make mrproper
5. Configure kernel
Option-1: Generate the .config file from the pre-packaged raspberry pi template:
$ make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- bcmrpi_defconfig
Note: In case of Raspberry Pi 2, use "bcm2709_defconfig" in the above command.
Option-2: In case you want to use the existing Raspbian OS linux kernel configuration, get the .config file by using below command from your RPi shell (Note that this command is to be run from Raspberry Pi).
RPi # zcat /proc/config.gz > .config
In case you don’t find /proc/config.gz in your RPi (missing) load the configs module as shown below and try above command again.
RPi # modprobe configs
Copy this config file as .config file to linux source directory to be built on Ubuntu. Then run below command to prepare the old configuration file to be compatible with this kernel version you are building.
$ make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- oldconfig
For all the prompts select default by just pressing Enter key.
You have created default .config file through one of the two options above. Now it is time to customize your kernel using below optional command.
$ make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- menuconfig
6. Building kernel and modules
Build kernel using following command. “-j3” says that I have (3-1) CPUs in my Ubuntu build machine.
$ make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -k -j3
$ mkdir ../modules
$ make modules_install ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- INSTALL_MOD_PATH=../modules/
Now create kernel image.
$ cd ../tools/mkimage/
$ ./imagetool-uncompressed.py ../../linux/arch/arm/boot/Image
Now you should see kernel.img file built in current directory.
7. Copying kernel and modules to Raspberry Pi SD Card
Plug your Raspberry Pi Card to Ubuntu machine and ensure that both boot and root partitions are mounted properly.
Take backup of existing kernel.img in boot parition of SD card and replace it with newly built kernel.
$ sudo cp kernel.img /<boot-parition-mount-point>/
Take backup of existing /lib/modules and /lib/firmware directories in root partition of SD card. Now copy all the firmware and kernel modules built to SD card in archive mode.
$ cd ../../modules/
$ sudo cp -a lib/modules/ /<root-partition-mount-point>/lib/
$ sudo cp -a lib/firmware/ /<root-partition-mount-point>/lib/
Now your SD card is updated with kernel you have built. Just plug this SD card in Raspberry Pi to boot!