HOWTO: Compile toolchain to cross-compile Android Kernel

I did the following because I needed my server, running on FreeBSD, to be able to compile the Android Kernel. A cross-compile toolchain has to be built. For this, binutils, eglibc (or glibc) and gcc are needed components to be manually compiled and consist the canadian cross. Additionally, the Linux kernel headers are needed.

Here I used the ones from Linaro: https://releases.linaro.org/14.07/components/toolchain. The present example builds an ARMv7 gcc cross-compiler able to build the Android Kernel for Samsung Galaxy Nexus. Although a large part of this is written in the EGLIBC.cross-building file in eglibc source, a lot of smaller modifications documented here are needed. The following has been tested on a FreeBSD 9.3p0 up-to-date system.

1) On the HOST machine install the following packages
Code:
# pkg install gettext mpc mpfr gmp gcc49 gsed gmake

2) Replace: /usr/bin/sed with a symlink to gsed
Code:
# mv /usr/bin/sed /usr/bin/sed.org
# ln -s /usr/local/bin/gsed /usr/bin/sed

3) Set working directory and shell variables
Code:
$ mkdir /home/user/src/linaro
$ mkdir /home/user/src/linaro/tools
$ mkdir /home/user/src/linaro/sysroot
$ export TOOLS_PATH=/home/user/src/linaro/tools
$ export SYSROOT_PATH=/home/user/src/linaro/sysroot
$ export TRIPLET=arm-unknown-linux-gnueabi

4) Get the source of the components and extract them in the working directory
https://releases.linaro.org/14.07/c...naro/binutils-linaro-2.24.0-2014.07-1.tar.bz2
https://releases.linaro.org/14.07/c...ibc-linaro/eglibc-linaro-2.19-2014.07.tar.bz2
https://releases.linaro.org/14.07/c...cc-linaro/4.9/gcc-linaro-4.9-2014.07-1.tar.xz
https://www.kernel.org/pub/linux/kernel/v2.6/longterm/v2.6.32/linux-2.6.32.63.tar.xz
Code:
$ cd /home/user/src/linaro
$ tar xf *.tar*

5) Compile and install binutils
Code:
$ cd binutils-linaro-2.24.0-2014.07-1
$ mkdir build; cd build
$ CXX=g++49 CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH ../configure --target=$TRIPLET \
--prefix=$TOOLS_PATH --with-sysroot=$SYSROOT_PATH

$ CXX=g++49 CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH gmake
$ CXX=g++49 CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH gmake install

6) Compile gcc, a bare one, in order to build eglibc
Code:
$ cd gcc-linaro-4.9-2014.07-1
$ mkdir build; cd build
$ CXX=g++49 CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH ../configure --target=$TRIPLET \
--prefix=$TOOLS_PATH --without-headers \
--disable-shared --disable-threads --disable-libssp --disable-libgomp \
--disable-libmudflap --enable-languages=c --disable-libquadmath \
--disable-libatomic --with-arch=armv7-a --with-tune=cortex-a9 --with-fpu=neon \
--with-float=hard

$ CXX=g++49 CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH gmake
$ CXX=g++49 CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH gmake install

7) Install the Linux Kernel Headers
Code:
$ cd ../..
$ cd linux-2.6.32.63
$ PATH=$TOOLS_PATH/bin:$PATH gmake headers_install ARCH=arm \
CROSS_COMPILE=$TRIPLET- INSTALL_HDR_PATH=$SYSROOT_PATH/usr

8) Install the eglibc headers and libs
Code:
$ cd ../..
$ cd eglibc-2.19-2014.07
$ mkdir build; cd build
The source needs to be patched as following:
sunrpc/rpc_main.c replace all stat64 references with stat

Then:
Code:
$ BUILD_CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH RANLIB=$TOOLS_PATH/bin/$TRIPLET-ranlib ../configure \
--prefix=/usr --with-headers=$SYSROOT_PATH/usr/include --host=$TRIPLET --disable-profile \
--without-gd --without-cvs --enable-add-ons
$ DESTDIR=$SYSROOT_PATH gmake install-headers install_root=$SYSROOT_PATH install-bootstrap-headers=yes
$ mkdir -p $SYSROOT_PATH/usr/lib
$ gmake csu/subdir_lib
$ cp csu/crt1.o csu/crti.o csu/crtn.o $SYSROOT_PATH/usr/lib
$ $TOOLS_PATH/bin/$TRIPLET-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o $SYSROOT_PATH/usr/lib/libc.so

