Building your own toolchain
Contents[hide] |
Selecting the right hardware
Before you build your toolchain, you should know which architecture you are building the toolchain for. Though the code generated would execute perfectly irrespective of the arm architecture, you would not be able to take advantage of the features specific to that architecture because of slight difference in the Instruction set.
Let us consider arbitrary e.g. of a chip which does not have math co-processor.
So a simple instruction in C like
x=y*z
would translate in assembly language as
loop: add y to itself dnz z, loop
If you are multiplying 10*100, the loop would run for 100 times. Just imagine what would happen for floating point arithmetics.
If the chip has math co-processor, the compiler would generate
mul y,z
Which would possibly take just 1 machine cycle.
Arm 7
- ARM7+Thumb+Debug+Multiplier+ICE
- This generation introduced the Thumb 16 bit instruction set
Some famous gadget built on Arm 7 series.
- Audio controller in the SEGA Dreamcast
- DLink DSL604+ Wireless ADSL Router.
- iPod ,iRiver
- Most of Nokia's mobile phone range.
Arm 9
- ARM moved from a von Neumann architecture (Princeton architecture) to a Harvard architecture with separate instruction and data bus (and caches), significantly increasing its potential speed.
- Most important change was introduction of MMU, POSIX compliant OS could be ported.
All smart phones are based on ARM 9 Architecture.
Arm 11
- SIMD instructions which can double MPEG4 and audio digital signal processing algorithm speed
- Cache is physically addressed, solving many cache aliasing problems and reducing context switch overhead.
- TI OMAP2 series processors.
- All touch based smart phones
Code cross-complied on ARM 7 toolchain would run perfectly on ARM 9 or ARM 11 processors, but then you won't be able to utilize hardware features implemented by those architectures. Hence it is important that you build your toolchain for correct architecture.
Steps of Cross Compilation
- gcc: Run the cross-compiler on the host machine to produce assembler files for the target machine.
- as: Assemble the files produced by the cross-compiler.
- ld: Link those files to make an executable. You can do this either with a linker on the target machine, or with a cross-linker on the host machine.
Specifing target for your toolchain
- arm-linux : Generic arm processor
- Armv4l : This makes support for the ARM v4 architecture, as used in the StrongARM,ARM7TDMI, ARM9.
- Armv5l : This makes support for the ARM v5 architecture, as used in the XScale and ARM11.
EABI target
You would most likely want to use build your toolchain compliant to EABI standards. EABI is like POSIX standard for cross-compilers.
* arm-none-gnueabi: this is the name as arm none-eabi (specific to GNU compiler) * arm-unknown-eabi: bare metal * arm-linux-eabi: Designed to be used to build programs with glibc under a Linux environment. This would what you would use to build programs for an embedded device running on Linux OS.
Setting up build environment.
- Preferably use virtual box / Vmware
- Create a new user for the installation.
- Set up the configure parameters in the .profile
- Create separate dir for build and source.
- Set PREFIX dir. It is very important that the directory should be anything apart from your /usr/bin directory. The output of our activity would generate binaries for arm processor. Now these would have same name as that of your x86 binaries. So if you specify /usr/bin directory all your existing binary would be replaced by ARM elf binary and then you won't be able to run a single application on your machine.
Scripts
Configure default settings for the toolchain
Copy this in your ~/.bashrc file.
- LFS is the root directory for your installation.
export LFS=/mnt/lfs export TARGET=arm-none-eabi export PREFIX=/usr/arm export PATH=$PATH:$PREFIX/bin export PATH=$PATH:$PREFIX/lib export TOOLPATH=$PREFIX
Scripts for compiling toolchain
#!/bin/bash cd $LFS/source #get the source code for bin utils wget -c http://ftp.gnu.org/gnu/binutils/binutils-2.20.tar.bz2 $LFS/source #get the source code for gmp: required for multi precision wget -c ftp://ftp.gmplib.org/pub/gmp-5.0.1/gmp-5.0.1.tar.bz2 #get the source code for gmp: required for mpfr wget -c http://www.mpfr.org/mpfr-2.4.2/mpfr-2.4.2.tar.bz2 #get the source code for gcc wget -c http://ftp.gnu.org/gnu/gcc/gcc-4.4.3/gcc-4.4.3.tar.bz2 #get newlib wget -c ftp://sources.redhat.com/pub/newlib/newlib-1.18.0.tar.gz # 1. Install binutils , extarct tar file. Run configure, make, make install tar -xjf $LFS/source/binutils-2.20.tar.bz2 cd binutils-2.20 ./configure --target=$TARGET --prefix=$PREFIX --enable-interwork --enable-multilib --disable-nls --disable-werror make sudo make install # 2. Install gcc dependancies: # 2.1 Install gmp # 2.2 Install MFPR # 2.3 Install mpc if required # 2.1 Install gmp cd $LFS/build/source tar -xjf $LFS/source/gmp-5.0.1.tar.bz2 mkdir $LFS/build/gmp build all the sources from the build directory and not the source directory cd $LFS/build/gmp # run this command if error for "checking for suitable m4... configure: error: No usable m4 in $PATH or" # sudo aptitude install build-essential m4 $LFS/source/gmp-5.0.1/configure --prefix=$PREFIX #Tue Sep 7 13:36:14 IST 2010 make sudo make install # 2.2 Install MFPR cd $LFS/source tar -xjf $LFS/source/mpfr-2.4.2.tar.bz2 mkdir $LFS/build/mpfr cd $LFS/build/mpfr $LFS/source/mpfr-2.4.2/configure --prefix=$PREFIX --with-gmp=$PREFIX make # Tue Sep 7 14:22:08 IST 2010 sudo make install
This is probably the trickiest stage to get right. There are a few factors to consider:Do you have a fully-working and installed version of glibc for the same ABI (i.e. selection of binary format, processor type, etc.) as that for which you are building gcc?If this is your first time building a cross compiler, then the answer is almost certainly no. If this is not your first time building, and you built glibc previously, in the same format as you’re using for gcc now, then the answer might be yes.If the answer is no, then you cannot build support for any language than C, because all the other front-ends depend on libc (i.e. the final gcc binary would expect to link with libc) If this is your category, then you must append LANGUAGES="c" to each make command line inside gcc.
# 3 Installation of gcc first pass cd $LFS/source tar -xjf $LFS/source/gcc-4.4.3.tar.bz2 mkdir $LFS/build/gcc cd $LFS/build/gcc $LFS/source/gcc-4.4.3/configure --target=$TARGET --prefix=$PREFIX --enable-interwork --enable-multilib --enable-languages="c" --with-newlib --without-headers --disable-shared --with-gmp=$PREFIX --with-mpfr=$PREFIX make all-gcc # Tue Sep 7 17:54:37 IST 2010 sudo make install-gcc # 4 Installation of newlib cd $LFS/source tar -xzf $LFS/source/newlib-1.18.0.tar.gz mkdir $LFS/build/newlib cd $LFS/build/newlib $LFS/source/newlib-1.18.0/configure --target=$TARGET --prefix=$PREFIX --enable-interwork --enable-multilib --disable-nls --disable-newlib-supplied-syscalls --with-gmp=$PREFIX/lib --with-mpfr=$PREFIX # in case there is a makeinfo error run this command. delete the makefile and run configuration againg # sudo apt-get install texinfo # In case of arm-none-eabi-cc error create a softlink for arm-none-eabi-gcc # In case of libgmp.so.10 error, create a softlink in /usr/lib directory make # Thu Sep 9 00:01:39 IST 2010 sudo make install cd $LFS/build/gcc $LFS/source/gcc-4.4.3/configure --target=$TARGET --prefix=$PREFIX --enable-interwork --enable-multilib --enable-languages="c" --with-newlib --without-headers --disable-shared --with-gmp=$PREFIX --with-mpfr=$PREFIX make sudo make install
Now link the path.
# Thu Sep 9 05:04:51 IST 2010 sudo sh -c 'echo "/usr/arm/bin/" > /etc/paths.d/arm-none-eabi' sudo sh -cn 'echo "/usr/arm/share/man\n/usr/arm/man"> /etc/manpaths.d/arm-none-eabi'