Cross-compiling for ARM



In order to do program in ARM board [9TDMI], I cross-compiled using the Linux ‘C’ compiler for ARM and here is the procedure that I used.

The sources I used are as follows:

  1. Binutils – v2.19.1
  2. Linux Kernel -v2. 4. 17
  3. ARM Kernel patch -v2. 4. 17
  4. gcc- v4.5.1
  5. mpc [supporting package for gcc] – v0.8.1
  6. mpfr[supporting package for gcc] – v2.4.2
  7. gmp [supporting package for gcc] -v4.3.1
  8. glibc – v2.10.1
  9. glibc-ports[supporting package for glibc-to support ARM] – v2.10.1

First, download all the sources and put them into a directory.

Creating a TOOLCHAIN path:

  1. Create a tool chain path to maintain the old compiler as well as this new cross compiler.
  2. In this example, I choose, /home/cross_compile/bin/binutils.
  3. Load this path into std path i.e, in .bash_profile then save and execute the following cmd.

. ~/.bash_profile

Hereafter TOOLCHAIN refers to /home/cross_compile/bin/binutils .

Installation of Cross Binutils:

It is important that Binutils be the first package compiled because both Glibc and GCC perform various tests on the available linker and assembler to determine which of their own features to enable.

Here’s the procedure:

First, uncompress the binutils-2.19.1.tar.gz tarball:

# tar xvfz binutils-2.19.1.tar.gz

Second, create one new directory for building binutils.


# mkdir binutils-build
# cd binutils-build


Third, configure the binutils. This will take about 30 to 50 seconds.

# ../binutils-2.19.1/configure --target=arm-linux -prefix=TOOLCHAIN --disable-nls --disable-werror

The meaning of the configure options:

–prefix=/TOOLCHAIN This tells the configure script to prepare to install the Binutils programs in the TOOL CHAIN directory.
–disable-nls This disables internationalization,and is not needed for the temporary tools.
–disable-werror This prevents the build from stopping in the event that there are warnings from the host’s compiler.

Suppose if any error occurred, which says about ‘if’ block statement means, go to that file, i.e., binutils2.19.1/gas/config/t-arm.c and at the line 2489, put brackets for those statements. Now do the configuration again.

This error will occur if we miss the “–disable-werror” option in the configuration command.

Now execute make then make install commands.

Now we can check the files by getting into various directories in the arm-linux dir in the tool chain path.

Installation of Cross GCC:

From the sources dir, tar the gcc,mpfr,gmp,mpc files.

  1. tar xvfz gcc-4.5.1.tar.gz
  2. cd gcc-4.5.1
  3. tar -jxvf ../mpfr-2.4.2.tar.bz2
  4. mv -v mpfr-2.4.2 mpfr
  5. tar -jxvf ../gmp-4.3.1.tar.bz2
  6. mv -v gmp-4.3.1 gmp
  7. tar xvfz ../mpc-0.8.1.tar.gz
  8. mv -v mpc-0.8.1 mpc

Create one new dir for building gcc.

# mkdir gcc-build
# cd gcc-build

Now configure gcc:


--target=arm-linux  --prefix=TOOLCHAIN
--disable-nls --disable-shared --disable -multilib
--disable-decimal-float --disable-threads
--disable-libmudflap --disable-libssp
--disable-libgomp --enable-languages=c


The meaning of the configure options are:

--disable-shared This switch forces GCC to link its internal libraries statically. We do this to avoid possible issues with the host system.
--disable-multilib To avoid the supporting issues in x86_64. This switch is harmless for x86.
--enable-languages=c This option ensures that only the C compiler is built. This is the only language needed now.
--disable-decimal-float, --disable-threads, --disable-libmudflap, --disable-libssp, --disable-libgomp These switches disable support for the decimal floating point extension, threading, libmudflap, libssp and libgomp respectively.

Now compile GCC and install the package using make and make install. This will take around 15-20 minutes to compile and just a few seconds to install.

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.

# tar xvfz Linux2.6.35 .tar.gz
# cd linux 2.6.35

We need to patch the kernel with the ARM kernel patch. We can do this by running this command:

# zcat ../patch-2.6.35-rmk4.gz

Now, execute this

cp -dR include/* /TOOLCHAINPATH/include/

Finally change to the tool chain directory and create a symbolic link from include to sys-linux:


# cd /TOOLCHAIN/arm-linux/
# ln -s include sys-linux


GCC, which we will compile now, is searching for the include files in sys-linux by default. Verify this with ls -l command.

Installation of Glibc

Go to the sources directory and tar the glibc-2.3.6.tar.gz

# tar xvfz glibc-2.10.1.tar.gz

Now, move into this directory and tar the add-ons:


# cd   glibc-2.10.1
# tar  ../glibc-ports-2.10.1.tar.gz


Create one new dir for building binutils.


cd ..
mkdir glibc-build
cd glibc-build


Configure glibc-2.10.1:

# ../glibc-2.10.1 /configure --target=arm-linux --prefix=TOOLCHAIN --enable-add-ons libc_cv_forced_unwind=yes libc_cv_c_cleanup=yes --disable-profile --host=arm-linux --build=$(../glibc-2.10.1/scripts/config.guess)

If we don’t want the add-ons we have to specify “–disable-sanity-checks” instead of “–enable-add-ons”. But disabling the add-ons will leads to disabling of more features.

Compile the package using make. This will take about 20-25min. Then install the package with make install.

Now we can compile the program with arm-linux-gcc instead of cc to make output run on ARM board with Linux in it. I used LFS book as my reference. In that a lot more steps are explained after this. For my needs, I stopped here and started to test with board.