Setting up a cross-compilation toolchain


From SamyGO
Revision as of 17:41, 10 December 2012 by Juzis28 (talk | contribs) (Prepare toolchain)
Jump to: navigation, search

A tool chain is a set of executable programs that enables you to build (assemble, compile and link) your own executable programs from source code (typically C, C++, fortran or other programming languages). To build these executables, the source code needs to be translated into machine-readable code. This is what a tool chain does. The translation proceeds in three steps (well, you may think of it this way): translation into low-level code (compilation), translation to machine-readable code (assembly), combination with other code libraries (linking). Compilation/assembly mostly proceeds in a single go. So, for a tool chain you need at least three programs: a compiler, an assembler, and a linker. In almost all cases you will also need a C-library to link with.

Unlike source code, executables are machine-specific. That means that executables built for the Intel x86 architecture (the basis for most computers in the world today) will not run on other types of processors, for example the ARM architecture, the basis for many embedded systems. To build executables for a Samsung TV on an x86-based machine, you will need a tool chain that runs on the x86-architecture and builds executable code for the ARM-architecture. This procedure is called cross-compilation, and requires a cross compilation tool chain. This wiki page deals with the installation of different tool chain provided by various providers, executing on various platforms such as on an x86, Linux or Windows (Cygwin) platform.

This tutorial describes different ways to set up a cross tool chain to compile programs that can be executed on a TV set.

The tutorial do not describe how to create applications that can be downloaded and executed on the TV via it's standard menus or by Samsung provided value chain systems.

The TV need to be hacked according to one of the several ways described on the SamyGo Wiki so it is possible to use telnet/ssh to log on to the TV and execute the example program via a shell.



Using pre compiled compilers

A pre compiled compiler means that someone have already built the compiler and the user only have to install the tool, there are no steps involving building the tool chain from scratch

The example source code in this tutorial is using stdout for output and do not include any drawing on the actual TV screen.

This part of the article about pre compiled cross tool chains was inspired by the following persons work scottrix, arris69, aaaaa75 from the SamyGo forums http://forum.samygo.tv/viewtopic.php?f=12&t=1537&start=0&hilit=codesourcery and
Moozing, http://moozing.wordpress.com/2011/04/05/cross-compile-in-debian/

Thanks to Roman, the original designer and developer of WebGui SamyGo used in the hotel mode hack.



First step

As a first step it is necessary to know what type of CPU there is in the target TV set and it's architecture so the right tool chain can be downloaded. The CPU is easily recognised by executing the following at the telenet/ssh prompt of the TV set

# cat /proc/cpuinfo 

produce the following output for a TV set UEC46C5105

system type             : MStar Titania3
processor               : 0
cpu model               : MIPS 34Kc V5.4
BogoMIPS                : 351.23
wait instruction        : yes
microsecond timers      : yes
tlb_entries             : 16
extra interrupt vector  : yes
hardware watchpoint     : yes, count: 4, address/irw mask: [0x0000, 0x02a0, 0x0448, 0x0288]
ASEs implemented        : mips16 dsp mt
shadow register sets    : 1
core                    : 0
VCED exceptions         : not available
VCEI exceptions         : not available


In this example the target CPU is a Mips of the type 34kc.

It is also necessary to know if the CPU is running in little endian or big endian mode, on some TV series it can be guessed from the name of the software, enable the service menu on the TV and look at the top most lines that indicate the software version,

For the C series TV set.
If the number starts with T-MSX the architecture is little endian
If the number starts with T-TDT the architecture is big endian

For example, for the TV set UEC465105 it says
T-MSX5DEUC-2005.4
T-MSX5DEUS-1001

This indicate that that the architecture for UEC465105 is little endian. If there are any doubts about what type of architecture the CPU is executing in, ask in the SamyGo forum, http://forum.samygo.tv
Done






Microsoft Windows (i686/AMD)

Native

The Codesourcery tool chain works in Microsoft Windows

