Cross Compilation of the Odroid C2 Kernel on an Ubuntu Host

Cross-compilation is a viable option when one needs to build a custom kernel for an ARM device such as the Odroid C2 on an alternate system with a different architecture, such as your commodity PC.

Reasons for cross-compilation may be that: (a). The user’s target device lacks sufficient storage to carry out the cross-compilation. (b). The user’s preference to speed relative to the target device outweighs the need for a native compilation. (c). The user in question may not be having the target device in hand to test a native compilation on, and as such, a cross-compilation offers the user both a development platform and a (faster, in many cases) build toolkit.

Installing required packages:

You will need to install required packages before you start to build the Linux kernel on your Ubuntu desktop.

sudo apt-get update
sudo apt-get install git lzop build-essential gcc libncurses5-dev libc6-i386

Download the tool-chain from here. (Note that newer versions may be available as of the time of writing).

Update: You will find current versions of the toolkit here. See notes below on the current module file written against the latest release.

Once the download is done, extract the tarball for version 4.9 to /apps/gcc-linaro-toolchain/4.9(as is on my system).

sudo mkdir -p /apps/gcc-linaro-toolchain/4.9
sudo tar Jxvf gcc-linaro-aarch64-linux-gnu-4.9-2014.09_linux.tar.xz -C /apps/gcc-linaro-toolchain/4.9

For the latest version (6.1.1), do this to fetch the tarball with wget and deploy it:

wget -v https://releases.linaro.org/components/toolchain/binaries/latest/aarch64-linux-gnu/gcc-linaro-6.1.1-2016.08-x86_64_aarch64-linux-gnu.tar.xz
sudo tar Jxvf gcc-linaro-6.1.1-2016.08-x86_64_aarch64-linux-gnu.tar.xz -C /apps/gcc-linaro-toolchain/6.1.1

We will now write an environment module that can load the required environment variables on demand (via the environment-modules system) without having to muck around with the local ~/.bashrc as so many cross-compilation tool-kits dictate. Keeps the system lean and clean.

Here are the environment variables that the environment module will be exporting when loaded, given as a guide on how the environment module will be generated. Note that I’m using the full path on my system, modify as needed:

For version 4.9:

export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
export PATH=/apps/gcc-linaro-toolchain/4.9/gcc-linaro-aarch64-linux-gnu-4.9-2014.09_linux/bin:/apps/gcc-linaro-toolchain/4.9/gcc-linaro-aarch64-linux-gnu-4.9-2014.09_linux/aarch64-linux-gnu/include

For version 6.1.1:

export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
export PATH=/apps/gcc-linaro-toolchain/6.1.1/gcc-linaro-6.1.1-2016.08-x86_64_aarch64-linux-gnu/bin:/apps/gcc-linaro-toolchain/6.1.1/gcc-linaro-6.1.1-2016.08-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/include

Now I’ll generate a module file for version 4.9 that you can adapt to your environment as needed:

#%Module1.0#####################################################################
##
## modules compilers/gcc-linaro-toolchain
##
## modulefiles/compilers/gcc-linaro-toolchain.  Written by Dennis Mungai
##
proc ModulesHelp { } {
        global version modroot

        puts stderr "This is the linaro toolchain, use it for cross-compilations (ARM)"
}

module-whatis   "Sets the environment for using the linaro toolchain (C, Fortran)"


set     topdir          /apps/gcc-linaro-toolchain/4.9/gcc-linaro-aarch64-linux-gnu-4.9-2014.09_linux
set     version         4.9

conflict    gcc

setenv          CC              $topdir/bin/aarch64-linux-gnu-gcc
setenv          GCC             $topdir/bin/aarch64-linux-gnu-gcc
setenv          FC              $topdir/bin/aarch64-linux-gnu-gfortran
setenv          F77             $topdir/bin/aarch64-linux-gnu-gfortran
setenv          F90             $topdir/bin/aarch64-linux-gnu-gfortran
setenv      ARCH        arm64
setenv      CROSS_COMPILE   aarch64-linux-gnu-
prepend-path    PATH            $topdir/aarch64-linux-gnu/include
prepend-path    PATH            $topdir/bin
prepend-path    MANPATH         $topdir/share/doc/gcc-linaro-aarch64-linux-gnu/man
prepend-path    LD_LIBRARY_PATH $topdir/aarch64-linux-gnu/lib:$topdir/lib

