Tuesday, May 12, 2009

Installing Gnuarm ARM Toolchain on Ubuntu 9.04

It can be surprisingly difficult to install an ARM toolchain on Linux. As far as I know, there's no apt package that is currently maintained, so you have to build it from source. This posting shows how I installed the gnuarm toolchain on Ubuntu 9.04 (Jaunty Jackalope). I installed Ubuntu on a VirtualBox virtual machine, but it should work the same for a regular install.

The toolchain includes a number of pieces: binutils, which includes the linker, assembler, etc; gcc, the compiler; newlib, a standard C library for embedded systems; and GDB, the debugger. I also included Sam_I_Am and sam7utils, which allow one to program ATMEL SAM microcontrollers over USB.

First you need to install some dependencies. It's a good idea to upgrade your system at this time also.

sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install libgmp3-dev libmpfr-dev build-essential zlib1g-dev libncurses5-dev patch texinfo libreadline5-dev


The following script should install the components. It's based on a script from Uwe Hermann which fails to build on Ubuntu. Comment out the last section if you're not using ATMEL harware. The USB serial modules isn't included in the 2.6.28-11-generic kernel that is the current kernel, so you may have to upgrade to 2.6.28-12-generic using the pre-release sources. You can check your kernel version with
uname -a

The .samiamrc file is for AT91SAM7S256 device; you'll have to edit it if you use a different one.
Run the following script with 'sudo' and get a coffee, it takes a while.

#!/bin/sh
# Written by Uwe Hermann , released as public domain.
# Edited by Travis Wiens

TARGET=arm-elf # Or: TARGET=arm-none-eabi
PREFIX=/usr/local/arm # Install location of your final toolchain
PARALLEL="" # Or: PARALLEL=""

BINUTILS=binutils-2.19.1
GCC=gcc-4.3.3
NEWLIB=newlib-1.17.0
GDB=gdb-6.8

export PATH="$PATH:$PREFIX/bin"

mkdir build

wget -c http://ftp.gnu.org/gnu/binutils/$BINUTILS.tar.bz2
tar xfvj $BINUTILS.tar.bz2
cd build
../$BINUTILS/configure --target=$TARGET --prefix=$PREFIX --enable-interwork --enable-multilib --with-gnu-as --with-gnu-ld --disable-nls --with-float=soft --disable-werror
make $PARALLEL all
make install
cd ..
#rm -rf build/* $BINUTILS $BINUTILS.tar.bz2

wget -c ftp://ftp.gnu.org/gnu/gcc/$GCC/$GCC.tar.bz2
tar xfvj $GCC.tar.bz2
cd build
../$GCC/configure --target=$TARGET --prefix=$PREFIX --enable-interwork --enable-multilib --enable-languages="c,c++" --with-newlib --without-headers --disable-shared --with-gnu-as --with-gnu-ld --with-float=soft --disable-werror
make $PARALLEL all-gcc
make install-gcc
cd ..
#rm -rf build/* $GCC.tar.bz2

wget -c ftp://sources.redhat.com/pub/newlib/$NEWLIB.tar.gz
tar xfvz $NEWLIB.tar.gz
cd build
../$NEWLIB/configure --target=$TARGET --prefix=$PREFIX --enable-interwork --enable-multilib --with-gnu-as --with-gnu-ld --disable-nls --with-float=soft --disable-werror
make $PARALLEL
make install
cd ..
#rm -rf build/* $NEWLIB $NEWLIB.tar.gz

# Yes, you need to build gcc again!
cd build
../$GCC/configure --target=$TARGET --prefix=$PREFIX --enable-interwork --enable-multilib --enable-languages="c,c++" --with-newlib --disable-shared --with-gnu-as --with-gnu-ld --with-float=soft --disable-werror
make $PARALLEL
make install
cd ..
#rm -rf build/* $GCC

wget -c ftp://ftp.gnu.org/gnu/gdb/$GDB.tar.bz2
tar xfvj $GDB.tar.bz2
cd build
../$GDB/configure --target=$TARGET --prefix=$PREFIX --enable-interwork --enable-multilib --disable-werror
make $PARALLEL
make install
cd ..
#rm -rf build $GDB $GDB.tar.bz2

sudo ln -s $PREFIX/bin/arm-elf* /usr/bin

