Building a GCC cross-compiler for the Rio Receiver
Jeff Mock
2/6/1
There are a lot of good sources for information about building
GCC cross compilers:
http://www.inkvine.fluff.org/~chris/arm-tools.html
http://www.objsw.com/CrossGCC/
There is a chicken-n-egg problem building a GCC and glibc
toolchain as a cross-compiler from scratch. In order to build the compiler
you need the include files for target, but you can't build the include files
until you have a compiler. This gets slightly more complicated
if you are building a cross compiler for a Linux system because
you need the include files for a configured linux kernel as well when
building the compiler. Aside from this weirdness it's pretty
straight forward.
This is how I build an arm-linux cross compiler and kernel
from scratch for the Dell Audio Receiver on an RH7 X86 machine. If
you aren't inclined to duplicate the effort you can get a binary
copy of my toolchain at:
ftp://ftp.mock.com/pub/arm-linux/arm-linux-toolchain.tgz (32MB)
This must be placed in /usr/local/arm-linux or it won't work properly.
It was built to run on a Redhat 7.0 system. This is GCC 2.95.2 with
some Arm patches, binutils 2.10.1.0.4, and glibc-2.1.3.
Useful defines for my build process:
BASE=/home/jeff/mercury
TOOLCHAIN=$BASE/toolchain
TARGET=arm-linux
DEST=/usr/local/$TARGET
KERNEL=/home/jeff/mercury/linux-mercury
Here are some useful files for building the toolchain. The other
items can be found in the usual places.
GCC 2.95.2 mods for Arm
ftp://ftp.mock.com/pub/arm-linux/gcc-2.95.2-diff-991022.gz (26k)
2.2.14 kernel with rmk4 patches for Arm with Empeg patches for
digital audio receiver product.
ftp://ftp.mock.com/pub/arm-linux/linux-kernel-v1.01.tar.gz (16MB)
If you prefer you can derive the kernel for the Dell audio
receiver from source material. Get a copy of the distribution
kernel 2.2.14 from kernel.org and apply these patches in order.
This should produce a tree identical to the above kernel:
The rmk4 arm patches for 2.2.14:
ftp://ftp.mock.com/pub/arm-linux/patch-2.2.14-rmk4.gz (454k)
Patches specific to the Dell Audio Receiver:
ftp://ftp.mock.com/pub/arm-linux/patch-mercury.gz (85k)
I had a small problem building this kernel, the solution is
described below.
$TOOLCHAIN directory should contain stuff to make tools, empty otherwise
binutils-2.10.1.0.4.tar.gz
gcc-2.95.2.tar.gz
gcc-2.95.2-diff-991022
glibc-2.1.3.tar.gz
glibc-linuxthreads-2.1.3.tar.gz
Delete any vestige of old toolkit
rm -rf $DEST
Build binutils
tar zxvf binutils-2.10.1.0.4.tar.gz
rm -rf build-binutils
mkdir build-binutils
cd build-binutils
../binutils-2.10.1.0.4/configure --target=$TARGET --prefix=$DEST
make
make install
Setup kernel sources for Arm kernel, configure kernel, and do
a "make dep". This does not need an arm compiler, uses host
compiler. The kernel includes are necessary to build the compiler.
If you are using the kernel image listed above for the Dell Digital
Audio Receiver, a suitable kernel configuration is
arch/arm/def-configs/mercury:
cd $KERNEL
cp arch/arm/def-configs/mercury .config
make oldconfig
make dep
Manually link kernel includes into toolchain includes
cd $DEST/$TARGET
mkdir include
cd include
ln -s $KERNEL/include/asm-arm asm
ln -s $KERNEL/include/linux linux
build just C compiler in special way that doesn't require libc
include files.
# untar and patch compiler sources
cd $TOOLCHAIN
tar zxvf gcc-2.95.2.tar.gz
cd gcc-2.95.2
patch -p0 < ../gcc-2.95.2-diff-991022
# Make mod so C compiler will build without libc includes
Edit file $TOOLCHAIN/gcc-2.95.2/gcc/config/arm/t-linux, change line:
TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC
Change to:
TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc \
-D__gthr_posix_h
# Configure to build only C compiler
cd $TOOLCHAIN
rm -rf build-gcc0
mkdir build-gcc0
cd build-gcc0
../gcc-2.95.2/configure $TARGET --prefix=$DEST --disable-threads \
--enable-languages="c" --with-cpu=strongarm110
make
make install
At this point the C compiler and utilties are suitable for building the
kernel, but there is no libc or includes for building user code.
I had a little problem building the Arm kernel listed above for
the Dell Audio Receiver. ld fails during the final link building
the zImage file. I don't know the source of the problem, but the
problem can be fixed by removing the following line near the end
of arch/arm/boot/compressed/vmlinux.lds.in:
.comment 0 : { *(.comment) } (remove this line)
Add /usr/local/arm-linux/bin to your path, the kernel should build
properly and you should have a zImage suitable for the audio receiver.
Build glibc, this takes the longest...
# Extract glibc
cd $TOOLCHAIN
tar zxvf glibc-2.1.3.tar.gz
cd glibc-2.1.3
tar zxvf ../glibc-linuxthreads-2.1.3.tar.gz
# configure libc
cd $TOOLCHAIN
rm -rf build-glibc
mkdir build-glibc
cd build-glibc
CC=$TARGET-gcc
../glibc-2.1.3/configure $TARGET --build=i686-linux \
--prefix=$DEST/$TARGET --enable-add-ons --disable-sanity-checks
make
make install
Now that libc is built and the includes are installed, go back and rebuild
C and C++ compilers properly.
# Remove hack used to build temp C compiler
Edit file $TOOLCHAIN/gcc-2.95.2/gcc/config/arm/t-linux, change line:
TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc \
-D__gthr_posix_h
Change back to:
TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC
# Configure to build full C and C++ compilers
cd $TOOLCHAIN
rm -rf build-gcc1
mkdir build-gcc1
cd build-gcc1
../gcc-2.95.2/configure $TARGET --prefix=$DEST --enable-languages="c,c++" \
--with-cpu=strongarm110
make
make install
Rebuild libc with newly built compiler (might not be necessary)
# configure libc
cd $TOOLCHAIN
rm -rf build-glibc1
mkdir build-glibc1
cd build-glibc1
CC=$TARGET-gcc
../glibc-2.1.3/configure $TARGET --build=i686-linux \
--prefix=$DEST/$TARGET --enable-add-ons --disable-sanity-checks
make
make install
All done, toolchain for Arm-linux running on x86 linux is in
/usr/local/arm-linux, add /usr/local/arm-linux/bin to your path.