Thursday, December 27, 2007

Roll your own GCC

Although the optimizations are pretty weak I prefer to use gcc, probably because I prefer to develop on Linux over Windows. With gcc, esp a homebrew, I can switch back and forth without too much trouble. Yes, the same is true if I use Codesourcery G++ Lite.

The ARM Cortex-M3 core is a new (relative to the ARM7 we all know and love) core. To make it nice and confusing the Cortex cores can support one or more of ARM mode, (traditional) Thumb mode, the new Thumb2 additions to thumb mode, and some DSP extensions to the ARM instructions. The Cortex-M3 on these chips only supports Thumb and Thumb2 instructions. Basically, ARM filled in the weaknesses in the Thumb instruction set with some ARM Like instructions, in theory, with a good compiler, you can come much closer to ARM ISA performance while staying close to Thumb ISA binary size. Thats the theory.

The code I share here is not necessarily one size fits all. There will be some hardcoding from time to time per platform. And in no way, shape, or form do I think that embedded programming means making api/operating system calls. I dont use operating systems, and for the time being I dont even have a C library. And if you really know gcc you know to just forget about floating point.

Cygwin is good, has its place, does its job, but for a gcc cross compiler I prefer statically compiled MinGW binaries, no dll hell and a performance boost for those big jobs. Yes, talking about Windows. The build instructions are almost identical for Linux and Windows, MinGW and/or windows provides some extra problems so they are identified as extra steps. Currently using Ubuntu Gutsy and Windows XP. These build instructions, which are quite simple, have evolved from gcc 2.95 to the present from Windows NT4 and Slackware whatever to the present.

As of 4.2.2 gcc does not yet support the Thumb2 instructions. The next release should have it. Codesourcery has added/included Thumb2 support in their 4.2.2 gcc.

Lets begin:



#IF WINDOWS
Go to http://www.mingw.org, find and download

MinGW=5.1.3.exe
MSYS-1.0.11-2004.04.30-1.exe

Install both
Run the Msys shell/prompt to continue as if on a native Linux system.
#ENDIF

#IF LINUX
Make sure you have texinfo, bison, and flex installed, as well as gcc, make and other typical programs
On ubuntu this would be

sudo apt-get install build-essential bison flex texinfo

Note the makeinfo error I am trying to avoid here is part of the texinfo package
#ENDIF

Most of this section is simply a list of the commands to type.

#IF LINUX
You probably dont run as root all the time so you may need to use a directory other than /arm or
as root create /arm and chown to your username so that you can finish the build as the user.
It wants to run from the path used to create it so think about where you want it and who you want
to use it. If you do all of this as root and keep it in /arm (and make it readable by everyone) everyone
can use it.
#ENDIF

Download http://ftp.gnu.org/gnu/gcc/gcc-4.2.2/gcc-core-4.2.2.tar.bz2
Download http://ftp.gnu.org/gnu/binutils/binutils-2.18.tar.gz

ZZZ='--target=arm-thumb-elf --prefix=/arm'
mkdir /arm
cd /arm
tar xzvf /path/to/binutils-2.18.tar.gz
cd binutils-2.18
mkdir build
cd build
../configure $ZZZ

#IF WINDOWS
edit the Makefile in this directory
Find and change the line from

MAKEINFO = /arm/binutils-2.18/missing makeinfo

to

MAKEINFO = /bin/makeinfo

#ENDIF

make all install

(this will take a while)

/arm/bin/arm-thumb-elf-as --version

GNU assembler (GNU Binutils) 2.18
...

Now binutils, the assembler, linker and other utilties is complete. If you only want to use assembly language this is all you need

To clean up the binutils build files

cd /arm
rm -rf binutils-2.18

On to gcc

cd /arm
tar xjvf /path/to/gcc-core-4.2.2.tar.bz2
cd gcc-4.2.2
mkdir build
cd build
../configure $ZZZ --disable-libssp
make all install

#IF WINDOWS
This will fail at some point with errors that look like

In file included from ../../gcc/libgcc2.c:35:
./tm.h:6:28: error: config/dbxelf.h: No such file or directory
...

It doesnt like the -I by itself in the xgcc command line
The culprit is in gcc/Makefile, a line that starts with

INCLUDES = -I. -I$(@D) -I$(srcdir) ...

Just get rid of that second include

INCLUDES = -I. -I$(srcdir) ...

Then start the build again

make all install

and it will complete this time
#ENDIF

/arm/arm-thumb-elf-gcc --version

arm-thumb-elf-gcc.exe (GCC) 4.2.2

To clean up the gcc build files

cd /arm
rm -rf gcc-4.2.2

#IF WINDOWS
You can exit msys and then copy the arm directory tree from
z:\msys\1.0\arm to z:\arm
(so that your binaries are in z:\arm\bin\)
z:\ is of course whatever directory you happen to be working with C:\ for example
#ENDIF