TV CPU Architecture Status
UE46C5105 Mips Little endian Working

Download the (lite, this is free of charge) tool chain for the Mips CPU from CodeSourcery (http://www.codesourcery.com/sgpp/lite_edition.html) and install it, during the installation it is possible add the path to the tool chain to the environment variables PATH which can be recommended. This compiler have support both for little endian and big endian which is controlled by a switch, see below.

After installing the tool, Start a command window and enter the following

c:\
mkdir C:\temp\sample1
cd C:\temp\sample1

create a helloword.c file, see Hello world

mips-linux-gnu-gcc.exe -mel -mglibc -march=34kc helloworld.c -o hellocs

-mel tells the compiler to generate code for a little endian architecture, use switch -meb for big endian architecture.
-mglibc tells the compiler to use GNU/libc instead of uclibs
-march defines a very specific CPU type, if not given, the compiler generates generic code that is not optimized for a specific variant of the CPU
-o defines the output file

copy the file hellocs to the TV with ftp or any other file transfer tool and enter the following at the prompt

./hellocs

Done






Cygwin

See Microsoft windows, the cross tool chain described there works in Cygwin as well

Done






GNU/Linux environment (i686/AMD architecture)

Samsung tool chain

This tool chain works in GNU/Linux hosted on a i686 architecture, for example Ubunutu/Debian on a standard PC.

TV CPU Architecture Cross compiler Status
UE46C5105 Mips Little endian VDLinux-mips34kc-toolchain-lite-20100223.tgz Working

Samsung provide two tool chains via their open source download page, http://opensource.samsung.com VDLinux-mips34kc-toolchain-lite-20100223.tgz for Mips cpu little endian architectures
toolchain_mips24ke_nfp_be.tgz for Mips cpu big endian architectures.
In this example the little endian version will be used
Download VDLinux-mips34kc-toolchain-lite-20100223.tgz and enter the following at the prompt

cd
mkdir tc
cd tc
tar -zxvf ../VDLinux-mips34kc-toolchain-lite-20100223.tgz
cd
mkdir sample1
cd sample1

create the helloword.c file, see http://en.wikipedia.org/wiki/Hello_world_program_examples#C

~/tc/VDLinux-mips34kc-toolchain-lite-20100223/bin/mips-linux-gnu-gcc -mglibc -march=34kc  helloworld.c -o hellovd

-mglibc tells the compiler to use GNU/libc instead of uclibs
-march defines the very specific target CPU, if not given, the compiler generates generic code that is not optimized for a specific variant of the CPU. Note, this tool chain can only produce little endian code
The flag -mel is not needed and the flag -meb will cause an error.
copy the file hellovd to the TV and execute at the prompt

./hellovd

Done






Compiling wifi adapter driver

In example, we compile Realtek rtl8191SU driver for LE32C530, with firmware MSX5DEUC.
It is recommended (by Samsung) to use CentOS 5.0.

Prepare toolchain

If you have working toolchain (look at Using pre compiled compilers), you can skip this step.
If you`re doing all from scratch, Ready-To-Use toolchain will be available after you finish next step (Prepare kernel sources) on /home/tv/kernel/VDLinux-mips34kc-toolchain-lite-20100223/bin. This path we export to use mips-linux-gnu compiler for our needs in this manual.

Export PATH to your compiler`s bin directory.

PATH=/home/tv/kernel/VDLinux-mips34kc-toolchain-lite-20100223/bin:$PATH

For future use, you can edit ~/bashrc file and add line above at the end. To check if path is exported properly, enter

echo $PATH
Prepare kernel sources

This step is needed only once. If you want compile another drivers later, skip this.
1. Download kernel sources from http://opensource.samsung.com, (10_LA32C530_X4.tar.gz) and place it to /tmp directory.
2. Extract kernel sources to /home/tv/kernel

tar -xzvf ./10_LA32C530_X4.tar.gz -C /home/tv/kernel 

3. Go to kernel`s dir and prepare toolchain to compile driver module

cd /home/tv/kernel/vdlinux-mstar-kernel/2.6.28.9
make clean; make prepare; make modules_prepare

If procedure finishes without errors, this step if finished, you`re ready to compile custom drivers.
In case you get errors (ignore warnings), ask on forum for support.

Driver sources

1. Download wifi driver sources, grab it from here. Choose your required driver and copy to /tmp directory:

cd /tmp/ && wget ftp://WebUser:wK9xBuD5@207.232.93.28/cn/wlan/RTL819xSU_usb_linux_v2.6.6.0.20120405.zip

If wget won`t work, download archive using web browser and place it to /tmp directory.
2. Unzip archive:

unzip ./RTL819xSU_usb_linux_v2.6.6.0.20120405.zip

3. Navigate to extracted directory and unpack driver sources:

cd ./rtl8712_8188_8191_8192SU_usb_linux_v2.6.6.0.20120405/driver
tar -xzvf ./rtl8712_8188_8191_8192SU_usb_linux_v2.6.6.0.20120405.tar.gz

4. Copy required to compilation directories to /home/drv

mv -f ./rtl8712_8188_8191_8192SU_usb_linux_v2.6.6.0.20120405 /home/tv/drv

5. go to /home/tv/drv and edit Makefile

cd /home/tv/drv
nano ./Makefile

Enable mstar architecture (disabled by default)

CONFIG_PLATFORM_MSTAR389 = y

Other patforms must be n: CONFIG_PLATFORM_* = n
Go down and edit path to kernel sources

ifeq ($(CONFIG_PLATFORM_MSTAR389), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MSTAR389
ARCH:=mips
CROSS_COMPILE:= mips-linux-gnu-
KVER:= 2.6.28.9
KSRC:= /home/tv/kernel/vdlinux-mstar-kernel/2.6.28.9/
endif

Save Makefile
6. Edit config

nano ./config

make sure you have y for MSTAR389

CONFIG_PLATFORM_MSTAR389        =       y

Other patforms must be n: CONFIG_PLATFORM_* = n
Save config
7. Start driver compilation:

make

8. If no errors, strip driver:

/home/tv/kernel/VDLinux-mips34kc-toolchain-lite-20100223/bin/mips-linux-gnu-strip --strip-unneeded 8712u.ko

9. Take 8712u.ko and use for your needs on TV (insmod 8712u.ko)

References

This how to is based on Otr`s and Nikel2007`s posts on forum.ixbt.com

Emdebian toolchain)

This tool chain works in GNU/Linux hosted on a i686 architecture, for example Ubunutu/Debian on a standard PC.

TV CPU Architecture Cross compiler Status
UE46C5105 Mips Little endian gcc-4.4-mipsel-linux-gnu Working

Emdebian provides a number pre compiled packages that can be installed using apt-get, in this example the cross compiler will target a MIPS cpu with an little endian architecture. Use http://www.emdebian.org/toolchains/search.php for other pre compiled packages targeting other cpu's

At the prompt

cd
apt-get install linux-libc-dev-mipsel-cross libc6-mipsel-cross libc6-dev-mipsel-cross binutils-mipsel-linux-gnu gcc-4.4-mipsel-linux-gnu g++-4.4-mipsel-linux-gnu
mkdir -p sample1
cd sample1

create the helloword.c file, see http://en.wikipedia.org/wiki/Hello_world_program_examples#C

mipsel-linux-gnu-gcc -mglibc -march=34kc  helloworld.c -o helloed

-mglibc tells the compiler to use GNU/libc instead of uclibs
-march defines the very specific target CPU, if not given, the compiler generates generic code that is not optimized for a specific variant of the CPU. Note, this tool chain can only produce little endian code
The switch -mel is not needed and the flag -meb will cause an error.
copy the file helloed to the TV and execute at the prompt

./helloed

Installing a big endian MIPS tool chain would be

apt-get install linux-libc-dev-mips-cross libc6-mips-cross libc6-dev-mips-cross binutils-mips-linux-gnu gcc-4.4-mips-linux-gnu g++-4.4-mips-linux-gnu

Errors during apt-get
Not allowed: You need to put sudo first on the line, like sudo apt-get ....
Not found:
Do the following at the prompt (read http://emdebian.org/tools/crosstools.html)
NOTE the >> on the echo line, DO NOT USE single >

echo "deb http://www.emdebian.org/debian/ squeeze main" >> /etc/apt/sources.list
apt-get update
apt-get install emdebian-archive-keyring

then redo the apt-get install linux .....
Out of cache memory:
add "-o apt::Cache-Limit=XXXXXXX " to the apt-get line where XXXXXXX is a number bigger than the the reported cache size when the error message is given, like this (using sudo, mips target, little endian, cache size 30000000)

sudo apt-get -o apt::Cache-Limit=30000000 install linux-libc-dev-mipsel-cross libc6-mipsel-cross libc6-dev-mipsel-cross binutils-mipsel-linux-gnu gcc-4.4-mipsel-linux-gnu g++-4.4-mipsel-linux-gnu

Done






Hello world

#include <stdio.h>

int main(void)
{
       printf("Hello world\n");
       return (0);
}








Toolchains 101, building and compiling the tool chain from scratch

This page is a brief summary of the cross-compilation discussion on the SamyGO forum. Main contributors to this information are Robbiesz and marcelru. The information in this page pertains to the building of a tool chain, based on the source code as stored in the file 32B650.zip, available from Samsung.

We are still in the testing phase, for now, check out the forum discussion (topic: cross-compilation [1]). Especially the Windows building procedure is not completely established yet and relies (for now) on the Linux scripts. When fully reliable, a separate set of scripts for Windows/Cygwin will be released. For more info, errors you may encounter, support for other Samsung tool chains, please refer to the forum, or better still, participate.

The Samsung toolchain

The source code for the Samsung ARM toolchain is available on the net, but needs some adjustments before it can be built. We will discuss that later. The main parts are:

  • GNU binutils (containing among other things an assembler and a linker)
  • GCC, the GNU C/C++ compiler (and a host of other languages we will not use)
  • Glibc, the GNU C library
  • linux kernel sources, for operating system/processor specific details.

For the remainder of this wiki page, we will use the toolchain for the 32B650/32B550/... TV's as an example. The source code for this toolchain is stored in the file 32B650.zip [2]. Download this file and store it in the directory where you want to build your toolchain. Download the SamyGO patches that enable compilation of the toolchain here: [3]

Building the toolchain on Linux

Since most Linux distro's come standard with a full toolchain for building packages, building the cross-compilation toolchain on this platform is fairly straightforward, and proceeds in 6 stages (You will need approximately 2.5GB diskspace for the build).

Source installation

Unpack and install the source code files. This is done with the script install_sources.sh: edit paths and code versions to your liking:

#! /bin/sh
#
# install_sources.sh installs the source code for the toolchain for Samsung
# TV's, as found in the file 32B650.zip. Place this file together with the 
# patches tarball (SamyGO-toolchain_fc11_patches.tgz) in the ${BUILDROOT} 
# directory, defined below, and run this script.
#
BUILDROOT=/tmp/arm-tools         # edit according to your needs. 

cd ${BUILDROOT}
mkdir -p ${BUILDROOT}/src

# unpack the Samsung zip file

unzip 32B650.zip

# remove unnecessary stuff and move the kernel and toolchain code

rm -f libgphoto2-2.3.1.tar.zip
rm -f libusb-0.1.12.tar.gz
rm -f SDL-1.2.11.zip
mv linux.chelsea.tgz ${BUILDROOT}/src

# unpack the toolchain and remove unnecessary stuff

tar -zxvf SELP.3.2.x-Chelsea.src.tgz
rm -f SELP.3.2.x-Chelsea.src.tgz

mv ./SELP.3.2.x-Chelsea.src/Toolchain/gcc-4.2.0-4.0.9.tgz ${BUILDROOT}/src
mv ./SELP.3.2.x-Chelsea.src/Toolchain/binutils-2.17.50.tgz ${BUILDROOT}/src
mv ./SELP.3.2.x-Chelsea.src/Toolchain/glibc-2.5.90-9.0.9.tgz ${BUILDROOT}/src

rm -rf ./SELP.3.2.x-Chelsea.src

# unpack the patches and move them

tar -zxvf SamyGO-toolchain_fc11_patches.tgz
mv *.patch ${BUILDROOT}/src

Notice for binutils: If original binutils-2.17.50 don't compile on your computer, you can try it with different versions of binutils. On OpenSUSE 11.2, I compile it via binutils-2.19.1

Kernel headers installation

Install the kernel header files. You will need these when you want to build your own kernel modules for your TV. For that, the kernel source code's version has to match your TV's kernel version _exactly_. The installation is done with the install_kernel_src.sh script: again, edit to meet your needs.

#! /bin/sh 

# how to install kernel headers using this script:
# 
# Create the ${BUILDROOT} directory, put this script (install_kernel_src.sh) 
# in it.
# In ${BUILDROOT}, create a directory ./src and put the linux tarball in it.

# go up one directory and run this script. 

TARGET=arm-SamyGO-linux-gnueabi
BUILDROOT=/tmp/arm-tools
PREFIX=/usr/local                            # change to your needs
SYSROOT=${BUILDROOT}/sysroot

export ARCH=arm
export CROSS_COMPILE=${TARGET}-
export PATH=$PATH:${PREFIX}/bin
 
cd ${BUILDROOT}/src

# remove previous installation if it is there:
rm -rf linux 
rm -rf linux-r011 
rm -rf RFS 
rm -rf ssdtv_platform

# unpack, move up one dir and link:

tar -zxvf linux.chelsea.tgz              # from 32B650.zip
mv ./linux/* .
rm -rf linux/

ln -s ./linux-r011 linux

cd linux

# copy header files to sysroot:
mkdir -p ${SYSROOT}/usr/include
cp -a ${BUILDROOT}/src/linux/include/linux ${SYSROOT}/usr/include/linux
cp -a ${BUILDROOT}/src/linux/include/asm-arm ${SYSROOT}/usr/include/asm
cp -a ${BUILDROOT}/src/linux/include/asm-generic ${SYSROOT}/usr/include/asm-generic

# remove stale link to ssdtv headers:
rm -rf ${SYSROOT}/usr/include/asm/arch-ssdtv

# ... and copy these as well:
cp -a ${BUILDROOT}/src/ssdtv_platform/include/asm-arm/arch-ssdtv ${SYSROOT}/usr/include/asm

Everything is now installed (but not yet unpacked). The remainder of the installation consists of the actual building of the tools: First the binutils are built: as, ld and a bunch of others. For cross-compilation, these tools do not need any resources for the target platform (ARM, in this case).

Building of binutils

Apart from a small bug in one of the source files and a configuration change to be made to part of the code (patches are included) the build is straightforward, done with mkbinutils.sh:

#! /bin/sh

# how to build binutils using this script:
# 
# Create the ${BUILDROOT} directory, put this script (mkbinutils.sh) in it.
# In ${BUILDROOT}, create a directory ./src and put the binutils tarball and 
# the patch in it.

# go up one directory and run this script. 

TARGET=arm-SamyGO-linux-gnueabi
BUILDROOT=/tmp/arm-tools                     # change to your needs
PREFIX=/usr/local                            # change to your liking 
SYSROOT=${BUILDROOT}/sysroot
UTILS=binutils-2.17.50

export ARCH=arm
export CROSS_COMPILE=${TARGET}-
export PATH=$PATH:${PREFIX}/bin
 
cd ${BUILDROOT}/src

tar -zxvf binutils-2.17.50.tgz               # from 32B650.zip
patch -p0 < ./binutils-2.17.50_fc11.patch 

mkdir -p BUILD/${UTILS}
cd BUILD/${UTILS}

../../${UTILS}/configure --prefix=${PREFIX} --target=${TARGET} \
    --with-sysroot=${SYSROOT} 
make

make install

mkdir -p $PREFIX/$TARGET/include
cp ${BUILDROOT}/src/${UTILS}/include/libiberty.h $PREFIX/$TARGET/include

When all goes well, you will now have the following executables in /usr/local/bin:

arm-SamyGO-linux-gnueabi-addr2line
arm-SamyGO-linux-gnueabi-ar
arm-SamyGO-linux-gnueabi-as
arm-SamyGO-linux-gnueabi-c++filt
arm-SamyGO-linux-gnueabi-gprof
arm-SamyGO-linux-gnueabi-ld
arm-SamyGO-linux-gnueabi-nm
arm-SamyGO-linux-gnueabi-objcopy
arm-SamyGO-linux-gnueabi-objdump
arm-SamyGO-linux-gnueabi-ranlib
arm-SamyGO-linux-gnueabi-readelf
arm-SamyGO-linux-gnueabi-size
arm-SamyGO-linux-gnueabi-strings
arm-SamyGO-linux-gnueabi-strip

GCC installation, stage 1

The C-compiler (gcc) has to be built in two stages: First, it is built and linked against the existing C-library (glibc). This version of the compiler is used to build glibc for the target platform, and then gcc is built again, now with the just compiled C-library.

The stage 1 build of gcc renders a barebones gcc, just useful for compiling glibc, as described in the next step: Edit install_gcc_stage1.sh according to your needs and execute. The source code will be patched to prevent building of two runtime objects that cannot be linked yet (because we don't have a working C-library for ARM, yet)

#! /bin/sh

# how to install gcc stage 1 using this script:
# 
# Create the ${BUILDROOT} directory, put this script (install_gcc_stage1.sh) 
# in it.
# In ${BUILDROOT}, create a directory ./src and put the gcc tarball in it.

# go up one directory and run this script. 

TARGET=arm-SamyGO-linux-gnueabi
BUILDROOT=/tmp/arm-tools
PREFIX=/usr/local                            # change to your liking
SYSROOT=${BUILDROOT}/sysroot
GCC=gcc-4.2.0-4.0.9

export ARCH=arm
export CROSS_COMPILE=${TARGET}-
export PATH=$PATH:${PREFIX}/bin
 
cd ${BUILDROOT}/src

# unpack

tar -zxvf ${GCC}.tgz      # from 32B650.zip

patch -p0 < ./gcc-4.2.0-4.0.9_t-linux-eabi.patch

mkdir -p BUILD/${GCC}-stage1 

cd BUILD/${GCC}-stage1
  ../../${GCC}/configure --prefix=${PREFIX} --target=${TARGET} \
      --enable-languages=c --disable-shared --disable-threads \
      --disable-libmudflap --disable-libssp --disable-nls \
      --disable-libgomp --with-cpu=arm1136jf-s --with-fpu=vfp

  make all-gcc
  make install-gcc

Glibc installation

Build glibc for ARM: Edit the paths in mkglibc.sh (if needed) and execute:

#! /bin/sh

# how to install glibc using this script:
# 
# Create the ${BUILDROOT} directory, put this script (mkglibc.sh) 
# in it.
# In ${BUILDROOT}, create a directory ./src and put the glibc tarball in it.

# go up one directory and run this script. 

TARGET=arm-SamyGO-linux-gnueabi
BUILDROOT=/tmp/arm-tools                     # change to meet your needs
PREFIX=/usr/local                            # change to your liking
SYSROOT=${BUILDROOT}/sysroot
GLIBC_VER=glibc-2.5.90-9.0.9

export ARCH=arm
export CROSS_COMPILE=${TARGET}-
export PATH=$PATH:${PREFIX}/bin
 
cd ${BUILDROOT}/src

# unpack

tar -zxvf ${GLIBC_VER}.tgz              # from 32B650.zip

patch -p0 < ./${GLIBC_VER}_fc11.patch

rm -rf ${BUILDROOT}/src/glibc-build-localedef
mv ${BUILDROOT}/src/${GLIBC_VER}/glibc-build-localedef ./

mkdir -p ${BUILDROOT}/src/BUILD/${GLIBC_VER}
cd BUILD/${GLIBC_VER}

# create some cached defaults: 
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" >> config.cache

export GCC_PATH=${PREFIX}/bin

BUILD_CC=gcc CC=${GCC_PATH}/${CROSS_COMPILE}gcc ../../${GLIBC_VER}/configure \
    --target=${TARGET} --host=${TARGET} --prefix=${PREFIX}/${TARGET} \
    --with-__thread \
    --cache-file=config.cache --with-headers=${SYSROOT}/usr/include \
    --with-glibc=${BUILDROOT}/src/${GLIBC_VER} \
    --disable-profile --enable-add-ons
make 
make install

GCC installation, stage 2

Finally, gcc needs to be rebuilt and linked against the just built glibc for ARM. Now C++-support will be included as well.

Edit install_gcc_stage2.sh and execute. In this script, links to the kernel header files are created in the include/ directory of the toolchain. That's not very elegant. Normally, the C-compiler should try and find the kernel headers in e.g., /usr/src/linux/include, but that's where the native kernel sources for your build platform reside. Your build platform is not necessarily the same as your target platform (most likely not). The method presented here works, but needs some editing in the future.

#! /bin/sh

# how to install gcc stage 2 using this script:
# 
# Create the ${BUILDROOT} directory, put this script (install_gcc_stage2.sh) 
# in it.
# In ${BUILDROOT}, create a directory ./src and put the gcc tarball in it.

# go up one directory and run this script. 

TARGET=arm-SamyGO-linux-gnueabi
BUILDROOT=/tmp/arm-tools
PREFIX=/usr/local                            # change to your liking
SYSROOT=${BUILDROOT}/sysroot
GCC=gcc-4.2.0-4.0.9 

export ARCH=arm
export CROSS_COMPILE=${TARGET}-
export PATH=$PATH:${PREFIX}/bin
 
cd ${BUILDROOT}/src

# remove links to kernel headers if they exist:
rm -f  ${PREFIX}/${TARGET}/include/linux
rm -f  ${PREFIX}/${TARGET}/include/asm
rm -f  ${PREFIX}/${TARGET}/include/asm-generic

# create symlinks to kernel headers:

ln -s ${SYSROOT}/usr/include/linux ${PREFIX}/${TARGET}/include/linux
ln -s ${SYSROOT}/usr/include/asm ${PREFIX}/${TARGET}/include/asm
ln -s ${SYSROOT}/usr/include/asm-generic ${PREFIX}/${TARGET}/include/asm-generic

# make builddir: 

mkdir -p BUILD/${GCC}-stage2

cd BUILD/${GCC}-stage2

CC=gcc ../../${GCC}/configure --target=${TARGET} --prefix=${PREFIX} \
   --enable-languages=c,c++ --enable-threads --enable-shared \
   --disable-nls --enable- __cxa_atexit --enable-long-long \
   --enable-c99 --with-cpu=arm1136jf-s --with-fpu=vfp

make
make install

When you look in /usr/local/bin now, you should see the cross-compilers for C and C++ for arm-SamyGO-linux-gnueabi.

Building the toolchain on Windows (Cygwin)

The toolchain build on Windows/Cygwin proceeds in the same way as the build on Linux. If you have the choice between Windows and Linux, go for Linux. Shell script execution is orders of magnitude faster on Linux, and the installation procedure is carried out through _many_ shell scripts. Don't say that you haven't been warned. To be able to build the toolchain you need to have Cygwin installed, see the Cygwin website [4] for details on installation. At the time of writing, the Cygwin stable release version was 1.5.25-15, and that is the version used for the build here, on Windows XP Home Edition. Cygwin creates a Unix-style environment on the Windows platform, and comes with pretty much the same development environment as GNU/Linux. You will need this GNU/Linux-style environment to be able to build your toolchain. The native Windows environment (visual studio and the likes) will NOT work.

Cygwin installation notes

When installing Cygwin, select "Unix-style linefeeds" (the default) when prompted. Otherwise you will find yourself editing ALL installation scripts, not just the handful presented here. Apart from the default (minimal) installation, which you shouldn't touch, you should have at least the following packages installed:

(Untick the "Hide obsolete packages" box in the "Select Packages" installer window to view everything, the packages in the following list may have been selected already for default installation)

  • autoconf
  • automake
  • bash
  • binutils
  • bison
  • byacc
  • bzip2
  • diffutils
  • flex
  • gawk
  • gcc
  • gcc-core
  • gcc-g++
  • gcc4
  • gcc4-core
  • gcc4-g++
  • gettext
  • gzip
  • libgcc1
  • libiconv
  • m4
  • make
  • patch
  • patchutils
  • texinfo
  • unzip
  • vim
  • zip

It is not clear whether you actually need all of these, but most packages take little disk space and little time to install. Running into errors because of lacking packages will take more time.

With Cygwin properly installed, the same 6 steps as described in the Linux installation section need to be taken. Download the SamyGO patches and scripts [5] and edit these.

Editing of installation scripts

In the following, only differences with respect to the Linux installation will be described. Start Cygwin by double-clicking on its Desktop icon. You will get a window in which the standard Cygwin shell runs (ash, if I'm not mistaken). At the prompt, type the following command to make the BUILDROOT directory (take your pick with respect to the name, this is what I've been using):

mkdir -p ./tmp/arm-tools

Copy the Samsung sources (32B650.zip) and the SamyGO patches and scripts to this directory. Windows explorer will do. Unpack the patches:

cd ./tmp/arm-tools
tar -zxvf SamyGO-toolchain-install_fc11.tgz

Edit the environment variable BUILDROOT in the installation scripts (all just installed files that end with .sh). By default, Cygwin is installed in C:/cygwin. All paths used in Cygwin are relative to this installation path, but for some reason the BUILDROOT environment variable needs to point to the full path. Edit the line BUILDROOT in all installation scripts to make it point to the full path of your build (be sure to use the forward slashes!!):

...
BUILDROOT=c:/cygwin/home/username/tmp/arm-tools         # edit according to your needs. 
...

When using notepad.exe or another DOS-style editor, revert the scripts, after saving, to unix-style linefeeds with the command:

dos2unix ./install_sources.sh

Do this for all scripts you edit, BEFORE execution. Failing to do so may render errors like:

$'\r': command not found

This error type occurs when shell scripts with DOS rather than Unix-style linefeeds are being processed. When using the vi editor (in the Cygwin shell window) you don't have this problem.

Installation of the sources and kernel headers

Execute ./install_sources.sh and ./install_kernel_src.sh after one another by typing their names with a leading ./ and their extension .sh. Unlike Windows, Unix does not guess filename extensions. They are considered to be part of the filename, nothing else. This step installs the sources and kernel headers in the right place.

Building of binutils and gcc, stage 1

Edit ./mkbinutils.sh and ./install_gcc_stage1.sh. In both scripts, add a line to make the environment variable CC point to gcc-4:

...
export ARCH=arm
export CROSS_COMPILE=${TARGET}-
export PATH=$PATH:${PREFIX}/bin
export CC=/usr/bin/gcc-4
...

and build the binutils with ./mkbinutils.sh. After successful completion, build gcc stage 1 with ./install_gcc_stage1.sh.


To be continued soon ...

Well, building glibc on Cygwin proves to be a bit harder than I thought. For now only statically linked stuff is possible. Will get back here as soon as it's working properly, sorry, folks ...