Thomas (boggyb) wrote,
Thomas
boggyb

  • Mood:
  • Music:

Silly things with cross-compilers, parts 2 (building binutils) and 3 (kernel and libc headers)

Where was I? Ah yes, building stuff...

Part 2: Building binutils

The one thing that all the instructions agree on is that you have to compile binutils before you can even start on gcc. So, unpack the binutils sources into /cross/src (I'm using binutils version 2.21.53 here):

cd /cross/src
tar -xvf /mingw/var/cache/mingw-get/packages/binutils-2.21.53-1-mingw32-src.tar.lzma

Then build the thing using the usual linux mantra of configure, make, make install. I'm using relative paths to invoke configure because some stuff (gcc in particular) will fail to build if you use an absolute path.

mkdir -p $PREFIX/build/binutils-2.21.53
cd $PREFIX/build/binutils-2.21.53
../../../src/binutils-2.21.53/configure --prefix=$PREFIX --target=$TARGET --with-sysroot=$SYSROOT
make
make install

That was surprisingly easy. The hard part was figuring out what to specify as the target, since there's no such thing as an up-to-date list of valid targets. After a bit of trial and error I came up with armv5l-linux - this doesn't quite match the NAS (uname -m claims it's an armv5tel) but with any luck will be close enough.

Part 3: Kernel and libc headers

The kernel and libc headers tend to be highly specific to a particular target. If the manufacturer's been good, there should be a zip or tarball containing the kernel and libc they've used (look for a file on their website like "GPL firmware"). If they've been bad, then you'll have to put your own one together and hope it matches whatever they've used. Thecus fall somewhere in the middle - the GPL sources for the N2100 contain the kernel but not libc. Fortuantly they've used glibc and not some ultra-optimised alternative, so with any luck I should be able to get away with building my own glibc.

Anyway, time to unpack their kernel and get the files in the right place. I'm running tar twice because in some cases it tries to create a symlink before creating the file the symlink points to. Since I'm running on Windows, MinGW simulates symlinks by copying the target and so fails if the target doesn't already exist.

cd $PREFIX/src
tar -xvf "N2100 Firmware 2.01.10 GPL sources.tar.bz2"
tar -xvf "N2100 Firmware 2.01.10 GPL sources.tar.bz2"

There's still a few warnings about symlinks to files outside that directory structure, but hopefully those won't be an issue as I don't intend to actually build the kernel. That's just as well, because the kernel sources contains several files where the name differs only in case - Windows treats those files are identical and so the later one in the archive blats the earlier one!

Anyway, I now have a kernel. Now to run some magic commands (based on these) to get everything in hopefully the right place. I'm trusting the current configuration to be accurate, so I'll skip running make.

cd n2100_2.01.10_GPL/linux/
cp -a include/linux ${SYSROOT}/usr/include/linux
cp -a include/asm-arm ${SYSROOT}/usr/include/asm
cp -a include/asm-generic ${SYSROOT}/usr/include/asm-generic

Next step is to get hold of glibc. This seems slightly out of order, but apparently to compile gcc you either need your libc for whatever you're targetting or have to apply some horrid hack. Anyway, running libc.so.6 claims that the NAS has "GNU C Library stable release version 2.2.5". It also claims that it was compiled by "GNU CC version 3.3.2", which may be an issue as I'm trying to build GCC 4.6.1. Anyway, grab the necessary files and unpack them into /cross/src:

cd /cross/src
tar -xvf glibc-2.2.5.tar.gz
cd glibc-2.2.5
tar -xvf ../glibc-linuxthreads-2.2.5.tar.gz

And run configure (yes, this is being run with the host compiler - remember, I don't have a cross-compiler yet):

cd $PREFIX/build
mkdir glibc-2.2.5
cd glibc-2.2.5
../../../src/glibc-2.2.5/configure --prefix=/usr --host=${TARGET} --enable-add-ons=linuxthreads --with-headers=${SYSROOT}/usr/include
...
checking for gcc... gcc
checking version of gcc... 4.6.1, bad
checking for gnumake... no
checking for gmake... no
checking for make... make
checking version of make... 3.81, ok
configure: error:
*** These critical programs are missing or too old:gcc
*** Check the INSTALL file for required versions

Um. It should be noted that the INSTALL file recommends "GCC 2.95 or newer". One would hope that GCC 4.6.1 would suffice, but apparently not. In fact, the configure script rejects anything that's more recent than the current versions of the time. Or, at least it did until I fixed it. Muwhahaha.

Anyway, here's a diff of what I changed:

--- /cross/src/glibc-2.2.5/configure.orig       2012-01-20 23:08:43 +0000
+++ /cross/src/glibc-2.2.5/configure    2012-01-20 23:10:47 +0000
@@ -1476,7 +1476,7 @@
   ac_prog_version=`$CC -v 2>&1 | sed -n 's/^.*version \([egcygnustpi-]*[0-9.]*\).*$/\1/p'`
   case $ac_prog_version in
     '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
-    *gcc-2.9[5-9].*|*2.8.[1-9]*|*2.9|*2.9.[0-9]*|2.9[5-9]*|3.[0-9]*|cygnus-2.9[1-9]*|gcc-2.9[5-9]|gcc-2.1[0-9][0-9]|sgicc-*)
+    *gcc-2.9[5-9].*|*2.8.[1-9]*|*2.9|*2.9.[0-9]*|2.9[5-9]*|3.[0-9]*|cygnus-2.9[1-9]*|gcc-2.9[5-9]|gcc-2.1[0-9][0-9]|sgicc-*|4.[0-9.]*)
        ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
     *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;

This time configure worked, although it complained that I wasn't using versioning because my binutils package was too old. Meh. The next step is to run make install-headers, and then create a couple of files that gcc apparently needs to exist but not necessarily actually contain any content:

make cross-compiling=yes install_root=${SYSROOT} install-headers
mkdir ${SYSROOT}/usr/include/gnu
touch ${SYSROOT}/usr/include/gnu/stubs.h
touch ${SYSROOT}/usr/include/bits/stdio_lim.h

In theory I've now got a vaguely sensible set of glibc headers that gcc can actually use when compiling. The next step will be to at long last actually build my cross-compiler.

Tags: computing, nas adventures
Subscribe
  • Post a new comment

    Error

    default userpic
    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 3 comments