ZipIt Arm Toolchain

Jump to: navigation, search

Submitted by subversion on Wed, 2005-09-14 13:32. from

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:

  • 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 LittleChips.
  • 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

LittleChips 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 LittleChips. 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)

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.

  • From your home directory, create a new directory for all your tools and source. I use 'armlinux'
  • Download to your newly created directory.
  • Extract crosstools with tar -zxf crosstool-0.28-rc37.tar.gz
  • cd crosstool-0.28-rc37

Using your favorite editor, edit - I use the same gcc / binutils and glibc that was used to create the root filesystem by LittleChips, 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.

set -ex


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

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

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.


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


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 / and place them in your TARBALLS_DIR which was set up above in 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.

./ in your crosstools directory:

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

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 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 PATH=$PATH:$GCC_ARM_HOME/bin:$GCC_ARM_HOME/lib/gcc-lib/arm-linux/2.95.3

I saved it as and made it executable by doing chmod +x 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 LittleChips 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 

for i in *; do 
   if [ $i !=  ${i/arm-linux-/} ]; then
        ln -s $i ${i/arm-linux-/} 

ln -s arm-linux-gcc cc

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

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**     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


# Move these out of the way as they are supplied by the kernel.
# The kernel header files distributed in the toolchain are quite obsolete
# 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

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

# 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.)

#define KDriveXServer              YES
#define TinyXServer                YES
#define CrossCompiling             YES
#define TouchScreen                YES
#undef  BuildRandR
#define BuildRandR                 YES
#define BuildXInputLib             YES
#define ProjectRoot                /usr/X11R6
#define Freetype2Dir               $(TOP)/extras/freetype2
#define Freetype2LibDir            $(TOP)/exports/lib
#define BuildXTrueType             YES
#define BuildScreenSaverExt        YES
#define BuildScreenSaverLibrary    YES
#define SharedLibXss               YES
#define ServerXdmcpDefines
#define XfbdevServer               YES
#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>