Embedded Handbook/General/Cross-compiling the kernel
Cross-compile a kernel for a system with flair!
Sources
The relevant kernel sources should be installed first. 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.
The kernel should be installed into the sysroot so if desired to cross-compile packages which include kernel modules, the process will be transparent. Otherwise, the actual location where the kernel is built 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 the build environment, but of course that environment here does not match the target embedded system, so they will need to be overriden. 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 refers to the architecture that the kernel is being built for, as recognized by the kernel itself. So while portage and other people may use "x86", the kernel uses "i386". The arch/ subdirectory should be quickly checked to determine which architecture is to be used.
Hopefully the CROSS_COMPILE variable is pretty self-explanatory. It should be set to the prefix of the toolchain (including the trailing dash "-"). So if the toolchain is invoked as say x86_64-pc-linux-gnu-gcc, the trailing gcc should be chopped off and that's what should be used: 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. The kernel sources do not have to be transferred to the target device, but if any modules are built, this directory will be needed.
There are really two ways in which the system can be set up. The toplevel Makefile can be modified or the relevant variables can be overridden on the command line. Both methods are acceptable, so both will be covered. One of the following options can be chosen.
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?=
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-
A little helper script can be used if it is necessary to switch between different kernel trees at the same time. The script will be referred to as xkmake:
#!/bin/sh
exec make ARCH="arm" CROSS_COMPILE="arm-unknown-linux-gnu-" INSTALL_MOD_PATH="${SYSROOT}" "$@"
Now, when building a kernel or performing any other action, xkmake should be executed instead of make.
Configure and compile
At this point, configuring and compiling the kernel is the same as any other kernel, so it won't be discussed in depth here. There are numerous HOWTOs and guides available that can cover 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.