Step-by-step Cross-compiling a Kernel
This tutorial is for developers, primarily for those interested in Debian/Ubuntu systems. The techniques may be used to generate a kernel for Android systems, but the specifics of how the kernel and kernel modules are placed on the media would be different.
Contents
Introduction
These procedures assume you have an Debian-based distribution loaded on your host and your odroid. Kernel building is not different between the distros, but getting ready to build is.
Debian/Ubuntu/Mint and others use "Debian packages", .deb files. They use tools like dpkg, apt, synaptic and so on to manage a package database.
RedHat, Centos, Fedora and Gentoo would not know about apt-get and friends -- so these instructions will not be of much use.
This tutorial has not been tested on a clean machine. There may be steps you need to do to set up for a build. You might need to install packages on your host to be able to build -- like build-essentials.
Prerequisites
Overview
We are going to:
Setting up the Toolchain
If you are happy with your arm cross-compiler, you can skip this step. Some people prefer the CodeSourcery toolchains, but the free version does not support hard floating point.
The kernel is much easier to build than a whole root file system because there are few dependencies. We need a compiler that can generate code for the cortex-a9. We prefer hard-float (armhf rather than armel in Debian lingo)
On your Linux host, setup a shared work area
sudo mkdir -p /usr/local/arm >/dev/null sudo chmod 777 /usr/local/arm cd /usr/local/arm
On your Linux host, get the toolchain and expand it.
cd /usr/local/arm wget https://launchpadlibrarian.net/129963014/gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130125_linux.tar.xz xz -d gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130125_linux.tar.xz tar -xvf gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130125_linux.tar
I need to change compilers depending on the project I'm working on, so I prefer to use a symlink to select the 'active' version.
ln -s gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130125_linux /usr/local/arm/toolchain
Setup the c-compiler cache (optional)
cd /usr/local/arm/toolchain mkdir bin-ccache # you may already have ccache installed, but for the sake of illustration... sudo apt-get install ccache ln -s $(which ccache) arm-linux-gnueabihf-gcc ln -s $(which ccache) arm-linux-gnueabihf-g++ ln -s $(which ccache) arm-linux-gnueabihf-cpp ln -s $(which ccache) arm-linux-gnueabihf-c++
Set Environment Variables
It is convenient to edit your ~/.bashrc file and re-launch a shell rather than just export. That way, any session you start will have them already set. Some people prefer not to set these variable because it can cause x86 builds to fail. VMWare will fail to build kernel modules if you have CROSS_COMPILE and/or ARCH set -- try to remember that you set these variables.
Add the bin-ccache directory in front of the toolchain/bin directory in the PATH
export PATH=/usr/local/arm/toolchain/bin-ccache:/usr/local/arm/toolchain/bin:$PATH export CROSS_COMPILE=arm-linux-gnueabihf- export ARCH=arm
Grabbing the Kernel Source
Go to a convenient work area, here I show $HOME/work
cd $HOME mkdir work cd work
You can get the latest kernel snapshot or get a source for a specific Hardkernel released build. This link shows how to get a specific release: Use git and commit tag . If a snapshot is acceptable, use the wget step as shown next.
Get the kernel snapshot, and unzip it
wget --no-check-certificate https://github.com/hardkernel/linux/archive/odroid-3.0.y.zip unzip odroid-3.0.y.zip
Prepare to Build
Move into the kernel source directory, select the configuration you want, and build it (you can see the alternatives in ./arch/arm/configs/odroid*)
cd linux-odroid-3.0.y/ make odroidu2_ubuntu_defconfig make -j8 zImage
Building
make -j8 zImage
make -j8 modules
Make a directory for the kernel modules and let the kernel make system strip and copy them out. Create a tarball for quick copy/transfer.
mkdir ../rfs export INSTALL_MOD_PATH=$PWD/../rfs make modules_install cd ../rfs # remove symlinks that point to files we do not need in root file system find . -name source | xargs rm find . -name build | xargs rm # Compress sudo tar -cvzf ../modules.tgz . cd ../
Mounting the Boot Partition
The boot partition is the section on the media, either SD-Card or eMMC, that holds the kernel image and the initial root filesystem. For the Hardkernel Ubuntu systems, the boot partition would be mounted at /media/boot. For other distros, the boot partition may not be mounted automatically and by default if might like to be mounted to a different location. For example, the Debian Wheezy distro does not currently mount it, and this and other tutorials mount it at /boot when necessary.
You can work the tutorial and substitute /boot/media for /boot if you like, although it will not cause a problem if you just use /boot. Create the /boot directory to use as a mount point if you need to.
This code snippet shows one way to mount the boot partition
if [ ! -d /boot ]; then mkdir -p /boot || exit 1 fi mountpoint /boot >/dev/null if [ $? -ne 0 ]; then mount -o rw /dev/mmcblk0p1 /boot || exit 1 fi
Copying the Build Results
Copy our new kernel and modules to the target. This method copies over the network. The thing to remember is that the kernel goes on the boot partition and the kernel modules go on the rootfs partition. Here odroidu2 is the name of my odroid target, defined in /etc/hosts. You can do ifconfig on your odroid to see what IP Address it is using and then use it explicitly instead of the technique I show here (the dotted quad instead of odroidu2)
scp modules.tgz root@odroidu2:/ scp linux-odroid-3.0.y/arch/arm/boot/zImage root@odroidu2:/boot
Now go to the odroid Linux console, expand the kernel modules tarball and reboot
tar -xvzf modules.tgz rm modules.tgz sync reboot
Checking the Kernel Version
Check the kernel version, with uname -a
Linux odroidu2-1 3.0.61 #1 SMP Sat Feb 2 15:28:35 PST 2013 armv7l GNU/Linux