Monday, March 06, 2006

Building Cross-Compiling Toolchain

The following packages are needed:
Package Used version Download
Linux Kernel 2.4.17 ftp.kernel.org
ARM Kernel patch 2.4.17-rmk4 ftp.arm.linux.org
binutils 2.11.2 ftp.gnu.org
gcc 2.95.3 ftp.gnu.org
glibc 2.2.4 ftp.gnu.org
glibc linuxthreads add-on 2.2.4 ftp.gnu.org


binutils

Unpack the binutils tarball into a temporary directory, change to the unpacked binutils directory and run the following commands:

# ./configure --target=arm-linux
# make
# make install

You have now some arm-linux-* binaries in /usr/local/bin. These are the binutils used by the cross-compiling toolchain. And you'll find the new directory /usr/local/arm-linux/. This is where the cross-compiling toolchain will be installed.

You can check if the binutils are compiled correctly by calling arm-linux-ar. This tool outputs the supported targets in its command line help. You should find targets like elf32-littlearm there.

Linux Kernel header files

To compile gcc we need some header files from the linux kernel source. Unpack the kernel source code in a temporary directory and change to the unpacked source directory. You'll need to patch the kernel with the ARM kernel patch. You do this by running this command:

# zcat path-to-arm-patch/patch-2.4.17-rmk4.gz | patch -p1

Now you need to configure the kernel by calling this command:

# make menuconfig ARCH=arm

Notice that you need to specify ARCH=arm otherwise you are going to configure the kernel for your host architecture which maybe a x86 machine.

You don't need to do a complete configuration unless you want to compile the kernel now. Up to now you don't have a cross compiler so you can't compile it anyway. All you need to do is to select the correct processer type. Now save the configuration and call the following command to finish the kernel configuration:

# make dep

Now copy the include files from the kernel source to the toolchain directory:

# mkdir /usr/local/arm-linux/include
# cp -dR include/asm-arm /usr/local/arm-linux/include/asm
# cp -dR include/linux /usr/local/arm-linux/include/linux

Finally change to the toolchain directory and create a symbolic link from include to sys-include:

# cd /usr/local/arm-linux/
# ln -s include sys-linux

gcc, which we will compile now, is searching for the include files in sys-linux by default. You can use the --with-headers configure-option to specify an other directory but this results in copying the specifed directory to sys-linux. So I think it's better to create a symbolic link to avoid redundant files.

gcc

Unpack the gcc source code and change to the unpacked source directory. We currently don't have a running glibc so we can't compile the whole compiler suite. But for now it is enough to compile only the C compiler. Later we can compile the glibc with this cross compiler and after that we can compile the whole compiler suite.

It may be necessary to modify the gcc source a little bit. Edit the file gcc/config/arm/t-linux, search this line:

TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC

And change it to this:

TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h

Now configure the source code, compile and install:

# ./configure --target=arm-linux --disable-threads --enable-languages=c
# make
# make install

You have now a running cross compiler (/usr/local/bin/arm-linux-gcc) but without glibc it is not really useful.

glibc

Before, proceeding with glibc, check link files /usr/local/arm-linux/include/asm/proc and /usr/local/arm-linux/include/asm/arch are correctly link. In my case, I'm using ARM920T and these links should be proc-armv and arch-integrator respectively.

Unpack the glibc tarball in a temporary directory as usual. Then switch to the unpacked source directory and unpack the linuxthreads add-on into it:

# tar xvfz glibc-2.2.4.tar.gz
# cd glibc-2.2.4
# tar xvfz ../glibc-linuxthreads-2.2.4.tar.gz

Now set the environment variable CC to arm-linux-gcc because we want the glibc to be cross-compiled for the ARM platform. Then configure, compile and install:

# export CC=arm-linux-gcc
# ./configure arm-linux --target=arm-linux --prefix=/usr/local/arm-linux --enable-add-ons
# make
# make install

Be sure you use the --prefix parameter correctly, otherwise you mess up your hosts glibc installation.

You'll now find a lot of new files and directories in /usr/local/arm-linux. These are the glibc headers, libraries and utitilies.

Notice that you can't use this compiled glibc on the target machine because of the specified prefix. If you want to compile a glibc which you can copy to your target machine, use an empty prefix (--prefix=) instead and use the install_root parameter to specify the installation directory:

# make install install_root=/path/to/target/root

Finally, make sure you unset the CC environment variable (with unset CC).


Thanks to http://www.ailis.de/~k/docs/crosscompiling/toolchain.php

No comments: