ZipIt Arm Toolchain

Submitted by subversion on Wed, 2005-09-14 13:32. from http://www.nerdnet.com/node/1 This is a work in progress. It documents the steps I've taken to get a cross compiler and Tiny-X working for the LN2410SBC/TFT (Arm 920T / Samsung S3C2410 Chip) All the steps below show the tools I used and the steps I took to get my system working. Your mileage may vary. I am -NOT- responsible for any damage you do to your own hardware. If you are new to Linux and particulary Embedded Linux, I recommend reading Building Embedded Linux Systems

I had hoped to get a development environment working on my Apple Powerbook running OS X. As of this writing I haven't been entirely successful, but I am still working on it. I have installed the GNUARM Toolchain for Mac OS X on my powerbook, but haven't been able to get a full kernel compile out of it. Small binaries seem to build fine on it. If I figure it out, I'll post the information here.

Things you'll need:

Little Chips ships their LN2410SBC with a working 2.4.18 Linux kernel and root filesystem prebuilt and patched. You can purchase this unit from a couple other vendors but I will recommend Little Chips. They have been very good at offering support for their product. You are certainly welcome to rebuild your kernel or root filesystem, but I will not be covering that here (yet)
 * A working Linux system. I built my toolchain on PC x86 based Linux server. I tried Cygwin but had a lot of problems with it.
 * An ARM toolchain with gcc / glibc / binutils - I recommend Dan Kegel's crosstool
 * An ARM based development system. I use the LN2410SBC/TFT Combo development system. I purchased mine from Little Chips.
 * U-Boot bootloader installed and working on your target system. My board came with it preinstalled, but if you dont have it, its highly recommended and available here.
 * A JTAG Emulator Cable/ICE - You can build your own or buy one. I opted to purchase one with a 3rd party flash programmer. The JTAG header on the LN2410SBC is 14 pin, make sure your cable matches. If you buy a 3rd party system, make sure it supports 14 pin / ARM920T core (Samsung S3C2410 CPU) and the flash installed on your target board. Check your documentation You can render your system useless if not careful. I purchased the following from uCpros
 * Embest ARM JTAG Debugger & Programmer, 25kByte/sec
 * Embest JTAG FLASH Programming Software

Building a working ARM toolchain:
Crosstool is a great way to automate the making of a cross-compiler toolchain. Here, I describe how to set it up with the following:


 * gcc-2.95.3
 * glibc-2.2.3
 * glibc-linuxthreads-2.2.3
 * binutils-2.10
 * linux-2.4.18 (see build instructions below after the toolchain has successfully compiled)

I chose these versions because the board I had already came with a root filesystem built on these versions. If I decide to recreate the filesystem manually (which I plan to do eventually) I will update my toolchain and my kernel. I could build a 2.6.x kernel now but as of yet it hasnt been tested on the board I've received (to the best of my knowledge.) I may test it myself in the near future and I will post an update here.

Using your favorite editor, edit demo-arm.sh - I use the same gcc / binutils and glibc that was used to create the root filesystem by Little Chips, so there won't be any broken lib dependencies. You can add --testlinux after --notest to also build the Linux kernel after the toolchain has compiled, but I recommend against it. It often fails for me this way because the argument passed to the compiler is too long when configuring / building the new kernel. I'll go over the kernel later in this document.
 * From your home directory, create a new directory for all your tools and source. I use 'armlinux'
 * Download http://kegel.com/crosstool/crosstool-0.28-rc37.tar.gz to your newly created directory.
 * Extract crosstools with tar -zxf crosstool-0.28-rc37.tar.gz
 * cd crosstool-0.28-rc37

set -ex TARBALLS_DIR=$HOME/armlinux/downloads RESULT_TOP=$HOME/arm-linux
 * 1) !/bin/sh

export TARBALLS_DIR RESULT_TOP GCC_LANGUAGES="c,c++" export GCC_LANGUAGES

mkdir -p $RESULT_TOP
 * 1) Really, you should do the mkdir before running this,
 * 2) and chown /opt/crosstool to yourself so you don't need to run as root.

eval `cat arm.dat gcc-2.95.3-glibc-2.2.3.dat` sh all.sh --notest echo Done.
 * 1) Build the toolchain.  Takes a couple hours and a couple gigabytes.

