Welcome to AVR32 Linux... Users Groups

Getting Started with AVR32 Linux

This is a short guide to get started doing development with AVR32 Linux. We're assuming everything is compiled from source, as you're going to need the sources anyway if you're going to do any serious hacking.

Obtaining the sources

At a minimum, you need the following source packages:

Binutils
http://ftp.gnu.org/pub/gnu/binutils/
GCC
http://gcc.gnu.org/mirrors.html
Linux Kernel
http://www.kernel.org/pub/linux/kernel/v2.6/
uClibc
http://www.uclibc.org/downloads/
u-boot
ftp://ftp.denx.de/pub/u-boot/

You also need to download the latest AVR32 patches for each source package. Make sure the version match, or you may have problems applying the patches.

These patches are also distributed as part of the STK1000 BSP.

Preparing the sources

All the source packages are distributed as tar archives compressed with either gzip or bzip2. They can be unpacked using the tar command like this:

    $ tar xjvf package-version.tar.bz2
or
    $ tar xzvf package-version.tar.gz
for packages compressed with bzip2 and gzip, respectively.

Applying a single patch

Usually, the AVR32 patchset is distributed as a single patch which can be applied to the unpacked source tree like this:

    $ cd package-version
    $ patch -p1 < $patchdir/package-version-avr32.patch
where $patchdir represents the directory where you stored the patches you just downloaded.

When specifying -p1, patch strips off the first component in the pathname stored for each file in the patch. This is necessary because by convention, this first component is the top-level source directory itself. It is usually recommended that you enter the source directory and use the -p1 option rather than issuing the patch command in the directory one level above the source tree, as it will work even if you or the one preparing the patch changes the name of the top-level source directory. Often, the patch will use generic names like "a" and "b" for the top-level directory.

Applying a broken-out patchset

Sometimes, the AVR32 patchset is distributed in "broken-out" form, that is, a collection of patches where each patch only makes a single logical change. This was the case with early versions of the STK1000 BSP, so if you've got one of those, you need to follow this procedure.

A broken-out patchset contains a special file called "series", which lists all the patches in the order they are meant to be applied. Thus, you simply have to go through the series file and apply each and every patch as described in the previous section. If you think that sounds like a boring task (I would agree), you can let the shell do it for you:

    $ cd package-version
    $ for patch in `cat $patchdir/series`; do
    > patch -p1 < $patchdir/$patch
    > done
The '>' character above is the shell continuation character. It shows up automatically when you type in an incomplete statement (e.g. a for statement with no "done" keyword to end it.)

Building the cross-toolchain

Binutils

First thing to do here is to visit the BinutilsPatches page and either grab the pre-prepared source or the patch. Note that if you get the patch you must follow the rest of the procedure on that page in order to prepare your source for building, you cannot simply dive in.

Once you have your prepared source, either manually prepared or downloaded pre-prepared the rest of the process is to execute the familiar configure: make: make install procedure:

    $ ./configure --target=avr32-linux
    $ make
    $ sudo make install

You may also build binutils in a different directory than the top-level source directory. This is actually the preferred way, as it allows you to build several different toolchains from the same source. For example, to build binutils for avr32-linux, you may create a directory called "build-avr32-linux-binutils":

    $ mkdir build-avr32-linux-binutils
    $ cd build-avr32-linux-binutils
    $ ../binutils-2.16.1-avr32/configure --target=avr32-linux
    $ make
    $ sudo make install

GCC (bootstrap version)

A full-fledged build of GCC won't succeed unless the C library has already been installed. And the C library obviously can't be built and installed before the C compiler is installed. To solve this chicken-and-egg problem, we initially install a reduced version of GCC which can be used to build the C library and install the full version later.

The basic procedure is the same. Note that gcc actually requires that you build in some other directory than the source tree:

    $ mkdir build-avr32-linux-gcc
    $ cd build-avr32-linux-gcc
    $ ../gcc-4.0.2-avr32/configure --target=avr32-linux --enable-languages=c --disable-threads --disable-libmudflap
    $ make
    $ sudo make install
