[go: up one dir, main page]

0% found this document useful (0 votes)
152 views13 pages

Cross Toolchain For ARM

The document discusses the process of building a cross-toolchain from scratch for an ARM architecture. It explains that a cross-toolchain requires compiling binutils, GCC, glibc and other libraries. The document outlines the common steps, which include obtaining sources, compiling binutils first, then the Linux kernel headers, a "bootstrap" GCC, glibc, and finally GCC with all libraries. It provides compiler options and environment variables used during the build process.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
152 views13 pages

Cross Toolchain For ARM

The document discusses the process of building a cross-toolchain from scratch for an ARM architecture. It explains that a cross-toolchain requires compiling binutils, GCC, glibc and other libraries. The document outlines the common steps, which include obtaining sources, compiling binutils first, then the Linux kernel headers, a "bootstrap" GCC, glibc, and finally GCC with all libraries. It provides compiler options and environment variables used during the build process.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

Home

Small reminder for Linux user very keen of embedded system.


We will detail the design of a cross-toolchain "From Scratch".

The purpose of this webpage is to understand the design method of a cross-toolchain of a pedagogical perspective.

1°) Obtaining a cross-toolchain for ARM architecture


There are several ways to obtain a cross-toolchain. First, the most tedious requiring one to one to compile the sources is commonly called "From Scratch". Another
method, more comfortable, is the one requiring the implementation of a tool to generate a string. There crosstool ( http://www.kegel.com/crosstool/ ) which is obsolete but
is still able to produce beautiful though somewhat veillotte chains. Crosstool is replaced by crosstool-ng (ng: New Generation) ( http://crosstool-ng.org ). It is maintained
and managed by a French. Its setting is kind of like the nucleus (ncurses menu to the sauce). There are chains of cross-made compilations and downloadable on the website
of the German company DENX Software Engineering ( http://www.denx.de/en/News/WebHome ). Finally, there are also tools for creating complete embedded Linux
distribution (kernel + file system + toolchain cross) as Buildroot, OpenEmbedded, PTXdist. Disadvantage, in many cases, these chains are specific to cross-compilation
tool for creating distribution.

A cross toolchain consists of different elements as follows:


- The file header of a Linux kernel,
- A set of software development tools: binutils (binary utilities),
- A Compiler: GCC,
- A C library: glibc
- For more recent versions of GCC: a set of libraries for scientific computing: MPFR and GMP.
All these elements are vital to achieving a toolchain. Their various combinations can generate a cross-toolchain with the help of a few patches or not at all be compatible
with each other. It should be to experiment with different versions of each element before reaching a channel without too much difficulty. The library used in the following
examples is glibc. It is mainly used in the Linux world. This library contains the main C library system. Glibc provides a set of routines (opening / - closing file; memory
allocation etc ...) necessary for the proper functioning of the system based on GNU Linux kernel. It acts as an interface between the kernel and operating system calls with
these systems it provides. However, there are other C library that are much lighter and more suitable for embedded systems, for example, the library uClibc, dietlibc library
or library newlib.

2) What you need to know or own

Base for a cross toolchain fully functional, it should obviously have:


- Preferably a fast machine (reduced build time),
- A Linux operating system,
- A GCC compiler,
Whichever method of designing the cross-toolchain, it should also have prior program "autoconf" installed in the host machine. This program is responsible for producing
a file (called make) that automates the compilation of all sources of a package. To generate such a file, the "configure" script has the mission to inspect the system to
ensure that sources can find all dependencies set on the system to properly compile the sources. It should also clarify some terms passed as parameters to the configure
script:
- build : refers to the machine where the source code is compiled,
- host : is the machine where the compiler is running,
- target : is the machine for which code is generated.
In all cases the name of the chain will be final type arm-none-linux-gnueabi . The four values mean:
- arm : information on the processor name. It can be mips, i686, x86_64 etc. ...
- none : provides information on additional information. Sometimes this field does not exist. In the case of its presence, the field type is unknown or none,
- linux : information about the operating system,
- gnueabi : information on the type of libc. There are other gnuabi, gnulibc, uclibc.

3) The common steps of creating a chain

1. Obviously obtaining sources is essential. Downloading them from an official website can be done either by hand (systematic use of the wget command for each
package), or automatically by script (this is the case with crosstool-ng and crosstool). You can download the sources from CVS (Concurrent Versions System). The latter is
a version control system client-server that allows multiple people to work simultaneously on a single set of files. This method allows for the latest update sources. In our
case, since we will work with a little packet of old and whose changes are included in the next higher versions, CVS is not used.

2. The first package to be compiled because the compiler is GCC binutils depends on the tools of it to create executables. Indeed, this is binutils which assembles the
object files generated by GCC in an executable image,

3. We need the functions header of the Linux kernel specifically for the ARM architecture. They contain essential functions such as system calls to interact with the kernel.
These headers are used to produce the C library (glibc) for ARM,

4. Formal credit We will compile a GCC compiler depleted basic functions. Often called "bootstrap GCC", the compiler is still able to produce a library for ARM using
Glibc functions of the kernel headers from the previous step,
5.t We use our "bootstrap GCC" to produce the file header of Glibc,

6, We get a C library function for ARM.

6. We have all the tools to start designing our next GCC compiler for ARM,

4. We compile the GMP and MPFR math libraries for ARM,

9. Finally, we compile the final GCC with previous libraries.

4) The alchemy of different versions of components of a cross toolchain

