Cross compiling kernels (2014 edition)

Published on July 9, 2014

Archived Notice

This article has been archived and may contain broken links, photos and out-of-date information. If you have any questions, please Contact Us.

A while back, we posted some notes about how to cross compile an i.MX6 kernel using the LTIB toolchain. Fast forward to the middle of 2014 and these are a bit dated.

In particular:

Cross Compiler


As a result of the first two points, we now recommend these simple steps to install a cross-compiler:

~/$ sudo apt-get install gcc-arm-linux-gnueabihf
~/$ arm-linux-gnueabihf-gcc -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/lto-wrapper
Target: arm-linux-gnueabihf
...
gcc version 4.8.2 (Ubuntu/Linaro 4.8.2-16ubuntu4)

Other dependencies


A couple of other tools are also needed for compilation of the kernel when building a U-Boot wrapped kernel:

~/$ sudo apt-get install u-boot-tools lzop

Compilation


This is clearly simpler than installing LTIB and configuring your PATH to point at the toolchain, and is sufficient to replace the arm-none-linux-gnueabi- from LTIB with arm-linux-gnueabihf-, but the process for a 3.0.35 kernel is essentially the same:

~/$ git clone git://github.com/boundarydevices/linux-imx6.git
~/$ cd linux-imx6
~/linux-imx6$ export ARCH=arm
~/linux-imx6$ export CROSS_COMPILE=arm-linux-gnueabihf-
~/linux-imx6$ export
~/linux-imx6$ git checkout boundary-imx_3.10.17_1.0.2_ga
~/linux-imx6$ make nitrogen6x_defconfig
~/linux-imx6$ make uImage modules -j4

As in the previous post, the output will be placed in ~/linux-imx6/arch/arm/boot/uImage.

Module installation


Also unchanged is the module installation process. To get a directory tree suitable for placement into a rootfs (that is, without any symlinks), you can install them into a temporary location as follows.

~/linux-imx6$ make INSTALL_MOD_PATH=~/tmp modules_install
~/linux-imx6$ find ~/tmp/lib/modules -type l -exec rm -f {} ;
~/linux-imx6$ cp -ravf ~/tmp/lib/modules/* /media/myrootfs/lib/modules/

Device Tree


For kernels after 3.0.35, a couple of other wrinkles are added:

  • You'll need to set the LOADADDR environment variable to 10008000, and
  • You'll need to make the dtbs target and copy the Device Tree Binary files into your boot directory.

The files *.dtb are placed in the arch/arm/boot/dts directory, so the following shows the complete process for kernel 3.10.17:

~/$ git clone git://github.com/boundarydevices/linux-imx6.git
~/$ cd linux-imx6
~/linux-imx6$ export ARCH=arm
~/linux-imx6$ export CROSS_COMPILE=arm-linux-gnueabihf-
~/linux-imx6$ export LOADADDR=10008000
~/linux-imx6$ git checkout boundary-imx_3.10.17_1.0.2_ga
~/linux-imx6$ make nitrogen6x_defconfig
~/linux-imx6$ make uImage modules dtbs -j4
~/linux-imx6$ cp -fv arch/arm/boot/uImage /media/myboot/
~/linux-imx6$ cp -fv arch/arm/boot/dts/*.dtb /media/myboot/
~/linux-imx6$ make INSTALL_MOD_PATH=~/tmp modules_install
~/linux-imx6$ find ~/tmp/lib/modules -type l -exec rm -f {} ;
~/linux-imx6$ cp -ravf ~/tmp/lib/modules/* /media/myrootfs/lib/modules/

Note that depending on your O/S distribution, the uImage and *.dtb files may go in the root of a partition (Yocto, Buildroot, Timesys, OpenWRT), or into the /boot directory (Debian, Ubuntu). The key is to match the boot script.

Notes if switching versions


If you're switching from the 3.0.35 to 3.10.17 kernel versions within the same tree, you'll need to delete include/linux/version.h from your tree, or you'll get mysterious error messages about missing mach/hardware.h while compiling gc_hal_kernel_device.c.