You will also need to edit arm.dat - mine is shown below. I took out a lot of the extra info in the target line to help shorten the paths used when running configures / makes etc.

KERNELCONFIG=`pwd`/arm.config TARGET=arm-linux TARGET_CFLAGS="-O"

Next, edit gcc-2.95.3-glibc-2.2.2.dat and make sure you save it as gcc-2.95.3-glibc-2.2.3.dat

BINUTILS_DIR=binutils-2.10 GCC_DIR=gcc-2.95.3 GLIBC_DIR=glibc-2.2.3 LINUX_DIR=linux-2.4.18 GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.2.3

You should now be ready to build the toolchain. This takes considerable disk space and time, depending on your host system. Crosstool will download everything it needs bases on the configuration files we've given it above. Make sure you have a working Internet connection. If not, have someone download the files you need from gnu.org / kernel.org and place them in your TARBALLS_DIR which was set up above in demo-arm.sh. Do not extract them, crosstool will do this for you as it needs them. DO NOT BUILD CROSSTOOLS AS ROOT If you haven't configured it properly you run the risk of overwriting your system compiler and glibc, which would be disasterous.

./demo-arm.sh in your crosstools directory:

[jjenkins@gandalf crosstool-0.28-rc37]$ ./demo-arm.sh

You should now see crosstool downloading, extracting, patching and building what it needs for the toolchain. If for some reason it fails, go back over your configuration files carefully. There is a crosstool how-to on Dan Kegel's website (see above.)

If your crosstool builds successfully, it will create the toolchain directory structure under RESULT_TOP that you set up in arm-demo.sh Everything you need to cross-compile for ARM will be installed into this directory. You shouldn't need to change anything in this structure, and doing so will easily break the toolchain.

Before you can use the cross-compiler, its helpful to set up some environment variables (this will also depend on which shell you are using.) As I am using bash, I have created the following shell script for this:

export GCC_ARM_HOME=$HOME/arm-linux/arm-linux/gcc-2.95.3-glibc-2.2.3 export GCC_EXEC_PREFIX=$GCC_ARM_HOME/lib/gcc-lib/ export LD_LIBRARY_PATH=$GCC_ARM_HOME/lib export PATH=$PATH:$GCC_ARM_HOME/bin:$GCC_ARM_HOME/lib/gcc-lib/arm-linux/2.95.3
 * 1) !/bin/sh

I saved it as armenv.sh and made it executable by doing chmod +x armenv.sh You should now be ready to test your cross-compiler. I recommend building a full linux kernel for this. For my board, I do the following (detailed also on Little Chips website) The following steps and patches may not be needed depending on what hardware you are using. Check with your manufacturer and check the kernel configurtion. For my board, they are needed.


 * tar -zxf linux-2.4.18.tar.gz
 * gzip -dc patch-2.4.18-rmk7.gz | (cd linux;patch -p1)
 * gzip -dc patch-2.4.18-rmk7-swl8.gz | (cd linux;patch -p1)
 * gzip -dc patch-2.4.18-rmk7-swl8-cy2.gz | patch -p0
 * cd linux
 * make oldconfig
 * make dep
 * make zImage

This should get the kernel compile going. If your toolchain and environment are configured correctly, in a few minutes you should have a shiny new ARM kernel for your target hardware. It can be found in /arch/arm/boot and is called zImage. The kernel is now ready for uploading to your target. This varies greatly based on your hardware and your bootloader and I will not cover it here.

Building Tiny-X for an ARM-based embedded computer. (-in progress-)
If your target system has an LCD or other display, you can build a small version of the X Windowing system server to run on your device. To get a useful display output from the LN2410SBC, you will need to use the linux's frame buffer. The Tiny-X server has support for the linux frame buffer.

X will not build properly with the toolchain until you create some symbolic links, as follows:

[jjenkins@gandalf ~]$ cd $GCC_ARM_HOME/bin

In this directory, create this simple shell script, chmod +x and execute it.

[jjenkins@gandalf bin]$ vi ln.sh

for i in *; do   if [ $i !=  ${i/arm-linux-/} ]; then ln -s $i ${i/arm-linux-/} fi done
 * 1) !/bin/sh

ln -s arm-linux-gcc cc

[jjenkins@gandalf bin]$ chmod +x ln.sh; ./ln.sh