For the generation of a chain "from scratch", you have to hand all the previous steps. Versions of the various components work well with only a few patches:

- The Linux kernel 2.6.28.3 in its version, downloadable from the address http://www.kernel.org/pub/linux/kernel/v2.6/ ,

The other ingredients are downloadable from the address: http://ftp.gnu.org/gnu/ ,

- Binutils in its version 2.20,

- GCC version 4.3.3,

- Glibc in version 2.9,

- Glibc-ports in its version 2.9,

- GMP version 4.3.2,

- MPFR version in 3.0.1:

5) Get a cross-toolchain "From Scratch"

a) Introduction

This procedure is inspired by the book "Pro Linux Embedded Systems" by Gene Sally by Apress. There is also here and there web sites more or less serious that get a
toolchain smoothly and without patch. I confess to being very cautious about getting a chain smoothly and without a shadow of one patch. Here is detailed, with patch, all
the compiler options and each step is discussed.
The compilation of the chain was performed in a PC which is running a 64 bit Ubuntu 4.11. The elements of the host system interfere little in the construction of the chain,
but it should be clarified version of the various components installed:

- Binutils in its version 2.21,


- GCC version 4.5.2,

- Glibc in version 2.13,

- Glibc-ports in the version 2.13,

- GMP version 4.3.2,

- In its MPFR version 3.0.0.

For reasons of convenience, we will use two terminals to generate our cross toolchain. These terminals can be called T1 and T2. Both terminals have similar environment
variables. However, the terminal T2 advantage of environment variables to facilitate the compilation. In each terminal, enter the following common environment variables:

export SRCDIR=/root/chaine/sources
This directory home all sources downloaded.

export BUILDDIR=/root/chaine/build
It is in this directory that will compile all source packages.

export TARGETMACH=arm-none-linux-gnueabi
This variable specifies the type of target architecture.

export BUILDMACH=x86_64-pc-linux-gnu
This variable specifies the type of architecture in which the package is compiled.

export INSTALLDIR=/opt/arm
This variable provides information about the folder hosting the cross-toolchain.

export SYSROOTDIR=/opt/arm/sysroot
This variable provides information on the directory hosting the libraries and header files the kernel of the target system.

T2 to add more environment variables as follows:

export CROSS=arm-none-linux-gnueabi
Indicates that we use the variable fields CROSS with arm-none-linux-gnueabi.

export CC=${CROSS}-gcc
Indicates that we use the GCC compiler for the ARM architecture.

export LD=${CROSS}-ld
Indicates that we use the dynamic library of the ARM architecture.
export AS=${CROSS}-as
Indicates that we use the assembler of the ARM architecture.

b) Compilation of Binutils

The first package to be compiled is Binutils. Its compilation is not a problem and is fast. From the terminal T1, let's type the following lines:

mkdir $BUILDDIR/binutils
cd $BUILDDIR/binutils
../../sources/binutils-2.20/configure \
--disable-werror \
--build=$BUILDMACH \
--prefix=$INSTALLDIR \
--with-sysroot=$SYSROOTDIR \
--target=$TARGETMACH
make
make install

-> A few explanations:

