Embedded Handbook/General/Cross-compiling the kernel

From Gentoo Wiki
Jump to:navigation Jump to:search
General topics
Creating a cross-compiler
Cross-compiling with Portage
Cross-compiling the kernel
Compiling with qemu user chroot
Frequently asked questions
Das U-Boot
Hammer Board and Nail Board
QNAP TurboStation 109/209/409
Marvell Sheevaplug
Genesi Efika MX
BeagleBone Black
Intel Edison

Cross-compile a kernel for a system with flair!


First install the relevant kernel sources. A kernel sources package can be quickly emerged from the Gentoo ebuild repository or fetch the latest sources from kernel.org. The method for actually compiling the kernel is all the same.

You should install the kernel into the sysroot so that if you want to cross-compile packages which include kernel modules, the process will be transparent. Otherwise, the actual place where you build the kernel does not matter. Some people build all their kernels in /usr/src/ for example.

Setup cross-compiling

There are two fundamental variables that the kernel uses to select the target architecture. Normally these values are guessed based on your build environment, but of course that environment here does not match our target embedded system, so we'll need to override them. The variables in question are ARCH and CROSS_COMPILE. The default values for both are found in the top-level Makefile and the values of both may be overridden on the command line.

The ARCH variable is the architecture you're targeting as the kernel knows it. So while portage and other people may use "x86", the kernel uses "i386". Peek in the arch/ subdirectory real quick to figure out what you want to use.

Hopefully the CROSS_COMPILE variable is pretty self-explanatory. Set this to the prefix of your toolchain (including the trailing dash "-"). So if your toolchain is invoked as say x86_64-pc-linux-gnu-gcc, just chop off that trailing gcc and that's what you use: x86_64-pc-linux-gnu-.

There is an additional variable, INSTALL_MOD_PATH, which defines where the /lib directory will be created, and all the modules stored. While you don't have to transfer the kernel sources to your target device, if you build any modules, you'll want this directory.

There are really two ways you can setup the system. You can modify the toplevel Makefile or you can override the relevant variables on the command line. How you do it is largely a matter of taste, so we'll cover both. Pick one of the following.

FILE MakefileThe vanilla Makefile
ARCH            ?= $(SUBARCH)
FILE MakefileSet the ARCH and CROSS_COMPILE default values
ARCH            ?= arm
CROSS_COMPILE   ?= arm-unknown-linux-gnu-

Overriding on the command-line (instead of in the Makefile) would look something like this:

root #make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnu-

You can use a little helper script if you need to hop between different kernel trees at the same time. We'll call this script xkmake:

FILE xkmake
exec make ARCH="arm" CROSS_COMPILE="arm-unknown-linux-gnu-" INSTALL_MOD_PATH="${SYSROOT}" "$@"

So now when you want to build a kernel or do anything else, you just execute xkmake in place of make.

Configure and compile

At this point, configuring and compiling the kernel is like any other kernel, so we won't go into depth as there are plenty of HOWTOs and guides out there which can treat the subject in much greater detail.

root #cd "${SYSROOT}/usr/src/linux"
root #xkmake menuconfig
root #xkmake

This page is based on a document formerly found on our main website gentoo.org.
The following people contributed to the original document: Mike Frysinger, Ned Ludd, Robin H. Johnson, Alex Tarkovsky, Alexey Shvetsov, Raúl Porcel, Joshua Saddler on April 28, 2013.
They are listed here because wiki history does not allow for any external attribution. If you edit the wiki article, please do not add yourself here; your contributions are recorded on each article's associated history page.