Homepage Johann Hanne 
Valid XHTML 1.0 Strict
About | Projects | Gadgets | Photos | Links
Projects - Actiontec DPCM stuff - Toolchain 

I strongly recommend building your toolchain from source using the files at http://www.uclinux.org/pub/uClinux/arm-elf-tools/tools-20030314/. Using the pre-compiled toolchain from www.uclinux.org will result in buggy binaries because it has FPU instructions enabled.

Things to do before building the toolchain (if you don't do it, you will get a buggy toolchain or it won't even compile):

  • The build-uclinux-tools.sh script contains the config which is used to build uClibc. You probably want to change the following two things in the uClibc config.
    • The default build-uclinux-tools.sh script will compile uClibc with "HAS_FPU=y" in .config. This will result in "Illegal instruction" errors when certain uClibc functions are called (e.g. setjmp() which is used by busybox's msh) because the CX821xx has no FPU. One way to work around this is to modify the fix_uclibc_config function in build-uclinux-tools.sh to filter the "HAS_FPU=y" line out and put "# HAS_FPU is not set" into the uClibc .config file.
    • The default build-uclinux-tools.sh script will compile uClibc without RPC support which will have the consequence that you can't compile busybox with nfs-mount support. To work around this, modify the build-uclinux-tools.sh script to include "UCLIBC_HAS_RPC=y" and "UCLIBC_HAS_FULL_RPC=y" in the uClibc .config file.
    Patch for both things: build-uclinux-tools.sh-nofpu-enablerpc.patch.
  • The uClibc used by the 20030314 toolchain contains the constant "BUS_ISA" which has been changed to "CTL_BUS_ISA" in recent kernels. Replace
    static int iobase_name[] = { CTL_BUS, BUS_ISA, BUS_ISA_PORT_BASE };
    static int ioshift_name[] = { CTL_BUS, BUS_ISA, BUS_ISA_PORT_SHIFT };
    static int iobase_name[] = { CTL_BUS, CTL_BUS_ISA, BUS_ISA_PORT_BASE };
    static int ioshift_name[] = { CTL_BUS, CTL_BUS_ISA, BUS_ISA_PORT_SHIFT };
    in uClibc/libc/sysdeps/linux/arm/ioperm.c to solve the problem. The build-uclinux-tools.sh script tells you to extract the uClibc tarball before building the toolchain anyway, so you don't have to repackage it. Patch: uclibc-CTL_BUS_ISA.patch.
  • The build-uclinux-tools.sh tries to apply a patch named gcc-2.95.3-m68k-zext.patch which is not in the toolchain download directory and which we don't need anyway because it's m68k related. So edit the build-uclinux-tools.sh file and remove the line which wants to apply the patch (approximately line 179).
  • Optionally you can use a gcc 2.95.4 prerelease instead of the supplied 2.95.3 release. If you want this, grab gcc-20011006.tar.bz2 and apply this patch: use-gcc-20011006.patch.

After you've followed the above instructions, read and edit the build-uclinux-tools.sh script as you have to change/insert at least 3 variables (KERNEL, PREFIX and PATH) and extract some packages (elf2flt, uClibc and the kernel sources) before running the script. I recommend using the kernel described on the kernels page. You have to configure the kernel and do a "make dep" to be able compile the toolchain, so run "ARCH=armnommu make oldconfig" (use the .config file from the kernels page) and "make dep". But don't try to compile it yet - it won't compile as it needs a toolchain which is what we are building right now ;-). I recommend setting PREFIX to /usr/local and leave PATH at the default value (just comment it in). You can choose a different path for PREFIX, but please note that some other instructions on my pages refer to that path, so be careful to replace it by your path then. Now compile and install your toolchain by running "./build-uclinux-tools.sh build". It will be installed into $PREFIX/arm-elf with some symlinks put into $PREFIX/bin.

After compiling the toolchain, there are some more things you might want to do so that compiling actually works:

  • /usr/local/arm-elf/include/paths.h contains the line "#include <config/autoconf.h>"; this file does not exist, so I simply have commented it out
  • /usr/local/arm-elf/include/err.h defines warn, vwarn, warnx, vwarnx, err, verr, errx, verrx as extern void, but at least uClibc 0.9.19 doesn't seem to really have these functions, so compiling programs which are using them (e.g. ipsec-tools) will fail. As a workaround, comment out the definitions in include/err.h and put the following macros in instead:
    #define warn(format, ...) { fprintf(stderr, format "\n", ##__VA_ARGS__); }
    #define warnx(format, ...) { fprintf(stderr, format "\n", ##__VA_ARGS__); }
    #define err(rc, format, ...) { fprintf(stderr, format "\n", ##__VA_ARGS__); exit(rc); }
    #define errx(rc, format, ...) { fprintf(stderr, format "\n", ##__VA_ARGS__); exit(rc); }
    Additionally you may want to add "#include <stdio.h>" to the include-statements, otherwise you might get warnings about implicit declarations of 'printf'

Attention: This toolchain will still have a bug (found by Bas Doeksen and discussed on the actionhack mailing list): It will generate a buggy bFLT header in every compiled program. You have to fix that by opening the file in an hex editor and change byte number 12 (which is the byte at offset 11/0x0b) from 0x50 to 0x40. Apart from that problem the toolchain works fine for me with every program I throw at it!