#!/bin/sh # This script runs as a mortal user, and builds a cross-development # toolchain, plus kernel, for arm-linux in general, and in particular # the SA1100 on a Bright Star Engineering nanoEngine board. Only # slight adjustments should be needed for other StrongARM boards, # and the basic flow holds for building any other cross-build # environment. # # This script only very weakly depends on the host system, as long as it # has a halfway-working gcc and gmake. Tested on i686-unknown-linux-gnu, # kernel-2.0.36, gcc-2.95.3, gmake-3.79.1, glibc-2.0.7. Eariler versions # were tested with gcc-2.7.2. # # # Mostly follows "HOW-To build a cross Tool Chain in brief by George France" # # todo: # more initial sanity checks set -e ARCH=arm TARGET=$ARCH-linux if [ ! -d $PRISTINE -o ! -d $BUILD -o ! -d $PREFIX ]; then echo "$0: configuration error" exit 1 fi if [ "X$UID" = "X0" ]; then echo "$0: script too dangerous to run as root" exit 1 fi KHOME=$BUILD/linux-2.4.18-rmk7-lrd1 HOST_SYS=i386-linux # only needed for glibc configure --build=$HOST_SYS PATH=$PREFIX/bin:$PATH # ................................... # build, and install binutils # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ echo "================binutils============="; date cd $BUILD mkdir binutils-2.10.1-$ARCH cd binutils-2.10.1-$ARCH $PRISTINE/binutils-2.10.1/configure --prefix=$PREFIX --target=$TARGET make make install # .................... # configure the kernel # ^^^^^^^^^^^^^^^^^^^^ echo "================kernel_config============="; date cd $KHOME # # Don't need to touch up ARCH and CROSS_COMPILE, # because diff-2.4.0-test4-np1.gz did that already. # mv Makefile Makefile.orig # sed -e '/^CROSS_COMPILE/s/=$/= arm-linux-/' -e '/^ARCH/{s/^/#/ # a \ # ARCH=arm # }' Makefile # # XXXX really, really needs to have all defaults covered # XXXX issue: CONFIG_CMDLINE can't be blank cp arch/arm/def-configs/nanoengine .config # XXXX fix a problem here, instead of making a new patch file sed -e 's/CMDLINE="root=1f04/CMDLINE="root=\/dev\/ram/' .config # XXXX gets into minor trouble because the Makefile attempts to see if the # compiler takes '-fno-strict-aliasing', but $TARGET-gcc isn't built yet. # Maybe we can shift the 'configure-kernel' step until after building # the first gcc? make oldconfig # # $PREFIX/$TARGET/include was created by the install of binutils # Should we "cp -a" instead of "ln -s"? # certainly not now, because it doesn't include version.h yet. # # gcc config (coming up) will look for $PREFIX/$TARGET/sys-include/limits.h, # to decide whether or not to chain its limits.h via #include_next. # We need that test to succeed. # ( cd $PREFIX/$TARGET mkdir -p include ln -s include sys-include cd include ln -s $KHOME/include/asm-$ARCH asm ln -s $KHOME/include/linux linux ) # ........................ # build first round of gcc # ^^^^^^^^^^^^^^^^^^^^^^^^ echo "================gcc_nolibc============="; date # consider using gcc-2.95.x-$ARCH-nolibc, totally separate from second build cd $BUILD mkdir gcc-2.95.3-$ARCH cd gcc-2.95.3-$ARCH # what about --with-headers and --with-libs? --enable-shared? $PRISTINE/gcc-2.95.3/configure -target=$TARGET --prefix=$PREFIX --enable-languages=c -disable-threads -with-cpu=strongarm110 # # patch gcc/Make-target and gcc/Makefile for the first compile phase, that # happens without use of glibc. The Makefiles really ought to leave a better # hook for this step. I tried overriding the variables from the command line, # but they don't propagate to make in the gcc subdir. ( cd gcc mv Make-target Make-target.orig sed -e '/^TARGET_LIBGCC2_CFLAGS/s/$/ -Dinhibit_libc -D__gthr_posix_h/' \ -e 's/ _dvmd_lnx$/ _dvmd_tls/' \ Make-target mv Makefile Makefile.orig sed -e '/^TARGET_LIBGCC2_CFLAGS/s/$/ -Dinhibit_libc -D__gthr_posix_h/' \ -e 's/ _dvmd_lnx$/ _dvmd_tls/' \ Makefile ) make # # Q: Why do we get # checking whether the C compiler (/mnt/rffe/ldoolitt/gcc-2.95.3-arm/gcc/xgcc -B/mnt/rffe/ldoolitt/gcc-2.95.3-arm/gcc/ -B/home/ldoolitt/rffe/arm-devel/arm-linux/bin/ -g -O2 ) works... no # configure: error: installation or configuration problem: C compiler cannot create executables. # near the end of that last "make"? # # A: ld: cannot open crt1.o: No such file or directory # make install # Double check $PREFIX/bin doesn't have anything in it that # keeps us from building native code; like cpp? # does $PREFIX/include need to be replaced with a symlink back to $PREFIX/include? # why include, and not sys-include? aargh! # # we just touched: # arm-linux/include (but no files in it) # arm-linux/bin/gcc # bin/arm-linux-gcc # bin/arm-linux-protoize # bin/arm-linux-unprotoize # bin/cpp # bin/gcov # info/* # lib/gcc-lib/* # lib/libiberty.a # man/man1/arm-linux-gcc.1 # man/man1/cccp.1 # There's only one of those that I can't accept, I fix it now: ###( cd $PREFIX/$TARGET ### rmdir include ### ln -s ../include include ###) # since glibc's include directory is architecture-neutral. # I'm also confused why host binaries are installed in arm-linux/bin, # by both gcc and binutils. Is this what --exec-prefix is for? # That wouldn't really match glibc's usage, below. # .................. # build linux kernel # ^^^^^^^^^^^^^^^^^^ # see below, has to happen before glibc build, and therefore also before # the second gcc build. echo "================kernel============="; date cd $KHOME make dep make zImage # builds, decompresses, initializes, runs. Kewl! # ................................................... # build, and install glibc+crypt+linuxthreads # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ echo "================glibc============="; date cd $BUILD mkdir glibc-2.1.3-$ARCH cd glibc-2.1.3-$ARCH # but but but, no "--with-headers=$KHOME/include --with-binutils=$PREFIX/bin --disable-sanity-checks"? # The following step needs to find , so it has to happen # after a real build of the kernel. Or, as the glibc FAQ 1.8 suggests, after # `make include/linux/version.h'. CC=$TARGET-gcc $PRISTINE/glibc-2.1.3/configure $TARGET --build=$HOST_SYS --prefix="" --enable-add-ons=linuxthreads,crypt --program-prefix=$TARGET- make # DANGER: You WILL screw up your system if you forget the install_root # part of the next command. Well, if you were running as root, that is. make install_root=$PREFIX/$TARGET install # # Fix up glibc ld script, which has paths that need to be used on the host # XXX total hack, might not even be Right[TM] echo "touching up $PREFIX/$TARGET/lib/libc.so" ( cd $PREFIX/$TARGET/lib mv libc.so libc.so.orig sed -e "/^GROUP/s, /lib/, $PREFIX/$TARGET/lib/,g" libc.so ) # ..................................................... # go back and re-build gcc with glibc, g++, and threads # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ echo "================gcc_final============="; date cd $BUILD/gcc-2.95.3-$ARCH $PRISTINE/gcc-2.95.3/configure -target=$TARGET --prefix=$PREFIX --enable-languages=c,c++ -with-cpu=strongarm110 # I ran into problems with missing c++ include files "typeinfo" # and "new", that went away after a "make clean". make clean make make install # ................ # build libtermcap # ^^^^^^^^^^^^^^^^ echo "================termcap============="; date cd $BUILD mkdir termcap-1.3.1-$ARCH cd termcap-1.3.1-$ARCH CC=$TARGET-gcc RANLIB=$TARGET-ranlib $PRISTINE/termcap-1.3.1/configure make cp libtermcap.a $PREFIX/$TARGET/lib cp $PRISTINE/termcap-1.3.1/termcap.h $PREFIX/$TARGET/include # ..................................................... # build genext2fs for use on host # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ echo "================genext2fs============="; date cd $BUILD mkdir genext2fs-1.3-host cd genext2fs-1.3-host make -f $PRISTINE/genext2fs-1.3.orig/Makefile VPATH=$PRISTINE/genext2fs-1.3.orig cp genext2fs $PREFIX/bin # ................................. # build nanofix, a boot-time helper # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ echo "================nanofix============="; date cd $BUILD/nanofix make combo KERNEL=$KHOME echo "================done============="; date # done with toolchain!