Category Archives: arm

Building GCC ARM Toolchain on Slackware64

ARM, is one of popular processor architecture on market. ARM is a family of RISC-based computer processor designed and licensed by British company ARM Holdings. First developed in the 1980s. This processors are the major choice for embedded systems such as smartphones, hard disk drives, digital television, microcontrollers, mobile computer, etc.

We know that x86 (and also x86_64) is different to ARM. Therefore, we can not use famous GCC for x86 or x86_64 compiler to compile application for ARM. We need compiler who have the capability to do so. Fortunately, with proper set up GCC can be used to build application for ARM.

In this article we will about how to build GCC ARM Toolchain for ARM architecture. The built GCC can be used to compile application into ARM’s machine codes. The toolchain then reside on /usr/local path.

For this article, I use:

  1. Slackware64 14.0
  2. GCC
  3. Binutils
  4. newlib
  5. MPFR
  6. GMP
  7. MPC

Acquiring the Materials

Before we proceed to main phase, make sure you have at least (2) to (6). Slackware64 14.0 is optional. You can use any linux distribution you like.

Download latest binutils and GCC version. At the time of writing this article, the latest version of binutils is 2.23.1 which you can obtain at here. The latest GCC is 4.7.2 which you can obtain here. Extract them into a working directory, let say /home/xathrya/ARMGCC. You will get binutils-2.23.1 and gcc-4.7.2 directory. And then make two new directory, binutils-obj and gcc-obj. The commands for that (adjust if you have other than .tar.bz2):

cd ~/ARMGCC
tar -Jxf binutils-2.23.0.tar.bz2
tar -Jxf gcc-4.7.2 .tar.bz2
mkdir binutils-obj gcc-obj

Next is obtaining newlib. Newlib is an alternative to GLIBC. At time of writing this article, the latest newlib is 1.20.0 which can be downloaded here. Again, extract the content from archive and create a folder newlib-obj.

cd ~/ARMGCC
tar -xf newlib-1.20.0.tar.gz
mkdir newlib-obj

The MPFR, GMP, and MPC is not the latest version, but at least we can build GCC. Supposing your working directory at /home/xathrya/ARMGCC, to obtain MPDR, GMP, and MPC invoke following command:

cd ~/ARMGCC/gcc-4.7.2
./contrib/download_prerequisites

You then will gave three more directories on ~/ARMGCC/gcc-4.7.2. Rename them with eliminating their version number. Thus you will get three directories: mpfr, gmp, mpc.

Optionally you can build GDB. Download the latest version (at this time is 7.5) at here. Extrace the archive and make sure it is on working directory.

cd ~/ARMGCC
tar -jxf gdb-7.5.tar.bz2
mkdir gdb-obj

Deciding the Target

In ARM, there is a naming convention which explain what toolchain will do. The target alias, or target, is the target of the toolchain. It’s more than just an architecture. The tools on this toolchain will have some profix, such as: arm-none-eabi-gcc, arm-linux-eabi-gcc, etc.

This distinguish one toolchain from native host compiler and have different purpose for each name.

Basically, “arm-none-eabi” is consist of three part:

  1. architecture / processor name. Which is ARM architecture (ARM, Thumb, Thumb-2, etc)
  2. something about OS/libraries. This part is varies. Some have none and other has linux, etc. The ‘none’ means that the toolchains are not targetting specific operating system (aka ‘bare-metal’). ‘unknown’ is the same as ‘none’ while ‘linux’ designed to be used to build programs with glibc under a Linux environment, usually for built for embedded linux ARM devices.
  3. ABIs. This part describes how binary files (libraries, etc) are stored (the actual file formats), and calling conventions, register usage, etc. Some common are gnuabi, eabi, etc.

In this article, we will build both arm-none-eabi and arm-linux-eabi.

Building the Toolchains

Building stage is pretty simple. Honestly speaking, the tricky part is about how GCC and built concept and ordering them in correct order.

First, built binutils. This will provide lots of useful tools in building ARM libraries and binaries (like objdump, ld, ranlib, etc). Invoke following commands:

cd ~/ARMGCC/binutils-obj
../binutils-2.23.1/configure --target=arm-none-eabi --prefix=/usr/local --enable-interwork --enable multilib
make all install

