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:
- Slackware64 14.0
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:
- architecture / processor name. Which is ARM architecture (ARM, Thumb, Thumb-2, etc)
- 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.
- 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.