9) Compile and install gcc, 2nd level
Code:
$ cd ../..
$ cd gcc-linaro-4.9-2014.07-1
$ mkdir build2; cd build2
$ CXX=g++49 CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH ../configure --target=$TRIPLET \
--prefix=$TOOLS_PATH --with-sysroot=$SYSROOT_PATH --disable-libssp \
--disable-libgomp --disable-libmudflap --enable-languages=c \
--disable-libquadmath --disable-libatomic --with-arch=armv7-a \
--with-tune=cortex-a9 --with-fpu=neon --with-float=hard

$ CXX=g++49 CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH gmake
$ CXX=g++49 CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH gmake install

10) Compile and Install eglibc
Code:
$ cd ../..
$ cd eglibc-2.19-2014.07
$ mkdir build2; cd build2
$ BUILD_CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH RANLIB=$TOOLS_PATH/bin/$TRIPLET-ranlib ../configure \
--prefix=/usr --with-headers=$SYSROOT_PATH/usr/include --host=$TRIPLET --disable-profile \ 
--without-gd --without-cvs --enable-add-ons

$ PATH=$TOOLS_PATH/bin:$PATH gmake
$ PATH=$TOOLS_PATH/bin:$PATH gmake install install_root=$SYSROOT_PATH

11) Compile and Install the complete gcc
Code:
$ cd ../..
$ cd gcc-linaro-4.9-2014.07-1
$ mkdir build3; cd build3
$ CXX=g++49 CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH ../configure --target=$TRIPLET --prefix=$TOOLS_PATH \
--with-sysroot=$SYSROOT_PATH --enable-__cxa_atexit --enable-languages=c,c++ --with-arch=armv7-a \
--with-tune=cortex-a9 --with-fpu=neon --with-float=hard

$ CXX=g++49 CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH gmake
$ CXX=g++49 CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH gmake install

12) Compile the Galaxy Nexus Kernel:
Get the source according to https://source.android.com/source/building-kernels.html
As in FreeBSD the echo command lacks the -e switch the following needs to be changed:
In kernel-source: script/Kbuild.include, function as-instr, replace echo -e with printf "%s\n"

Code:
$ cd "kernel-source-dir"
$ ARCH=arm SUBARCH=arm CROSS_COMPILE=$TRIPLET- PATH=$TOOLS_PATH/bin:$PATH gmake tuna_defconfig
$ ARCH=arm SUBARCH=arm CROSS_COMPILE=$TRIPLET- PATH=$TOOLS_PATH/bin:$PATH gmake

The compiled kernel should be in "kernel-source-dir"/arch/arm/boot/zImage. It now needs to be converted to boot.img in order to be flashed to the boot partition of the device (hint: mkbootimg).

13) Set back sed
Code:
# rm /usr/bin/sed
# mv /usr/bin/sed.org /usr/bin/sed
 
As the eglibc is now deprecated, the following builds the toolchain by using glibc. Only the changing steps are provided.

4) Source:
http://ftp.gnu.org/gnu/libc/glibc-2.19.tar.xz

8) Only the source needs to be patched. No option to install only the headers. Proceed with step 10.
sunrpc/rpc_main.c replace all stat64 references with stat.

9) Not needed.

10) Compile and install glibc
Code:
$ cd glibc-2.19
$ make build; cd build
$ BUILD_CC=gcc49 PATH=$TOOLS_PATH/bin:$PATH ../configure --prefix=/usr --with-headers=$SYSROOT_PATH/usr/include --host=$TRIPLET --target=$TRIPLET

$ PATH=$TOOLS_PATH/bin:$PATH gmake 
$ PATH=$TOOLS_PATH/bin:$PATH gmake install install_root=$SYSROOT_PATH

11) The --enable-__cxa_atexit parameter is not needed.
 
Back
Top