Note, however, the extra options to configure. Since we don't have a C library, there is simply no way we can build the C++ support libraries. Thread support requires support from the C library as well, so it must be disabled for now.

libmudflap and libssp are both run-time checking libraries which have been known to cause errors at this early stage. They can safely be disabled for this bootstrap build though neither seem to cause an error for the main build described below.

Preparing the kernel headers

The C library requires a fully configured kernel source tree to build. So now would be a good time to at least prepare the kernel sources for compilation so that the C library can be built.

Note that you must always specify the architecture you're compiling for as well as any cross-compilation options when you invoke make in the kernel tree. Alternatively, you may edit the top-level Makefile and modify the ARCH and CROSS_COMPILE variables like this:

ARCH            := avr32
CROSS_COMPILE   := avr32-linux-

Now, to configure the kernel, simply type

    $ make ARCH=avr32 CROSS_COMPILE=avr32-linux- menuconfig
and tweak all the options you want. What to do next depends on the kernel version

Linux 2.6.18-rc1 and newer

A new headers_install target was added during the 2.6.18 merge window. This is part of the effort of "sanitizing" the kernel headers to make them more suitable for user space, like the C library and other software packages more than usually tightly coupled to the kernel.

For more details about the rationale behind this, please see http://lkml.org/lkml/2006/7/2/24.

If your kernel version is 2.6.18-rc1 or newer (including the 2.6.18-mm series), you can install a sanitized set of headers for uClibc like this:

    $ make ARCH=avr32 CROSS_COMPILE=avr32-linux- headers_install INSTALL_HDR_PATH=$somewhere
where $somewhere can be any temporary directory. Just make sure you specify the same directory as the location of the kernel sources when configuring uClibc later.

Linux 2.6.17.x and older

These versions do not have the headers_install target, so you just need to make sure that the include/asm symlink is set up correctly, and that a few other header files have been generated.

    $ make ARCH=avr32 CROSS_COMPILE=avr32-linux- prepare

Building the C library

Now that you have a C compiler and a fully prepared set of kernel sources, you can proceed to build the C library. At the moment, there's only one C library available for AVR32: uClibc. In the future, glibc may be ported as well.

uClibc

First, to get sane defaults, you should run make defconfig. I'm not sure why this makes any difference, but it's apparently a good idea.

Configure uClibc by running make menuconfig. Make sure you specify AVR32 as the target architecture as well as avr32-linux- as a cross-compilation prefix. You also need to specify the location of the kernel headers you installed in the previous step, or the location of the kernel source directory if your kernel doesn't have the headers_install target. The rest of the options are for you to decide.

Note that the "kernel source directory" is the top-level directory of either the Linux kernel itself or the headers that were installed by the headers_install target. That is, the uClibc build system automatically appends "/include" to the value you specify.

Build the uClibc libraries by executing make CROSS=avr32-linux-. Installing the libraries is a little more tricky, especially if you configured uClibc with shared library support.

NOTE: On new kernels (2.6.18-rcX), a define has been moved from linux/version.h to linux/utsrelease.h. This causes the uClibc build to break. A simple fix is to simply kill all the version-checking crap from extra/scripts/fix_includes.sh.

uClibc prefixes

uClibc operates with a handful of "prefixes" which you can use to specify where stuff is going to be installed:

PREFIX
Global prefix added in front of everything
DEVEL_PREFIX
Prefix to where the development stuff is installed, i.e. the header files and static libraries.
RUNTIME_PREFIX
Prefix to where the runtime stuff is installed, i.e. the dynamic libraries.
SHARED_LIB_LOADER_PREFIX
The directory where the dynamic loader is located. This should almost always be "/lib".

Note that some of these paths (SHARED_LIB_LOADER_PREFIX and, I think, RUNTIME_PREFIX) are hardcoded into the dynamic loader, so you need to get them right from a runtime point of view before compilation. They can always be overridden at install time, in case the development host's view of the filesystem is different than that of the target (it usually is.)

