Difference between revisions of "Setting up a cross-compilation toolchain"
Line 357: | Line 357: | ||
In the following, only differences with respect to the Linux installation will be described. | In the following, only differences with respect to the Linux installation will be described. | ||
− | + | Edit the environment variable BUILDROOT in the installation scripts. | |
− | By default, cygwin is installed in C:/cygwin. All paths used in Cygwin are relative to this installation 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!!) | + | 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. | BUILDROOT=c:/cygwin/home/username/tmp/arm-tools # edit according to your needs. |
Revision as of 19:52, 25 October 2009
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 toolchain, 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]). For more info, errors you may encounter, support for other Samsung toolchains, please refer to the forum, or better still, participate.
Contents
Toolchains 101
A toolchain 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 toolchain 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 toolchain 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. Our Sammys are ARM-based machines. To build executables for a Samsung TV on an x86-based machine, you will need a toolchain 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 toolchain. This wiki page deals with the installation of the toolchain provided by Samsung, on an x86, Linux or Windows (Cygwin) platform.
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.
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
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
- 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.
Edit the environment variable BUILDROOT in the installation scripts. 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.
Installation of the sources and kernel headers
Execute ./install_sources.sh and ./install_kernel_src.sh after one another. This installs the sources and kernel headers in the right place.
Building of binutils
Edit ./mkbinutils.sh. Add a line to make the environment variable CC to 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.
To be continued soon ...