Wink Saville’s Blog

November 15, 2007

Making a mips cross compiler

Filed under: programming — wink @ 9:05 pm

Followed instructions for ‘Roll your own’ cross compiler at http://www.linux-mips.org/wiki/Toolchains. The minor difference was in the exports:

export WDIR=~/foss/mips/wdir
export TARGET=mipsel-unknown-linux-gnu
export PREFIX=/opt/mips

It then only took less than 5 minutes to build the binutils and gcc.

It looks like I then need to compile the kernel so that glibc has the appropriate headers. So I grabbed the nxp-2.6.19.1 git-repo and ran into some problems because I don’t have the full environment. So using menuconfig on the current nxp config file I disabled:

/Device Drivers/NXP Drivers
/Device Drivers/pnx-sata driver
**/Device Drivers/Graphics support/Support for Video Denc devices
/Device Drivers/Multimedia devices/Digital Video Broadcasting Devices/DVB For Linux

After 30 minutes I gave up on getting the nxp version working. Instead I started with linux-2.6.19.1.tar.bz2. I menuconfig using:

make ARCH=mips CROSS_COMPILE=mipsel-unknown-linux-gnu menuconfig

I selected:

/Machine selection/Qemu
/Endianess selection/Little endian

and then deselected everything else except

/Exectuable file formats/Kernel support for ELF binaries

To then built using:

make ARCH=mips CROSS_COMPILE=mipsel-unknown-linux-gnu

Using time on the above and the kernel took 42.771 seconds to build on ic2d1 and vmlinux is 995,404 bytes long and arch/mips/boot/mvlinux.bin is 843,909 bytes long.

The above was all good but only built a minimal compiler and the binutils but no runtime library. The toolchain I decided on consisted of; gcc-3.4.4, binutils-2.16.1, glibc-2.3.5 plust glibc-linuxthreads.2.3.5. I chose this set because it looks to be a recommended set from http://linux-mips.org. I also decided on using crosstool as the basis for building a complete tool chain, Dan Kegel and group seem to be relatively active and helpful. Initially I’m only going to use crosstool.sh as I wanted to concentrate on the building phase, but that means a bunch of environment variables need to be setup. So I created a Makefile and a shell script as time went on some patches needed to be applied which is done in the shell script. Anyway, on with the story.

Initially I needed to modify build-glibc/csu/version-info.h by joining lines 2 & 3 and added ‘\n’. But the problem turned out to be my bin/sh was dash not bash. Searching the net for <version-info.h missing terminating> I found that Dan Kagel and helped someone else with this exact problem.

Next was a problem with glibc-2.3.5/Makeconfig; the make file is created had references to gcc_eh which from a search on the net appears not to be needed, I patched it as follows:

— glibc-2.3.5/Makeconfig 2005-02-16 02:50:19.000000000 -0800
+++ Makeconfig 2007-11-15 23:35:51.000000000 -0800
@@ -503,12 +503,12 @@ else
libunwind = -lunwind
endif
ifneq ($(have-as-needed),yes)
- libgcc_eh := -lgcc_eh $(libunwind)
+ libgcc_eh := $(libunwind)
else
libgcc_eh := -Wl,–as-needed -lgcc_s$(libgcc_s_suffix) $(libunwind) -Wl,–no-as-needed
endif
gnulib := -lgcc $(libgcc_eh)
-static-gnulib := -lgcc -lgcc_eh $(libunwind)
+static-gnulib := -lgcc $(libunwind)
libc.so-gnulib := -lgcc
endif
ifeq ($(elf),yes)

Next problem was a use of the attribute always_inline in the file wordexp.c that apparently isn’t supported in gcc 3.4.4 .

+++ glibc-2.3.5/sysdeps/generic/wordexp.c 2005-02-16 02:56:31.000000000 -0800
— ../mips-1/glibc-2.3.5/sysdeps/generic/wordexp.c 2007-11-15 16:47:28.000000000 -0800
@@ -810,7 +810,7 @@ parse_arith (char **word, size_t *word_l

/* Function called by child process in exec_comm() */
static void
-internal_function __attribute__ ((always_inline))
+//internal_function __attribute__ ((always_inline))
exec_comm_child (char *comm, int *fildes, int showerr, int noexec)
{
const char *args[4] = { _PATH_BSHELL, “-c”, comm, NULL };

After these changes I was able to build the compiler and created a hello world program. At that point I didn’t have the MIP machine so I couldn’t test it but hey, if it compiles it runs, actually the next day I did test it and it did run. But in the mean time I refined the Makefile/m.sh files and tried again. Hmm, failed:

# /usr/bin/install: cannot stat `/home/wink/foss/mips-cc/wdir/build-glibc-headers/gnu/lib-names.h’: No such file or directory
# make[2]: *** [/opt/mipsel/mipsel-unknown-linux-gnu/include/gnu/lib-names.h] Error 1
# make[2]: Leaving directory `/home/wink/foss/mips-cc/glibc-2.3.5′
# make[1]: *** [install-headers] Error 2

This error occurs when creating headers, line 448, before the “Build gcc-core” at line 474. At least that’s what I remember. Anyway apparently this sequence isn’t needed and just doing it again seems to work. So I added the notion of doing pass1 & pass2. After this the compiler, binutils and glibc get built and does run helloworld as well as test1 of tmSal.

But it couldn’t build the MIPS stb225 system, I had to apply a couple more patches which I found in the crosstool/patches directory. One was to generate a full syscall.h so the SYS_xxxxx defines were created:

patches/glibc-2.3.5/pr758.patch

The other was to make sure limits.h includes linux/limits.h PATH_MAX gets defined, as well as some other defines:

patches/gcc-3.4.4/fix-fixincl.patch

After figuring these things I successfully built the stb225 system, except for the dsp code which uses some precompiled libraries so and I hope for the moment things will work with those being built with the eldk-4.0 toolchain.

Download here.

No Comments

No comments yet.

RSS feed for comments on this post. TrackBack URL

Sorry, the comment form is closed at this time.

Powered by WordPress