This page describes how I got a working 2.6 linux kernel and cross compilation toolchain in order to use Maverick Crunch FPU on Cirrus EP93XX processor series.
WARNING : These informations and sripts and patches and whatever are for EP93xx rev. D1 or better. For DO rev. processors they might not work.
The Maverick Crunch is not yet officially supported by Cirrus on 2.6 linux kernels, so here is a summary of usefull informations about it.
Nucleusys have made some scripts and patches to add Maverick FPU support on 2.6 series kernel and build a cross compilation toolchain. It consists of :
- A patch for the linux kernel (here)
- Some scripts and patches for gcc/glibc/binutils in order to build a cross compilation toolchain (here)
1st step : the kernel
Nucleus' kernel patch applies against a 18.104.22.168 kernel. Unfortunaly, I was not able to use Maverick instructions with this patch applied to the kernel. I got some 'illegal instruction' errors, as well as segfaults.
That's it, now you can configure and compile your kernel as usual.
Eric Benard provided on the Linux-ep93xx mailing-list a patch based on Nucleusys' one. It worked fine, thanks Eric !
I made a patch (avail. here) from these two patches so that it applies to a "vanilla" kernel.
2nd step : the toolchain
Nucleusys also provide some scripts to automaticaly build the cross-compilation toolchain. The cross-compilation toolchain is a set of utilities (gcc/binutils/glibc) allowing to compile program for a target system (here ARM) from a host system (x86). There are a lot of cross-compilation toolchains for ARM, but none allows to use Maverick FPU instructions.
Unfortunaly, Nucleus' scripts did not work for me, so I've made a new script, which is avalaible here
If you want to use it, you must edit it and replace some vars :
SRCDIR="SOMEWHERE" to SRCDIR=/the/path/where/are/the/sources/
The SRCDIR directory must contain :
For linux-kernel-headers, I've extracted them from my kernel source tree. (version 22.214.171.124-ep93xx with Eric Benard's patches).
- the gcc-GCCVERS.tar.bz2 file (available from gnu ftp site)
- the binutils-BUVERS.tar.bz2 file (available from gnu ftp site)
- the glibc-GLIBCVERS.tar.bz2 file (available from gnu ftp site)
- the glibc-linuxthread-GLTVERS.tar.bz2 file (available from gnu ftp site)
- the linux-kernel-headers file
GCCVERS can be 3.4.3 or 3.4.4 (other versions not tested)
BUVERS can be 2.15 or 2.16 (other versions not tested)
GLIBCVERS can be 2.3.3 or 2.3.5 (other versions not tested). GLTVERS should be the same than GLIBCVERS.
The script searches in this SRCDIR directory if there is a "gcc-GCCVERS.patch" file. If yes, it applies it to gcc before compiling. I made a patch from Nucleusys' gcc patches + some other patches from kegel.com. They are available for gcc-3.4.3 and gcc-3.4.4
Idem for glibc and binutils; glibc-2.3.3.patch , glibc-2.3.5.patch and binutils-2.15.patch (no patch needed for binutils 2.16)
Important note if using glibc-2.3.5 :
It seems that glibc-2.3.5 uses _unorddf2() and _unordsf2() functions. glibc-2.3.3 did not use these functions which are provided by gcc. For arm, they are defined in gcc-source-dir/gcc/config/arm/ieee754-df.S file for _unorddf2(), and gcc-source-dir/gcc/config/arm/ieee754-sf.S file for _unordsf2().
Nucleus' gcc patches adds new ieee754 files optimized for MaverickCrunch (ieee754-df-crunch.S and ieee754-sf-crunch.S) used instead of these files. But the new ones do not provide _unorddf2() and _unordsf2() functions.
So to be able to compile glibc-2.3.5 with Maverick crunch support, I've copied the _unorddf2() function from ieee754-df.S to ieee754-df-crunch.S and _unordsf2() from ieee754-sf.S to ieee754-sf-crunch.S
This change is present ONLY in gcc-3.4.4.patch. So, if you want to use glibc-2.3.5 you must use gcc-3.4.4, or report these changes to your prefered compiler version.
Once done, your SRCDIR contains (for example), gcc-3.4.4.tar.bz2, gcc-3.4.4.patch, glibc-2.3.5.tar.bz2, glibc-2.3.5.patch, binutils-2.16.tar.bz2, glibc-linuxthreads-2.3.5.tar.bz2 and linux-kernel-headers-126.96.36.199-ep93xx-eb.tar.bz2
Launch the script, answer the location you want your toolchain to be built (DESTDIR), and wait ... If you're not out of luck, should be fine.
When it's finished, your cross compilation toolchain is located in DESTDIR/ep93xx/.
You can try to compile and run programs with the command :
$DESTDIR/ep93xx/bin/arm-linux-gcc -mcpu=ep9312 -mfix-crunch-d1 -o hello hello.c
Don't forget -mcpu=ep9312 and -mfix-crunch-d1 !!!
In order to build more complicated softwares, such as those who need './configure; make; make install' to be built and installed, you can try to :
- Add the toolchain location in your path : export PATH=$PATH:$DESTDIR/ep93xx/bin
- export CC=arm-linux-gcc; export CXX=arm-linux-g++; export LD=arm-linux-ld; export AR=arm-linux-ar; export CFLAGS='-mcpu=ep9312 -mfix-crunch-d1'; export CXXFLAGS=$CFLAGS; export LD_PATH=$DESTDIR/ep93xx/lib ...
- Don't hesitate to modify configure scripts when it yells (for example : arm-linux-g++ failed sanity check, cannot create executable). I use to remove the test in the configure script.
According to this page, applications compiled using this toolchain can only be statically linked, I don't know why. I have successfully compiled nbench in both static and dynamic versions, it worked fine. But for flac, only the static linked version worked.
I've rewritten the build script. The new one, called build-test.sh, is available here.
It is not supposed to work better than old one, but it is "cleaner".
I've removed the substitutions in make and config files (perl -pi ...) in order to configure and build tools in a more conventionnal way, with options passed to configure and make.
Binaries are now called arm-gnu-linuc-gcc, arm-gnu-linux-strip ... and so on, instead of arm-linux-gcc, arm-linux-strip ...
I've tested it only with gcc-3.4.4, binutils-2.16 and glibc-2.3.3.
If you have problems with this script, try to use the old one.
To test the built toolchain, I use the flac program to encode a 23m44s/251MB .wav file into a .flac file.
Flac uses a lot of 32/64 bits floats and integers computing, so this should be a good test.
With glibc-2.3.3, it takes 15m30s on my ep9312@200MHz board to encode, and 3m40s to decode.
With glibc-2.3.5 it takes 14m55s to encode and 3m40s to decode.
Plans / TODO
I've planned to have a look at these points :
- See if we can get it work for dynamic linked libraries
- See if we can get it work (with Maverick FPU enabled) with uClibc
- See if we can add some new Maverick optimized code in libc and gcc (I haven't yet been able to check if all Mavercik functions are implemented)
- See if we can get a full-functional / DMA-enabled IDE driver (for EP9312 and EP9315)
- [ Not maverick related ] : see how to enable XIP (execute in place)
- [ Not maverick related ] : see how get the smaller kernel possible (some infos)
- [ Not maverick related ] : see how get the fastest booting time (some infos)
If you are interested by one of these subject and/or have some informations, I'd be glad to ear from you !
Hope you'll understand my english, it's far from being perfect ;-)
yann at yannouch dot net
- May 31 2005 : New build script (build-test.sh) posted.
- May 31 2005 : typo fixed in gcc-3.4.4.patch. New file posted.
- May 26 2005 : 'DESTDIR/arm-linux' toolchain location changed to 'DESTDIR/ep93xx' in the build.sh script to avoid confusions
- May 26 2005 : It works with binutils 2.16. The patch needed for glibc-2.15 in not needed anymore because the modification has been included in binutils-2.16. Then no binutils-2.16.patch is needed. But the build.sh script had to be modified for binutils 2.16, new script posted.
- MAY 24 2005 : patch provided by Jon Marsh, corrects a typo in linux-188.8.131.52-ep93xx-eb.patch. ATCH_EP9302 changed to ARCH_EP9302. New linux-184.108.40.206-ep93xx-eb.patch posted
- MAY 24 2005 : initial version