Assuming you got everything right for the runtime part, here's how you override it for installation:

    $ make install PREFIX=/usr/local/avr32-linux/  DEVEL_PREFIX= RUNTIME_PREFIX=

This will install headers files, static libraries and dynamic libraries into appropriate locations under /usr/local/avr32-linux. Substitute with whatever you specified as prefix + target when configuring gcc and binutils.

If you want to run dynamically linked programs, you need to install the shared libraries onto the target filesystem as well. Assuming your target filesystem is accessible from "/mnt/target" on the host (i.e. you've either mounted your SD card there, or you're exporting the directory through your NFS server), here's how you do it:

    $ make install_runtime PREFIX=/mnt/target RUNTIME_PREFIX=

Building the boot loader

Even though you may have a working boot loader installed on your target, there's a critical piece of host-side functionality you need: mkimage. This utility is used for creating uImage files of the Linux kernel that can be easily loaded by u-boot.

In the u-boot source directory with the AVR32 patchset applied, execute the following commands:

    $ make atstk1002_config
    $ make
If successful, the mkimage utility can be found in the tools subdirectory. Copy it to a directory included in your PATH, e.g. /usr/local/bin.

This will also build the actual u-boot image. The only way to install it at the moment is by using the JTAGICEmkII and the avr32program utility distributed with the STK1000 BSP. If you already have a working boot loader, you should probably stick with it for now.

Building the kernel

The kernel is built by simply executing make. If you didn't modify the ARCH and CROSS_COMPILE variables in the Makefile, you need to specify them on the command line as explained above.

After the build completes successfully, you'll end up with the file arch/avr32/boot/images/uImage, which should be copied somewhere the boot loader can access it. This could be /tftpboot/ if you're booting over the network, or the root of the filesystem on your SD card if you prefer to boot off a memory card.

If you built the kernel with module support, you must run make modules_install with the variable INSTALL_MOD_PATH set to where the root filesystem of the target is mounted.

Building the final GCC compiler

Now that you have a working C library, you may build GCC with all features enabled:

    $ ./configure --target=avr32-linux --enable-languages=c,c++
    $ make
    $ sudo make install

NOTE: C++ support may not always build correctly. Please see this thread on avrfreaks.net for a discussion, including a patch that supposedly fixes the problem.

Comments

 
  • Richard-- It seems like this excellent project requires the NGW1000 or EVK110x starter kits from Atmel, which (I believe) are set up so you can log into them and download directly to the AVR32. Admin-- is this correct??

BTW I have a UC3A3256 breadboarded (no starter kit) and running standalone apps compiled in AVR32Studio , but am confused as to how to make the jump to AVR32Linux as described on this page. Any total-newbie help information would be appreciated! -- DannGreen - 16 Aug 2009 - 17:23

  • Hi, Still a bit confused on getting started. If I have an old computer with a bootable CD ROM and nothing on the hard drive how do I load Linux? I'm assuming I Down Load somthing then build a bootable CD ROM. Am I close? What do I Down Load first? Thanks. -- RichardEmerson - 13 Aug 2008 - 23:26
  • I have a question, why not have agree of the uclinux project ? -- YannK - 11 Mar 2007 - 16:51

Not the place for questions, but an answer anyway: uCLinux has no reason to care about avr32linux. The AVR32 has an mmu and therefore does not use uClinux which is for no-mmu processors only. --Ben Nizette

  • libmudflap is a set of runtime-linked libraries in gcc which catches illegal pointer and memory use in c and c++. It has a clause in it's configure script attempting to check whether the compiler works at all but in fact also checks for the c++ libraries. As such, it must be disabled in the gcc bootstrap build. -- BenNizette - 01 Oct 2006 - 06:04
r17 - 2009-08-16 - 15:23:00 - DannGreen
Copyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Linux® is the registered trademark of Linus Torvalds in the U.S. and other countries.
Atmel®, AVR® and others are registered trademarks or trademarks of Atmel Corporation or its subsidiaries.
All other trademarks are the property of their respective owners.
Syndicate this site RSSATOM