You will notice a few configure options that are really critical for getting things to work properly.

  • –target=arm-none-eabi Says we want a compiler to generate binaries for the arm-none-eabi platform. You can change to arm-linux-eabi if you want to build arm-linux-eabi.
  • –enable-interwork This allows for assembling Thumb and ARM code mixed into the same binaries (for those chips that support that)
  • –enable-multilib Multilib allows the use of libraries that are compiled multiple times for different targets/build types (see
  • –prefix=/usr/local, our path for installed directory

Next we will build the GCC. But please note that we are only intereset on C and C++ so we will ignore other language. To built GCC, do this:

cd ~/ARMGCC/gcc-obj
../gcc-4.7.2/configure --target=arm-none-eabi --prefix=/usr/local --enable-interwork --enable multilib --enable-languages="c,c++" 
   --with-new-lib --with-headers=../newlib-1.20.0/newlib/libc/include
make all-gcc install-gcc

If you want to build arm-linux-eabi, do this one instead (you should see the difference):

cd ~/ARMGCC/gcc-obj
../gcc-4.7.2/configure --target=arm-none-eabi --prefix=/usr/local --enable-interwork --enable multilib --enable-languages="c,c++"
make all-gcc install-gcc

Now, the important points are:

  • –enable-languages=”c,c++” Only build C and C++.
  • –with-newlib Use Newlib instead of the standard C libraries.
  • –with-headers This adds a header inlude path during build time and will allow the build to find the newlib header files

Now build Newlib using our new cross-compiler

cd ~/ARMGCC/newlib-obj
 ../newlib-1.20.0/configure --target=arm-none-eabi --prefix=/usr/local --enable-interwork --enable multilib
 make all install

If you build one for arm-linux-eabi, you don’t need to build the newlib.

Optionally you can build GDB. To do so, invoke following:

cd gdb-obj
../gdb-7.5/configure --target=arm-none-eabi --prefix=/usr/local --enable-interwork --enable-multilib
make all install

And that’s it. You should have them now.

The post Building GCC ARM Toolchain on Slackware64 appeared first on Xathrya.ID.

Building GCC ARM Toolchain Cross Compiler (Bare Metal)

In this article we will about how to build GCC ARM Toolchain, which is a cross compiler to build ARM program. The built GCC can be used to compile application into ARM’s machine codes. The toolchain then reside on /usr/local path.

For this article, I use:

  1. Slackware64 14.0
  2. GCC 4.9.2
  3. GDB 7.8.1
  4. Binutils 2.24
  5. Newlib 2.1
  6. GMP 6.0.0
  7. MPFR 3.1.2
  8. MPC 1.0.2

Deciding the Target

In ARM, there is a naming convention which explain what toolchain will do. The target alias, or target, is the target of the toolchain. It’s more than just an architecture. The tools on this toolchain will have some profix, such as: arm-none-eabi-gcc, arm-linux-eabi-gcc, etc.

This distinguish one toolchain from native host compiler and have different purpose for each name.

Basically, “arm-none-eabi” is consist of three part:

  1. architecture / processor name. Which is ARM architecture (ARM, Thumb, Thumb-2, etc)
  2. something about OS/libraries. This part is varies. Some have none and other has linux, etc. The ‘none’ means that the toolchains are not targetting specific operating system (aka ‘bare-metal’). ‘unknown’ is the same as ‘none’ while ‘linux’ designed to be used to build programs with glibc under a Linux environment, usually for built for embedded linux ARM devices.
  3. ABIs. This part describes how binary files (libraries, etc) are stored (the actual file formats), and calling conventions, register usage, etc. Some common are gnuabi, eabi, etc.

In this article, we will build arm-none-eabi to make bare metal arm compiler.

Preparation

We will need some disk space (~2GB should be enough). We also need root access to install it on “system-wide”.

Slackware64 14.0 is optional. You can use any linux distribution you like.

We will create a working directory. We will refer it as $ARMGCC, so $ARMGCC/src should really be something like ~/ARMGCC/src (the ~ means your home directory). So go ahead and create following directory structure:

# set aliases
export ARMGCC=~/ARMGCC
export TARGET=arm-none-eabi
export PREFIX=/usr/local

export BINUTILS_BUILD=${ARMGCC}/build/binutils-build
export GCC_BUILD=${ARMGCC}/build/gcc-build
export GDB_BUILD=${ARMGCC}/build/gdb-build

export BINUTILS_SRC=${ARMGCC}/src/binutils-2.24
export GCC_SRC=${ARMGCC}/src/gcc-4.9.2
export GDB_SRC=${ARMGCC}/src/gdb-7.8.1
export NEWLIB_SRC=${ARMGCC}/src/newlib-2.1.0

# make base dir, original archives dir (orig), source code dir (src), 
# and working / building dir (build) 
mkdir ${ARMGCC}{,/{orig,src,build}}

# Make build directory for each component
mkdir ${ARMGCC}/build/{binutils,gcc,gdb}-build

Acquiring the Materials

Download latest packages of GCC, GDB, binutils, and Newlib.You can download it using wget or alternatively download via browser and move it to $ARMGCC/orig. The version we will use is GCC 4.9.0, GDB 7.7, binutils 2.24, and newlib 2.1.0.

cd ${ARMGCC}/orig
wget ftp://ftp.gnu.org/pub/gnu/gcc/gcc-4.9.2/gcc-4.9.2.tar.bz2
wget ftp://ftp.gnu.org/pub/gnu/gdb/gdb-7.8.1.tar.xz
wget ftp://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.bz2
wget ftp://sources.redhat.com/pub/newlib/newlib-2.1.0.tar.gz

wget ftp://ftp.gnu.org/pub/gnu/gmp/gmp-6.0.0a.tar.xz
wget ftp://ftp.gnu.org/pub/gnu/mpc/mpc-1.0.2.tar.gz
wget ftp://ftp.gnu.org/pub/gnu/mpfr/mpfr-3.1.2.tar.gz

Then, extract them to src directory.

cd ${ARMGCC}/src

tar -jxf ${ARMGCC}/orig/gcc-4.9.2.tar.bz2
tar -Jxf ${ARMGCC}/orig/gdb-7.8.1.tar.xz
tar -jxf ${ARMGCC}/orig/binutils-2.24.tar.bz2
tar -zxf ${ARMGCC}/orig/newlib-2.1.0.tar.gz

Next we need to download some prerequisites, especially GMP (GNU Multiple Precision), MPC (Multiple-Precision Complex), and MPFR (Multiple-Precision Floating Point Reliably) which is used for computation. The prerequisites can be downloaded by invoking following command:

The MPFR, GMP, and MPC is not the latest version, but at least we can build GCC. Suppose your working directory at /home/xathrya/ARMGCC, to obtain MPDR, GMP, and MPC invoke following command:

cd ${GCC_SRC}
./contrib/download_prerequisites

However, the version of GMP, MPC, MPFR, PPL, CLOOG, and ISL is not the latest version. We can switch to the latest version by download the latest version and create symbolic link to it.

cd ${GCC_SRC}

rm {gmp,mpc,mpfr}

tar -Jxf ${ARMGCC}/orig/gmp-6.0.0a.tar.xz
tar -zxf ${ARMGCC}/orig/mpc-1.0.2.tar.gz
tar -zxf ${ARMGCC}/orig/mpfr-3.1.2.tar.gz

ln -s gmp-6.0.0 gmp
ln -s mpc-1.0.2 mpc
ln -s mpfr-3.1.2 mpfr

Building the Toolchains

Building stage is pretty simple. Honestly speaking, the tricky part is about how GCC and built concept and ordering them in correct order.

Binutils

First, built binutils. This will provide lots of useful tools in building ARM libraries and binaries (like objdump, ld, ranlib, etc). Invoke following commands:

cd ${BINUTILS_BUILD}
${BINUTILS_SRC}/configure 
   --target=${TARGET} 
   --prefix=${PREFIX} 
   --enable-interwork 
   --enable-multilib 
   --with-gnu-as 
   --with-gnu-ld 
   --disable-werror 
   --disable-nls
make configure-host
make -j4 all
make install
make clean

You will notice a few configure options that are really critical for getting things to work properly.

  • –target=arm-none-eabi Says we want a compiler to generate binaries for the arm-none-eabi platform.
  • –enable-interwork This allows for assembling Thumb and ARM code mixed into the same binaries (for those chips that support that)
  • –enable-multilib Multilib allows the use of libraries that are compiled multiple times for different targets/build types
  • –enable-shared – enable the creation of the shared libraries.

GCC

Next we will build the GCC. But please note that we are only intereset on C and C++ so we will ignore other language. To built GCC, do this:

cd ${GCC_BUILD}
${GCC_SRC}/configure 
   --target=${TARGET} 
   --prefix=${PREFIX} 
   --enable-interwork 
   --enable-multilib 
   --enable-languages="c,c++" 
   --with-newlib 
   --without-headers 
   --disable-shared 
   --with-system-zlib 
   --with-gnu-as 
   --with-gnu-ld 
   --disable-nls 
   --enable-c99 
   --enable-long-long 
   --enable-__cxa_atexit
make -j4 all-gcc install-gcc
make clean

Now, the important points are:

  • –enable-languages=”c,c++” - means build C and C++ only.
  • –with-newlib – use Newlib instead of the standard C libraries.
  • –with-headers – this adds a header inlude path during build time and will allow the build to find the newlib header files
  • –enable-__cxa_atexit – allows use of __cxa_atexit, rather than atexit, to register C++ destructors for local statics and global objects and is essential for fully standards-compliant handling of destructors. It also affects the C++ ABI and therefore results in C++ shared libraries and C++ programs that are interoperable with other Linux distributions.
  • –enable-c99 – enable C99 support for C programs.
  • –enable-long-long – enables long long support in the compiler.

Newlib

Now build our newlib

cd ${NEWLIB_BUILD}
${NEWLIB_SRC}/configure 
  --target=${TARGET} 
  --prefix=${PREFIX} 
  --enable-interwork 
  --enable-multilib 
  --with-gnu-as 
  --with-gnu-ld 
  --disable-nls 
  --enable-target-optspace 
  --enable-newlib-reent-small 
  --enable-newlib-io-c99-formats 
  --enable-newlib-io-long-long 
  --disable-newlib-multithread 
  --disable-newlib-supplied-syscalls 
  CFLAGS_FOR_TARGET="
make -j4 all
make install
make clean

GCC (again)

Now that we have our runtime libraries, go back and ginish the GCC build:

cd ${GCC_BUILD}
make all-install

GDB

Optionally you can build GDB. To do so, invoke following:

cd ${GDB_BUILD}
${GDB_SRC}/configure 
   --target=${TARGET} 
   --prefix=${PREFIX} 
   --enable-interwork 
   --enable-multilib
make -j4 all 
make install

And that’s it. You should have them now.

Testing

The toolchain can be tested with the minimal code here:

int main()
{
   return 0;
}

void exit(int code)
{
   while(1);
}

List of Component and Device for ARM Tutorial Series

If you want to start tinkering in ARM, you may look at following list. This list is the parts you might need to follow my tutorials. You are not obligate to gather all because I always specify what materials you need in every article. However, you can see following as a reference.

Board

I have both learning board and development board.

For learning board I mainly focus on Nuvoton LB-NUC140.

For development board I mainly focus on DT-ARM NUC120.

Component

Buy one item of component isn’t too useful. A better idea is to buy a pack of that component, if possible.

  • Resistors:
    1. 100 ohm x 3
    2. 220 ohm x3
    3. 330 ohm x 3
    4. 10k ohm x 3
    5. 1k ohm x 3
  • Light Emitting Diode (LED): Choose 5mm LED any color. We use three LEDs at minimum.
  • Trimpot
  • Photocell
  • Pushbuttons x 2
  • Some wires, preferably breadboard jumper wires.
  • infrared LED
  • pin 0.1″ standard header x 6
  • Piezo speaker or buzzer

Some sensors we need:

  • Parallax PING))) sensor
  • TMP36 temperature sensor (or LM35 for alternative)
  • ADXL335 accelerometer breakout board
  • PNA4602 infrared sensor
  • Tilt sensor

and actuator:

  • Servo 5V, for example: Hitec HS-322HD or Vigor Hextronic

Tools

  • Standard A-B USB cable. This cable is used for connecting Arduino to computer
  • Breadboard. You can use either 400 pin or 170 pin breadboard.

Additional Gadgets

Of course this is optional.

  • Nintendo Nunchuk controller