Assabet 1.01

Node: Top, Next: , Previous: (dir), Up: (dir)

This file is an ad-interim document to tell how to install a linux system (specifically, the EtLinux distribution on the assabet development platform

Node: Compiling a bootloader, Next: , Previous: Top, Up: Top

Compiling a bootloader

The boot loader of choice is redboot. A pre-compiled image of the loader can be found at, but you can also follow the instructions contained in this chapter and build it from the sources.

Redboot can be built by properly configuring and compiling the ecos operating system (ecos stands for embedded configurable operating system).

Node: Preparing the host, Next: , Previous: Compiling a bootloader, Up: Compiling a bootloader

Preparing the host

First of all you need to download ecos sources and tools, as well as install a cross-compiler for the ARM target.

Source code for Ecos and detailed instructions are available from <>, but the basic steps are included here for your reference.

To download source code, either use the CVS tree for Ecos, or get the latest snapshot from <> if your firewall prevents use of CVS. The corporate attitude stating that the Internet is nothing but web pages is exceedingly stupid and short-minded, but I know it's pretty pervasive, so most companies deny CVS access to developers.

In the following I'll assume you installed Ecos sources in /opt/ecos, and that development is hosted on an IA32 GNU/Linux system.

To compile the host tools, you need to follow the instructions in /opt/ecos/host/README. This is a real-world example of compilation for the tools:

        % cd /opt/ecos/host
        % mkdir build
        % cd build
        % ../configure --prefix=/opt/ecos-tools \
                --with-tcl=/usr --with-tcl-version=8.2
        ... configuration takes 8.5 kbogoMips-second and prints 149 lines ...
        % make
        ... compilation takes 125 kbogoMips-second and prints 81 lines ...
        % make install
        ... installation takes .5 kbogoMips-second and prints 75 lines ...

The configure line above declares where to install the tools (in this case /opt/ecos-tools/bin, /opt/ecos-tools/lib, etc.). It also declares that files related to the Tcl language are installed under /usr (/usr/include, /usr/bin, etc.), and it declares that the version of Tcl to look for is 8.2. You need to state the version only if Tcl-specific files are installed in directories named after the version (like /usr/include/tcl8.2) as opposed to generic directories (such as /usr/include).

In order to compile the boot loader, you'll need a cross-compiler installed on your host. If you have the MontaVista Hard-Hat-Linux CD set, you can just install their own binaries for the cross-compiler; otherwise you'll have to get it from somewhere else or build it by yourself, the latter is described in Building gcc.

If you have the MontaVista CDROM, go to install/assabet in their first CDROM and install the following packages or equivalent ones:


This will create binary files called sa110_le-gcc, sa110_le-ld and so on, all in the directory /opt/hardhat/devkit/arm/sa110_le/bin.

Node: Building gcc, Next: , Previous: Preparing the host, Up: Compiling a bootloader

Building gcc

If you have no cross-compiler preinstalled or want to roll your own, this is how to do that. I'll assume everything associated to arm cross-compiling will be installed to /opt/local. If you choose a different destination tree please replace any occurrence of /opt/local in all following examples.

First of all, you'll need to get hold of source code for both gcc and the binutils, that are required to be able to run the compiler. I used the following packages:


The source tar file for gcc can be retrieved from <>, that points you to a mirror site, to be selected from <>. Otherwise, use <> (or mirrors).

The binutils can be retrieved, for example, from <> (the <ftp://ftp.gnu.og/binutils/> repository only includes major versions).

After uncompressing the binutils package, create a build directory and run the configuration script with appropriate parameters, then make and make install as shown below. In this case I chose to create the build directory on the same level as the source directory, not inside it like I did for ecos tools.

        % mkdir binutils-build
        % cd binutils-build
        % ../binutils- \
                  --target=arm-elf --prefix=/opt/local
        ... configuration takes 76 kbogoMips-second and prints 830 lines ...
        % make
        ... compilation takes 220 kbogoMips-second and prints 692 lines ...
        % make install
        ... installation takes 22 kbogoMips-second and prints 492 lines ...

After this step you'll have slightly less than 19MB installed in /opt/local including documentation. This is in addition to 38MB in the current directory and 73MB in the source directory.

To build the compiler the steps are similar. Make a build directory, configure, compile, install. However, you first need to add /opt/local/bin to your path, so the cross-linker and cross-assembler can be found.

This is how I configured and compiled gcc:

        % export PATH="/opt/local/bin:$PATH"
        % mkdir gcc-build
        % cd gcc-build
        % ../gcc-2.95.2/configure --target=arm-elf --prefix=/opt/local \
                  --with-gnu-as --with-gnu-ld
        ... configuration takes 46 kbogoMips-second and prints 364 lines ...
        % make all-gcc LANGUAGES="C C++"
        ... compilation takes 360 kbogoMips-second and prints 781 lines ...
        % make install-gcc LANGUAGES="C C++"
        ... installation takes 6 kbogoMips-second and prints 299 lines ...

After installation you'll have 31MB in /opt/local (including the binutils installed earlier, as well as gcc documentation).

More information (for example the meaning of LANGUAGES=) is available inside the source trees, this section is only meant as a quick-start tutorial. I run the command shown on a Debian GNU/Linux system running Woody on a 686 CPU, lots of memory and an IDE hard disk.

Node: Actual compilation, Previous: Building gcc, Up: Compiling a bootloader

Actual compilation

Make sure that the environment variable ECOS_REPOSITORY is properly set. It must point to the directory containing the ecos packages. For example: if the ecos tree is in /opt/ecos, then

             export ECOS_REPOSITORY=/opt/ecos/packages

Make a fresh directory (for example /opt/assabet-redboot). cd to the new directory and configure ecos for the assabet target and the redboot template:

             % mkdir /opt/assabet-redboot
             % cd /opt/assabet-redboot
             % /opt/ecos-tools/bin/ecosconfig new assabet redboot
             ... this takes 1.5 kbogoMips-second and prints 7 lines ...

The command is very fast; after this step you should have just one new file (named ecos.ecc) in /opt/assabet-redboot. This is the ecos configuration file.

Now the ecos configuration tool should be told that the sources must be compiled and linked for ROM startup. This means that the redboot binaries will be stored in flash memory and that redboot will take control of the board at reset. To do this, type :

             % /opt/ecos-tools/bin/ecosconfig import \
             ... this takes 2 kbogoMips-second and prints nothing ...

(note that the pathname above must be a single word, it has been split only for page layout)

Now the build tree can be generated by typing:

             % /opt/ecos-tools/bin/ecosconfig tree
             ... this takes 4 kbogoMips-second and prints nothing ...

At this time a complete build tree (including a makefile) should be present in /opt/assabet-redboot.

Now the build process can be started. Just run make:

             % make
             ... this takes 45 kbogoMips-second and prints 1177 lines ...

Note that the default prefix for the cross-compiler is arm-elf. If this isn't correct for your environment, you should pass COMMAND_PREFIX on the command line of make. For example:

     	% make COMMAND_PREFIX=/opt/hardhat/devkit/arm/sa110_le/bin/sa110_le-

or, if you chose to add /opt/hardhat/devkit/arm/sa110_le/bin to your path, use:

     	make COMMAND_PREFIX=sa110_le-

This step takes more or less 30 kbogoMips-second. It should go straight to the end with no errors and produce the binary and S-RECORD files in /opt/assabet-redboot/install/bin

Warning: You should compile redboot with the compiler/binutils you built in Building gcc, as the Hard-Hat pair has problems in the last step building the binary; I didn't identify what exactly the problem is, after identifying an ELF section that triggers the problem.

Node: Flashing a boot loader, Next: , Previous: Compiling a bootloader, Up: Top

Flashing a boot loader

To write the image of the boot loader to flash memory, you'll need the Jflash utility, ported to compiled and run on Linux-i386 by Nicolas Pitre (and found in the same place as the boot loader pre/compiled binaries). I had to apply a small patch, though, already part of the included sources. To recompile the tool I pasted the line in the Readme.Linux (copied here as Jflash-linux-readme):

             gcc -O2 -s -o Jflash-linux Jflash.cpp

The Jflash tool writes on flash using the JTAG interface. The command I used is:

     	./Jflash-linux ../redboot-assabet/redboot.bin

When the development platform resets, the following prompt appears on the serial port (configured for 38400,8N1):

     RedBoot(tm) bootstrap and debug environment - built 14:07, Jun 2 2001
     Platform: Assabet development system (StrongARM 1110)
     Copyright (C) 2000, 2001, Red Hat, Inc.
     RAM: 0x00000000-0x02000000, 0x00011658-0x01fb0000 available

Node: Compiling a kernel, Next: , Previous: Flashing a boot loader, Up: Top

Compiling a kernel

I downloaded patch-2.4.18-rmk2.gz and applied it against Linux-2.4.18 vanilla (i.e., from or mirrors). The patch is available from i didn't try later patches, but i expect them to have no problem at all (currently the latest patch is patch-2.4.18-rmk6).

After applying the patch, i followed the instructions found in documentation/arm/sa1100/Assabet (within the kernel source). The file is the main source of information for compiling and booting an Assabet platform.

Since the kernel offers more configuration options than those preselected in the default assabet_config, you should reply no to those questions, but such reply is the default, so pressing return is enough. The suggested procedure, then, is the following if you are compiling natively (for compilation times etc. see the next example below):

        % make assabet_config
        % yes "" | make oldconfig
        % make dep
        % make zImage

Most likely you aren't compiling ARM code natively, so you'll need to run your cross-compiler (see Preparing the host and Building gcc. To this aim you have to specify the ARCH and CROSS_COMPILE variables for make to use. The variables can either be set in Makefile or passed on the command line. Since I'm reluctant to edit file (as edited files are known to reject further patches) I'd better use the command line. As for CROSS_COMPILE, you can use the simple command prefix (i.e., arm-elf- or sa110_le- or whatever) only if your PATH includes the directory where the compiler is found; otherwise, you can use the whole pathname (i.e., "/opt/local/bin/arm-elf-" or equivalent) in CROSS_COMPILE.

Here is an example of how to run the commands:

       % make assabet_config ARCH=arm
       % yes "" | make oldconfig ARCH=arm
       ... this takes 5 kbogoMips-second and prints 651 lines ...
       % make dep ARCH=arm CROSS_COMPILE=sa110_le-
       ... this takes 140 kbogoMips-second and prints 899 lines ...
       % make zImage ARCH=arm CROSS_COMPILE=sa110_le-
       ... this takes 400 kbogoMips-second and prints 874 lines ...

If you need to restart compilation from scratch because something has been messed up, you can always use "make mrproper" to restore the original clean source tree (note that mrproper is not a standard target for make, it's just used by Linus Torvalds after the name of a Finnish soap).

After you ran the following commands, the bootable image is found in arch/arm/boot/zImage.

Node: Loading a kernel, Next: , Previous: Compiling a kernel, Up: Top

Loading a kernel

The best way to load a kernel to your Assabet platform is using TFTP. To do so, you need to plug the Compact-flash Ethernet card in the Assabet slot and set up a workstation with BOOTP or DHCP installed. I added the following stanza to my /etd/dhcpd.conf:

        host muscorin {
          hardware ethernet 00:c0:1b:00:9c:8a;
          server-name "";

To make the kernel available to host muscorin, I placed it in my /boot/tftpboot directory, whence every host can read files. I called it zImage.arm.

Basic setup of dhcpd and tftpd is not describe here as it is considered common knowledge (and is well documented elsewhere).

With these blocks in place, you'll see a boot message like the following (printed by RedBoot):

        Socket Communications Inc: CF+ LPE Revision E 08/04/99
        IP:, Default server:

The command to type is then:

        load -m TFTP zImage.arm -r -b 0x100000

If you want, following the instructions set forth in the Assabet file, you can write the kernel to flash to be able to re-load it later even without a network connection. The following screenshot shows loading and flashing, complete with boot loader messages:

        RedBoot> load -m TFTP zImage.arm -r -b 0x100000
        Raw file loaded 0x00100000-0x001b18ac
        RedBoot> fis create "Linux kernel" -b 0x100000 -l 0xc0000
        ... Erase from 0x500c0000-0x50180000: ...
        ... Program from 0x00100000-0x001c0000 at 0x500c0000: ...
        ... Unlock from 0x51fc0000-0x52000000: .
        ... Erase from 0x51fc0000-0x52000000: .
        ... Program from 0x01fb0000-0x01ff0000 at 0x51fc0000: .
        ... Lock from 0x51fc0000-0x52000000: .

To boot the kernel, after loading, you'll need to invoke

        exec -b 0x100000 -l 0xc0000 -c "root=/dev/ram" -r 0x800000

Since there is no filesystem, yet, the kernel will then panic when trying to mount the root filesystem. This is the log of my session:

     Uncompressing Linux........... done, booting the kernel.
     Linux version 2.4.18-rmk2 (rubini@armadio)
     (gcc version 2.95.2 20000220 (Debian
     GNU/Linux)) #3 Fri May 31 11:05:40 UTC 2002
     Processor: Intel StrongARM-1110 revision 8
     Architecture: Intel-Assabet
     Warning: bad configuration page, trying to continue
     On node 0 totalpages: 8192
     zone(0): 8192 pages.
     zone(1): 0 pages.
     zone(2): 0 pages.
     Calibrating delay loop... 147.04 BogoMIPS
     Memory: 32MB = 32MB total
     Memory: 27436KB available (1347K code, 284K data, 72K init)
     ttySA0 at MEM 0x80010000 (irq = 15) is a SA1100
     ttySA2 at MEM 0x80050000 (irq = 17) is a SA1100
     SA-1100 PCMCIA (CS release 3.1.22)
     Kernel panic: VFS: Unable to mount root fs on 01:00

Node: Loading a filesystem, Next: , Previous: Loading a kernel, Up: Top

Loading a filesystem

To successfully boot the CPU you'll need a root filesystem. By default the kernel mounts whatever it finds at address 0x800000; and you can read a file via TFTP and place it here. The file fs/8M.gz is a 8MB ext2 filesystem with a more complete version of EtLinux, including bash and busybox, in a filesystem 8MB large, although only slightly more than 3MB are used:

        % df
         bsize blocks   used  avail     inum  iused  ifree   filename
          1024   7931   3155   4367     2048    348   1700      255

You can look in the filesystem by mounting it using the loop device.

         # zcat 8M.gz > 8M.ext2
         # mount -o loop 8M.ext2 /mnt
         # df /mnt
         Filesystem           1k-blocks      Used Available Use% Mounted on
                                   7931      3147      4375  42% /mnt
         # ls /mnt
         bin/   dev/  html/  local        mnt/   sbin/  usr
         boot/  etc/  lib/   lost+found/  proc/  tmp/   var/

To load it to the Assabet, use "load 8M.gz -r -b 0x800000". The command to execute the kernel is the same as above. Thus, the following three commands are all that's needed to boot EtLinux on the assabet (provided you have the everything in place with DHCP and TFTP):

        load zImage.arm -r -b 0x100000
        load 8M.gz  -r -b 0x800000
        exec -b 0x100000 -l 0xc0000 -c "root=/dev/ram" -r 0x800000

This is the log of my boot process:

     RedBoot>    load zImage.arm -r -b 0x100000
     Raw file loaded 0x00100000-0x001b26a4, assumed entry at 0x00100000
     RedBoot>    load 8M.gz  -r -b 0x800000
     Raw file loaded 0x00800000-0x008cff40, assumed entry at 0x00800000
     RedBoot> exec -b 0x100000 -l 0xc0000 -c "root=/dev/ram" -r 0x800000
     Uncompressing Linux.............. done, booting the kernel.
     Linux version 2.4.18-rmk6 (rubini@decio) [...]
     RAMDISK: Compressed image found at block 0
     Freeing initrd memory: 4096K
     VFS: Mounted root (ext2 filesystem).
     Freeing init memory: 72K
     Starting init process ...
     Remounting /
     Mounting /proc
     Removing /tmp/* and /var/run/*
     Configuring loopback interface
     Configuring network interfaces
     Application: README
     Application: httpd
     Application: telnetd

In order to load the 8M filesystem, an different kernel command line is needed (note that the third line below has been split for the documentation, but it must be typed as a single long line):

        load zImage.arm -r -b 0x100000
        load 8M.gz  -r -b 0x800000
        exec -b 0x100000 -l 0xc0000
                       -c "root=/dev/ram ramdisk_size=8192k" -r 0x800000

The "%" prompt is the console-interaction process running an EtTcl shell. You can run interactive commands on this shell; please refer to the Tcl and EtTcl manuals for details:

     % free
     total:    used:    free:  shared: buffers:  cached:
     Mem:  31313920  5664768 25649152        0    49152  4227072
     % ps
     User  PPid  Pid St Size   RSS  Name
     0     0     1 S  1348   744 init
     0     1     2 S     0     0 keventd
     0     0     3 S     0     0 ksoftirqd_CPU0
     0     0     4 S     0     0 kswapd
     0     0     5 S     0     0 bdflush
     0     0     6 S     0     0 kupdated
     0     1     7 S     0     0 mtdblockd
     0     1     8 R  1364   764 console-interaction
     0     1    10 S  1364   748 httpd
     0     1    11 S  1356   740 telnetd
     % df
     bsize blocks   used  avail     inum  iused  ifree   filename
     1024   3019   2163    703      384    210    174      255
     % ls /*
     d  755  2      0     0    12288 /lost+found
     d  755  2      0     0     1024 /bin
     d  775  2      0     0     1024 /boot
     d  775  2      0     0     2048 /dev
     d  775  4      0     0     1024 /etc
     d  775  2      0     0     1024 /html
     d  775  3      0     0     1024 /lib
     l  777  1      0     0        1 /local -> .
     d  775  2      0     0     1024 /mnt
     d  555 21      0     0        0 /proc
     d  755  2      0     0     1024 /sbin
     d  775  2      0     0     1024 /tmp
     l  777  1      0     0        1 /usr -> .
     d  775  3      0     0     1024 /var
     % cat /proc/meminfo
     total:    used:    free:  shared: buffers:  cached:
     Mem:  31313920  5799936 25513984        0    49152  4243456
     Swap:        0        0        0
     MemTotal:        30580 kB
     MemFree:         24916 kB
     MemShared:           0 kB
     Buffers:            48 kB
     Cached:           4144 kB
     SwapCached:          0 kB
     Active:            520 kB
     Inactive:         4184 kB
     HighTotal:           0 kB
     HighFree:            0 kB
     LowTotal:        30580 kB
     LowFree:         24916 kB
     SwapTotal:           0 kB
     SwapFree:            0 kB
     % cat /proc/cpuinfo
     Processor       : Intel StrongARM-1110 rev 8 (v4l)
     BogoMIPS        : 147.04
     Features        : swp half 26bit fastmult
     Hardware        : Intel-Assabet
     Revision        : 0000
     Serial          : 0000000000000000

Node: Cross-Compiling Applications, Previous: Loading a filesystem, Up: Top

Cross-Compiling Applications

While building a whole filesystem is outside of the scope of this document, it's worth detailing at least how to compile ARM applications on a PC host and how to build a gdb version that can cope with ARM binaries.

Node: ARM Applications, Next: , Previous: Cross-Compiling Applications, Up: Cross-Compiling Applications

ARM Applications

Having a compiler and binutils installed is not enough, since user-space code need to link to a library, and the compiler must access proper header files so you need therefore to install additional packages. If you use the MontaVista cd, the right files to install are:


The former is the library (and associated headers), and the latter is the set of kernel headers needed by the library. The specific kernel version being linked is not usually a problem, provided the headers have been fixed to properly interoperate with the library.

To compile your application, then, you'll just need to use the right cross-compiler, by forcing CC in the Makefile of in the environment before running the configure script. According to the application and how it is compiled, you may need to change also the path to ld, ar or other tools part of the binutils package. Same applies to C++ programs.

For example, to compile ettclsh, the following steps suffice, and compilation takes 40 kbogoMips-second in total:

      % CC=/opt/hardhat/devkit/arm/sa110_le/bin/sa110_le-gcc ./configure
      % make

Please note that with cross-compilation you'll have on average more problems than with normal compilation, especially with path names and makefiles.

Node: Compiling the debugger, Next: , Previous: ARM Applications, Up: Cross-Compiling Applications

Compiling the debugger

If you need to debug applications that run on the target computer, you most likely can't run a native gdb compiler on the target, what you need, then is a gdbserver running on the target and a copy of gdb that controls it from the host system.

The subject of remote debugging is out of the scope of this document, and compiling gdbserver is like compiling any other target application. On the other hand, compiling the debugger itself is somewhat different. Here is the suggested procedure, provided you have gdb-5.2.

      % tar xvzf gdb-5.2.tar.gz
      % mkdir gdb-arm-build
      % cd gdb-arm-build
      % ../gdb-5.2/configure --target=arm-linux \
      ... this takes 130 kbogoMips-second and prints 1006 lines ...
      % make
      ... this takes 490 kbogoMips-second and prints 627 lines ...
      % make install
      ... this takes 34 kbogoMips-second and prints 343 lines ...

The procedure above installs arm-linux-gdb in /usr/tools/gdb-arm-linux-5.2/bin (you'll probably want to symlink this executable file from /usr/local/bin. This is the gdb you'll want to use to control your target application from the host computer.

Node: Compiling Strace, Previous: Compiling the debugger, Up: Cross-Compiling Applications

Compiling Strace

Strace is a good aid in debugging. Cross-compiling it is easy as it resolves in the usual steps. This is how I successfully compiled version 4.4:

        export CC=your-cross-compiler
        ./configure --target=arm-linux

The only problem you may have is in the kernel headers being included by default by your compiler. If such headers are too old, you need to augment your CC definition with a reference to the kernel headers:

        export CC="your-cross-compiler -I/usr/src/linux-arm/inlude

The resulting binary weights 200kB and is only linked with libc.

Table of Contents