If you’ve upgraded to the latest Linaro toolchain (version 6.1.1), here’s its’ modulefile, assuming you followed the deployment semantics above:

#%Module1.0#####################################################################
##
## modules compilers/gcc-linaro-toolchain
##
## modulefiles/compilers/gcc-linaro-toolchain.  Written by Dennis Mungai
##
proc ModulesHelp { } {
        global version modroot

        puts stderr "This is the linaro toolchain, use it for cross-compilations (ARM)"
}

module-whatis   "Sets the environment for using the linaro toolchain version 6.1.1 (C, Fortran)"


set     topdir          /apps/gcc-linaro-toolchain/6.1.1/gcc-linaro-6.1.1-2016.08-x86_64_aarch64-linux-gnu
set     version         6.1.1

conflict    gcc-linaro-toolchain/4.9

setenv          CC              $topdir/bin/aarch64-linux-gnu-gcc
setenv          GCC             $topdir/bin/aarch64-linux-gnu-gcc
setenv          FC              $topdir/bin/aarch64-linux-gnu-gfortran
setenv          F77             $topdir/bin/aarch64-linux-gnu-gfortran
setenv          F90             $topdir/bin/aarch64-linux-gnu-gfortran
setenv      ARCH        arm64
setenv      CROSS_COMPILE   aarch64-linux-gnu-
prepend-path    PATH            $topdir/aarch64-linux-gnu/include
prepend-path    PATH            $topdir/bin
prepend-path    MANPATH         $topdir/share/doc/gcc-linaro-aarch64-linux-gnu/man
prepend-path    LD_LIBRARY_PATH $topdir/aarch64-linux-gnu/lib:$topdir/lib

Now, you can load the module above (after deployment) as follows:

module load gcc-linaro-toolchain/4.9

Change to the name under which you saved the module file under. That name used above is what it looks like on my workstation.

You can check if the tool chain installed above works properly while checking it’s version. If you can find gcc version 4.9.2 20140904 (prerelease) at the end of the line, the toolchain is well installed.

$ aarch64-linux-gnu-gcc -v
Using built-in specs.
COLLECT_GCC=aarch64-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/apps/gcc-linaro-toolchain/4.9/gcc-linaro-aarch64-linux-gnu-4.9-2014.09_linux/../libexec/gcc/aarch64-linux-gnu/4.9.2/lto-wrapper
Target: aarch64-linux-gnu
Configured with: /cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/.build/src/gcc-linaro-4.9-2014.09/configure --build=i686-build_pc-linux-gnu --host=i686-build_pc-linux-gnu --target=aarch64-linux-gnu --prefix=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/install --with-sysroot=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/install/aarch64-linux-gnu/libc --enable-languages=c,c++,fortran --disable-multilib --enable-multiarch --with-arch=armv8-a --with-pkgversion='crosstool-NG linaro-1.13.1-4.9-2014.09 - Linaro GCC 4.9-2014.09' --with-bugurl=https://bugs.launchpad.net/gcc-linaro --enable-__cxa_atexit --disable-libmudflap --enable-libgomp --disable-libssp --with-gmp=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/.build/aarch64-linux-gnu/build/static --with-mpfr=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/.build/aarch64-linux-gnu/build/static --with-mpc=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/.build/aarch64-linux-gnu/build/static --with-isl=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/.build/aarch64-linux-gnu/build/static --with-cloog=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/.build/aarch64-linux-gnu/build/static --with-libelf=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/.build/aarch64-linux-gnu/build/static --enable-threads=posix --disable-libstdcxx-pch --enable-linker-build-id --enable-plugin --with-local-prefix=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/install/aarch64-linux-gnu/libc --enable-c99 --enable-long-long
Thread model: posix
gcc version 4.9.2 20140904 (prerelease) (crosstool-NG linaro-1.13.1-4.9-2014.09 - Linaro GCC 4.9-2014.09) 

