Chapter 2. Embedded ARMLinux: Fundamentals

Introduction

The fundamental requirement for a GNU/Linux system is a kernel and a filing system for it to execute things from.

The kernel is an autonomous piece of code that doesn't need any other files or libraries to get started, although without a root filing system it will simply stop after initialising the system as it no files to operate on.

The filing system can be loaded from a range of different hardware devices (hard disk, RAM, ROM, CD and NFS mount) and must be in a format that the kernel understands. For embedded systems it is often a RAMdisk. The kernel and RAMdisk both need to be loaded to correct places in memory and the kernel executed. This can be done in various ways, typically by loading over a serial connection or from local flash RAM.

In order to be able to load anything from anywhere some kind of bootloader must be present on the target hardware which knows how to load files and execute them. This can be installed in a physical fashion by inserting a pre-programmed ROM/EEPROM or flash chip, but is more usually installed using a JTAG port, which allows instructions to be executed from an external input, and thus an initial program loaded.

As there are so many possible boot scenarios we cannot describe them all in detail. We will describe only the most common (which are the most useful for typical situations) but also make the principles clear so you can do something more exotic if you need to.

Bootloaders

Bootloaders are highly system-specific. Some ARM platforms share the same loaders, but on the whole you get a different one on every system. This can be a boot ROM like the NeTTrom in a Netwinder, or it can be the native OS like RISCOS in a RiscPC, or EPOC in a Psion5, or it can be a dedicated bootloader installed into Flash, like Angel or Blob in the LART and Assabet. If you are porting to a new ARM platform then you will need your own bootloader. You may well be able to base this on one of the existing GPLed ones, or you may already have something that can be modified to load ARMLinux instead of whatever the device used before.

When talking about bootloaders it is important to remember that if the target is not autonomous then the loader has two parts:

  1. One part on the target to receive the kernel and RAMdisk; and

  2. another on the host to send it.

There are two bootloaders commonly used with the LART and Assabet: Blob and Angel. Angel is part of ARM's Development toolkit, and can also be used as a debugger, but we use it with a companion program Angelboot instead. Angel is a simple loader that receives a kernel and RAMdisk over the serial port and loads them to specified addresses before running the kernel. Blob is a more complex program that can do the same as Angel but can also install a kernel and RAMdisk permanently in flash RAM so that the target can subsequently boot autonomously.

See Chapter 6 for details of configuring and using these programs. Brief typical use is covered in the install section for the relevant target device.

JTAG

Getting the target side of the bootloader installed is normally done with the Jflash utility (both Windows and Linux versions exist). This drives the JTAG interface through the printer port of the host PC. The Linux version is called JFlash-linux. Note that this program is different for each target as it depends on knowing the exact hardware of the target, so JFlash-linux for Assabet and JFlash-linux for LART are different and you need to use the right one.

Table of devices and tools

DeviceJTAGBoot loader(s)
LARTJflash,Jflash-linuxBlob
AssabetJflash,JFlash-linuxAngel, blob
Psion5-Arlo

Host machine

If the target has sufficient IO devices (eg screen and keyboard) then it can be used without a host. However, during initial development a host is normally used as a console (screen and keyboard), for compiling new code and for monitoring debug output.

There are several reasons why this is practical:

  • you will probably keep rebooting the target;

  • it will probably crash a lot if you are doing any low-level development, or the hardware's not quite debugged yet;

  • there may well not be space for the toolchain software on the target;

  • you will normally be more familiar with the host environment.

As the host is usually an x86 PC rather than another ARM-based machine this means that you will need to cross-compile software to run on the target processor. You can arrange to use an ARM machine as the host (eg an Acorn Risc PC, Netwinder, CATS board) but even here you usually need to separate the host and target environments as they will probably be using different kernel versions and perhaps library versions.

You can have either a GNU/Linux or a Windows box as the host. As you are working with Linux on the target it is useful in many ways to also have a Linux host - the toolchain is easier to set up, you can easily mount and try out your RAMdisks etc. Much of this book assumes that you have access to a GNU/Linux host. However we recognise that many developers wil have a Windows box on their desks and may not wish or be able to change just yet. The best solution is to the use the Cygnus unix-like environment for Windows which gives you the functionality you need. A chapter for this book, describing the necessary software and techniques, is in preparation for the next edition. In the meantime either use your skill and judgement, or get a GNU/Linux box too.

Getting a cross-compiler toolchain set up used to be very difficult, requiring much gurudom and attention to a host of details but with the precompiled toolchains on this CD it is very easy. Chapter 8 gives details of both the ready built toolchains you can install, and explains how to build a new one should you need something different from that which is provided.

RAMdisks

The RAMdisk is a very useful kernel facility that lets you load the files you need on the system into RAM along with the kernel. It take the form of a compressed filesystem. The kernel automatically allocates RAM for it and uncompresses it, then mounts it as the root filing system.

Again, there are many variations possible on this theme, but the conventional setup is to format the RAMdisk as ext2, the normal Linux disk filesystem. For this to work you need to specify the correct kernel options: RAMdisk support (CONFIG_BLK_DEV_RAM, CONFIG_BLK_DEV_RAM_SIZE, CONFIG_BLK_DEV_INITRD) and support for the filesystem used (normally ext2 - CONFIG_EXT2_FS).

There are suitable example RAMdisks provided for the devices covered in this manual on the CD. There are also several available on-line, where developers have made their own available for others to use. We recommend that you use one of these to get started, however for many applications you will need to make your own. It's not difficult, and the process is described in the section called Making a RAMdisk in Chapter 7.