Compiling for Khepera3 The Korebot The Khepera3 uses a KoreBot motherboard. This motherboard uses an Intel PXA255 with at least 64Mb of RAM. This processor is an ARM processor that complies with ARM v5TE and supports the XScale instruction set. Note that this processor does not have an FPU. (Wikipedia:XScale) Also note that this processor, like most ARM processors (if not all) is a bi-endian processor, that is it can be configured to run either in big-endian or in little endian. Here we'll assume that we want a cross compiler for a little-endian ARM CPU. In order to create a big-endian toolchain, use the GCC flag -mbig-endian. How to get an ARM compiler In order to compile for khepera3 you need two things: arm-linux-gcc and the libkorebot. ELDK In order to get arm-linux-gcc the easiest thing to do (if you're on Linux) is to install ELDK (Embedded Linux Development Kit). Basically ELDK is a complete environment for cross-compiling but we'll only use its cross compiler. ELDK install instructions. Note that ELDK comes in the form of an ISO you need to mount. As a reminder, here is how to mount an ISO: mount -o loop /path/to/ arm-2006-01-16.iso /mnt/mountpoint Building a cross compiler: GCC ARM Introduction For the time being, the BuildFarm compiles with ELDK, so you're advised to do the same if you can. If you can't (for instance you're not running on Linux, say you have MacOSX x86), then you must download, compile and install arm-linux-gcc yourself. In order to avoid possible troubles, we'll stick to GCC 4.0 arm-linux so we're 100% sure we're compatible with the code compiled by ELDK, but in the end it would be better to use a more recent version of GCC and compile with XScale as a backend instead of generic ARM (the befenits are manifold, especially on an embedded plateform such as korebot). You must carry out the following steps in order to setup a fully functionnal cross compiler: 1. Install binutils 2. Build a "bare-bone" cross-GCC with binutils 3. Build a cross-libc with the bare-bone cross-gcc and kernel headers 4. Build a complete cross-GCC. Before starting, remember that you might need to: $ export ftp_proxy="http://FIXME-YOUR-FTP-PROXY:8888" $ export http_proxy="http://FIXME-YOUR-HTTP-PROXY:8888" Installing binutils FIXME: Do not use binutils 2.17 because of this bug Grab a recent version of binutils and install it for your target, that is arm-linux here. $ wget http://ftp.gnu.org/gnu/binutils/binutils-2.16.1.tar.gz $ tar xfz binutils-2.16.1.tar.gz $ cd binutils-2.16.1 $ mkdir _build $ cd _build $ ../configure --target=arm-linux $ make $ make install Pretty simple... Note that you might want to throw a --prefix=path/to/install unless you do want to install it under /usr/local. If you change the prefix, either give GCC and binutils the same prefix or put binutils' prefix in your PATH before building GCC. Installing a "bare-bone" cross-GCC Here we build a minimal cross-compiler which we'll use in order to build the cross-libc. We cannot build the complete cross-compiler yet, because doing so requires the cross-libc which in turn requires the cross-compiler! There somewhat of a chicken-egg-bootstrap problem here :) hence the minimal aka "bare-bone" cross-GCC. $ for i in gcc-4.0.0.tar.gz gcc-core-4.0.0.tar.gz gcc-g++-4.0.0.tar.gz md5.sum; do wget ftp://ftp.uvsq.fr/pub/gcc/releases/gcc-4.0.0/$i; done $ md5 gcc* check the md5 sums $ for i in gcc*; do echo $i; tar xfz $i || echo FAILED $i; done $ cd gcc-4.0.0 Alright now we have the sources, we'll keep them clean. Let's build the minimal cross compiler: $ mkdir _build1 $ cd _build1 $ `pwd`/../configure --target=arm-linux --disable-nls --enable-symvers=gnu \ --enable-__cxa_atexit --enable-languages=c --enable-c99 \ --enable-long-long --without-headers --disable-shared --disable-threads $ make all-gcc $ make install-gcc You must invoke configure with its absolute path otherwise it might not work. Don't ask why, I don't know, but I already ran into troubles and I found out on the gcc-help ML that invoking configure with an absolute path solved the problem. Note that here, we use the targets all-gcc and install-gcc. And yes, you install the minimal cross-compiler with install-gcc in the prefix where the complete compiler will be later. Getting the Linux kernel headers Since the korebot runs on Linux 2.4.19, that's what we'll use too. $ wget http://kernel.org/pub/linux/kernel/v2.4/linux-2.4.19.tar.gz $ tar xfz linux-2.4.19.tar.gz $ cd linux-2.4.19 $ umask 022 $ mkdir -p /usr/local/arm-linux/include $ mkdir -p /usr/local/arm-linux/include/asm $ cp -r include/linux /usr/local/arm-linux/include $ cp -r include/asm-arm /usr/local/arm-linux/include/asm $ chmod -R a+rX /usr/local/arm-linux $ cd /usr/local/arm-linux/include/asm $ ln -s proc-armv proc $ mkdir arch $ touch arch/param.h $ cd /usr/local/arm-linux/include/linux $ touch autoconf.h Of course, you might need to use sudo if you need superpowers to put the files under /usr/local. The last steps are just here to fixup things so that the compilation of the glibc will work. They are specific to this ARM target. Building the cross-libc Alright so now we must install a libc. Basically, we have to chose between the glibc and uClibc. Here we'll use the glibc but it should be pretty much the same thing if you want to use the uClibc. So we need a the libc and the kernel headers of the target operating system. Note: Linux 2.4 uses LinuxThreads whereas Linux 2.6 uses Native POSIX Thread Library (NPTL) so here we'll also need to grab an extra tarball for the glibc to work with LinuxThreads. Since ELDK uses the glibc 2.3.5, that's what we'll use as well. Alright let's get down to the tricky stuff: $ wget http://ftp.gnu.org/gnu/glibc/glibc-2.3.5.tar.gz $ wget http://ftp.gnu.org/gnu/glibc/glibc-linuxthreads-2.3.5.tar.gz $ tar xfz glibc-2.3.5.tar.gz $ cd glibc-2.3.5 $ tar xfz ../glibc-linuxthreads-2.3.5.tar.gz $ FIXME PATCHES HERE $ mkdir _build $ cd _build $ libc_cv_linux2010='2.0.10 or later' ../configure --host=arm-linux --prefix=/usr/local/arm-linux \ --enable-add-ons=linuxthreads --with-headers=/usr/local/arm-linux/include \ CC=arm-linux-gcc AS=arm-linux-as LD=arm-linux-ld \ AR=arm-linux-ar RANLIB=arm-linux-ranlib $ make $ make install Notes: * Yes, we're using --host=arm-linux instead of --target=arm-linux otherwise the glibc complains that "The GNU C library is currently not available for this platform." This might be evil, but it works and I didn't find any other way to get it to work. * In order to get this to work, I had to symlink arm-linux-as to as and arm-linux-ld to ld first in my PATH. For some reason, configure and GCC itself will invoke as and ld which will fail. * The libc_cv_linux2010='2.0.10 or later' thing is a cheat to bypass a test in sysdeps/unix/sysv/linux/configure because the step above in which we copied kernel headers did not copy linux/version.h (most probably because this file is generated) * The patches to apply have been reported here and can be easily downloaded from here. Building the complete cross-compiler $ mkdir _build2 $ cd _build2 $ `pwd`/../configure --target=arm-linux --disable-nls --enable-threads=posix \ --enable-symvers=gnu --enable-__cxa_atexit --enable-languages=c,c++ \ --enable-shared --enable-c99 --enable-long-long $ make $ make install