Checkout

You can check out the Linux kernel source tree from Hardkernel’s Github repositories.Please note that HardKernel distributes the Linux kernel in different branches for Android and other Linux distributions.

Android:

$ git clone --depth 1 https://github.com/hardkernel/linux.git -b odroidc2-3.14.y-android
$ cd linux

Linux:

$ git clone --depth 1 https://github.com/hardkernel/linux.git -b odroidc2-3.14.y
$ cd linux

Compile:

Note:

If you want to download & build only the Android Linux kernel source code without another Android BSP, you will face the error message as below:

  drivers/amlogic/wifi/Kconfig:26: can't open file “../hardware/wifi/realtek/drivers/8192cu/rtl8xxx_CU/Kconfig”

Please delete the last line below in drivers/amlogic/wifi/Kconfig file if you will only build the Android Linux kernel.

source “../hardware/wifi/realtek/drivers/8192cu/rtl8xxx_CU/Kconfig”

You must do a kernel configuration step for ODROID-C2 prior to building it. We use nproc to automatically assign all online processors to the make command:

$ make -j$(nproc) odroidc2_defconfig
$ make -j$(nproc) Image dtbs modules

That will build the Linux kernel (Image), the device tree file (.dtb) and kernel modules (.ko).

Custom Kernel Build

If you have some kernel drivers that you wish to include for your custom build, you can select the drivers easily in the Linux kernel tree. Running make menuconfig will show you an ncurses-based menu that will help you to select kernel drivers.

$ make -j$(nproc) menuconfig

Once you’re done selecting the drivers, exit from the menu screen. Then you can start kernel build with make again.

$ make -j$(nproc) Image modules

When you exit from the kernel menu screen, you will have a .config file in the current directory with the changes set for your custom build. You can optionally back up this as a file, my_kernel.config for example, or even make a patch if you manage your own git repository:

$ cp .config arch/arm64/configs/odroidc2_defconfig
$ git add arch/arm64/configs/odroidc2_defconfig
$ git commit -s -m "Change the kernel config file for ODROID-C2"
$ git push

Installation

There are different installation routes to both the Linux kernel image and the device tree for Android and Linux. Since Android loads both from a boot partition, we have to use fastboot to install into the dedicated partition. Please refer the partition table from here. In contrast, Linux boots by the instructions described in boot.ini , the first FAT partition.

Android:

This details the installation process used to install the kernel image to the boot partition on the target device:

$ fastboot flash boot <path/of/your/Image>

Next, install a device tree file, meson64_odroidc2.dtb.

$ fastboot flash dtb <path/of/your/meson64_odroidc2.dtb>

Linux:

This explanation assumes that your USB memory CARD reader (and/or the eMMC reader, if applicable) is assigned at /dev/sde. Change as appropriate.You may use lsblk to see which entry it appears under on your system.

  1. Plug the Boot-Device (eMMC or SD) into the USB memory CARD reader and connect the USB memory CARD reader to your build host (the Linux PC).
  2. Copy the Image and the Device Tree file (hereby named meson64_odroidc2.dtb) to the FAT partition (1st partition) in the Boot-Device.
     mkdir -p mount
     sudo mount /dev/sde1 ./mount
     sudo cp arch/arm64/boot/Image arch/arm64/boot/dts/meson64_odroidc2.dtb ./mount
     sync
     sudo umount ./mount
    
  3. Copy the driver modules to the EXT4 partition(2nd partition) in the Boot-Device.
     sudo mount /dev/sde2 ./mount
     sudo make modules_install ARCH=arm64 INSTALL_MOD_PATH=./mount
     sync
     sudo umount ./mount
     rm -rf mount
    

And that should be all for the cross-compilation of the Linux kernel for the Odroid C2 on Linux.

Categories ARM Development Boards, LinuxTags , , , , ,

2 thoughts on “Cross Compilation of the Odroid C2 Kernel on an Ubuntu Host

  1. Thanks for this, really helpful.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this:
search previous next tag category expand menu location phone mail time cart zoom edit close