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.
At a minimum, you need the following source packages:
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.
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.bz2or
$ tar xzvf package-version.tar.gzfor packages compressed with bzip2 and gzip, respectively.
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.patchwhere $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.
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 > doneThe '>' 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.)
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
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 installNote, 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.
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- menuconfigand tweak all the options you want. What to do next depends on the kernel version
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=$somewherewhere $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.
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
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.
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 operates with a handful of "prefixes" which you can use to specify where stuff is going to be installed:
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=
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 $ makeIf 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.
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.
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.
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