Friday, January 25, 2013

Building Arduino firmware on NetBSD

I needed to rebuild the firmware for the atmega8u2 used as a usb to serial bridge on an arduino UNO clone.  Unfortunately, at the time I was doing this the version of avr-gcc in NetBSD pkgsrc did not support the atmega8u2, even the one in pkgsrc Work In Progress (pkgsrc-wip) was not sufficient.  This meant I had to manually build the toolchain myself to get a version of avr-gcc with the atmega8u2 support.  Fortunately, the process for performing the build is straightforward.  These are the steps I used.

Firstly, I made a working directory for all the various components I needed, I also selected the path /usr/local/avr as a destination for all the resultant binaries and libraries.  I did this to keep all the avr related stuff together instead of being splattered around /usr/local which is the default install location.

I downloaded and unpacked the latest binutils sources, changed directory into the bin utils, in there I created a build directory:

tar zxf binutils-2.23.tar.gz
cd binutils-2.23
mkdir build
cd build

Then configured the binutils build with the correct prefix and target, built and installed the binutils:

../configure --prefix=/usr/local/avr --target=avr
gmake
gmake install

Next, I downloaded and unpacked the latest gmp library sources:

tar xjf gmp-5.0.2.tar.bz2
cd gmp-5.0.2

Configured it, build and install:

./configure --prefix=/usr/local/avr
gmake
gmake check
gmake install

Then the mpfr library sources, unpack:

tar xjf mpfr-3.1.1.tar.bz2
cd mpfr-3.1.1

This build needs to reference libraries and includes I had installed in the previous steps so before going further  I needed to let the compiler and linker know where the dependencies were:

export CFLAGS="-I/usr/local/avr/include"
export LDFLAGS="-L/usr/local/avr/lib -Wl,-rpath -Wl,/usr/local/avr/lib"

Once this was done I could configure, build and install:

./configure --prefix=/usr/local/avr
gmake
gmake install

The mpc library was next, download, unpack, configure, build and install:

tar zxf mpc-1.0.1.tar.gz
cd mpc-1.0.1
./configure --prefix=/usr/local/avr
gmake
gmake install

Once all the gcc dependencies were built, I could build the compiler itself.  Again, download, unpack, created a build directory, configure, build and install:

tar jxf gcc-4.7.2.tar.bz2
cd gcc-4.7.2
mkdir build
cd build
../configure --prefix=/usr/local/avr --target=avr --with-gcc --with-gnu-as --enable-languages=c,c++ --disable-nls --disable-libssp --with-dwarf2
gmake
gmake install

Then I built the AVR c library, for this the avr-gcc compiler was required so I had to add the appropriate bin directory to the PATH:

PATH=/usr/local/avr/bin:$PATH
export PATH

tar jxf avr-libc-1.8.0.tar.bz2
cd avr-libc-1.8.0
mkdir build
cd build
../configure --prefix=/usr/local/avr --build=`../config.guess` --host=avr
gmake
gmake install

Once all the toolchain was in place, rebuilding the firmware was just a matter of following the instructions in the arduino firmware readme file and then using gnu-make to build the firmware.  I had to fix a few things the compiler complained about, all of them seemed to be gcc being more strict about writable strings being defined in read-only memory but once these were fixed the firmware built without problem.  I had to resort to Windows and flip to load the firmware onto the board, the new firmware booted up and ran fine.  I was then able to load modified versions of the firmware to try and debug the problem of this particular arduino board not attaching properly under NetBSD.  More on this later.