|
Assabet 1.01 |
This file is an ad-interim document to tell how to install a linux system (specifically, the EtLinux distribution on the assabet development platform
The boot loader of choice is redboot. A pre-compiled image of the
loader can be found at
http://kernel.pe.kr/pub/armlinux/people/nico/, 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).
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
<http://sources.redhat.com/ecos>, 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 <ftp://ftp.skynet.ie/cvs/ecos-latest.tar.gz> 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:
hhl-arm_sa110_le-binutils-2.10.0.12-1.i386.rpm
hhl-arm_sa110_le-c++-2.95.2-13.i386.rpm
hhl-arm_sa110_le-gcc-2.95.2-13.i386.rpm
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.
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:
binutils-2.12.90.0.9
gcc-2.95.2
The source tar file for gcc can be retrieved from
<http://gcc.gnu.org/releases.html>, that points you to a mirror
site, to be selected from <http://gcc.gnu.org/mirrors.html>.
Otherwise, use <ftp://ftp.gnu.org/gcc/> (or mirrors).
The binutils can be retrieved, for example, from
<http://ftp.kernel.org/pub/linux/devel/binutils/> (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-2.12.90.0.9/configure \
--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.
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 \
/opt/ecos/packages/hal/arm/sa11x0/
assabet/current/misc/redboot_ROM.ecm
... 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.
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
RedBoot>
I downloaded patch-2.4.18-rmk2.gz and applied it against
Linux-2.4.18 vanilla (i.e., from ftp.kernel.org or mirrors). The
patch is available from
ftp://ftp.arm.linux.org.uk/pub/linux/arm/kernel/v2.4. 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.
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;
fixed-address muscorin.systemy.it;
server-name "morgana.systemy.it";
}
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: 192.168.16.40, Default server: 192.168.16.1
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: .
RedBoot>
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
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
/home/develop/arm/8M.ext2
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
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.
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:
hhl-arm_sa110_le-glibc-2.1.3-1e.noarch.rpm
hhl-arm_sa110_le-kernel-headers-2.4.0-test2-1.2.3-1.noarch.rpm
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.
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 \
--prefix=/usr/tools/gdb-arm-linux-5.2
... 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.
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
make
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.