If done correctly, your directory should now look like this (note the newly created symlinks)

[jjenkins@gandalf bin]$ ls addr2line@           arm-linux-c++filt*  arm-linux-objcopy*   arm-linux-strings*     c++filt@  ld@        ranlib@ ar@                  arm-linux-g++*      arm-linux-objdump*   arm-linux-strip*       cpp*      ln.sh*     readelf@ arm-linux-addr2line* arm-linux-gasp*     arm-linux-protoize*  arm-linux-unprotoize*  g++@      nm@        size@ arm-linux-ar*        arm-linux-gcc*      arm-linux-ranlib*    as@                    gasp@     objcopy@   strings@ arm-linux-as*        arm-linux-ld*       arm-linux-readelf*   c++@                   gcc@      objdump@   strip@ arm-linux-c++*       arm-linux-nm*       arm-linux-size*      cc@                    gcov*     protoize@  unprotoize@ [jjenkins@gandalf bin]$

Next, its a good idea to use your kernel's headers instead of those provided with the cross-compiler tool chain. If you built the kernel as above, you can do the following to symlink its header files for use in your Tiny X (and other) build. The directories are based on the directory structure I have been using throughout this entire document. Set it executable with chmod +x and then run it from the command line. I created it in $HOME/armlinux


 * 1) !/bin/sh


 * 1) Move these out of the way as they are supplied by the kernel.
 * 2) The kernel header files distributed in the toolchain are quite obsolete
 * 3) and you cannot successfully build against them.

if [ -d $GCC_ARM_HOME/include/linux && ! -d $GCC_ARM_HOME/include/linux.old ]; then mv $GCC_ARM_HOME/include/linux $GCC_ARM_HOME/include/linux.old fi

if [ -d $GCC_ARM_HOME/include/asm && ! -d $GCC_ARM_HOME/include/asm.old ]; then mv $GCC_ARM_HOME/include/asm $GCC_ARM_HOME/include/asm.old fi


 * 1) now create the links

ln -s $HOME/armlinux/linux/include/linux $GCC_ARM_HOME/include/linux ln -s $HOME/armlinux/linux/include/asm $GCC_ARM_HOME/include/asm

To build Tiny X, I recommend checking out X from cvs sources at Xfree CVS. Create a directory for your X CVS tree (I used $HOME/armlinux/xfree) Follow the Xfree86 website instructions for accessing CVS and then do a checkout with: cvs checkout -A xc - BE WARNED: The XFree86 source tree is LARGE. It can easily take up to 500MB of disk space, before you've even started compiling it. Luckily, you won't end up sticking 98% of it on your target device.

After the CVS checkout, cd into the newly created xc directory. I recommend reading the BUILD file for more information on the X build process. From here, go into the config/cf directory. You will need to create a host.def file based on your target. For my system, my host.def file looks like this (I am still working on it, so it may or may not work (I haven't tested it yet on the target.)


 * 1) define KDriveXServer             YES
 * 2) define TinyXServer               YES
 * 3) define CrossCompiling            YES
 * 4) define TouchScreen               YES
 * 5) undef BuildRandR
 * 6) define BuildRandR                YES
 * 7) define BuildXInputLib            YES
 * 8) define ProjectRoot               /usr/X11R6
 * 9) define Freetype2Dir              $(TOP)/extras/freetype2
 * 10) define Freetype2LibDir           $(TOP)/exports/lib
 * 11) define BuildXTrueType            YES
 * 12) define BuildScreenSaverExt       YES
 * 13) define BuildScreenSaverLibrary   YES
 * 14) define SharedLibXss              YES
 * 15) define ServerXdmcpDefines
 * 16) define XfbdevServer              YES
 * 17) define HasZlib                   NO

You will also need to customize cross.def depending on your target and host environment. To see mine, click here. These files define the way the cross-compiler works and where it can find its binaries and libs.

You should be ready to compile X, so change back to the xc directory and start the build proccess with:

[jjenkins@gandalf xc]$ make World CROSSCOMPILEDIR=$GCC_ARM_HOME/bin

Currently I am having build problems with X (most of it is building fine, however.) My current problem has something to do with xkbfile(?) I am working on it :)

If you are also building a root filesystem for your target, you can install the new Tiny X to your root filesystem directory.

make -k install DESTDIR=Target Root File System Dir