Parameters Fonction
--disable-werror Disabling "warning": avoid blocking the compilation
--build=$BUILDMACH Architecture of the host PC which is the compilation
--prefix=$INSTALLDIR Home directory of the executable
--with-sysroot=$SYSROOTDIR Home directory of booksellers
--target=$TARGETMACH Target architecture

c) kernel header files

Compiling the kernel header files generates an error due to a function name reused by different codes when compiling. Open the file linux-
2.6.28.3/script/unifdef.c by an editor like vim. Change the function name by removing the letter "e" of the name of the function getline() in getlin() .
You can complete the transaction by directly applying the patch unifdef.c.patch . It simply copy this patch into the directory linux-2.6.28.3/script/ , to go to that
directory and apply it by typing: patch < unifdef.c.patch
Now, the compilation and installation is done without hassle.
From the terminal T1, let's type the following lines:

cd $SRCDIR/linux-2.6.28.3
make mrproper
make ARCH=arm kb9202_defconfig
make ARCH=arm headers_check
make ARCH=arm INSTALL_HDR_PATH=$INSTALLDIR/sysroot/usr headers_install

-> A few explanations:

Option ARCH=arm accurate, of course, the type of target architecture. We will use this string for the card (a little older, I admit) KwikByte KB9202C which is,
unfortunately, more for sale on the manufacturer's website http://www.kwikbyte.com

That is why we specify its use by the entrance kb9202_defconfig . This file includes all the options for the Linux kernel map. To map a generic ARM: Option
integrator_defconfig brings together all the common options of the kernel for all ARM. In the kernel directory linux-2.6.28.3/arch/configs/ , we can
see all cards natively taken into account by the kernel.

d) Bootstrap GCC