cd ..
mkdir Sam_I_Am
cd Sam_I_Am
wget http://claymore.engineer.gvsu.edu/%7Esteriana/Software/Sam_I_Am-0.3.tar.gz
tar xfvz Sam_I_Am-0.3.tar.gz
cd Sam_I_Am-0.3
python setup.py install
cd ..
echo "
open /dev/ttyUSB0
version
set readallow 0 0x300000
set ramwriteallow 0x202000 57344
set flashwriteallow 0x100000 0x40000
" >> .samiamrc
cp .samiamrc ~/

rm /usr/bin/Sam_I_Am
echo "
#!/bin/sh
python /usr/local/lib/python2.6/dist-packages/Sam_I_Am/samiam.py $*
" >> /usr/bin/Sam_I_Am
chmod a=rx /usr/bin/Sam_I_Am

sudo modprobe usbserial vendor=0x3eb product=0x6124
#this fails on kernel 2.6.28-11-generic, upgrade to latest prerelease


#install sam7utils
cd ..
wget http://oss.tekno.us/sam7utils/sam7utils-0.2.1.tar.gz
tar xfvz sam7utils-0.2.1.tar.gz
cd sam7utils-0.2.1
./configure
make
make install
ln -s /dev/ttyUSB0 /dev/at91_0




You'll have to run

sudo modprobe usbserial vendor=0x3eb product=0x6124

each time you restart.

To program the device, use

sam7 --exec set_clock --exec unlock_regions --exec "flash main.bin"

12 comments:

daa said...

I followed the instructions verbatim and it worked great for me.

Muchas gracias for the post....

Anonymous said...

I followed your instructions. When I try to use the complier "arm-elf-gcc" ,there is no error on the screen. However, the screen show the "Segmentation fault" when I try to use command "arm-elf-run" to run my output file (a.out). Could you help me to solve this problem? My machine is Vmware 6.5+ Ubuntu 9.04.

Thank you so much.

My E-mail : yuhung1212@gmail.com

Travis said...

"
the screen show the "Segmentation fault" when I try to use command "arm-elf-run" to run my output file (a.out)
"

Sorry, I don't use arm-elf-run, so I can't say anything about it. If it's anything like other simulators, it's probably something to do with not using memory correctly. Did you check that you don't address a location outside of the bounds of an array?

Anonymous said...

Thanks for your reply.

"Did you check that you don't address a location outside of the bounds of an array?" I don't know what you mean. I just write a simple code that just print "Hello world" on the screen. However,the screen just show the segmentation fault when I use the arm-elf-run to test my output file (a.out). But when I use the arm-elf-strings,the string "Hello world" strings will show on the screen correctly. I can't find out how to fix the problem. Any idea?

My E-mail: yuhung1212@gmail.com
Thanks again.

Travis said...

"I can't find out how to fix the problem. Any idea?"

Nope, sorry.

Anonymous said...

Thanks for your help.

Vic said...

Hi Travis
I could not use the arm-elf-gdb. Whenever a file is loaded, I get an "segmentation fault". I am trying to use the evaluator7t board with an serial port emulated by an USB port. I see that your script is in that direction but, although I could compile using arm-elf-gcc I could not debug. Any idea? Thanks.

Travis said...

>Vic
Sorry, I don't use gdb to debug. No idea why you're getting segmentation faults.

Sean said...

I tried compiling this, and everything but arm-elf-ld gets built, so I can compile but not link. When I run your script, it goes to completion but the output for the compilation of binutils gives the following errors

earmelf.o: In function `gldarmelf_write_build_id_section':
/home/sean/build/ld/earmelf.c:1098: undefined reference to `sha1_init_ctx'
/home/sean/build/ld/earmelf.c:1099: undefined reference to `sha1_process_bytes'
/home/sean/build/ld/earmelf.c:1103: undefined reference to `sha1_finish_ctx'
collect2: ld returned 1 exit status
make[4]: *** [ld-new] Error 1
make[3]: *** [all-recursive] Error 1
make[2]: *** [all] Error 2
make[1]: *** [all-ld] Error 2
make: *** [all] Error 2

I tried a newer version of binutils (2.20) and it does not give the error, but it also does not generate arm-elf-ld.

Any idea what might be causing the problem and how I can get a linker? Am I missing another dependency?

Sean said...

Don't worry, I worked it out. It was a problem with dependencies. Nice script.

Ras said...

Since My Computer already have binutils, newlib-1.17.0, gdb-6.8. I think these are installed with Eclipse CDT, so do I need to compile and install these things again? Or it makes any conflicts with existing binaries?

Anonymous said...

Sean said...

Don't worry, I worked it out. It was a problem with dependencies. Nice script.

See how it would have been fine if you told which dependency it was for those that stumble upon this dependency too ...