Tim Allen

Software Reverse Engineer

Build environment for BrailleBuzz (the GNU tool-chain for STM32F103) January 29, 2015

Building gcc from scratch.

gmp (a prereq for building gcc)

One creates a directory in which to one builds gmp. I created a small bash script.

#!/bin/bash
../../src/gmp-5.1.3/configure 
--disable-shared 
--enable-static 
--prefix=$HOME/usr

mpc (another prereq for building gcc)

One creates a directory in which to one builds mpc. I created a small bash script.

#!/bin/bash
../../src/mpc-1.0.2/configure 
--prefix=$HOME/usr 
--with-gmp=$HOME/usr 
--with-mpfr=$HOME/usr 
--disable-shared 
--enable-static

mpfr (another prereq for building gcc)

One creates a directory in which to one builds mpfr. I created a small bash script.

#!/bin/bash
../../src/mpfr-3.1.2/configure 
--prefix=$HOME/usr 
--with-gmp=$HOME/usr 
--disable-shared 
--enable-static

gcc (finally???)

One builds gcc in two steps and the previous tasks are prerequisites. Let’s take a moment and think about what we’re actually doing here. We are using the host’s native gcc compiler to build a cross compiler from (more or less) the same source that built the native compiler (look up what GNU actually stands for and see if you get the joke); that is, a compiler that runs on one arch (the host, probably an Intel variant) but produces code that will run on another arch (the target, in this case, an ARM variant). To make things more confusing the compiler actually needs itself. So one builds a striped down version of gcc (just C), and then one builds the full version of gcc (C & C++). Confused yet, no? GNUs not unix… GNUs not unix…

gcc_1

One creates a directory in which to one builds the stripped down gcc, gcc_1. I created a small bash script.

#!/bin/bash -x
../../src/gcc-4.8.2/configure 
--target=arm-none-eabi 
--prefix=$HOME/usr 
--enable-interwork 
--enable-multilib 
--disable-libssp 
--enable-languages="c" 
--with-newlib 
--without-headers 
--disable-shared 
--disable-threads 
--with-gnu-as 
--disable-nls 
--with-gnu-ld 
--with-gmp=$HOME/usr 
--with-mpfr=$HOME/usr 
--with-mpc=$HOME/usr

Don’t forget to do “make install”

newlib or libc

You’ll need newlib or libc to build the full compiler. The full compiler needs libc stuff for it’s built-ins. One needs to build newlib, this is a slightly stripped down version of libc especially for MCUs and SOCs. So use the stripped down gcc to build newlib, I created a small bash script.

#!/bin/bash
../../src/newlib/configure 
--target=arm-none-eabi 
--prefix=$HOME/usr 
--enable-interwork 
--enable-multilib 
--with-float=soft 
--enable-soft-float 
--disable-nls 
--with-gnu-ld 
--with-gnu-as 
--disable-shared 
CFLAGS_FOR_TARGET=" 
-g 
-Ofast 
-ffunction-sections 
-fdata-sections 
-DPREFER_SIZE_OVER_SPEED 
-D__OPTIMIZE_SIZE__ 
-fomit-frame-pointer 
-mcpu=cortex-m3 
-mthumb 
-mfix-cortex-m3-ldrd 
-D__thumb2__ 
-D__BUFSIZ__=256" 
CCASFLAGS="-mcpu=cortex-m3 
-mthumb 
-mfix-cortex-m3-ldrd 
-D__thumb2__"

gcc_1 (finally)

Then one builds the fill compiler in the directory gcc_2. I created a small bash script.

#!/bin/bash -x
../../src/gcc-4.8.2/configure 
--target=arm-none-eabi 
--prefix=$HOME/usr 
--enable-interwork 
--enable-multilib 
--disable-libssp 
--enable-languages="c,c++" 
--with-newlib 
--disable-shared 
--with-float=soft 
--with-cpu=cortex-m3 
--with-tune=cortex-m3 
--with-mode=thumb 
--with-system-zlib 
--with-gnu-as 
--with-gnu-ld 
--disable-nls 
--with-gmp=$HOME/usr 
--with-mpfr=$HOME/usr 
--with-mpc=$HOME/usr

Notice the “–with-newlib” the full compiler needs libc stuff for it’s built-ins. One needs to build newlib, this is a slightly stripped down version of libc especially for MCUs and SOCs. So use the stripped down gcc to build newlib, then build the full version of gcc and then re-build newlib.

gdb

Your gonna want a debugger and if doesn’t get any better than gdb. Okay, it’s got a steep learning curve, the the curses stuff has issues, but it has features. Perhaps my favorite feature is that it works more or less the same on whatever platform and I don’t know about you but I haven’t the time to learn a bunch of proprietary UIs. GDB works with openocd to do remote debugging.

#!/bin/bash
../../src/gdb-7.7/configure 
--prefix=$HOME/usr 
--target=arm-none-eabi 
--enable-interwork 
--enable-multilib

openocd

I had to build openocd from scratch to get a workable version. This was over a year ago and openocd was very young, it has matured a lot and the stock copy that comes with your distro will probably work for you nowadays, I include it here just for completeness.

#!/bin/bash
../../src/openocd-0.7.0/configure 
--enable-ft2232_libftdi 
--prefix=$HOME/usr