Before proceeding with the compilation and installation of primer GCC (bootstrap GCC), ensure that the GMP and MPFR math libraries are installed in your Linux
system.
The GMP library (download at: http://gmplib.org ), contains arithmetic functions to multi-particulars. It is used mainly in research in cryptography and algebraic. GMP is
defined as a Debian / Ubuntu as the package to download / install via the Synaptic package manager. The packages are:
- libgmp3c2 (C library),
- libgmp3-dev (C libraries and C + +),
- lib32gmp3-dev (C libraries and C + + in 32-bit)
- libgmpxx4ldbl (C + + library).

The MPFR library (download at: http://www.mpfr.org ), contains mathematical functions that can perform calculations multi clarification floating point with rounded
accurate. It is maintained by Laurent Fousse ( laurent@komite.net ) professor at Grenoble.
The library is downloadable and installable under Debian / Ubuntu, in the form of package via Synaptic:
- libmpfr4 (Main Library)
- libmpfr-dev (header functions needed for compiling)
- lib32mpfr4 (32-bit version)
- lib32mpfr-dev (header functions required to compile in 32-bit version).

From the terminal T1, let's type the following lines:

mkdir $BUILDDIR/amorce-gcc
cd $BUILDDIR/amorce-gcc
../../sources/gcc-4.3.3/configure \
--build=$BUILDMACH \
--host=$BUILDMACH \
--target=$TARGETMACH \
--prefix=$INSTALLDIR \
--without-headers \
--enable-bootstrap \
--enable-languages=c \
--disable-threads \
--enable-__cxa_atexit \
--disable-libmudflap \
--with-gnu-ld \
--with-gnu-as \
--disable-libssp \
--disable-libgomp \
--disable-nls \
--disable-shared

make all-gcc install-gcc

make all-target-libgcc install-target-libgcc

ln -s /opt/arm/lib/gcc/arm-none-linux-gnueabi/4.3.3/libgcc.a \
/opt/arm/lib/gcc/arm-none-linux-gnueabi/4.3.3/libgcc_sh.a

-> A few explanations:

Most settings entered on the command line disable a number of options not required for the design of a standard library.

Parameters Fonction
--without-
headers
not compile with the headers in comment
--enable-
bootstrap
mode activation "bootstrap"
--enable-
languages=c
we compile for the C language and it is also possible to compile the C + +
--disable- Disabling include files multithreaded because they have not yet been created for the target architecture. GCC will be able to find
threads information on multi-threaded after the headers are created Glibc library
--enable-
__cxa_atexit
option describing the implementation of the function atexit ()
--disable- library used for complex débuger errors in a userspace program. Not necessary here.
libmudflap
--with-gnu-ld Compiling with native linker
--with-gnu-as Compiling with native assembler
--disable-
libssp
deactivation of the bookstore that specializes in memory or stack overflow
--disable-
libgomp
Disabling the OpenMP API specialized in parallel computing
--disable-nls Disabling all local languages except English (POSIX)
--disable-
shared
native compiler (GCC bootstrap) will not support dynamic libraries time to design the final GCC compiler.

Command Explanation
make all-gcc install-gcc
created the basic compiler and installs it in the directory
specified by the variable $ INSTALLDIR
Construction of a core library used by GCC to produce code.
make all-target-libgcc install-target-libgcc This library must be built before the final because it depends
entirely on it.
ln -s /opt/arm/lib/gcc/arm-none-linux-gnueabi/4.3.3/libgcc.a By this symbolic link, we force the design of the library of static
/opt/arm/lib/gcc/arm-none-linux-gnueabi/4.3.3/libgcc_sh.a toolchain.

e) Creation of header files from glibc

These header files are used for defining the functions created by the compiler installed on the target system (our famous Bootstrap GCC).
Before proceeding with the compilation and installation of header files glibc, it should be patched two files. The first patch changes the version number supported by Glibc
and is configure.patch (applicable in the root of glibc-2.9).
The second solves a problem with sed backslash and is gen-sorted.awk.patch . (Applicable in the directory glibc-2.9/scripts/ ).

Since the terminal T2, let's type the following lines:

mkdir $BUILDDIR/libc-header
cd $BUILDDIR/libc-header
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" » config.cache
export PATH=$INSTALLDIR/bin:$PATH
../../sources/glibc-2.9/configure \
--build=$BUILDMACH \
--host=$TARGETMACH \
--prefix=$SYSROOTDIR/usr \
--with-headers=$SYSROOTDIR/usr/include \
--config-cache \
--enable-add-ons=glibc-ports-2.9,nptl \
--enable-kernel=2.6.0
make -k install-headers cross_compiling=yes install_root=$SYSROOTDIR
ln -s /opt/arm/lib/gcc/arm-none-linux-gnueabi/4.3.3/libgcc.a \
/opt/arm/lib/gcc/arm-none-linux-gnueabi/4.3.3/libgcc_eh.a

Parameters Fonction
--prefix=$SYSROOTDIR/usr Home directory of the executable.
--with-headers=$SYSROOTDIR/usr/include Use of the headers of the core of step c).
--config-cache Force the executable configure to read the instructions file config.cache
--enable-add-ons=glibc-ports-2.9,nptl Using the additional library glibc-ports for ARM (our case). Also valid for MIPS and PowerPC.
--enable-kernel=2.6.0 Design of the library to the Linux kernel 2.6.0 kind.

Command Explanation
echo "libc_cv_forced_unwind=yes" > The file config.cache contains these two lines that prevent the execution of code compiled for ARM
config.cache
echo "libc_cv_c_cleanup=yes" » config.cache toolchain with cross installed on the host which is the x86.
make -k install-headers cross_compiling=yes
install_root=$SYSROOTDIR
The header files are cross-compiled and installed into the $SYSROOTDIR
ln -s /opt/arm/lib/gcc/arm-none-linux-
gnueabi/4.3.3/libgcc.a \
/opt/arm/lib/gcc/arm-none-linux-
Same here: by this symbolic link, we force the design of the library of static toolchain.
gnueabi/4.3.3/libgcc_eh.a

e) Establishment of Glibc

Well, here we are, we have all the elements in the directory $INSTALLDIR to be able to design our Glibc for ARM. You will notice that the controls are very similar
compared to the previous step.
Note: The compilation takes a long time and most of the parameters have already been explained.

Since the terminal T2, let's type the following lines:


mkdir $BUILDDIR/glibc
cd $BUILDDIR/glibc
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" » config.cache
../../sources/glibc-2.9/configure \
--build=$BUILDMACH \
--host=$TARGETMACH \
--prefix=/usr \
--with-headers=$SYSROOTDIR/usr/include \
--config-cache \
--enable-add-ons=glibc-ports-2.9,nptl \
--enable-kernel=2.6.0
make -k install-headers cross_compiling=yes install_root=$SYSROOTDIR
make
make install_root=$SYSROOTDIR install

f) Creation of the GCC compiler for ARM

