Toolchain Directory Structure
Directory Structure
For this tutorial, we will put the toolchain in /arm directory rather than the usual /usr/local. I prefer this approach since it's easier to manage (for example, to delete everything when things don't work or when we're finished with it, or to put it on portable drive to be carried to different system).
We'll put files related to installation in /arm/setup directory:
/arm +- setup +- download --> Put downloaded .tgz files here +- srcs --> Unpack .tgz source files here +- objs --> Build sources here
Once the toolchain is built, they'll be installed in these directories:
/arm +- arm-elf +- bin +- include +- info +- lib .. etc..
This tutorial assumes that you have write access to /arm directory.
Setup Environment Variables for the Build Process
export TARGET=arm-elf export PREFIX=/arm export SYSROOT=${PREFIX}/sysroot export ARCH=arm export CROSS_COMPILE=${TARGET}-
Prepare Toolchains
Download Latest binutils, GCC, and newlib
Download latest toolchain:
- binutils: http://ftp.gnu.org/gnu/binutils/
- linux: http://www.kernel.org
- gcc: http://ftp.gnu.org/gnu/gcc/
- newlib: ftp://sources.redhat.com/pub/newlib/index.html
- glibc: http://ftp.gnu.org/gnu/glibc
$ mkdir -p ${PREFIX}/setup/download $ cd ${PREFIX}/setup/download $ wget -c http://ftp.gnu.org/gnu/binutils/binutils-2.18.tar.bz2 $ wget -c http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.24.tar.bz2 $ wget -c http://ftp.gnu.org/gnu/gcc/gcc-3.4.6/gcc-3.4.6.tar.bz2 $ wget -c ftp://sources.redhat.com/pub/newlib/newlib-1.16.0.tar.gz $ wget -c http://ftp.gnu.org/gnu/glibc/glibc-2.5.tar.gz $ wget -c http://ftp.gnu.org/gnu/glibc/glibc-linuxthreads-2.5.tar.bz2
You will also need mkinfo from texinfo package to build the toolchain (for building the manuals etc). On Debian based system (Debian, Ubuntu, etc.) you can install it with:
$ sudo apt-get install texinfo
Or if you're with RedHat (Fedora, etc), you can install it with:
$ yum install texinfo
Preparing to build
Unpack archives
$ mkdir -p ${PREFIX}/setup/srcs $ cd ${PREFIX}/setup/srcs $ tar xjf ../download/binutils-2.18.tar.bz2 $ tar xjf ../download/linux-2.6.24.tar.bz2 $ tar xjf ../download/gcc-3.4.6.tar.bz2 $ tar xzf ../download/newlib-1.16.0.tar.gz $ tar xzf ../download/glibc-2.5.tar.gz $ cd glibc-2.5 $ tar xjf ../../download/glibc-linuxthreads-2.5.tar.bz2
Build Everything
Build binutils
$ mkdir -p ${PREFIX}/setup/objs/binutils-arm $ cd ${PREFIX}/setup/objs/binutils-arm $ ../../srcs/binutils-2.18/configure --target=${TARGET} --prefix=${PREFIX} --with-sysroot=${SYSROOT} $ make $ make install
(if you're wondering, that will take 5 minutes on a Core2Duo 2GHz)
Prepare Linux Kernel Header Files
You need to have ncurses development package to do this. To install ncurses development package on Debian:
$ sudo apt-get install ncurses-dev
or on RedHat?:
$ yum install ncurses-devel
Configure Linux:
$ cd ${PREFIX}/setup/srcs/linux-2.6.24/ $ make menuconfig ARCH=arm
(Note: don't forget the ARCH=arm part above)
We don't need need to build the kernel now.
Now lets fix include directories:
mkdir -p /arm/arm-elf/include cd /arm/arm-elf/include ln -sd /arm/setup/srcs/linux-2.6.24/include/asm-arm asm ln -sd /arm/setup/srcs/linux-2.6.24/include/linux linux cd .. ln -sd include sys-linux
Update binutils Path
Before we build gcc and the rest of the toolchain, add the path to (thew newly installed) binutils.
(if you're using Bash):
$ export PATH=/arm/bin:$PATH
Build gcc
First prepare newlib to be built along with gcc:
$ cd /arm/setup/srcs/gcc-3.4.6 $ ln -sd ../newlib-1.16.0/newlib .
Now lets build the beast:
$ mkdir -p /arm/setup/objs/gcc-arm $ cd /arm/setup/objs/gcc-arm $ ../../srcs/gcc-3.4.6/configure --target=arm-elf --prefix=/arm --enable-threads \ --enable-languages=c,c++ \ --disable-nls --with-newlib --disable-shared \ --with-fpu=-softfpa --with-float=soft $ make $ make install $ cd ..
(if you're wondering again, that will take about 8 minutes on a Core2Duo 2GHz)
Build glibc
Glibc headers:
$
Glibc:
$ mkdir /arm/setup/objs/glibc-arm $ cd /arm/setup/objs/glibc-arm
PJSIP
Build
$ cd /your/pjproject/directory $ make distclean $ ./aconfigure --host=arm-elf --disable-floating-point \ --disable-sound \ CFLAGS='-I/arm/arm-elf/include -msoft-float -D_POSIX_SOURCE' $ make dep $ make
Common Problems
Link Errors Because of Floating Point Mismatch
You may get error about configure not being able to create executable, and config.log reveals error message similar to:
"/arm/lib/gcc/arm-elf/3.4.6/../../../../arm-elf/bin/ld: ERROR: /arm/lib/gcc/arm-elf/3.4.6/crtn.o uses hardware FP, whereas a.out uses software FP"
I think, it's because gcc was compiled without --with-fpu=-softfpa and --with-float=soft options above.
Conflicting Types
Something like:
/arm/lib/gcc/arm-elf/3.4.6/../../../../arm-elf/include/linux/types.h:19: error: conflicting types for 'dev_t' /arm/lib/gcc/arm-elf/3.4.6/../../../../arm-elf/include/sys/types.h:163: error: previous declaration of 'dev_t' was here