The GCC compiler generated after this step, is able to compile code static. You can stop after this step if you develop applications using extensions static libraries.

From the terminal T1, let's type the following lines:

mkdir $BUILDDIR/gcc
cd $BUILDDIR/gcc
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" » config.cache
export CC=gcc
../../sources/gcc-4.3.3/configure \
--build=$BUILDMACH \
--target=$TARGETMACH \
--prefix=$INSTALLDIR \
--with-sysroot=$SYSROOTDIR \
--enable-languages=c \
--with-gnu-as \
--with-gnu-ld \
--disable-multilib \
--with-float=soft \
--disable-sjlj-exceptions \
--disable-nls \
--enable-threads=posix \
--enable-long-longx
make all-gcc
make install-gcc

Parameters Fonction
export CC=gcc The environment variable forces the compiler for ARM GCC compiler of the host.
--disable-multilib Different variants for different library arhitecture different is not designed.
--with-float=soft Support for floating point numbers emulated by the software because the ARM have no FPU (Floating Point Unit)
--disable-sjlj-exceptions Exceptions specific to C + +, they should be seen off our string only supports C.
--enable-threads=posix Threads are POSIX format
--enable-long-longx C, support for long integers

g) Cross-compiling bibilothèques GMP and MPFR

Add functionality to our final GCC by implementing special libraries for multiprecision GMP and MPFR. Prior to cross-compile GMP (GMP is compiled first because
MPFR depends on it), it is necessary to install the package m4 is a macro processing language (maintained by Santiago Vila at sanvila@debian.org) . GMP and MPFR
libraries to compile statically with the previous CCG. They will move into the directory /opt/arm/lib

Since the terminal T2, let's type the following lines:

mkdir $BUILDDIR/gmp
cd $BUILDDIR/gmp
export CFLAGS=-static
../../sources/gmp-4.3.2/configure \
--build=$BUILDMACH \
--host=$TARGETMACH \
--prefix=$INSTALLDIR \
--disable-shared
make
make install

Since the terminal T2, let's type the following lines:

mkdir $BUILDDIR/mpfr
cd $BUILDDIR/mpfr
../../sources/mpfr-3.0.1/configure \
--build=$BUILDMACH \
--host=$TARGETMACH \
--prefix=$INSTALLDIR \
--with-gmp=$INSTALLDIR
make
make install

h) Creating final GCC compiler

We have all the elements to finalize the design of the GCC compiler. The toolchain is obitent in the cross compiling with the compiler of the host (where the line export
CC=gcc ). This is a rather long operation.
The arguments passed are the same as f) with some exceptions: support for libraries and compiler previous final supporting dynamic compilation.

From the terminal T1, let's type the following lines:

mkdir $BUILDDIR/gcc-final
cd $BUILDDIR/gcc-final
export CC=gcc
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" » config.cache
../../sources/gcc-4.3.3/configure \
--build=$BUILDMACH \
--target=$TARGETMACH \
--prefix=$INSTALLDIR \
--with-sysroot=$SYSROOTDIR \
--enable-languages=c \
--with-gnu-ld \
--with-gnu-as \
--disable-multilib \
--with-float=soft \
--disable-sjlj-exceptions \
--disable-nls \
--enable-threads=posix \
--disable-libmudflap \
--disable-libssp \
--enable-long=longx \
--with-shared \
--with-gmp=$INSTALLDIR \
--with-mpfr=$INSTALLDIR
make
make install

The final library of GCC is in the directory: /opt/arm/arm-none-linux-gnueabi/lib . The cross toolchain is in the directory /opt/arm/bin . In the
terminal T1, we can add the executables of cross-toolchain in the environment variable PATH by typing: export PATH=$INSTALLDIR/bin:$PATH
By typing the first letters of executable arm and pressing the tab key, we now have direct access to executables.

6) Test of the cross-toolchain "From Scratch"

Do a test build with our newly installed chain. We will compile the program celebrates Helloworld that just prints a terminal in the message "Hello World".
In compiling the program by:

arm-none-linux-gnueabi-gcc -o helloworld helloworld.c

We can check the file type compiled using the command line:
file helloworld

gives:

helloworld: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux
2.6.16, not stripped

Well, this little test tells us that the executable is generated for the ARM architecture. You diposez now a beautiful cross-toolchain for ARM made for yourself!

Page updated on 06/04/2012

You might also like