The DENX U-Boot and Linux Guide (DULG) for canyonlands


Table of contents:

1. Abstract

This is the DENX U-Boot and Linux Guide to Embedded PowerPC, ARM and MIPS Systems.

The document describes how to configure, build and use the firmware Das U-Boot (typically abbreviated as just "U-Boot") and the operating system Linux for Embedded PowerPC, ARM and MIPS Systems.

The focus of this version of the document is on canyonlands boards.

This document was generated at 24 Jan 2012 - 20:15.

2. Introduction

This document describes how to use the firmware U-Boot and the operating system Linux in Embedded Power Architecture®, ARM and MIPS Systems.

There are many steps along the way, and it is nearly impossible to cover them all in depth, but we will try to provide all necessary information to get an embedded system running from scratch. This includes all the tools you will probably need to configure, build and run U-Boot and Linux.

First, we describe how to install the Cross Development Tools Embedded Linux Development Kit which you probably need - at least when you use a standard x86 PC running Linux or a Sun Solaris 2.6 system as build environment.

Then we describe what needs to be done to connect to the serial console port of your target: you will have to configure a terminal emulation program like cu or kermit.

In most cases you will want to load images into your target using ethernet; for this purpose you need TFTP and DHCP / BOOTP servers. A short description of their configuration is given.

A description follows of what needs to be done to configure and build the U-Boot for a specific board, and how to install it and get it working on that board.

The configuration, building and installing of Linux in an embedded configuration is the next step. We use SELF, our Simple Embedded Linux Framework, to demonstrate how to set up both a development system (with the root filesystem mounted over NFS) and an embedded target configuration (running from a ramdisk image based on busybox).

This document does not describe what needs to be done to port U-Boot or Linux to a new hardware platform. Instead, it is silently assumed that your board is already supported by U-Boot and Linux.

The focus of this document is on canyonlands boards.

2.1. Copyright

Copyright (C) 2001 - 2011 by Wolfgang Denk, DENX Software Engineering.
Copyright (C) 2003 - 2011 by Detlev Zundel, DENX Software Engineering.
Copyright (C) 2003 - 2011 by contributing authors

You have the freedom to distribute copies of this document in any format or to create a derivative work of it and distribute it provided that you:

It is requested that corrections and/or comments be forwarded to the author.

If you are considering to create a derived work other than a translation, it is requested that you discuss your plans with the author.

2.2. Disclaimer

Use the information in this document at your own risk. DENX disavows any potential liability for the contents of this document. Use of the concepts, examples, and/or other content of this document is entirely at your own risk. All copyrights are owned by their owners, unless specifically noted otherwise. Use of a term in this document should not be regarded as affecting the validity of any trademark or service mark. Naming of particular products or brands should not be seen as endorsements.

2.3. Availability

The latest version of this document is available in a number of formats:

2.4. Credits

A lot of the information contained in this document was collected from several mailing lists. Thanks to anybody who contributed in one form or another.

2.5. Translations

None yet.

2.6. Feedback

Any comments or suggestions can be mailed to the author: Wolfgang Denk at wd@denx.de.

2.7. Conventions

Descriptions Appearance
Warnings ALERT!
Hint TIP
Notes Note.
Information requiring special attention Warning
File Names file.extension
Directory Names directory
Commands to be typed a command
Applications Names another application
Prompt of users command under bash shell bash$
Prompt of root users command under bash shell bash#
Prompt of users command under tcsh shell tcsh$
Environment Variables VARIABLE
Emphasized word word
Code Example ls -l

3. Embedded Linux Development Kit

The Embedded Linux Development Kit (ELDK) includes the GNU cross development tools, such as the compilers, binutils, gdb, etc., and a number of pre-built target tools and libraries necessary to provide some functionality on the target system.

It is provided for free with full source code, including all patches, extensions, programs and scripts used to build the tools.

Some versions of ELDK (4.1) are available in two versions, which use Glibc resp. uClibc as the main C library for the target packages.

Packaging and installation is based on the RPM package manager.

3.1. ELDK Availability

The ELDK is available

3.2. ELDK Getting Help

Community support for the ELDK is available through the ELDK Mailing List.
Previous postings to this mailing list are available from the ELDK archives.

Commercial support is also available; please feel free to contact DENX Software Engineering GmbH.

3.3. Supported Host Systems

The ELDK can be installed onto and operate with the following operating systems:

Users also reported successful installation and use of the ELDK on the following host systems:

Note: It may be necessary, and is usually recommended, to install the latest available software updates on your host system. For example, on Fedora systems, you can use yum or apt-get to keep your systems current.

3.4. Supported Target Architectures

The ELDK includes target components and supports code generation for the following Power Architecture® types of processors:

There is also an ELDK for ARM and MIPS systems.

3.5. Installation

3.5.1. Product Packaging

Stable versions of the ELDK are distributed in the form of an ISO image, which can be either burned onto a DVD or mounted directly, using the loopback Linux device driver (Linux host only).

For the Power Architecture® target, the ELDK distribution was split into three independent ISO images: one targeting the 4xx family of processors (AMCC), one targeting the ppc64 family of processors and another one for the 8xx, 6xx, 74xx and 85xx families (Freescale). This makes the ISO images fit on standard DVDROM media.

If you are not bound by the DVDROM size limitiation there is still a single image containing all 32-bit targets (AMCC and Freescale).

Development versions of the ELDK are available as directory trees so it is easy to update individual packages; instructions for download of these trees and creation of ISO images from it is described in section 3.5.2. Downloading the ELDK.

The ELDK contains an installation utility and a number of RPM packages, which are installed onto the hard disk of the cross development host by the installation procedure. The RPM packages can be logically divided into two parts:

The first part contains the cross development tools that are executed on the host system. Most notably, these are the GNU cross compiler, binutils, and gdb. For a full list of the provided ELDT packages, refer to section 3.9.1. List of ELDT Packages below.

The target components are pre-built tools and libraries which are executed on the target system. The ELDK includes necessary target components to provide a minimal working NFS-based environment for the target system. For a list of the target packages included in the ELDK, refer to section 3.9.2. List of Target Packages below.

The ELDK contains several independent sets of the target packages, one for each supported target architecture CPU family. Each set has been built using compiler code generation and optimization options specific to the respective target CPU family.

3.5.2. Downloading the ELDK

You can either download the ready-to-burn ISO-images from one of the mirror sites (see 3.1. ELDK Availability), or you can download the individual files of the ELDK from the development directory tree and either use these directly for installation or create an ISO image that can be burned on DVD-ROM.

Change to a directory with sufficient free disk space; for the Power Architecture® version of the ELDK you need about 1.6 GiB, or twice as much (3.2 GiB) if you also want to create an ISO image in this directory.

To download the ISO image from the ppc-linux-x86/iso directory of one of the mirror sites you can use standard tools like wget or ncftpget, for example:

bash$ wget ftp://ftp.sunet.se/pub/Linux/distributions/eldk/4.2/ppc-linux-x86/iso/ppc-2008-04-01.iso

If you want to download the whole ELDK directory tree instead you can - for example - use the ncftp FTP client:

bash$ ncftp ftp.sunet.se
...
ncftp / > cd /pub/Linux/distributions/eldk/4.2
ncftp /pub/Linux/distributions/eldk/4.2 > bin
ncftp /pub/Linux/distributions/eldk/4.2 > get -R ppc-linux-x86/distribution
...
ncftp /pub/Linux/distributions/eldk/4.2 > bye

TIP If you don't find the ncftp tool on your system you can download the NcFTP client from http://www.ncftp.com/download/

There are a few executable files (binaries and scripts) in the ELDK tree. Make sure they have the execute permissions set in your local copy:

bash$ for file in \
>       tools/bin/rpm \
>       tools/usr/lib/rpm/rpmd \
>       install \
>       ELDK_MAKEDEV \
>       ELDK_FIXOWNER
> do
> chmod +x ppc-linux-x86/distribution/$file
> done

Now create an ISO image from the directory tree:

bash$ mkisofs \
> -A "ELDK-4.2 -- Target: PowerPC -- Host: x86 Linux" \
> -publisher "(C) `date "+%Y"` DENX Software Engineering,   www.denx.de" \
> -p "`id -nu`@`hostname` -- `date`" \
> -V ppc-linux-x86 \
> -l -J -R -o eldk-ppc-linux-x86.iso ppc-linux-x86/distribution

This will create an ISO image eldk-ppc-linux-x86.iso in your local directory that can be burned on DVD or mounted using the loopback device and used for installation as described above. Of course you can use the local copy of the directory tree directly for the installation, too.

Please refer to section 3.10.2. Setting Up ELDK Build Environment for instructions on obtaining the build environment needed to re-build the ELDK from scratch.

3.5.3. Initial Installation

The initial installation is performed using the install utility located in the root of the ELDK ISO image directory tree. The install utility has the following syntax:

$ ./install [-d <dir>] [<cpu_family1>] [<cpu_family2>] ...

-d <dir> Specifies the root directory of the ELDK being installed. If omitted, the ELDK goes into the current directory.
<cpu_family> Specifies the target CPU family the user desires to install. If one or more <cpu_family> parameters are specified, only the target components specific to the respective CPU families are installed onto the host. If omitted, the target components for all supported target architecture CPU families are installed.

Note: Make sure that the "exec" option to the mount command is in effect when mounting the ELDK ISO image. Otherwise the install program cannot be executed. On some distributions, it may be necessary to modify the /etc/fstab file, adding the "exec" mount option to the cdrom entry - it may also be the case that other existing mount options, such as "user" prevent a particular configuration from mounting the ELDK DVD with appropriate "exec" permission. In such cases, consult your distribution documentation or mount the DVD explicitly using a command such as "sudo mount -o exec /dev/cdrom /mnt/cdrom" (sudo allows regular users to run certain privileged commands but may not be configured - run the previous command as root without "sudo" in the case that "sudo" has not been setup for use on your particular GNU/Linux system).

You can install the ELDK to any empty directory you wish, the only requirement being that you have to have write and execute permissions on the directory. The installation process does not require superuser privileges.

Depending on the parameters the install utility is invoked with, it installs one or more sets of target components. The ELDT packages are installed in any case.

Refer to section 3.6. Working with ELDK for a sample usage of the ELDK.

ALERT! Note: If you intend to use the installation as a root filesystem exported over NFS, then you now have to finish the configuration of the ELDK following the instructions in 3.7. Mounting Target Components via NFS.

ALERT! Note: Installation of the Glibc- and uClibc-based ELDK versions into one directory is not yet supported.

ALERT! Note: Installation of the 32-bit and 64-bit ELDK versions into one directory is not yet supported.

3.5.4. Installation and Removal of Individual Packages

The ELDK has an RPM-based structure. This means that on the ISO image, individual components of the ELDK are in the form of RPM packages, and after installation, the ELDK maintains its own database which contains information about installed packages. The RPM database is kept local to the specific ELDK installation, which allows you to have multiple independent ELDK installations on your host system. (That is, you can install several instances of ELDK under different directories and work with them independently). Also, this provides for easy installation and management of individual ELDK packages.

To list the installed ELDK RPM packages, use the following command:

bash$ ${CROSS_COMPILE}rpm -qa

To remove an ELDK package, use the following command:

bash$ ${CROSS_COMPILE}rpm -e <package_name>

To install a package, use the following command:

bash$ ${CROSS_COMPILE}rpm -i <package_file_name>

To update a package, use the following command:

bash$ ${CROSS_COMPILE}rpm -U <package_file_name>

For the above commands to work correctly, it is crucial that the correct rpm binary gets invoked. In case of multiple ELDK installations and RedHat-based host system, there may well be several rpm tools installed on the host system.

You must make sure, either by using an explicit path or by having set an appropriate PATH environment variable, that when you invoke rpm to install/remove components of a ELDK installation, it is the ELDK's rpm utility that gets actually invoked. The rpm utility is located in the bin subdirectory relative to the ELDK root installation directory.

To avoid confusion with the host OS (RedHat) rpm utility, the ELDK creates symlinks to its rpm binary with the names such that it could be invoked using the ${CROSS_COMPILE}rpm notation, for all supported $CROSS_COMPILE values.

TIP The standard (host OS) rpm utility allows various macros and configuration parameters to specified in user-specific ~/.rpmrc and ~/.rpmmacros files. The ELDK rpm tool also has this capability, but the names of the user-specific configuration files are ~/.eldk_rpmrc and ~/.eldk_rpmmacros, respectively.

3.5.5. Removal of the Entire Installation

To remove the entire ELDK installation, use the following command while in the ELDK root directory:

bash$ rm -rf <dir>

where <dir> specifies the root directory of the ELDK to be removed.

3.6. Working with ELDK

After the initial installation is complete, all you have to do to start working with the ELDK is to set and export the CROSS_COMPILE environment variable. Optionally, you may wish to add the bin and usr/bin directories of your ELDK installation to the value of your PATH environment variable. For instance, a sample ELDK installation and usage scenario looks as follows:

     bash$ export CROSS_COMPILE=ppc_4xxFP-
     

The value of the CROSS_COMPILE variable must correspond to the target CPU family you want the cross tools to work for. Refer to the table below for the supported CROSS_COMPILE variable values:

3.6.A Table of possible values for $CROSS_COMPILE

CROSS_COMPILE Value Predefined Compiler Flag FPU present or not
ppc_4xx- -mcpu=403 No
ppc_4xxFP- -mcpu=405fp Yes
ppc_6xx- -mcpu=603 Yes
ppc_74xx- -mcpu=7400 Yes
ppc_8xx- -mcpu=860 No
ppc_85xx- -mcpu=8540 Yes
ppc_85xxDP- -mcpu=8540 Yes
ppc64-linux- -mcpu=powerpc64 Yes
TIP For compatibility with older versions of the ELDK and with other toolkits the following values for $CROSS_COMPILE can be used, too: ppc_7xx- and ppc_82xx-. These are synonyms for ppc_6xx.

3.6.1. Switching Between Multiple Installations

No special actions are required from the user to switch between multiple ELDK installations on the same host system. Which ELDK installation is used is determined entirely by the filesystem location of the binary that is being invoked. This approach can be illustrated using the following example.

Assume the directory /work/denx_tools/usr/bin, where the ppc-linux-gcc compiler binary has been installed, is a part of the PATH environment variable. The user types the command as follows:

$ ppc_8xx-gcc -c myfile.c

To load the correct include files, find the correct libraries, spec files, etc., the compiler needs to know the ELDK root directory. The compiler determines this information by analyzing the shell command it was invoked with ( ppc_8xx-gcc - without specifying the explicit path in this example) and, if needed, the value of the PATH environment variable. Thus, the compiler knows that it has been executed from the /work/denx_tools/usr/bin directory.

Then, it knows that the compiler is installed in the usr/bin subdirectory of the root installation directory, so the ELDK, the compiler is a part of, has been installed in the subdirectories of the /work/denx_tools directory. This means that the target include files are in /work/denx_tools/<target_cpu_variant>/usr/include, and so on.

3.7. Mounting Target Components via NFS

The target components of the ELDK can be mounted via NFS as the root file system for your target machine. For instance, for an 8xx-based target, and assuming the ELDK has been installed into the /opt/eldk directory, you can use the following directory as the NFS-based root file system:

/opt/eldk/ppc_8xx

ALERT! Before the NFS-mounted root file system can work, you must create necessary device nodes in the <ELDK_root>/<target_cpu_variant>/dev directory. This process requires superuser privileges and thus cannot be done by the installation procedure (which typically runs as non-root). To facilitate creation of the device nodes, the ELDK provides a script named ELDK_MAKEDEV, which is located in the root of the ELDK distribution ISO image. The script acccepts the following optional arguments:

-d <dir> Specifies the root directory of the ELDK being installed. If omitted, then the current directory is assumed.
-a <cpu_family> Specifies the target CPU family directory. If omitted, all installed target architecture directories will be populated with the device nodes.
-h Prints usage.

# /mnt/cdrom/ELDK_MAKEDEV -d /opt/eldk
NOTE: Compared to older versions of the ELDK, options and behaviour of this command have been changed significantly. Please read the documentation.

ALERT! Some of the target utilities included in the ELDK, such as mount and su, have the SUID bit set. This means that when run, they will have privileges of the file owner of these utilities. That is, normally, they will have the privileges of the user who installed the ELDK on the host system. However, for these utilities to work properly, they must have superuser privileges. This means that if the ELDK was not installed by the superuser, the file owner of the target ELDK utilities that have the SUID bit set must be changed to root before a target component may be mounted as the root file system. The ELDK distribution image contains an ELDK_FIXOWNER script, which you can use to change file owners of all the appropriate files of the ELDK installation to root. The script accepts the same arguments as the ELDK_MAKEDEV script above. Please note that you must have superuser privileges to run this script. For instance, if you have installed the ELDK in the /opt/eldk directory, you can use the following commands:

# cd /opt/eldk
# /mnt/cdrom/ELDK_FIXOWNER

Please note, that in the case that the installation directory, where the new ELDK distribution is being installed, is already populated with other ELDK distributions, the execution of the ELDK_FIXOWNER script without arguments will make the script work with all installed ELDK target architecture directories. This could take some time. To save the time, please use the -a argument to specify the appropriate target architecture. For instance:

# cd /opt/eldk
# /mnt/cdrom/ELDK_FIXOWNER -a ppc_8xx

3.8. Rebuilding ELDK Components

3.8.1. ELDK Source Distribution

The ELDK is distributed with the full sources of all the components, so you may rebuild any ELDK package. The sources are provided in the form of SRPM packages, distributed as a separate ISO image.

To rebuild a target or ELDT package, you must first install the appropriate source RPM package from the ISO image into the ELDK environment. This can be done using the following command:

$ ${CROSS_COMPILE}rpm -i /mnt/cdrom/SRPMS/<source_rpm_file_name>.src.rpm

After an ELDK source RPM is installed using the above command, its spec file and sources can be found in the subdirectories of the <ELDK_root>/usr/src/denx subdirectory.

The sections that follow provide detailed instructions on rebuilding ELDT and target components of the ELDK.

3.8.2. Rebuilding Target Packages

All the target packages can be rebuilt from the provided source RPM packages. At first you have to install the Source RPM itself:

bash$ ${CROSS_COMPILE}rpm -iv <package_name>.src.rpm

Then you can rebuild the binary target RPM using the following command from the ELDK environment:

bash$ ${CROSS_COMPILE}rpmbuild -ba <package_name>.spec

In order for the rebuilding process to work correctly, the following conditions must be true:

The newly built package can then be installed just as easily:

bash$ ${CROSS_COMPILE}rpm -i <package_name>.rpm

3.8.3. Rebuilding ELDT Packages

All the ELDT packages allow for rebuilding from the provided source RPM packages using the following command from the ELDK environment:

$ unset CROSS_COMPILE
$ <ELDK_root>/usr/bin/rpmbuild -ba <package_name.spec>

In order for the rebuilding process to work correctly, make sure all of the following is true:

Note that the newly built package should be installed with the "global" rpm, not with the arch specific one:

bash$ <ELDK_root>/bin/rpm -i <package_name>.rpm

3.9. ELDK Packages

3.9.1. List of ELDT Packages

Package Name Package Version
autoconf 2.61-8
automake 1.10-5
bison 2.3-3
crosstool-devel 0.43-3
dtc 20070802-1
elocaledef 1-1
ftdump 20070802-1
gdb 6.7-2
genext2fs 1.4.1-1
info 4.8-15
ldd 0.1-1
libtool 1.5.22-11
make 3.81-6
mkcramfs 1.1-1
mkimage 1.3.1-1
mtd-utils 1.0.1-2
rpm 4.4.2-46_2
rpm-build 4.4.2-46_2
sed 4.1.4-1
texinfo 4.8-15

ALERT! Note: The crosstool 0.43 ELDT package provides the following packages: gcc 4.2.2, gcc-c++ 4.2.2, gcc-java 4.2.2, cpp 4.2.2 and binutils 2.17.90. For more information about the crosstool package please refer to http://kegel.com/crosstool.

3.9.2. List of Target Packages

Package Name Package Version
acl 2.2.39-3.1
appweb 2.2.2-5
attr 2.4.32-2
autoconf 2.61-8
bash 3.2-9
bc 1.06-26
bind 9.4.1-8.P1
binutils 2.17.90-1
binutils-devel 2.17.90-1
boa 0.94.14-0.5.rc21
busybox 1.7.1-2
byacc 1.9.20050813-1
bzip2 1.0.4-10
bzip2-devel 1.0.4-10
bzip2-libs 1.0.4-10
ccid 1.2.1-10
chkconfig 1.3.34-1
coreutils 6.9-3
cpio 2.6-27
cpp 4.2.2-2
cracklib 2.8.9-11
cracklib-dicts 2.8.9-11
crosstool-targetcomponents 0.43-3
curl 7.16.2-1
cyrus-sasl 2.1.22-6
cyrus-sasl-devel 2.1.22-6
cyrus-sasl-lib 2.1.22-6
db4 4.5.20-5_2
db4-devel 4.5.20-5_2
db4-utils 4.5.20-5_2
device-mapper 1.02.17-7
device-mapper-devel 1.02.17-7
device-mapper-libs 1.02.17-7
dhclient 3.0.5-38
dhcp 3.0.5-38
diffutils 2.8.1-16
directfb 1.0.0-1
dosfstools 2.11-8
dropbear 0.50-1
dtc 20070802-1
duma 2.5.8-2
e2fsprogs 1.39-11
e2fsprogs-devel 1.39-11
e2fsprogs-libs 1.39-11
ethtool 5-1
expat 1.95.8-9
expat-devel 1.95.8-9
file 4.21-1
file-libs 4.21-1
findutils 4.2.29-2
flex 2.5.33-9
freetype 2.3.4-3
freetype-devel 2.3.4-3
ftdump 20070802-1
ftp 0.17-40
gawk 3.1.5-15
gcc 4.2.2-2
gcc-c++ 4.2.2-2
gcc-java 4.2.2-2
gdb 6.7-1
glib 1.2.10-26
glib2 2.12.13-1
glib2-devel 2.12.13-1
glib-devel 1.2.10-26
gmp 4.1.4-12.3
grep 2.5.1-57
groff 1.18.1.4-2
gzip 1.3.11-2
hdparm 6.9-3
httpd 2.2.4-4.1
httpd-devel 2.2.4-4.1
httpd-manual 2.2.4-4.1
initscripts 8.54.1-1
iproute 2.6.20-2
iptables 1.3.8-2
iputils 20070202-3
iscsitarget 0.4.15-1
kbd 1.12-22
kernel-headers 2.6.24-1
kernel-source 2.6.24-1
krb5-devel 1.6.1-2.1
krb5-libs 1.6.1-2.1
less 394-9
libattr 2.4.32-2
libattr-devel 2.4.32-2
libcap 1.10-29
libcap-devel 1.10-29
libpng 1.2.16-1
libpng-devel 1.2.16-1
libsysfs 2.1.0-1
libsysfs-devel 2.1.0-1
libtermcap 2.0.8-46.1
libtermcap-devel 2.0.8-46.1
libtirpc 0.1.7-7_2
libtirpc-devel 0.1.7-7_2
libtool 1.5.22-11
libtool-ltdl 1.5.22-11
libtool-ltdl-devel 1.5.22-11
libusb 0.1.12-7
libusb-devel 0.1.12-7
libuser 0.56.2-1
libuser-devel 0.56.2-1
libxml2 2.6.29-1
logrotate 3.7.5-3.1
lrzsz 0.12.20-22.1
lsof 4.78-5
ltp 20080131-eldk2
lvm2 2.02.24-1
m4 1.4.8-2
mailcap 2.1.23-1
make 3.81-6
MAKEDEV 3.23-1.2
man 1.6e-3
mdadm 2.6.2-4
microwindows 0.91-2
microwindows-fonts 0.91-1
mingetty 1.07-5.2.2
mktemp 1.5-25
module-init-tools 3.3-0.pre11.1.0
mtd-utils 1.0.1-2
ncompress 4.2.4-49
ncurses 5.6-17
ncurses-devel 5.6-17
net-snmp 5.4-14
net-snmp-devel 5.4-14
net-snmp-libs 5.4-14
net-snmp-utils 5.4-14
net-tools 1.60-82
newt 0.52.6-30
newt-devel 0.52.6-30
nfs-utils 1.1.0-1
ntp 4.2.4p2-1
open-iscsi 2.0-865.15
openldap 2.3.34-3
openldap-devel 2.3.34-3
openssl 0.9.8b-12_2
openssl-devel 0.9.8b-12_2
oprofile 0.9.2-8_2
pam 0.99.7.1-5.1
pam-devel 0.99.7.1-5.1
passwd 0.74-3
patch 2.5.4-29.2.2
pciutils 2.2.4-3_2
pciutils-devel 2.2.4-3_2
pcmciautils 014-9_2
pcre 7.0-2
pcsc-lite 1.3.3-1.0
pcsc-lite-devel 1.3.3-1.0
pcsc-lite-libs 1.3.3-1.0
perl 5.8.8-18_2
perl-libs 5.8.8-18_2
popt 1.12-1
portmap 4.0-65_2
postgresql 8.2.4-1_2
postgresql-devel 8.2.4-1_2
postgresql-libs 8.2.4-1_2
ppp 2.4.4-7
procps 3.2.7-14
psmisc 22.3-2
python 2.5.1-1
rdate 1.4-6
readline 5.2-4
readline-devel 5.2-4
routed 0.17-12_1
rpcbind 0.1.4-6
rpm 4.4.2-46_2
rpm-build 4.4.2-46_2
rpm-devel 4.4.2-46_2
rpm-libs 4.4.2-46_2
rsh 0.17-40
rsh-server 0.17-40
screen 4.0.3-50
sed 4.1.5-7
SELF 1.0-13
setup 2.6.4-1_2
shadow-utils 4.0.18.1-15
slang 2.0.7-17
slang-devel 2.0.7-17
smartmontools 5.38-2
strace 4.5.15-1
sysfsutils 2.1.0-1
sysklogd 1.4.2-9
sysvinit 2.86-17
tar 1.15.1-26
tcp_wrappers 7.6-48
tcp_wrappers-devel 7.6-48
tcp_wrappers-libs 7.6-48
telnet 0.17-38
telnet-server 0.17-38
termcap 5.5-1.20060701.1
tftp 0.42-4
tftp-server 0.42-4
thttpd 2.25b-13
time 1.7-29
u-boot 1.3.1-1
udev 106-4.1
unixODBC 2.2.12-2
unzip 5.52-4
util-linux 2.13-0.52_2
vim-common 7.1.12-1
vim-minimal 7.1.12-1
vixie-cron 4.1-82
vsftpd 2.0.5-16_2
which 2.16-8
wireless-tools 28-4
wpa_supplicant 0.5.7-3
wu-ftpd 2.6.2-1
xdd 65.013007-1
xenomai 2.4.2-1
xinetd 2.3.14-12
zip 2.31-3
zlib 1.2.3-10
zlib-devel 1.2.3-10

ALERT! Note 1: Not all packages will be installed automatically; for example the boa and thttpd web servers are mutually exclusive - you will have to remove one package before you can (manually) install the other one.

ALERT! Note 2: The crosstool 0.43 target package provides the following packages: glibc 2.6, glibc-common 2.6, glibc-devel 2.6, libstdc++ 4.2.2, libgcj 4.2.2, libgcj-devel 4.2.2 and libstdc++-devel 4.2.2. For more information about the crosstool package please refer to http://kegel.com/crosstool

ALERT! Note 3: The Xenomai and gcc-java packages are unavailable in ARM ELDK version.

3.10. Rebuilding the ELDK from Scratch

In this section, you will find instructions on how to build the ELDK from scratch, using the pristine package sources available on the Internet, and patches, spec files, and build scripts provided on the ELDK source CD-ROM.

3.10.1. ELDK Build Process Overview

The ELDK uses the Fedora 7 Linux distribution as source code reference. Any modifications to Fedora's sources the ELDK has introduced are in the form of patches applied by the RPM tool while building the packages. Also, the ELDK uses modified spec files for its RPM packages. So, the sources of almost every ELDK package consist of the following parts:

The Fedora pristine sources may be obtained from the Internet, see http://download.fedora.redhat.com/pub/fedora/linux/core.

The ELDK patches and spec files are available on the ELDK source CD-ROM and from the DENX GIT repositories. Also, for convenience, the pristine Fedora sources are available here, too.

Please use the following commands to check out a copy of one of the modules:

git-clone git://www.denx.de/git/eldk/module
The following ELDK modules are available:

Module Name Contents
tarballs Source tarballs
build Build tools, patches, and spec files
SRPMS Fedora 7 sources

Then you may switch to a specific release of the ELDK using the "git-checkout" command; for example, to get the files for ELDK release 4.1, please do the following from the module directory:

git-checkout ELDK_4_2

It must be noted that some of the packages which are included in the ELDK are not included in Fedora. Examples of such packages are appWeb, microwindows, and wu-ftpd. For these packages tarballs are provided in the DENX GIT repository.

To facilitate building of the ELDK, a build infrastructure has been developed. The infrastructure is composed of the following components:

The ELDK_BUILD script is the main script of the ELDK build procedure. It is the tool that you would normally use to build the ELDK from scratch. In the simplest case, the script may be invoked without arguments, and it will perform all necessary steps to build the ELDK in a fully automated way. You may pass the following optional arguments to the ELDK_BUILD script:

-a <arch> target architecture: "arm", "ppc" or "ppc64", defaults to "ppc".
-n <build_name> an identification string for the build. Defaults to the value based on the build architecture and current date, and has the following format: <arch>-YYYY-MM-DD
-v <version> ELDK version string
-u build the uClibc-based ELDK version (on the platforms and versions where this is available).
-p <builddir> Optional build directory. By default, build will place the work files and results in the current directory.

ALERT! Warning: The ELDK build scripts rely on standard behaviour of the RPM tool. Make sure you don't use non-standard settings in your personal ~/.rpmmacros file that might cause conflicts.

build.sh is a supplementary script that is called by ELDK_BUILD to accomplish certain steps of the build. Refer to section 3.10.3. build.sh Usage below for more details.

The cpkgs.lst and tpkgs.lst files are read by build.sh and must contain lines describing sub-steps of the eldt and trg build procedure steps. Essentially, the files contain the list of the ELDT and target packages to be included in the ELDK. The SRPMS.lst file contains the list of the Fedora source RPM packages used during the ELDK build. The tarballs.lst file contains the list of source tarballs of the packages that are included in the ELDK but are not present in Fedora 7.

For the ELDK_BUILD script to work correctly, it must be invoked from a certain build environment created on the host system. The build environment can be either checked out from the DENX GIT repository (see section 3.10.2. Setting Up ELDK Build Environment below for details) or copied from the ELDK build environment CD-ROM.

To be more specific, the following diagram outlines the build environment needed for correct operation of the ELDK_BUILD script:

<some_directory>/
                 build/cross_rpms/<package_name>/SPECS/...
                                                 SOURCES/...
                       target_rpms/<package_name>/SPECS/...
                                                  SOURCES/...
                       install/install.c
                               Makefile
                       misc/ELDK_MAKEDEV
                            ELDK_FIXOWNER
                            README.html
                       cpkgs.lst
                       tpkgs.lst
                       build.sh
                                                                                
                       ELDK_BUILD
                                                                                
                       SRPMS.lst
                                                                                
                       tarballs.lst

                 tarballs/....
                                                                                
                 SRPMS/....
                 SRPMS-updates/....

In subdirectories of the cross_rpms and target_rpms directories, the sources and RPM spec files of, respectively, the ELDT and target packages are stored. The install subdirectory contains the sources of the installation utility which will be built and placed in the root of the ISO image. tarballs directory contains the source tarballs of the packages that are included in the ELDK but are not present in Fedora 7.

The SRPMS and SRPMS-updates directories may contain the source RPM packages of Fedora 7. The ELDK_BUILD script looks for a package in the SRPMS directory and then, if the package is not found, in the SRPMS-updates directory. If some (or all) of the Fedora SRPMs needed for the build are missing in the directories, the ELDK_BUILD script will download the source RPMs automatically from the Internet.

The ELDK build environment CD-ROM provides a ready-to-use ELDK build environment. Please refer to section 3.10.2. Setting Up ELDK Build Environment below for detailed instructions on setting up the build environment.

The ELDK_BUILD script examines the contents of the ELDK_PREFIX environment variable to determine the root directory of the ELDK build environment. If the variable is not set when the script is invoked, it is assumed that the root directory of the ELDK build environment is /opt/eldk. To build the ELDK in the example directory layout given above, you must set and export the ELDK_PREFIX variable <some_directory> prior to invoking ELDK_BUILD.

After all the build steps are complete, the following subdirectories are created in the ELDK build environment:

build/<build_name>/work/             - full ELDK environment
build/<build_name>/logs/             - build procedure log files
build/<build_name>/results/b_cdrom/  - binary cdrom tree, ready for mkisofs
                   results/s_cdrom/  - source cdrom tree, ready for mkisofs
                   results/d_cdrom/  - debuginfo cdrom tree, ready for mkisofs

On Linux hosts, the binary and source ISO images are created automatically by the ELDK_BUILD script and placed in the results directory. On Solaris hosts, creating the ISO images is a manual step. Use the contents of the b_cdrom and s_cdrom directories for the contents of the ISO images.

3.10.2. Setting Up ELDK Build Environment

For your convenience, the ELDK build environment CD-ROM provides full ELDK build environment. All you need to do is copy the contents of the CD-ROM to an empty directory on your host system. Assuming the ELDK build environment CD-ROM is mounted at /mnt/cdrom, and the empty directory where you want to create the build environment is named /opt/eldk, use the following commands to create the build environment:

bash$ cd /opt/eldk
bash$ cp -r /mnt/cdrom/* .

These commands will create the directory structure as described in section 3.10.1. ELDK Build Process Overview above. All necessary scripts and ELDK specific source files will be placed in the build subdirectory, and the required tarballs can be found in the tarballs subdirectory. In the SRPMS subdirectory, you will find all the Fedora 7 SRPMS needed to build the ELDK.

Alternatively, you can obtain the ELDK build environment from the DENX GIT repository. Two modules are provided for check out: build and tarballs. The first one contains the files for the build subdirectory in the build environment, and the second one contains source tarballs of the packages that are included in the ELDK but are not present in Fedora 7. To create the ELDK build environment from the DENX GIT repository, use the following commands (the example below assumes that the root directory of the build environment is /opt/eldk):

bash$ cd /opt/eldk
bash$ git-clone git://www.denx.de/git/eldk/build
bash$ git-clone git://www.denx.de/git/eldk/tarballs
bash$ git-clone git://www.denx.de/git/eldk/SRPMS

ALERT! Note: To allow to install the ELDK on as many as possible Linux distributions (including old systems), we use a Red Hat 7.3 host system for building. Also, Fedora Core 5 is known to work as a build environment. Other, especially more recent Linux distributions, will most likely have problems. We therefor provide a Red Hat 7.3 based root file system image than can run in some virtualization environment (like qemu etc.). Here is an application note with detailed instructions: http://www.denx.de/wiki/DULG/AN2009_02_EldkReleaseBuildEnvironment

3.10.3. build.sh Usage

If you wish to perform only a part of the ELDK build procedure, for instance to re-build or update a certain package, it may sometimes be convenient to invoke the build.sh script manually, without the aid of the ELDK_BUILD script. Please note, however, that this approach is in general discouraged.

The whole build procedure is logically divided into six steps, and the build.sh must be told which of the build steps to perform. The build steps are defined as follows:

Further, the eldt and trg build steps are devided into sub-steps, as defined in the cpkgs.lst and tpkgs.lst

files (see below for details). You may specify which sub-steps of the build step are to be performed.

The formal syntax for the usage of build.sh is as follows:

bash$ ./build.sh [-a <arch>] [-n <name>] [-p <prefix>] [-r <result>] \
                 [-w <work>] <step_name> [<sub_step_number>]

-a <arch> target architecture: "ppc", "ppc64", "arm" or "mips", defaults to "ppc".
-n <build_name> an identification string for the build. It is used as a name for some directories created during the build. You may use for example the current date as the build name.
-p <prefix> is the name of the directory that contains the build environment. Refer to build overview above for description of the build environment.
-r <result> is the name of the directory where the resulting RPMs and SRPMs created on this step will be placed.
-w <work> is the name of the directory where the build is performed.
<stepname> is the name of the build step that is to be performed. Refer to the list of the build procedure steps above.
<sub_step_number> is an optional parameter which identifies sub-steps of the step which are to be performed. This is useful when you want to re-build only some specific packages. The numbers are defined in the cpkgs.lst and tpkgs.lst files discussed below. You can specify a range of numbers here. For instance, "2 5" means do steps from 2 to 5, while simply "2" means do all steps starting at 2.

ALERT! Please note that you must never use build.sh to build the ELDK from scratch. For build.sh to work correctly, the script must be invoked from the build environment after a successful build using the ELDK_BUILD script. A possible scenario of build.sh usage is such that you have a build environment with results of a build performed using the ELDK_BUILD script and want to re-build certain ELDT and target packages, for instance, because you have updated sources of a package or added a new package to the build.

When building the target packages (during the trg buildstep), build.sh examines the contents of the TARGET_CPU_FAMILY_LIST environment variable, which may contain a list indicating which target CPU variants the packages must be built for. Possible CPU variants are 4xx, 4xxFP, 6xx, 74xx, 8xx, 85xx and ppc64. For example, the command below rebuilds the target RPM listed in the tpckgs.lst file under the number of 47 (see section 3.10.4. Format of the cpkgs.lst and tpkgs.lst Files for description of the tpckgs.lst and cpkgs.lst files), for the 8xx and 85xx CPUs:

bash$ TARGET_CPU_FAMILY_LIST="8xx 85xx" \
> /opt/eldk/build.sh -a ppc \
>                    -n 2007-01-19 \
>                    -p /opt/eldk/build/ppc-2007-01-19 \
>                    -r /opt/eldk/build/ppc-2007-01-19/results \
>                    -w /opt/eldk/build/ppc-2007-01-19/work \
>                    trg 47 47

Note: If you are going to invoke build.sh to re-build a package that has already been built in the build environment by the ELDK_BUILD script, then you must first manually uninstall the package from ELDK installation created by the build procedure under the work directory of the build environment.

Note: It is recommended that you use the build.sh script only at the final stage of adding/updating a package to the ELDK. For debugging purposes, it is much more convenient and efficient to build both ELDT and target packages using a working ELDK installation, as described in the sections 3.8.2. Rebuilding Target Packages and 3.8.3. Rebuilding ELDT Packages above.

3.10.4. Format of the cpkgs.lst and tpkgs.lst Files

Each line of these files has the following format:

<sub_step_number> <package_name> <spec_file_name> \
  <binary_package_name> <package_version>

The ELDK source CD-ROM contains the cpkgs.lst and tpkgs.lst files used to build this version of the ELDK distribution. Use them as reference if you want to include any additional packages into the ELDK, or remove unneeded packages.

To add a package to the ELDK you must add a line to either the cpkgs.lst file, if you are adding a ELDT package, or to the tpkgs.lst file, if it is a target package. Keep in mind that the relative positions of packages in the cpkgs.lst and tpkgs.lst files (the sub-step numbers) are very important. The build procedure builds the packages sequentially as defined in the *.lst files and installs the packages in the "work" environment as they are built. This implies that if a package depends on other packages, those packages must be specified earlier (with smaller sub-step numbers) in the *.lst files.

Note: For cpkgs.lst, the package_version may be replaced by the special keyword "RHAUX". Such packages are used as auxiliary when building ELDK 4.2 on non-Fedora hosts. These packages will be built and used during the build process, but will not be put into the ELDK 4.2 distribution ISO images.

3.11. Notes for Solaris 2.x Host Environment

If you use a Solaris 2.x host environment, you need additional freeware packages (mostly GNU tools) to install and especially to build the ELDK packages. The following table lists all required packages that must be installed on the Solaris host system before attempting to build and/or install the ELDK. All these files except those marked with (**) (and the RPM and zlib-1.1.2 packages, which are available at ftp://rpmfind.net/linux/solaris are available for free download at ftp://ftp.sunfreeware.com/pub/freeware/sparc/2.6/

Necessary Freeware Packages:

Package Version Instance File Name
autoconf(**) 2.13 SMCautoc autoconf-2.13-sol26-sparc-local.gz
automake(**) 1.4 SMCautom automake-1.4-sol26-sparc-local.gz
bash 2.05 SMCbash bash-2.05-sol26-sparc-local.gz
binutils 2.11.2 SMCbinut binutils-2.11.2-sol26-sparc-local.gz
bison 1.28 SMCbison bison-1.28-sol26-sparc-local.gz
bzip2 1.0.1 SMCbzip2 bzip2-1.0.1-sol26-sparc-local.gz
ddd(*) 3.0 TUBddd ddd-3.0-sol26-sparc-local.gz
diffutils 2.7 GNUdiffut diffutils-2.7-sol26-sparc-local.gz
expect(*) 5.25 NTexpect expect-5.25-sol26-sparc-local.gz
fileutils 4.0 SMCfileu fileutils-4.0-sol26-sparc-local.gz
flex 2.5.4a FSFflex flex-2.5.4a-sol26-sparc-local.gz
gawk 3.1.0 SMCgawk gawk-3.1.0-sol26-sparc-local.gz
gcc 2.95.3 SMCgcc gcc-2.95.3-sol26-sparc-local.gz
gettext 0.10.37 SMCgtext gettext-0.10.37-sol26-sparc-local.gz
gzip 1.3 SMCgzip gzip-1.3-sol26-sparc-local
libiconv 1.6.1 SMClibi libiconv-1.6.1-sol26-sparc-local.gz
libtool 1.4 SMClibt libtool-1.4-sol26-sparc-local.gz
m4 1.4 SMCm4 m4-1.4-sol26-sparc-local.gz
make(**) 3.79.1 SMCmake make-3.79.1-sol26-sparc-local.gz
ncurses 5.2 SMCncurs ncurses-5.2-sol26-sparc-local.gz
patch 2.5 FSFpatch patch-2.5-sol26-sparc-local.gz
perl(**) 5.005_03 SMCperl perl-5.005_03-sol26-sparc-local.gz
python 1.5.2 SMCpython python-1.5.2-sol26-sparc-local.gz
rpm 2.5.2 RPM rpm-2.5.2.pkg
sed 3.02 SMCsed sed-3.02-sol26-sparc-local.gz
tar 1.13.19 SMCtar tar-1.13.19-sol26-sparc-local.gz
tcl(*) 8.3.3 SMCtcl tcl-8.3.3-sol26-sparc-local.gz
texinfo 4.0 SMCtexi texinfo-4.0-sol26-sparc-local.gz
textutils 2.0 SMCtextu textutils-2.0-sol26-sparc-local.gz
unzip 5.32 IZunzip unzip-5.32-sol26-sparc-local.gz
wget 1.7 SMCwget wget-1.7-sol26-sparc-local.gz
zlib(**) 1.0.4 SMCzlib zlib-1.0.4-sol26-sparc-local.gz
zlib 1.1.2 - zlib-1.1.2.tar.gz

The packages marked "(*)" are not absolutely required, but sooner or later you will need them anyway so we recommend to install them.

The packages marked "(**)" are older versions of the ones currently available at ftp://ftp.sunfreeware.com/pub/freeware/sparc/2.6/. You can obtain them from the DENX public FTP server.

The following symbolic links must be created in order to be able to build the ELDK on a Solaris machine:

/usr/local/bin/cc  --> /usr/local/bin/gcc
/usr/lib/libiconv.so.2 --> /usr/local/lib/libiconv.so.2
/usr/lib/libncurses.so.5 --> /usr/local/lib/libncurses.so.5

Additionally, to be able to build the ELDK on Solaris, you must place newer GNU gettext macros to the /usr/local/share/aclocal directory. This can be accomplished as follows:

4. System Setup

Some tools are needed to install and configure U-Boot and Linux on the target system. Also, especially during development, you will want to be able to interact with the target system. This section describes how to configure your host system for this purpose.

4.1. Serial Console Access

To use U-Boot and Linux as a development system and to make full use of all their capabilities you will need access to a serial console port on your target system. Later, U-Boot and Linux can be configured to allow for automatic execution without any user interaction.

There are several ways to access the serial console port on your target system, such as using a terminal server, but the most common way is to attach it to a serial port on your host. Additionally, you will need a terminal emulation program on your host system, such as cu or kermit.

4.2. Configuring the "cu" command

The cu command is part of the UUCP package and can be used to act as a dial-in terminal. It can also do simple file transfers, which can be used in U-Boot for image download.

On RedHat systems you can check if the UUCP package is installed as follows:

$ rpm -q uucp

If necessary, install the UUCP package from your distribution media.

To configure cu for use with U-Boot and Linux please make sure that the following entries are present in the UUCP configuration files; depending on your target configuration the serial port and/or the console baudrate may be different from the values used in this example: (/dev/ttyS0, 115200 bps, 8N1):

#
# /dev/ttyS0 at 115200 bps:
#
system          S0@115200
port            serial0_115200
time            any
     

#
# /dev/ttyS0 at 115200 bps:
#
port            serial0_115200
type            direct
device          /dev/ttyS0
speed           115200
hardflow        false
     

You can then connect to the serial line using the command

$ cu S0@115200
Connected.

To disconnect, type the escape character '~' followed by '.' at the beginning of a line.

See also: cu(1), info uucp.

4.3. Configuring the "kermit" command

The name kermit stands for a whole family of communications software for serial and network connections. The fact that it is available for most computers and operating systems makes it especially well suited for our purposes.

kermit executes the commands in its initialization file, .kermrc, in your home directory before it executes any other commands, so this can be easily used to customize its behaviour using appropriate initialization commands. The following settings are recommended for use with U-Boot and Linux:

set line /dev/ttyS0
set speed 115200
set carrier-watch off
set handshake none
set flow-control none
robust
set file type bin
set file name lit
set rec pack 1000
set send pack 1000
set window 5

This example assumes that you use the first serial port of your host system (/dev/ttyS0) at a baudrate of 115200 to connect to the target's serial console port.

You can then connect to the serial line:

$ kermit -c
Connecting to /dev/ttyS0, speed 115200.
The escape character is Ctrl-\ (ASCII 28, FS)
Type the escape character followed by C to get back,
or followed by ? to see other options.
----------------------------------------------------

TIP Due to licensing conditions you will often find two kermit packages in your GNU/Linux distribution. In this case you will want to install the ckermit package. The gkermit package is only a command line tool implementing the kermit transfer protocol.

TIP If you cannot find kermit on the distribution media for your Linux host system, you can download it from the kermit project home page: http://www.columbia.edu/kermit/

4.4. Using the "minicom" program

minicom is another popular serial communication program. Unfortunately, many users have reported problems using it with U-Boot and Linux, especially when trying to use it for serial image download. It's use is therefore discouraged.

4.5. Permission Denied Problems

The terminal emulation program must have write access to the serial port and to any locking files that are used to prevent concurrent access from other applications. Depending on the used Linux distribution you may have to make sure that:

4.6. Configuration of a TFTP Server

The fastest way to use U-Boot to load a Linux kernel or an application image is file transfer over Ethernet. For this purpose, U-Boot implements the TFTP protocol (see the tftpboot command in U-Boot).

To enable TFTP support on your host system you must make sure that the TFTP daemon program /usr/sbin/in.tftpd is installed. On RedHat systems you can verify this by running:

$ rpm -q tftp-server

If necessary, install the TFTP daemon program from your distribution media.

Most Linux distributions disable the TFTP service by default. To enable it for example on RedHat systems, edit the file /etc/xinetd.d/tftp and remove the line

disable = yes
or change it into a comment line by putting a hash character in front of it:

# default: off
# description: The tftp server serves files using the trivial file transfer
#       protocol.  The tftp protocol is often used to boot diskless
#       workstations, download configuration files to network-aware printers,
#       and to start the installation process for some operating systems.
service tftp
{
        socket_type             = dgram
        protocol                = udp
        wait                    = yes
        user                    = root
        server                  = /usr/sbin/in.tftpd
        server_args             = -s /tftpboot
#       disable                 = yes
        per_source              = 11
        cps                     = 100 2
}

Also, make sure that the /tftpboot directory exists and is world-readable (permissions at least "dr-xr-xr-x").

4.7. Configuration of a BOOTP / DHCP Server

BOOTP resp. DHCP can be used to automatically pass configuration information to the target. The only thing the target must "know" about itself is its own Ethernet hardware (MAC) address. The following command can be used to check if DHCP support is available on your host system:

$ rpm -q dhcp

If necessary, install the DHCP package from your distribution media.

Then you have to create the DHCP configuration file /etc/dhcpd.conf that matches your network setup. The following example gives you an idea what to do:

subnet 192.168.0.0 netmask 255.255.0.0 {
        option routers          192.168.1.1;
        option subnet-mask      255.255.0.0;

        option domain-name      "local.net";
        option domain-name-servers ns.local.net;

        host trgt {     hardware ethernet       00:30:BF:01:02:D0;
                        fixed-address           192.168.100.6;
                        option root-path        "/opt/eldk-4.2/ppc_4xx";
                        option host-name        "canyonlands";
                        next-server             192.168.1.1;
                        filename                "/tftpboot/canyonlands/uImage";
        }
}

With this configuration, the DHCP server will reply to a request from the target with the ethernet address 00:30:BF:01:02:D0 with the following information:

4.8. Configuring a NFS Server

For a development environment it is very convenient when the host and the target can share the same files over the network. The easiest way for such a setup is when the host provides NFS server functionality and exports a directory that can be mounted from the target as the root filesystem.

Assuming NFS server functionality is already provided by your host, the only configuration that needs to be added is an entry for your target root directory to your /etc/exports file, for instance like this:

/opt/eldk-4.2/ppc_4xx       192.168.0.0/255.255.0.0(rw,no_root_squash,sync)

This line exports the /opt/eldk-4.2/ppc_4xx directory with read and write permissions to all hosts on the 192.168.0.0 subnet.

After modifying the /etc/exports file you must make sure the NFS system is notified about the change, for instance by issuing the command:

# /sbin/service nfs restart

5. Das U-Boot

5.1. Current Versions

Das U-Boot (or just "U-Boot" for short) is Open Source Firmware for Embedded Power Architecture®, ARM, MIPS, x86 and other processors. The U-Boot project is hosted by DENX, where you can also find the project home page: http://www.denx.de/wiki/U-Boot/

The current version of the U-Boot source code can be retrieved from the DENX "git" repository.

You can browse the "git" repositories at http://git.denx.de/

The trees can be accessed through the git, HTTP, and rsync protocols. For example you can use one of the following commands to create a local clone of one of the source trees:

git clone git://git.denx.de/u-boot.git u-boot/
git clone http://git.denx.de/u-boot.git u-boot/
git clone rsync://git.denx.de/u-boot.git u-boot/

For details please see here.

Official releases of U-Boot are also available through FTP. Compressed tar archives can downloaded from the directory ftp://ftp.denx.de/pub/u-boot/.

5.2. Unpacking the Source Code

If you used GIT to get a copy of the U-Boot sources, then you can skip this next step since you already have an unpacked directory tree. If you downloaded a compressed tarball from the DENX FTP server, you can unpack it as follows:

$ cd /opt/eldk/usr/src
$ wget ftp://ftp.denx.de/pub/u-boot/u-boot-1.3.2.tar.bz2
$ rm -f u-boot
$ bunzip2 < u-boot-1.3.2.tar.bz2 | tar xf -
$ ln -s u-boot-1.3.2 u-boot
$ cd u-boot

5.3. Configuration

After changing to the directory with the U-Boot source code you should make sure that there are no build results from any previous configurations left:

$ make distclean

The following (model) command configures U-Boot for the canyonlands board:

$ make canyonlands_config


And finally we can compile the tools and U-Boot itself:

$ make all

By default the build is performed locally and the objects are saved in the source directory. One of the two methods can be used to change this behaviour and build U-Boot to some external directory:

1. Add O= to the make command line invocations:

make O=/tmp/build distclean
make O=/tmp/build canyonlands_config
make O=/tmp/build all

Note that if the 'O=output/dir' option is used then it must be used for all invocations of make.

2. Set environment variable BUILD_DIR to point to the desired location:

export BUILD_DIR=/tmp/build
make distclean
make canyonlands_config
make all

Note that the command line "O=" setting overrides the BUILD_DIR environment variable.

5.4. Installation

5.4.1. Before You Begin

5.4.1.1. Installation Requirements

The following section assumes that flash memory is used as the storage device for the firmware on your board. If this is not the case, the following instructions will not work - you will probably have to replace the storage device (probably ROM or EPROM) on such systems to install or update U-Boot.

5.4.1.2. Board Identification Data

All canyonlands boards use a serial number for identification purposes. Also, all boards have at least one ethernet (MAC) address assigned. You may lose your warranty on the board if this data gets lost. Before installing U-Boot or otherwise changing the software configuration of a board (like erasing some flash memory) you should make sure that you have all necessary information about such data.

5.4.2. Installation Using a BDM/JTAG Debugger

A fast and simple way to write new data to flash memory is via the use of a debugger or flash programmer with a BDM or JTAG interface. In cases where there is no running firmware at all (for instance on new hardware), this is usually the only way to install any software at all.

We use (and highly recommend) the BDI2000/BDI3000 by Abatron .

Other BDM / JTAG debuggers may work too, but how to use them is beyond the scope of this document. Please see the documentation for the tool you want to use.

Before you can use the BDI2000 you have to configure it. A configuration file that can be used with canyonlands boards is included in section 13.3. BDI2000 Configuration file

To install a new U-Boot image on your canyonlands board using a BDI2000, proceed as follows:

Note: Included topic DULGData_canyonlands.InstallUBootUsingBDI2000 does not exist yet

5.4.3. Installation using U-Boot

If U-Boot is already installed and running on your board, you can use these instructions to download another U-Boot image to replace the current one.

ALERT! Warning: Before you can install the new image, you have to erase the current one. If anything goes wrong your board will be dead. It is strongly recommended that:

ALERT! Proceed as follows:

=> setenv u-boot /tftpboot/duts/canyonlands/u-boot.bin
=> run load update
Using ppc_4xx_eth0 device
TFTP from server 192.168.1.1; our IP address is 192.168.100.6
Filename '/tftpboot/duts/canyonlands/u-boot.bin'.
Load address: 0x200000
Loading: ###########################
done
Bytes transferred = 393216 (60000 hex)
Un-Protected 3 sectors

... done
Erased 3 sectors
Copy to Flash... done
Saving Environment to Flash...
Un-Protected 1 sectors
Un-Protected 1 sectors
Erasing Flash...
. done
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
Protected 1 sectors
=> reset


U-Boot 2009.11.1 (Feb 05 2010 - 08:57:12)

CPU:   AMCC PowerPC 460EX Rev. B at 1066.667 MHz (PLB=266 OPB=88 EBC=88)
       Security/Kasumi support
       Bootstrap Option H - Boot ROM Location I2C (Addr 0x52)
       Internal PCI arbiter enabled
       32 kB I-Cache 32 kB D-Cache
Board: Canyonlands - AMCC PPC460EX Evaluation Board, 1*PCIe/1*SATA, Rev. 16
I2C:   ready
DRAM:  512 MB (ECC not enabled, 533 MHz, CL4)
FLASH: 64 MB
NAND:  128 MiB
PCI:   Bus Dev VenId DevId Class Int
PCIE1: link is not up.
DTT:   1 is 32 C
Net:   ppc_4xx_eth0, ppc_4xx_eth1

Type run flash_nfs to mount root filesystem over NFS

Hit any key to stop autoboot:  0
=> version

U-Boot 2009.11.1 (Feb 05 2010 - 08:57:12)
=>

5.5. Tool Installation

U-Boot uses a special image format when loading the Linux kernel or ramdisk or other images. This image contains (among other things) information about the time of creation, operating system, compression type, image type, image name and CRC32 checksums.

The tool mkimage is used to create such images or to display the information they contain. When using the ELDK, the mkimage command is already included with the other ELDK tools.

If you don't use the ELDK then you should install mkimage in some directory that is in your command search PATH, for instance:

$ cp tools/mkimage /usr/local/bin/

5.6. Initialization

To initialize the U-Boot firmware running on your canyonlands board, you have to connect a terminal to the board's serial console port.

The default configuration of the console port on the canyonlands board uses a baudrate of 115200/8N1 (115200 bps, 8 Bit per character, no parity, 1 stop bit, no handshake).

If you are running Linux on your host system we recommend either kermit or cu as terminal emulation programs. Do not use minicom, since this has caused problems for many users, especially for software download over the serial port.

For the configuration of your terminal program see section 4.1. Serial Console Access

Make sure that both hardware and software flow control are disabled.

5.7. Initial Steps

In the default configuration, U-Boot operates in an interactive mode which provides a simple command line-oriented user interface using a serial console on port UART1.

In the simplest case, this means that U-Boot shows a prompt (default: =>) when it is ready to receive user input. You then type a command, and press enter. U-Boot will try to run the required action(s), and then prompt for another command.

To see a list of the available U-Boot commands, you can type help (or simply ?). This will print a list of all commands that are available in your current configuration. [Please note that U-Boot provides a lot of configuration options; not all options are available for all processors and boards, and some options might be simply not selected for your configuration.]

=>
=> hel

With the command help <command> you can get additional information about most commands:

=> help tftpboot
tftpboot - boot image via network using TFTP protocol

Usage:
tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
=> help setenv printenv
setenv - set environment variables

Usage:
setenv name value ...
    - set environment variable 'name' to 'value ...'
setenv name
    - delete environment variable 'name'
printenv - print environment variables

Usage:
printenv
    - print values of all environment variables
printenv name ...
    - print value of environment variable 'name'
=>

Most commands can be abbreviated as long as the string remains unambiguous:

=> help fli tftp
flinfo - print FLASH memory information

Usage:
flinfo
    - print information for all FLASH memory banks
flinfo N
    - print information for FLASH memory bank # N
tftpboot - boot image via network using TFTP protocol

Usage:
tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
=>

5.8. The First Power-On

HELP Note: If you bought your canyonlands board with U-Boot already installed, you can skip this section since the manufacturer probably has already performed these steps.

Connect the port labeled UART1 on your canyonlands board to the designated serial port of your host, start the terminal program, and connect the power supply of your canyonlands board. You should see messages like this:

=>
=>
=> reset


U-Boot 2009.11.1 (Feb 05 2010 - 08:57:12)

CPU:   AMCC PowerPC 460EX Rev. B at 1066.667 MHz (PLB=266 OPB=88 EBC=88)
       Security/Kasumi support
       Bootstrap Option H - Boot ROM Location I2C (Addr 0x52)
       Internal PCI arbiter enabled
       32 kB I-Cache 32 kB D-Cache
Board: Canyonlands - AMCC PPC460EX Evaluation Board, 1*PCIe/1*SATA, Rev. 16
I2C:   ready
DRAM:  512 MB (ECC not enabled, 533 MHz, CL4)
FLASH: 64 MB
NAND:  128 MiB
PCI:   Bus Dev VenId DevId Class Int
PCIE1: link is not up.
DTT:   1 is 32 C
Net:   ppc_4xx_eth0, ppc_4xx_eth1

Type run flash_nfs to mount root filesystem over NFS

Hit any key to stop autoboot:  0
=>

You can interrupt the "Count-Down" by pressing any key. If you don't you will probably see some (harmless) error messages because the system has not been initialized yet.

ALERT! In some cases you may see a message

*** Warning - bad CRC, using default environment

This is harmless and will go away as soon as you have initialized and saved the environment variables.

At first you have to enter the serial number and the ethernet address of your board. Pay special attention here since these parameters are write protected and cannot be changed once saved (usually this is done by the manufacturer of the board). To enter the data you have to use the U-Boot command setenv, followed by the variable name and the data, all separated by white space (blank and/or TAB characters). Use the variable name serial# for the board ID and/or serial number, and ethaddr for the ethernet address, for instance:

=> setenv ethaddr !!!!!!FILL_THIS!!!!!!
=> setenv serial# 86BA-5AA1-BD9

Use the printenv command to verify that you have entered the correct values:

=> printenv serial# ethaddr
## Error: "serial#" not defined
ethaddr=00:10:ec:01:08:84
=>

Please double check that the printed values are correct! You will not be able to correct any errors later! If there is something wrong, reset the board and restart from the beginning; otherwise you can store the parameters permanently using the saveenv command:

=> saveenv
Saving Environment to Flash...
Un-Protected 1 sectors
Un-Protected 1 sectors
Erasing Flash...
. done
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
Protected 1 sectors
=>

5.9. U-Boot Command Line Interface

The following section describes the most important commands available in U-Boot. Please note that U-Boot is highly configurable, so not all of these commands may be available in the configuration of U-Boot installed on your hardware, or additional commands may exist. You can use the help command to print a list of all available commands for your configuration.

For most commands, you do not need to type in the full command name; instead it is sufficient to type a few characters. For instance, help can be abbreviated as h.

ALERT! The behaviour of some commands depends on the configuration of U-Boot and on the definition of some variables in your U-Boot environment.

ALERT! Almost all U-Boot commands expect numbers to be entered in hexadecimal input format. (Exception: for historical reasons, the sleep command takes it's argument in decimal input format.)

ALERT! Be careful not to use edit keys besides 'Backspace', as hidden characters in things like environment variables can be very difficult to find.

5.9.1. Information Commands

5.9.1.1. bdinfo - print Board Info structure

=> help bdinfo
bdinfo - print Board Info structure

Usage:
bdinfo
=>

The bdinfo command (short: bdi) prints the information that U-Boot passes about the board such as memory addresses and sizes, clock frequencies, MAC address, etc. This information is mainly needed to be passed to the Linux kernel.

=> bdi
memstart    = 0x00000000
memsize       = 0x20000000
flashstart  = 0xFC000000
flashsize   = 0x04000000
flashoffset = 0x00000000
sramstart   = 0x00000000
sramsize    = 0x00000000
bootflags   = 0xFFFE6530
intfreq       = 1066.667 MHz
busfreq       = 266.667 MHz
ethaddr       = 00:10:ec:01:08:84
eth1addr    = 00:10:ec:81:08:84
IP addr       = 192.168.100.6
baudrate    = 115200 bps
=>

5.9.1.2. coninfo - print console devices and informations

=> help conin
coninfo - print console devices and information

Usage:
coninfo
=>

The coninfo command (short: conin) displays information about the available console I/O devices.

=> conin
List of available devices:
serial    80000003 SIO stdin stdout stderr
serial1    00000003 .IO
serial0    00000003 .IO
nc    80000003 SIO
=>

The output contains the device name, flags, and the current usage. For example, the output

serial   80000003 SIO stdin stdout stderr

means that the serial device is a system device (flag 'S') which provides input (flag 'I') and output (flag 'O') functionality and is currently assigned to the 3 standard I/O streams stdin, stdout and stderr.

5.9.1.3. flinfo - print FLASH memory information

=> help flinfo
flinfo - print FLASH memory information

Usage:
flinfo
    - print information for all FLASH memory banks
flinfo N
    - print information for FLASH memory bank # N
=>

The command flinfo (short: fli) can be used to get information about the available flash memory (see Flash Memory Commands below).

=> fli

Bank # 1: CFI conformant FLASH (16 x 16)  Size: 64 MB in 512 Sectors
  AMD Standard command set, Manufacturer ID: 0x01, Device ID: 0x227E
  Erase timeout: 16384 ms, write timeout: 2 ms
  Buffer write timeout: 5 ms, buffer size: 32 bytes

  Sector Start Addresses:
  FC000000     FC020000     FC040000     FC060000     FC080000
  FC0A0000     FC0C0000     FC0E0000     FC100000     FC120000
  FC140000     FC160000     FC180000     FC1A0000     FC1C0000 E
  FC1E0000     FC200000     FC220000     FC240000     FC260000
  FC280000     FC2A0000     FC2C0000     FC2E0000     FC300000
  FC320000     FC340000     FC360000     FC380000     FC3A0000
  FC3C0000 E     FC3E0000 E     FC400000 E     FC420000 E     FC440000 E
  FC460000 E     FC480000 E     FC4A0000 E     FC4C0000 E     FC4E0000 E
  FC500000 E     FC520000 E     FC540000 E     FC560000 E     FC580000 E
  FC5A0000 E     FC5C0000 E     FC5E0000 E     FC600000 E     FC620000 E
  FC640000 E     FC660000 E     FC680000 E     FC6A0000 E     FC6C0000 E
  FC6E0000 E     FC700000 E     FC720000 E     FC740000 E     FC760000 E
  FC780000 E     FC7A0000 E     FC7C0000 E     FC7E0000 E     FC800000 E
  FC820000 E     FC840000 E     FC860000 E     FC880000 E     FC8A0000 E
  FC8C0000 E     FC8E0000 E     FC900000 E     FC920000 E     FC940000 E
  FC960000 E     FC980000 E     FC9A0000 E     FC9C0000 E     FC9E0000 E
  FCA00000 E     FCA20000 E     FCA40000 E     FCA60000 E     FCA80000 E
  FCAA0000 E     FCAC0000 E     FCAE0000 E     FCB00000 E     FCB20000 E
  FCB40000 E     FCB60000 E     FCB80000 E     FCBA0000 E     FCBC0000 E
  FCBE0000 E     FCC00000 E     FCC20000 E     FCC40000 E     FCC60000 E
  FCC80000 E     FCCA0000 E     FCCC0000 E     FCCE0000 E     FCD00000 E
  FCD20000 E     FCD40000 E     FCD60000 E     FCD80000 E     FCDA0000 E
  FCDC0000 E     FCDE0000 E     FCE00000 E     FCE20000 E     FCE40000 E
  FCE60000 E     FCE80000 E     FCEA0000 E     FCEC0000 E     FCEE0000 E
  FCF00000 E     FCF20000 E     FCF40000 E     FCF60000 E     FCF80000 E
  FCFA0000 E     FCFC0000 E     FCFE0000 E     FD000000 E     FD020000 E
  FD040000 E     FD060000 E     FD080000 E     FD0A0000 E     FD0C0000 E
  FD0E0000 E     FD100000 E     FD120000 E     FD140000 E     FD160000 E
  FD180000 E     FD1A0000 E     FD1C0000 E     FD1E0000 E     FD200000 E
  FD220000 E     FD240000 E     FD260000 E     FD280000 E     FD2A0000 E
  FD2C0000 E     FD2E0000 E     FD300000 E     FD320000 E     FD340000 E
  FD360000 E     FD380000 E     FD3A0000 E     FD3C0000 E     FD3E0000 E
  FD400000 E     FD420000 E     FD440000 E     FD460000 E     FD480000 E
  FD4A0000 E     FD4C0000 E     FD4E0000 E     FD500000 E     FD520000 E
  FD540000 E     FD560000 E     FD580000 E     FD5A0000 E     FD5C0000 E
  FD5E0000 E     FD600000     FD620000 E     FD640000 E     FD660000 E
  FD680000 E     FD6A0000 E     FD6C0000 E     FD6E0000 E     FD700000 E
  FD720000 E     FD740000 E     FD760000 E     FD780000 E     FD7A0000 E
  FD7C0000 E     FD7E0000 E     FD800000 E     FD820000 E     FD840000 E
  FD860000 E     FD880000 E     FD8A0000 E     FD8C0000 E     FD8E0000 E
  FD900000 E     FD920000 E     FD940000 E     FD960000 E     FD980000 E
  FD9A0000 E     FD9C0000 E     FD9E0000 E     FDA00000 E     FDA20000 E
  FDA40000 E     FDA60000 E     FDA80000 E     FDAA0000 E     FDAC0000 E
  FDAE0000 E     FDB00000 E     FDB20000 E     FDB40000 E     FDB60000 E
  FDB80000 E     FDBA0000 E     FDBC0000 E     FDBE0000 E     FDC00000 E
  FDC20000 E     FDC40000 E     FDC60000 E     FDC80000 E     FDCA0000 E
  FDCC0000 E     FDCE0000 E     FDD00000 E     FDD20000 E     FDD40000 E
  FDD60000 E     FDD80000 E     FDDA0000 E     FDDC0000 E     FDDE0000 E
  FDE00000 E     FDE20000 E     FDE40000 E     FDE60000 E     FDE80000 E
  FDEA0000 E     FDEC0000 E     FDEE0000 E     FDF00000 E     FDF20000 E
  FDF40000 E     FDF60000 E     FDF80000 E     FDFA0000 E     FDFC0000 E
  FDFE0000 E     FE000000 E     FE020000 E     FE040000 E     FE060000 E
  FE080000 E     FE0A0000 E     FE0C0000 E     FE0E0000 E     FE100000 E
  FE120000 E     FE140000 E     FE160000 E     FE180000 E     FE1A0000 E
  FE1C0000 E     FE1E0000 E     FE200000 E     FE220000 E     FE240000 E
  FE260000 E     FE280000 E     FE2A0000 E     FE2C0000 E     FE2E0000 E
  FE300000 E     FE320000 E     FE340000 E     FE360000 E     FE380000 E
  FE3A0000 E     FE3C0000 E     FE3E0000 E     FE400000 E     FE420000 E
  FE440000 E     FE460000 E     FE480000 E     FE4A0000 E     FE4C0000 E
  FE4E0000 E     FE500000 E     FE520000 E     FE540000 E     FE560000 E
  FE580000 E     FE5A0000 E     FE5C0000 E     FE5E0000 E     FE600000 E
  FE620000 E     FE640000 E     FE660000 E     FE680000 E     FE6A0000 E
  FE6C0000 E     FE6E0000 E     FE700000 E     FE720000 E     FE740000 E
  FE760000 E     FE780000 E     FE7A0000 E     FE7C0000 E     FE7E0000 E
  FE800000 E     FE820000 E     FE840000 E     FE860000 E     FE880000 E
  FE8A0000 E     FE8C0000 E     FE8E0000 E     FE900000 E     FE920000 E
  FE940000 E     FE960000 E     FE980000 E     FE9A0000 E     FE9C0000 E
  FE9E0000 E     FEA00000 E     FEA20000 E     FEA40000 E     FEA60000 E
  FEA80000 E     FEAA0000 E     FEAC0000 E     FEAE0000 E     FEB00000 E
  FEB20000 E     FEB40000 E     FEB60000 E     FEB80000 E     FEBA0000 E
  FEBC0000 E     FEBE0000 E     FEC00000 E     FEC20000 E     FEC40000 E
  FEC60000 E     FEC80000 E     FECA0000 E     FECC0000 E     FECE0000 E
  FED00000 E     FED20000 E     FED40000 E     FED60000 E     FED80000 E
  FEDA0000 E     FEDC0000 E     FEDE0000 E     FEE00000 E     FEE20000 E
  FEE40000 E     FEE60000 E     FEE80000 E     FEEA0000 E     FEEC0000 E
  FEEE0000 E     FEF00000 E     FEF20000 E     FEF40000 E     FEF60000 E
  FEF80000 E     FEFA0000 E     FEFC0000 E     FEFE0000 E     FF000000 E
  FF020000 E     FF040000 E     FF060000 E     FF080000 E     FF0A0000 E
  FF0C0000 E     FF0E0000 E     FF100000 E     FF120000 E     FF140000 E
  FF160000 E     FF180000 E     FF1A0000 E     FF1C0000 E     FF1E0000 E
  FF200000 E     FF220000 E     FF240000 E     FF260000 E     FF280000 E
  FF2A0000 E     FF2C0000 E     FF2E0000 E     FF300000 E     FF320000 E
  FF340000 E     FF360000 E     FF380000 E     FF3A0000 E     FF3C0000 E
  FF3E0000 E     FF400000 E     FF420000 E     FF440000 E     FF460000 E
  FF480000 E     FF4A0000 E     FF4C0000 E     FF4E0000 E     FF500000 E
  FF520000 E     FF540000 E     FF560000 E     FF580000 E     FF5A0000 E
  FF5C0000 E     FF5E0000 E     FF600000 E     FF620000 E     FF640000 E
  FF660000 E     FF680000 E     FF6A0000 E     FF6C0000 E     FF6E0000 E
  FF700000 E     FF720000 E     FF740000 E     FF760000 E     FF780000 E
  FF7A0000 E     FF7C0000 E     FF7E0000 E     FF800000 E     FF820000 E
  FF840000 E     FF860000 E     FF880000 E     FF8A0000 E     FF8C0000 E
  FF8E0000 E     FF900000 E     FF920000 E     FF940000 E     FF960000 E
  FF980000 E     FF9A0000 E     FF9C0000 E     FF9E0000 E     FFA00000 E
  FFA20000 E     FFA40000 E     FFA60000 E     FFA80000 E     FFAA0000 E
  FFAC0000 E     FFAE0000 E     FFB00000 E     FFB20000 E     FFB40000 E
  FFB60000 E     FFB80000 E     FFBA0000 E     FFBC0000 E     FFBE0000 E
  FFC00000 E     FFC20000 E     FFC40000 E     FFC60000 E     FFC80000 E
  FFCA0000 E     FFCC0000 E     FFCE0000 E     FFD00000 E     FFD20000 E
  FFD40000 E     FFD60000 E     FFD80000 E     FFDA0000 E     FFDC0000 E
  FFDE0000 E     FFE00000 E     FFE20000 E     FFE40000 E     FFE60000 E
  FFE80000 E     FFEA0000 E     FFEC0000 E     FFEE0000 E     FFF00000 E
  FFF20000 E     FFF40000 E     FFF60000   RO     FFF80000   RO     FFFA0000   RO
  FFFC0000   RO     FFFE0000   RO
=>

5.9.1.4. iminfo - print header information for application image

=> help iminfo
iminfo - print header information for application image

Usage:
iminfo addr [addr ...]
    - print header information for application image starting at
      address 'addr' in memory; this includes verification of the
      image contents (magic number, header and payload checksums)
=>

iminfo (short: imi) is used to print the header information for images like Linux kernels or ramdisks. It prints (among other information) the image name, type and size and verifies that the CRC32 checksums stored within the image are OK.

=> tftp ${ram_ws} ${bootfile}
Waiting for PHY auto negotiation to complete.... done
ENET Speed is 1000 Mbps - FULL duplex connection (EMAC0)
Using ppc_4xx_eth0 device
TFTP from server 192.168.1.1; our IP address is 192.168.100.6
Filename '/tftpboot/duts/canyonlands/uImage'.
Load address: 0x100000
Loading: T #################################################################
    #################################################################
    ####
done
Bytes transferred = 1958609 (1de2d1 hex)
=> imi ${ram_ws}

## Checking Image at 00100000 ...
   Legacy image found
   Image Name:    Linux-2.6.32.7-00007-g08eba26
   Created:    2010-02-04  17:54:22 UTC
   Image Type:    PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    1958545 Bytes =  1.9 MB
   Load Address: 00000000
   Entry Point:    00000000
   Verifying Checksum ... OK
=>

HELP Like with many other commands, the exact operation of this command can be controlled by the settings of some U-Boot environment variables (here: the verify variable). See below for details.

5.9.1.5. help - print online help

=> help help
help - print online help

Usage:
help [command ...]
    - show help information (for 'command')
'help' prints online help for the monitor commands.

Without arguments, it prints a short usage message for all commands.

To get detailed help information for specific commands you can type
'help' with one or more command names as arguments.
=>

The help command (short: h or ?) prints online help. Without any arguments, it prints a list of all U-Boot commands that are available in your configuration of U-Boot. You can get detailed information for a specific command by typing its name as argument to the help command:

=> help protect
protect - enable or disable FLASH write protection

Usage:
protect on  start end
    - protect FLASH from addr 'start' to addr 'end'
protect on start +len
    - protect FLASH from addr 'start' to end of sect w/addr 'start'+'len'-1
protect on  N:SF[-SL]
    - protect sectors SF-SL in FLASH bank # N
protect on  bank N
    - protect FLASH bank # N
protect on  all
    - protect all FLASH banks
protect off start end
    - make FLASH from addr 'start' to addr 'end' writable
protect off start +len
    - make FLASH from addr 'start' to end of sect w/addr 'start'+'len'-1 wrtable
protect off N:SF[-SL]
    - make sectors SF-SL writable in FLASH bank # N
protect off bank N
    - make FLASH bank # N writable
protect off all
    - make all FLASH banks writable
=>

5.9.2. Memory Commands

5.9.2.1. base - print or set address offset

=> help base
base - print or set address offset

Usage:
base
    - print address offset for memory commands
base off
    - set address offset for memory commands to 'off'
=>

You can use the base command (short: ba) to print or set a "base address" that is used as address offset for all memory commands; the default value of the base address is 0, so all addresses you enter are used unmodified. However, when you repeatedly have to access a certain memory region (like the internal memory of some embedded Power Architecture® processors) it can be very convenient to set the base address to the start of this area and then use only the offsets:

=> base
Base Address: 0x00000000
=> md 0 0xc
00000000: 00ff43a6 00000000 ffffffff ffffffff    ..C.............
00000010: 00ff43a6 00000000 ffffffff ffffffff    ..C.............
00000020: 0c904d01 320b4481 1ea3d0a2 c498293a    ..M.2.D.......):
=> base 0x100000
Base Address: 0x00100000
=> md 0 0xc
00100000: 0e0a0e81 bd86200a 60a19054 2c12c402    ...... .`..T,...
00100010: c101d028 00438198 7ab01239 62406128    ...(.C..z..9b@a(
00100020: 0c900d05 320b4581 1ca3d0a2 c498293a    ....2.E.......):
=>

5.9.2.2. crc32 - checksum calculation

The crc32 command (short: crc) can be used to caculate a CRC32 checksum over a range of memory:

=>  crc 0x100004 0x3FC
CRC32 for 00100004 ... 001003ff ==> 8083764e
=>

When used with 3 arguments, the command stores the calculated checksum at the given address:

=>  crc 0x100004 0x3FC 0x100000
CRC32 for 00100004 ... 001003ff ==> 8083764e
=> md 0x100000 4
00100000: 8083764e bd86200a 60a19054 2c12c402    ..vN.. .`..T,...
=>

As you can see, the CRC32 checksum was not only printed, but also stored at address 0x100000.

5.9.2.3. cmp - memory compare

=> help cmp
cmp - memory compare

Usage:
cmp [.b, .w, .l] addr1 addr2 count
=>

With the cmp command you can test of the contents of two memory areas is identical or not. The command will either test the whole area as specified by the 3rd (length) argument, or stop at the first difference.

=> cmp 0x100000 0x200000 0x400
word at 0x00100000 (0x8083764e) != word at 0x00200000 (0x27051956)
Total of 0 words were the same
=> md 0x100000 0xc
00100000: 8083764e bd86200a 60a19054 2c12c402    ..vN.. .`..T,...
00100010: c101d028 00438198 7ab01239 62406128    ...(.C..z..9b@a(
00100020: 0c900d05 320b4581 1ca3d0a2 c498293a    ....2.E.......):
=> md 0x200000 0xc
00200000: 27051956 552d426f 6f742032 3030392e    '..VU-Boot 2009.
00200010: 31312e31 20284665 62203035 20323031    11.1 (Feb 05 201
00200020: 30202d20 30383a35 373a3132 29000000    0 - 08:57:12)...
=>

Like most memory commands the cmp can access the memory in different sizes: as 32 bit (long word), 16 bit (word) or 8 bit (byte) data. If invoked just as cmp the default size (32 bit or long words) is used; the same can be selected explicitely by typing cmp.l instead. If you want to access memory as 16 bit or word data, you can use the variant cmp.w instead; and to access memory as 8 bit or byte data please use cmp.b.

ALERT! Please note that the count argument specifies the number of data items to process, i. e. the number of long words or words or bytes to compare.

=> cmp.l 0x100000 0x200000 0x400
word at 0x00100000 (0x8083764e) != word at 0x00200000 (0x27051956)
Total of 0 words were the same
=> cmp.w 0x100000 0x200000 0x800
halfword at 0x00100000 (0x8083) != halfword at 0x00200000 (0x2705)
Total of 0 halfwords were the same
=> cmp.b 0x100000 0x200000 0x1000
byte at 0x00100000 (0x80) != byte at 0x00200000 (0x27)
Total of 0 bytes were the same
=>

5.9.2.4. cp - memory copy

=> help cp
cp - memory copy

Usage:
cp [.b, .w, .l] source target count
=> help cp
cp - memory copy

Usage:
cp [.b, .w, .l] source target count
=>

The cp is used to copy memory areas.

=> cp 0x100000 0x200000 0x10000
=>

The cp understands the type extensions .l, .w and .b :

=> cp.l 0x200000 0x100000 0x10000
=> cp.w 0x200000 0x100000 0x20000
=> cp.b 0x200000 0x100000 0x40000
=>

5.9.2.5. md - memory display

=> help md
md - memory display

Usage:
md [.b, .w, .l] address [# of objects]
=>

The md can be used to display memory contents both as hexadecimal and ASCII data.

=> md 0x100000
00100000: 8083764e bd86200a 60a19054 2c12c402    ..vN.. .`..T,...
00100010: c101d028 00438198 7ab01239 62406128    ...(.C..z..9b@a(
00100020: 0c900d05 320b4581 1ca3d0a2 c498293a    ....2.E.......):
=>
00100030: 58f5c828 6029e009 d0718131 154b105b    X..(`)...q.1.K.[
00100040: 9019a424 7423a001 e064013c 016a0070    ...$t#...d.<.j.p
00100050: d0809820 12437140 0064e018 424be2a9    ... .Cq@.d..BK..
=>

This command, too, can be used with the type extensions .l, .w and .b :

=>
=> md.w 0x100000
00100000: 8083 764e bd86 200a 60a1 9054 2c12 c402    ..vN.. .`..T,...
00100010: c101 d028 0043 8198    ...(.C..
=> md.b 0x10000

The last displayed memory address and the value of the count argument are remembered, so when you enter md again without arguments it will automatically continue at the next address, and use the same count again.

=> md.b 0x100000 0x20
00100000: 2f 83 00 00 40 9e ff 38 38 60 00 00 4b ff ff 3c    /...@..88`..K..<
00100010: 83 5e 00 0c 80 9e 00 08 2b 9a 00 ff 82 9e 00 10    .^......+.......
=> md.w 0x100000
00100000: 2f83 0000 409e ff38 3860 0000 4bff ff3c    /...@..88`..K..<
00100010: 835e 000c 809e 0008 2b9a 00ff 829e 0010    .^......+.......
00100020: 82be 0014 7f45 d378 409d 000c 3b40 00ff    .....E.x@...;@..
00100030: 38a0 00ff 2b95 00ff 409d 0008 3aa0 00ff    8...+...@...:...
=> md 0x100000
00100000: 2f830000 409eff38 38600000 4bffff3c    /...@..88`..K..<
00100010: 835e000c 809e0008 2b9a00ff 829e0010    .^......+.......
00100020: 82be0014 7f45d378 409d000c 3b4000ff    .....E.x@...;@..
00100030: 38a000ff 2b9500ff 409d0008 3aa000ff    8...+...@...:...
00100040: 8002021c 3bfb000a 7f9f0040 419d002c    ....;......@A..,
00100050: 2f9a0000 419e0014 7c1f0050 3925ffff    /...A...|..P9%..
00100060: 7f890040 419d0014 7fe3fb78 4bf1401d    ...@A......xK.@.
00100070: 7c651b78 48000014 3c00bfff 6000ffff    |e.xH...<...`...
=>

5.9.2.6. mm - memory modify (auto-incrementing)

=> help mm
mm - memory modify (auto-incrementing address)

Usage:
mm [.b, .w, .l] address
=>

The mm is a method to interactively modify memory contents. It will display the address and current contents and then prompt for user input. If you enter a legal hexadecimal number, this new value will be written to the address. Then the next address will be prompted. If you don't enter any value and just press ENTER, then the contents of this address will remain unchanged. The command stops as soon as you enter any data that is not a hex number (like .):

=>
=> mm 0x100000
00100000: 8083764e ? 0
00100004: bd86200a ? 0xaabbccdd
00100008: 60a19054 ? 0x01234567
0010000c: 2c12c402 ? .
=> md 0x100000 0x10
00100000: 00000000 aabbccdd 01234567 2c12c402    .........#Eg,...
00100010: c101d028 00438198 7ab01239 62406128    ...(.C..z..9b@a(
00100020: 0c900d05 320b4581 1ca3d0a2 c498293a    ....2.E.......):
00100030: 58f5c828 6029e009 d0718131 154b105b    X..(`)...q.1.K.[
=>

Again this command can be used with the type extensions .l, .w and .b :

=>
=> mm.w 0x100000
00100000: 0000 ? 0x0101
00100002: 0000 ? 0x0202
00100004: aabb ? 0x4321
00100006: ccdd ? 0x8765
00100008: 0123 ? .
=> md 0x100000 0x10
00100000: 01010202 43218765 01234567 2c12c402    ....C!.e.#Eg,...
00100010: c101d028 00438198 7ab01239 62406128    ...(.C..z..9b@a(
00100020: 0c900d05 320b4581 1ca3d0a2 c498293a    ....2.E.......):
00100030: 58f5c828 6029e009 d0718131 154b105b    X..(`)...q.1.K.[
=>

=>
=> mm.b 0x100000
00100000: 01 ? 0x48
00100001: 01 ? 0x65
00100002: 02 ? 0x6c
00100003: 02 ? 0x6c
00100004: 43 ? 0x6f
00100005: 21 ? 0x20
00100006: 87 ? 0x20
00100007: 65 ? 0x20
00100008: 01 ? .
=> md 0x100000 0x10
00100000: 48656c6c 6f202020 01234567 2c12c402    Hello    .#Eg,...
00100010: c101d028 00438198 7ab01239 62406128    ...(.C..z..9b@a(
00100020: 0c900d05 320b4581 1ca3d0a2 c498293a    ....2.E.......):
00100030: 58f5c828 6029e009 d0718131 154b105b    X..(`)...q.1.K.[
=>

5.9.2.7. mtest - simple RAM test

=> help mtest
mtest - simple RAM read/write test

Usage:
mtest [start [end [pattern [iterations]]]]
=>

The mtest provides a simple memory test.

=>
=> mtest 0x100000 0x200000
Pattern 00000000  Writing...  Reading...Pattern FFFFFFFF  Writing...  Reading...Pattern 00000001  Writing...  Reading...Pattern FFFFFFFE  Writing...  Reading...Pattern 00000002  Writing...  Reading...Pattern FFFFFFFD  Writing...  Reading...Pattern 00000003  Writing...  Reading...Pattern FFFFFFFC  Writing...  Reading...Pattern 00000004  Writing...  Reading...Pattern FFFFFFFB  Writing...  Reading...Pattern 00000005  Writing...  Reading...Pattern FFFFFFFA  Writing...  Reading...Pattern 00000006  Writing...  Reading...Pattern FFFFFFF9  Writing...  Reading...Pattern 00000007  Writing...  Reading...Pattern FFFFFFF8  Writing...  Reading...Pattern 00000008  Writing...  Reading...Pattern FFFFFFF7  Writing...  Reading...Pattern 00000009  Writing...  Reading...Pattern FFFFFFF6  Writing...  Reading...Pattern 0000000A  Writing...  Reading...Pattern FFFFFFF5  Writing...  Reading...Pattern 0000000B  Writing...  Reading...Pattern FFFFFFF4  Writing...  Reading...Pattern 0000000C  Writing...  Reading...Pattern FFFFFFF3  Writing...  Reading...Pattern 0000000D  Writing...  Reading...Pattern FFFFFFF2  Writing...  Reading...Pattern 0000000E  Writing...  Reading...Pattern FFFFFFF1  Writing...  Reading...Pattern 0000000F  Writing...  Reading...
=>

ALERT! This tests writes to memory, thus modifying the memory contents. It will fail when applied to ROM or flash memory.

ALERT! This command may crash the system when the tested memory range includes areas that are needed for the operation of the U-Boot firnware (like exception vector code, or U-Boot's internal program code, stack or heap memory areas).

5.9.2.8. mw - memory write (fill)

=> help mw
mw - memory write (fill)

Usage:
mw [.b, .w, .l] address value [count]
=>

The mw is a way to initialize (fill) memory with some value. When called without a count argument, the value will be written only to the specified address. When used with a count, then a whole memory areas will be initialized with this value:

=> md 0x100000 0x10
00100000: 0000000f 00000010 00000011 00000012    ................
00100010: 00000013 00000014 00000015 00000016    ................
00100020: 00000017 00000018 00000019 0000001a    ................
00100030: 0000001b 0000001c 0000001d 0000001e    ................
=> mw 0x100000 0xaabbccdd
=> md 0x100000 0x10
00100000: aabbccdd 00000010 00000011 00000012    ................
00100010: 00000013 00000014 00000015 00000016    ................
00100020: 00000017 00000018 00000019 0000001a    ................
00100030: 0000001b 0000001c 0000001d 0000001e    ................
=> mw 0x100000 0 6
=> md 0x100000 0x10
00100000: 00000000 00000000 00000000 00000000    ................
00100010: 00000000 00000000 00000015 00000016    ................
00100020: 00000017 00000018 00000019 0000001a    ................
00100030: 0000001b 0000001c 0000001d 0000001e    ................
=>

This is another command that accepts the type extensions .l, .w and .b :

=>  mw.w 0x100004 0x1155 6
=> md 0x100000 0x10
00100000: 00000000 11551155 11551155 11551155    .....U.U.U.U.U.U
00100010: 00000000 00000000 00000015 00000016    ................
00100020: 00000017 00000018 00000019 0000001a    ................
00100030: 0000001b 0000001c 0000001d 0000001e    ................
=>  mw.b 0x100007 0xff 7
=> md 0x100000 0x10
00100000: 00000000 115511ff ffffffff ffff1155    .....U.........U
00100010: 00000000 00000000 00000015 00000016    ................
00100020: 00000017 00000018 00000019 0000001a    ................
00100030: 0000001b 0000001c 0000001d 0000001e    ................
=>

5.9.2.9. nm - memory modify (constant address)

=> help nm
nm - memory modify (constant address)

Usage:
nm [.b, .w, .l] address
=>

The nm command (non-incrementing memory modify) can be used to interactively write different data several times to the same address. This can be useful for instance to access and modify device registers:

=>
=> nm.b 0x100000
00100000: 00 ? 0x48
00100000: 48 ? 0x65
00100000: 65 ? 0x6c
00100000: 6c ? 0x6c
00100000: 6c ? 0x6f
00100000: 6f ? .
=> md 0x100000 8
00100000: 6f000000 115511ff ffffffff ffff1155    o....U.........U
00100010: 00000000 00000000 00000015 00000016    ................
=>

The nm command too accepts the type extensions .l, .w and .b.

5.9.2.10. loop - infinite loop on address range

=> help loop
loop - infinite loop on address range

Usage:
loop [.b, .w, .l] address number_of_objects
=>

The loop command reads in a tight loop from a range of memory. This is intended as a special form of a memory test, since this command tries to read the memory as fast as possible.

ALERT! This command will never terminate. There is no way to stop it but to reset the board!

=> loop 100000 8

5.9.3. Flash Memory Commands

5.9.3.1. cp - memory copy

=> help cp
cp - memory copy

Usage:
cp [.b, .w, .l] source target count
=> help cp
cp - memory copy

Usage:
cp [.b, .w, .l] source target count
=>

The cp command "knows" about flash memory areas and will automatically invoke the necessary flash programming algorithm when the target area is in flash memory.

=> cp.b 0x100000 0xFF900000 0x40000
Copy to Flash... done
=>

ALERT! Writing to flash memory may fail when the target area has not been erased (see erase below), or if it is write-protected (see protect below).

=> cp.b 0x100000 0xFF900000 0x40000
Copy to Flash... Can't write to protected Flash sectors
=>

ALERT! Remember that the count argument specifies the number of items to copy. If you have a "length" instead (= byte count) you should use cp.b or you will have to calculate the correct number of items.

5.9.3.2. flinfo - print FLASH memory information

The command flinfo (short: fli) can be used to get information about the available flash memory. The number of flash banks is printed with information about the size and organization into flash "sectors" or erase units. For all sectors the start addresses are printed; write-protected sectors are marked as read-only (RO). Some configurations of U-Boot also mark empty sectors with an (E).

=> fli

Bank # 1: CFI conformant FLASH (16 x 16)  Size: 64 MB in 512 Sectors
  AMD Standard command set, Manufacturer ID: 0x01, Device ID: 0x227E
  Erase timeout: 16384 ms, write timeout: 2 ms
  Buffer write timeout: 5 ms, buffer size: 32 bytes

  Sector Start Addresses:
  FC000000     FC020000     FC040000     FC060000     FC080000
  FC0A0000     FC0C0000     FC0E0000     FC100000     FC120000
  FC140000     FC160000     FC180000     FC1A0000     FC1C0000 E
  FC1E0000     FC200000     FC220000     FC240000     FC260000
  FC280000     FC2A0000     FC2C0000     FC2E0000     FC300000
  FC320000     FC340000     FC360000     FC380000     FC3A0000
  FC3C0000 E     FC3E0000 E     FC400000 E     FC420000 E     FC440000 E
  FC460000 E     FC480000 E     FC4A0000 E     FC4C0000 E     FC4E0000 E
  FC500000 E     FC520000 E     FC540000 E     FC560000 E     FC580000 E
  FC5A0000 E     FC5C0000 E     FC5E0000 E     FC600000 E     FC620000 E
  FC640000 E     FC660000 E     FC680000 E     FC6A0000 E     FC6C0000 E
  FC6E0000 E     FC700000 E     FC720000 E     FC740000 E     FC760000 E
  FC780000 E     FC7A0000 E     FC7C0000 E     FC7E0000 E     FC800000 E
  FC820000 E     FC840000 E     FC860000 E     FC880000 E     FC8A0000 E
  FC8C0000 E     FC8E0000 E     FC900000 E     FC920000 E     FC940000 E
  FC960000 E     FC980000 E     FC9A0000 E     FC9C0000 E     FC9E0000 E
  FCA00000 E     FCA20000 E     FCA40000 E     FCA60000 E     FCA80000 E
  FCAA0000 E     FCAC0000 E     FCAE0000 E     FCB00000 E     FCB20000 E
  FCB40000 E     FCB60000 E     FCB80000 E     FCBA0000 E     FCBC0000 E
  FCBE0000 E     FCC00000 E     FCC20000 E     FCC40000 E     FCC60000 E
  FCC80000 E     FCCA0000 E     FCCC0000 E     FCCE0000 E     FCD00000 E
  FCD20000 E     FCD40000 E     FCD60000 E     FCD80000 E     FCDA0000 E
  FCDC0000 E     FCDE0000 E     FCE00000 E     FCE20000 E     FCE40000 E
  FCE60000 E     FCE80000 E     FCEA0000 E     FCEC0000 E     FCEE0000 E
  FCF00000 E     FCF20000 E     FCF40000 E     FCF60000 E     FCF80000 E
  FCFA0000 E     FCFC0000 E     FCFE0000 E     FD000000 E     FD020000 E
  FD040000 E     FD060000 E     FD080000 E     FD0A0000 E     FD0C0000 E
  FD0E0000 E     FD100000 E     FD120000 E     FD140000 E     FD160000 E
  FD180000 E     FD1A0000 E     FD1C0000 E     FD1E0000 E     FD200000 E
  FD220000 E     FD240000 E     FD260000 E     FD280000 E     FD2A0000 E
  FD2C0000 E     FD2E0000 E     FD300000 E     FD320000 E     FD340000 E
  FD360000 E     FD380000 E     FD3A0000 E     FD3C0000 E     FD3E0000 E
  FD400000 E     FD420000 E     FD440000 E     FD460000 E     FD480000 E
  FD4A0000 E     FD4C0000 E     FD4E0000 E     FD500000 E     FD520000 E
  FD540000 E     FD560000 E     FD580000 E     FD5A0000 E     FD5C0000 E
  FD5E0000 E     FD600000     FD620000 E     FD640000 E     FD660000 E
  FD680000 E     FD6A0000 E     FD6C0000 E     FD6E0000 E     FD700000 E
  FD720000 E     FD740000 E     FD760000 E     FD780000 E     FD7A0000 E
  FD7C0000 E     FD7E0000 E     FD800000 E     FD820000 E     FD840000 E
  FD860000 E     FD880000 E     FD8A0000 E     FD8C0000 E     FD8E0000 E
  FD900000 E     FD920000 E     FD940000 E     FD960000 E     FD980000 E
  FD9A0000 E     FD9C0000 E     FD9E0000 E     FDA00000 E     FDA20000 E
  FDA40000 E     FDA60000 E     FDA80000 E     FDAA0000 E     FDAC0000 E
  FDAE0000 E     FDB00000 E     FDB20000 E     FDB40000 E     FDB60000 E
  FDB80000 E     FDBA0000 E     FDBC0000 E     FDBE0000 E     FDC00000 E
  FDC20000 E     FDC40000 E     FDC60000 E     FDC80000 E     FDCA0000 E
  FDCC0000 E     FDCE0000 E     FDD00000 E     FDD20000 E     FDD40000 E
  FDD60000 E     FDD80000 E     FDDA0000 E     FDDC0000 E     FDDE0000 E
  FDE00000 E     FDE20000 E     FDE40000 E     FDE60000 E     FDE80000 E
  FDEA0000 E     FDEC0000 E     FDEE0000 E     FDF00000 E     FDF20000 E
  FDF40000 E     FDF60000 E     FDF80000 E     FDFA0000 E     FDFC0000 E
  FDFE0000 E     FE000000 E     FE020000 E     FE040000 E     FE060000 E
  FE080000 E     FE0A0000 E     FE0C0000 E     FE0E0000 E     FE100000 E
  FE120000 E     FE140000 E     FE160000 E     FE180000 E     FE1A0000 E
  FE1C0000 E     FE1E0000 E     FE200000 E     FE220000 E     FE240000 E
  FE260000 E     FE280000 E     FE2A0000 E     FE2C0000 E     FE2E0000 E
  FE300000 E     FE320000 E     FE340000 E     FE360000 E     FE380000 E
  FE3A0000 E     FE3C0000 E     FE3E0000 E     FE400000 E     FE420000 E
  FE440000 E     FE460000 E     FE480000 E     FE4A0000 E     FE4C0000 E
  FE4E0000 E     FE500000 E     FE520000 E     FE540000 E     FE560000 E
  FE580000 E     FE5A0000 E     FE5C0000 E     FE5E0000 E     FE600000 E
  FE620000 E     FE640000 E     FE660000 E     FE680000 E     FE6A0000 E
  FE6C0000 E     FE6E0000 E     FE700000 E     FE720000 E     FE740000 E
  FE760000 E     FE780000 E     FE7A0000 E     FE7C0000 E     FE7E0000 E
  FE800000 E     FE820000 E     FE840000 E     FE860000 E     FE880000 E
  FE8A0000 E     FE8C0000 E     FE8E0000 E     FE900000 E     FE920000 E
  FE940000 E     FE960000 E     FE980000 E     FE9A0000 E     FE9C0000 E
  FE9E0000 E     FEA00000 E     FEA20000 E     FEA40000 E     FEA60000 E
  FEA80000 E     FEAA0000 E     FEAC0000 E     FEAE0000 E     FEB00000 E
  FEB20000 E     FEB40000 E     FEB60000 E     FEB80000 E     FEBA0000 E
  FEBC0000 E     FEBE0000 E     FEC00000 E     FEC20000 E     FEC40000 E
  FEC60000 E     FEC80000 E     FECA0000 E     FECC0000 E     FECE0000 E
  FED00000 E     FED20000 E     FED40000 E     FED60000 E     FED80000 E
  FEDA0000 E     FEDC0000 E     FEDE0000 E     FEE00000 E     FEE20000 E
  FEE40000 E     FEE60000 E     FEE80000 E     FEEA0000 E     FEEC0000 E
  FEEE0000 E     FEF00000 E     FEF20000 E     FEF40000 E     FEF60000 E
  FEF80000 E     FEFA0000 E     FEFC0000 E     FEFE0000 E     FF000000 E
  FF020000 E     FF040000 E     FF060000 E     FF080000 E     FF0A0000 E
  FF0C0000 E     FF0E0000 E     FF100000 E     FF120000 E     FF140000 E
  FF160000 E     FF180000 E     FF1A0000 E     FF1C0000 E     FF1E0000 E
  FF200000 E     FF220000 E     FF240000 E     FF260000 E     FF280000 E
  FF2A0000 E     FF2C0000 E     FF2E0000 E     FF300000 E     FF320000 E
  FF340000 E     FF360000 E     FF380000 E     FF3A0000 E     FF3C0000 E
  FF3E0000 E     FF400000 E     FF420000 E     FF440000 E     FF460000 E
  FF480000 E     FF4A0000 E     FF4C0000 E     FF4E0000 E     FF500000 E
  FF520000 E     FF540000 E     FF560000 E     FF580000 E     FF5A0000 E
  FF5C0000 E     FF5E0000 E     FF600000 E     FF620000 E     FF640000 E
  FF660000 E     FF680000 E     FF6A0000 E     FF6C0000 E     FF6E0000 E
  FF700000 E     FF720000 E     FF740000 E     FF760000 E     FF780000 E
  FF7A0000 E     FF7C0000 E     FF7E0000 E     FF800000 E     FF820000 E
  FF840000 E     FF860000 E     FF880000 E     FF8A0000 E     FF8C0000 E
  FF8E0000 E     FF900000 E     FF920000 E     FF940000 E     FF960000 E
  FF980000 E     FF9A0000 E     FF9C0000 E     FF9E0000 E     FFA00000 E
  FFA20000 E     FFA40000 E     FFA60000 E     FFA80000 E     FFAA0000 E
  FFAC0000 E     FFAE0000 E     FFB00000 E     FFB20000 E     FFB40000 E
  FFB60000 E     FFB80000 E     FFBA0000 E     FFBC0000 E     FFBE0000 E
  FFC00000 E     FFC20000 E     FFC40000 E     FFC60000 E     FFC80000 E
  FFCA0000 E     FFCC0000 E     FFCE0000 E     FFD00000 E     FFD20000 E
  FFD40000 E     FFD60000 E     FFD80000 E     FFDA0000 E     FFDC0000 E
  FFDE0000 E     FFE00000 E     FFE20000 E     FFE40000 E     FFE60000 E
  FFE80000 E     FFEA0000 E     FFEC0000 E     FFEE0000 E     FFF00000 E
  FFF20000 E     FFF40000 E     FFF60000   RO     FFF80000   RO     FFFA0000   RO
  FFFC0000   RO     FFFE0000   RO
=>

5.9.3.3. erase - erase FLASH memory

=> help era
erase - erase FLASH memory

Usage:
erase start end
    - erase FLASH from addr 'start' to addr 'end'
erase start +len
    - erase FLASH from addr 'start' to the end of sect w/addr 'start'+'len'-1
erase N:SF[-SL]
    - erase sectors SF-SL in FLASH bank # N
erase bank N
    - erase FLASH bank # N
erase all
    - erase all FLASH banks
=>

The erase command (short: era) is used to erase the contents of one or more sectors of the flash memory. It is one of the more complex commands; the help output shows this.

Probably the most frequent usage of this command is to pass the start and end addresses of the area to be erased:

=> era 0xFF900000 0xFF95FFFF

... done
Erased 3 sectors
=>

ALERT! Note that both the start and end addresses for this command must point exactly at the start resp. end addresses of flash sectors. Otherwise the command will not be executed.

Another way to select certain areas of the flash memory for the erase command uses the notation of flash banks and sectors:

Technically speaking, a bank is an area of memory implemented by one or more memory chips that are connected to the same chip select signal of the CPU, and a flash sector or erase unit is the smallest area that can be erased in one operation.

For practical purposes it is sufficient to remember that with flash memory a bank is something that eventually may be erased as a whole in a single operation. This may be more efficient (faster) than erasing the same area sector by sector.

[It depends on the actual type of flash chips used on the board if such a fast bank erase algorithm exists, and on the implementation of the flash device driver if is actually used.]

In U-Boot, flash banks are numbered starting with 1, while flash sectors start with 0.

To erase the same flash area as specified using start and end addresses in the example above you could also type:

=> era 1:455-456
Erase Flash Sectors 455-456 in Bank # 1
.. done
=>

To erase a whole bank of flash memory you can use a command like this one:

=> era bank 1
Erase Flash Bank # 1 - Warning: 5 protected sectors will not be erased!
........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... done
=>

ALERT! Note that a warning message is printed because some write protected sectors exist in this flash bank which were not erased.

With the command:

=> era all
Erase Flash Bank # 1 - Warning: 5 protected sectors will not be erased!
........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... done
=>

the whole flash memory (except for the write-protected sectors) can be erased.

5.9.3.4. protect - enable or disable FLASH write protection

=> help protect
protect - enable or disable FLASH write protection

Usage:
protect on  start end
    - protect FLASH from addr 'start' to addr 'end'
protect on start +len
    - protect FLASH from addr 'start' to end of sect w/addr 'start'+'len'-1
protect on  N:SF[-SL]
    - protect sectors SF-SL in FLASH bank # N
protect on  bank N
    - protect FLASH bank # N
protect on  all
    - protect all FLASH banks
protect off start end
    - make FLASH from addr 'start' to addr 'end' writable
protect off start +len
    - make FLASH from addr 'start' to end of sect w/addr 'start'+'len'-1 wrtable
protect off N:SF[-SL]
    - make sectors SF-SL writable in FLASH bank # N
protect off bank N
    - make FLASH bank # N writable
protect off all
    - make all FLASH banks writable
=>

The protect command is another complex one. It is used to set certain parts of the flash memory to read-only mode or to make them writable again. Flash memory that is "protected" (= read-only) cannot be written (with the cp command) or erased (with the erase command). Protected areas are marked as (RO) (for "read-only") in the output of the flinfo command:

=> fli

Bank # 1: CFI conformant FLASH (16 x 16)  Size: 64 MB in 512 Sectors
  AMD Standard command set, Manufacturer ID: 0x01, Device ID: 0x227E
  Erase timeout: 16384 ms, write timeout: 2 ms
  Buffer write timeout: 5 ms, buffer size: 32 bytes

  Sector Start Addresses:
  FC000000 E     FC020000 E     FC040000 E     FC060000 E     FC080000 E
  FC0A0000 E     FC0C0000 E     FC0E0000 E     FC100000 E     FC120000 E
  FC140000 E     FC160000 E     FC180000 E     FC1A0000 E     FC1C0000 E
  FC1E0000 E     FC200000 E     FC220000 E     FC240000 E     FC260000 E
  FC280000 E     FC2A0000 E     FC2C0000 E     FC2E0000 E     FC300000 E
  FC320000 E     FC340000 E     FC360000 E     FC380000 E     FC3A0000 E
  FC3C0000 E     FC3E0000 E     FC400000 E     FC420000 E     FC440000 E
  FC460000 E     FC480000 E     FC4A0000 E     FC4C0000 E     FC4E0000 E
  FC500000 E     FC520000 E     FC540000 E     FC560000 E     FC580000 E
  FC5A0000 E     FC5C0000 E     FC5E0000 E     FC600000 E     FC620000 E
  FC640000 E     FC660000 E     FC680000 E     FC6A0000 E     FC6C0000 E
  FC6E0000 E     FC700000 E     FC720000 E     FC740000 E     FC760000 E
  FC780000 E     FC7A0000 E     FC7C0000 E     FC7E0000 E     FC800000 E
  FC820000 E     FC840000 E     FC860000 E     FC880000 E     FC8A0000 E
  FC8C0000 E     FC8E0000 E     FC900000 E     FC920000 E     FC940000 E
  FC960000 E     FC980000 E     FC9A0000 E     FC9C0000 E     FC9E0000 E
  FCA00000 E     FCA20000 E     FCA40000 E     FCA60000 E     FCA80000 E
  FCAA0000 E     FCAC0000 E     FCAE0000 E     FCB00000 E     FCB20000 E
  FCB40000 E     FCB60000 E     FCB80000 E     FCBA0000 E     FCBC0000 E
  FCBE0000 E     FCC00000 E     FCC20000 E     FCC40000 E     FCC60000 E
  FCC80000 E     FCCA0000 E     FCCC0000 E     FCCE0000 E     FCD00000 E
  FCD20000 E     FCD40000 E     FCD60000 E     FCD80000 E     FCDA0000 E
  FCDC0000 E     FCDE0000 E     FCE00000 E     FCE20000 E     FCE40000 E
  FCE60000 E     FCE80000 E     FCEA0000 E     FCEC0000 E     FCEE0000 E
  FCF00000 E     FCF20000 E     FCF40000 E     FCF60000 E     FCF80000 E
  FCFA0000 E     FCFC0000 E     FCFE0000 E     FD000000 E     FD020000 E
  FD040000 E     FD060000 E     FD080000 E     FD0A0000 E     FD0C0000 E
  FD0E0000 E     FD100000 E     FD120000 E     FD140000 E     FD160000 E
  FD180000 E     FD1A0000 E     FD1C0000 E     FD1E0000 E     FD200000 E
  FD220000 E     FD240000 E     FD260000 E     FD280000 E     FD2A0000 E
  FD2C0000 E     FD2E0000 E     FD300000 E     FD320000 E     FD340000 E
  FD360000 E     FD380000 E     FD3A0000 E     FD3C0000 E     FD3E0000 E
  FD400000 E     FD420000 E     FD440000 E     FD460000 E     FD480000 E
  FD4A0000 E     FD4C0000 E     FD4E0000 E     FD500000 E     FD520000 E
  FD540000 E     FD560000 E     FD580000 E     FD5A0000 E     FD5C0000 E
  FD5E0000 E     FD600000 E     FD620000 E     FD640000 E     FD660000 E
  FD680000 E     FD6A0000 E     FD6C0000 E     FD6E0000 E     FD700000 E
  FD720000 E     FD740000 E     FD760000 E     FD780000 E     FD7A0000 E
  FD7C0000 E     FD7E0000 E     FD800000 E     FD820000 E     FD840000 E
  FD860000 E     FD880000 E     FD8A0000 E     FD8C0000 E     FD8E0000 E
  FD900000 E     FD920000 E     FD940000 E     FD960000 E     FD980000 E
  FD9A0000 E     FD9C0000 E     FD9E0000 E     FDA00000 E     FDA20000 E
  FDA40000 E     FDA60000 E     FDA80000 E     FDAA0000 E     FDAC0000 E
  FDAE0000 E     FDB00000 E     FDB20000 E     FDB40000 E     FDB60000 E
  FDB80000 E     FDBA0000 E     FDBC0000 E     FDBE0000 E     FDC00000 E
  FDC20000 E     FDC40000 E     FDC60000 E     FDC80000 E     FDCA0000 E
  FDCC0000 E     FDCE0000 E     FDD00000 E     FDD20000 E     FDD40000 E
  FDD60000 E     FDD80000 E     FDDA0000 E     FDDC0000 E     FDDE0000 E
  FDE00000 E     FDE20000 E     FDE40000 E     FDE60000 E     FDE80000 E
  FDEA0000 E     FDEC0000 E     FDEE0000 E     FDF00000 E     FDF20000 E
  FDF40000 E     FDF60000 E     FDF80000 E     FDFA0000 E     FDFC0000 E
  FDFE0000 E     FE000000 E     FE020000 E     FE040000 E     FE060000 E
  FE080000 E     FE0A0000 E     FE0C0000 E     FE0E0000 E     FE100000 E
  FE120000 E     FE140000 E     FE160000 E     FE180000 E     FE1A0000 E
  FE1C0000 E     FE1E0000 E     FE200000 E     FE220000 E     FE240000 E
  FE260000 E     FE280000 E     FE2A0000 E     FE2C0000 E     FE2E0000 E
  FE300000 E     FE320000 E     FE340000 E     FE360000 E     FE380000 E
  FE3A0000 E     FE3C0000 E     FE3E0000 E     FE400000 E     FE420000 E
  FE440000 E     FE460000 E     FE480000 E     FE4A0000 E     FE4C0000 E
  FE4E0000 E     FE500000 E     FE520000 E     FE540000 E     FE560000 E
  FE580000 E     FE5A0000 E     FE5C0000 E     FE5E0000 E     FE600000 E
  FE620000 E     FE640000 E     FE660000 E     FE680000 E     FE6A0000 E
  FE6C0000 E     FE6E0000 E     FE700000 E     FE720000 E     FE740000 E
  FE760000 E     FE780000 E     FE7A0000 E     FE7C0000 E     FE7E0000 E
  FE800000 E     FE820000 E     FE840000 E     FE860000 E     FE880000 E
  FE8A0000 E     FE8C0000 E     FE8E0000 E     FE900000 E     FE920000 E
  FE940000 E     FE960000 E     FE980000 E     FE9A0000 E     FE9C0000 E
  FE9E0000 E     FEA00000 E     FEA20000 E     FEA40000 E     FEA60000 E
  FEA80000 E     FEAA0000 E     FEAC0000 E     FEAE0000 E     FEB00000 E
  FEB20000 E     FEB40000 E     FEB60000 E     FEB80000 E     FEBA0000 E
  FEBC0000 E     FEBE0000 E     FEC00000 E     FEC20000 E     FEC40000 E
  FEC60000 E     FEC80000 E     FECA0000 E     FECC0000 E     FECE0000 E
  FED00000 E     FED20000 E     FED40000 E     FED60000 E     FED80000 E
  FEDA0000 E     FEDC0000 E     FEDE0000 E     FEE00000 E     FEE20000 E
  FEE40000 E     FEE60000 E     FEE80000 E     FEEA0000 E     FEEC0000 E
  FEEE0000 E     FEF00000 E     FEF20000 E     FEF40000 E     FEF60000 E
  FEF80000 E     FEFA0000 E     FEFC0000 E     FEFE0000 E     FF000000 E
  FF020000 E     FF040000 E     FF060000 E     FF080000 E     FF0A0000 E
  FF0C0000 E     FF0E0000 E     FF100000 E     FF120000 E     FF140000 E
  FF160000 E     FF180000 E     FF1A0000 E     FF1C0000 E     FF1E0000 E
  FF200000 E     FF220000 E     FF240000 E     FF260000 E     FF280000 E
  FF2A0000 E     FF2C0000 E     FF2E0000 E     FF300000 E     FF320000 E
  FF340000 E     FF360000 E     FF380000 E     FF3A0000 E     FF3C0000 E
  FF3E0000 E     FF400000 E     FF420000 E     FF440000 E     FF460000 E
  FF480000 E     FF4A0000 E     FF4C0000 E     FF4E0000 E     FF500000 E
  FF520000 E     FF540000 E     FF560000 E     FF580000 E     FF5A0000 E
  FF5C0000 E     FF5E0000 E     FF600000 E     FF620000 E     FF640000 E
  FF660000 E     FF680000 E     FF6A0000 E     FF6C0000 E     FF6E0000 E
  FF700000 E     FF720000 E     FF740000 E     FF760000 E     FF780000 E
  FF7A0000 E     FF7C0000 E     FF7E0000 E     FF800000 E     FF820000 E
  FF840000 E     FF860000 E     FF880000 E     FF8A0000 E     FF8C0000 E
  FF8E0000 E     FF900000 E     FF920000 E     FF940000 E     FF960000 E
  FF980000 E     FF9A0000 E     FF9C0000 E     FF9E0000 E     FFA00000 E
  FFA20000 E     FFA40000 E     FFA60000 E     FFA80000 E     FFAA0000 E
  FFAC0000 E     FFAE0000 E     FFB00000 E     FFB20000 E     FFB40000 E
  FFB60000 E     FFB80000 E     FFBA0000 E     FFBC0000 E     FFBE0000 E
  FFC00000 E     FFC20000 E     FFC40000 E     FFC60000 E     FFC80000 E
  FFCA0000 E     FFCC0000 E     FFCE0000 E     FFD00000 E     FFD20000 E
  FFD40000 E     FFD60000 E     FFD80000 E     FFDA0000 E     FFDC0000 E
  FFDE0000 E     FFE00000 E     FFE20000 E     FFE40000 E     FFE60000 E
  FFE80000 E     FFEA0000 E     FFEC0000 E     FFEE0000 E     FFF00000 E
  FFF20000 E     FFF40000 E     FFF60000   RO     FFF80000   RO     FFFA0000   RO
  FFFC0000   RO     FFFE0000   RO
=> prot on 0xFF900000 0xFF97FFFF
Protected 4 sectors
=> fli

Bank # 1: CFI conformant FLASH (16 x 16)  Size: 64 MB in 512 Sectors
  AMD Standard command set, Manufacturer ID: 0x01, Device ID: 0x227E
  Erase timeout: 16384 ms, write timeout: 2 ms
  Buffer write timeout: 5 ms, buffer size: 32 bytes

  Sector Start Addresses:
  FC000000 E     FC020000 E     FC040000 E     FC060000 E     FC080000 E
  FC0A0000 E     FC0C0000 E     FC0E0000 E     FC100000 E     FC120000 E
  FC140000 E     FC160000 E     FC180000 E     FC1A0000 E     FC1C0000 E
  FC1E0000 E     FC200000 E     FC220000 E     FC240000 E     FC260000 E
  FC280000 E     FC2A0000 E     FC2C0000 E     FC2E0000 E     FC300000 E
  FC320000 E     FC340000 E     FC360000 E     FC380000 E     FC3A0000 E
  FC3C0000 E     FC3E0000 E     FC400000 E     FC420000 E     FC440000 E
  FC460000 E     FC480000 E     FC4A0000 E     FC4C0000 E     FC4E0000 E
  FC500000 E     FC520000 E     FC540000 E     FC560000 E     FC580000 E
  FC5A0000 E     FC5C0000 E     FC5E0000 E     FC600000 E     FC620000 E
  FC640000 E     FC660000 E     FC680000 E     FC6A0000 E     FC6C0000 E
  FC6E0000 E     FC700000 E     FC720000 E     FC740000 E     FC760000 E
  FC780000 E     FC7A0000 E     FC7C0000 E     FC7E0000 E     FC800000 E
  FC820000 E     FC840000 E     FC860000 E     FC880000 E     FC8A0000 E
  FC8C0000 E     FC8E0000 E     FC900000 E     FC920000 E     FC940000 E
  FC960000 E     FC980000 E     FC9A0000 E     FC9C0000 E     FC9E0000 E
  FCA00000 E     FCA20000 E     FCA40000 E     FCA60000 E     FCA80000 E
  FCAA0000 E     FCAC0000 E     FCAE0000 E     FCB00000 E     FCB20000 E
  FCB40000 E     FCB60000 E     FCB80000 E     FCBA0000 E     FCBC0000 E
  FCBE0000 E     FCC00000 E     FCC20000 E     FCC40000 E     FCC60000 E
  FCC80000 E     FCCA0000 E     FCCC0000 E     FCCE0000 E     FCD00000 E
  FCD20000 E     FCD40000 E     FCD60000 E     FCD80000 E     FCDA0000 E
  FCDC0000 E     FCDE0000 E     FCE00000 E     FCE20000 E     FCE40000 E
  FCE60000 E     FCE80000 E     FCEA0000 E     FCEC0000 E     FCEE0000 E
  FCF00000 E     FCF20000 E     FCF40000 E     FCF60000 E     FCF80000 E
  FCFA0000 E     FCFC0000 E     FCFE0000 E     FD000000 E     FD020000 E
  FD040000 E     FD060000 E     FD080000 E     FD0A0000 E     FD0C0000 E
  FD0E0000 E     FD100000 E     FD120000 E     FD140000 E     FD160000 E
  FD180000 E     FD1A0000 E     FD1C0000 E     FD1E0000 E     FD200000 E
  FD220000 E     FD240000 E     FD260000 E     FD280000 E     FD2A0000 E
  FD2C0000 E     FD2E0000 E     FD300000 E     FD320000 E     FD340000 E
  FD360000 E     FD380000 E     FD3A0000 E     FD3C0000 E     FD3E0000 E
  FD400000 E     FD420000 E     FD440000 E     FD460000 E     FD480000 E
  FD4A0000 E     FD4C0000 E     FD4E0000 E     FD500000 E     FD520000 E
  FD540000 E     FD560000 E     FD580000 E     FD5A0000 E     FD5C0000 E
  FD5E0000 E     FD600000 E     FD620000 E     FD640000 E     FD660000 E
  FD680000 E     FD6A0000 E     FD6C0000 E     FD6E0000 E     FD700000 E
  FD720000 E     FD740000 E     FD760000 E     FD780000 E     FD7A0000 E
  FD7C0000 E     FD7E0000 E     FD800000 E     FD820000 E     FD840000 E
  FD860000 E     FD880000 E     FD8A0000 E     FD8C0000 E     FD8E0000 E
  FD900000 E     FD920000 E     FD940000 E     FD960000 E     FD980000 E
  FD9A0000 E     FD9C0000 E     FD9E0000 E     FDA00000 E     FDA20000 E
  FDA40000 E     FDA60000 E     FDA80000 E     FDAA0000 E     FDAC0000 E
  FDAE0000 E     FDB00000 E     FDB20000 E     FDB40000 E     FDB60000 E
  FDB80000 E     FDBA0000 E     FDBC0000 E     FDBE0000 E     FDC00000 E
  FDC20000 E     FDC40000 E     FDC60000 E     FDC80000 E     FDCA0000 E
  FDCC0000 E     FDCE0000 E     FDD00000 E     FDD20000 E     FDD40000 E
  FDD60000 E     FDD80000 E     FDDA0000 E     FDDC0000 E     FDDE0000 E
  FDE00000 E     FDE20000 E     FDE40000 E     FDE60000 E     FDE80000 E
  FDEA0000 E     FDEC0000 E     FDEE0000 E     FDF00000 E     FDF20000 E
  FDF40000 E     FDF60000 E     FDF80000 E     FDFA0000 E     FDFC0000 E
  FDFE0000 E     FE000000 E     FE020000 E     FE040000 E     FE060000 E
  FE080000 E     FE0A0000 E     FE0C0000 E     FE0E0000 E     FE100000 E
  FE120000 E     FE140000 E     FE160000 E     FE180000 E     FE1A0000 E
  FE1C0000 E     FE1E0000 E     FE200000 E     FE220000 E     FE240000 E
  FE260000 E     FE280000 E     FE2A0000 E     FE2C0000 E     FE2E0000 E
  FE300000 E     FE320000 E     FE340000 E     FE360000 E     FE380000 E
  FE3A0000 E     FE3C0000 E     FE3E0000 E     FE400000 E     FE420000 E
  FE440000 E     FE460000 E     FE480000 E     FE4A0000 E     FE4C0000 E
  FE4E0000 E     FE500000 E     FE520000 E     FE540000 E     FE560000 E
  FE580000 E     FE5A0000 E     FE5C0000 E     FE5E0000 E     FE600000 E
  FE620000 E     FE640000 E     FE660000 E     FE680000 E     FE6A0000 E
  FE6C0000 E     FE6E0000 E     FE700000 E     FE720000 E     FE740000 E
  FE760000 E     FE780000 E     FE7A0000 E     FE7C0000 E     FE7E0000 E
  FE800000 E     FE820000 E     FE840000 E     FE860000 E     FE880000 E
  FE8A0000 E     FE8C0000 E     FE8E0000 E     FE900000 E     FE920000 E
  FE940000 E     FE960000 E     FE980000 E     FE9A0000 E     FE9C0000 E
  FE9E0000 E     FEA00000 E     FEA20000 E     FEA40000 E     FEA60000 E
  FEA80000 E     FEAA0000 E     FEAC0000 E     FEAE0000 E     FEB00000 E
  FEB20000 E     FEB40000 E     FEB60000 E     FEB80000 E     FEBA0000 E
  FEBC0000 E     FEBE0000 E     FEC00000 E     FEC20000 E     FEC40000 E
  FEC60000 E     FEC80000 E     FECA0000 E     FECC0000 E     FECE0000 E
  FED00000 E     FED20000 E     FED40000 E     FED60000 E     FED80000 E
  FEDA0000 E     FEDC0000 E     FEDE0000 E     FEE00000 E     FEE20000 E
  FEE40000 E     FEE60000 E     FEE80000 E     FEEA0000 E     FEEC0000 E
  FEEE0000 E     FEF00000 E     FEF20000 E     FEF40000 E     FEF60000 E
  FEF80000 E     FEFA0000 E     FEFC0000 E     FEFE0000 E     FF000000 E
  FF020000 E     FF040000 E     FF060000 E     FF080000 E     FF0A0000 E
  FF0C0000 E     FF0E0000 E     FF100000 E     FF120000 E     FF140000 E
  FF160000 E     FF180000 E     FF1A0000 E     FF1C0000 E     FF1E0000 E
  FF200000 E     FF220000 E     FF240000 E     FF260000 E     FF280000 E
  FF2A0000 E     FF2C0000 E     FF2E0000 E     FF300000 E     FF320000 E
  FF340000 E     FF360000 E     FF380000 E     FF3A0000 E     FF3C0000 E
  FF3E0000 E     FF400000 E     FF420000 E     FF440000 E     FF460000 E
  FF480000 E     FF4A0000 E     FF4C0000 E     FF4E0000 E     FF500000 E
  FF520000 E     FF540000 E     FF560000 E     FF580000 E     FF5A0000 E
  FF5C0000 E     FF5E0000 E     FF600000 E     FF620000 E     FF640000 E
  FF660000 E     FF680000 E     FF6A0000 E     FF6C0000 E     FF6E0000 E
  FF700000 E     FF720000 E     FF740000 E     FF760000 E     FF780000 E
  FF7A0000 E     FF7C0000 E     FF7E0000 E     FF800000 E     FF820000 E
  FF840000 E     FF860000 E     FF880000 E     FF8A0000 E     FF8C0000 E
  FF8E0000 E     FF900000 E RO     FF920000 E RO     FF940000 E RO     FF960000 E RO
  FF980000 E     FF9A0000 E     FF9C0000 E     FF9E0000 E     FFA00000 E
  FFA20000 E     FFA40000 E     FFA60000 E     FFA80000 E     FFAA0000 E
  FFAC0000 E     FFAE0000 E     FFB00000 E     FFB20000 E     FFB40000 E
  FFB60000 E     FFB80000 E     FFBA0000 E     FFBC0000 E     FFBE0000 E
  FFC00000 E     FFC20000 E     FFC40000 E     FFC60000 E     FFC80000 E
  FFCA0000 E     FFCC0000 E     FFCE0000 E     FFD00000 E     FFD20000 E
  FFD40000 E     FFD60000 E     FFD80000 E     FFDA0000 E     FFDC0000 E
  FFDE0000 E     FFE00000 E     FFE20000 E     FFE40000 E     FFE60000 E
  FFE80000 E     FFEA0000 E     FFEC0000 E     FFEE0000 E     FFF00000 E
  FFF20000 E     FFF40000 E     FFF60000   RO     FFF80000   RO     FFFA0000   RO
  FFFC0000   RO     FFFE0000   RO
=> era 0xFF900000 0xFF97FFFF
- Warning: 4 protected sectors will not be erased!
 done
Erased 4 sectors
=> prot off 1:455
Un-Protect Flash Sectors 455-455 in Bank # 1
=> fli

Bank # 1: CFI conformant FLASH (16 x 16)  Size: 64 MB in 512 Sectors
  AMD Standard command set, Manufacturer ID: 0x01, Device ID: 0x227E
  Erase timeout: 16384 ms, write timeout: 2 ms
  Buffer write timeout: 5 ms, buffer size: 32 bytes

  Sector Start Addresses:
  FC000000 E     FC020000 E     FC040000 E     FC060000 E     FC080000 E
  FC0A0000 E     FC0C0000 E     FC0E0000 E     FC100000 E     FC120000 E
  FC140000 E     FC160000 E     FC180000 E     FC1A0000 E     FC1C0000 E
  FC1E0000 E     FC200000 E     FC220000 E     FC240000 E     FC260000 E
  FC280000 E     FC2A0000 E     FC2C0000 E     FC2E0000 E     FC300000 E
  FC320000 E     FC340000 E     FC360000 E     FC380000 E     FC3A0000 E
  FC3C0000 E     FC3E0000 E     FC400000 E     FC420000 E     FC440000 E
  FC460000 E     FC480000 E     FC4A0000 E     FC4C0000 E     FC4E0000 E
  FC500000 E     FC520000 E     FC540000 E     FC560000 E     FC580000 E
  FC5A0000 E     FC5C0000 E     FC5E0000 E     FC600000 E     FC620000 E
  FC640000 E     FC660000 E     FC680000 E     FC6A0000 E     FC6C0000 E
  FC6E0000 E     FC700000 E     FC720000 E     FC740000 E     FC760000 E
  FC780000 E     FC7A0000 E     FC7C0000 E     FC7E0000 E     FC800000 E
  FC820000 E     FC840000 E     FC860000 E     FC880000 E     FC8A0000 E
  FC8C0000 E     FC8E0000 E     FC900000 E     FC920000 E     FC940000 E
  FC960000 E     FC980000 E     FC9A0000 E     FC9C0000 E     FC9E0000 E
  FCA00000 E     FCA20000 E     FCA40000 E     FCA60000 E     FCA80000 E
  FCAA0000 E     FCAC0000 E     FCAE0000 E     FCB00000 E     FCB20000 E
  FCB40000 E     FCB60000 E     FCB80000 E     FCBA0000 E     FCBC0000 E
  FCBE0000 E     FCC00000 E     FCC20000 E     FCC40000 E     FCC60000 E
  FCC80000 E     FCCA0000 E     FCCC0000 E     FCCE0000 E     FCD00000 E
  FCD20000 E     FCD40000 E     FCD60000 E     FCD80000 E     FCDA0000 E
  FCDC0000 E     FCDE0000 E     FCE00000 E     FCE20000 E     FCE40000 E
  FCE60000 E     FCE80000 E     FCEA0000 E     FCEC0000 E     FCEE0000 E
  FCF00000 E     FCF20000 E     FCF40000 E     FCF60000 E     FCF80000 E
  FCFA0000 E     FCFC0000 E     FCFE0000 E     FD000000 E     FD020000 E
  FD040000 E     FD060000 E     FD080000 E     FD0A0000 E     FD0C0000 E
  FD0E0000 E     FD100000 E     FD120000 E     FD140000 E     FD160000 E
  FD180000 E     FD1A0000 E     FD1C0000 E     FD1E0000 E     FD200000 E
  FD220000 E     FD240000 E     FD260000 E     FD280000 E     FD2A0000 E
  FD2C0000 E     FD2E0000 E     FD300000 E     FD320000 E     FD340000 E
  FD360000 E     FD380000 E     FD3A0000 E     FD3C0000 E     FD3E0000 E
  FD400000 E     FD420000 E     FD440000 E     FD460000 E     FD480000 E
  FD4A0000 E     FD4C0000 E     FD4E0000 E     FD500000 E     FD520000 E
  FD540000 E     FD560000 E     FD580000 E     FD5A0000 E     FD5C0000 E
  FD5E0000 E     FD600000 E     FD620000 E     FD640000 E     FD660000 E
  FD680000 E     FD6A0000 E     FD6C0000 E     FD6E0000 E     FD700000 E
  FD720000 E     FD740000 E     FD760000 E     FD780000 E     FD7A0000 E
  FD7C0000 E     FD7E0000 E     FD800000 E     FD820000 E     FD840000 E
  FD860000 E     FD880000 E     FD8A0000 E     FD8C0000 E     FD8E0000 E
  FD900000 E     FD920000 E     FD940000 E     FD960000 E     FD980000 E
  FD9A0000 E     FD9C0000 E     FD9E0000 E     FDA00000 E     FDA20000 E
  FDA40000 E     FDA60000 E     FDA80000 E     FDAA0000 E     FDAC0000 E
  FDAE0000 E     FDB00000 E     FDB20000 E     FDB40000 E     FDB60000 E
  FDB80000 E     FDBA0000 E     FDBC0000 E     FDBE0000 E     FDC00000 E
  FDC20000 E     FDC40000 E     FDC60000 E     FDC80000 E     FDCA0000 E
  FDCC0000 E     FDCE0000 E     FDD00000 E     FDD20000 E     FDD40000 E
  FDD60000 E     FDD80000 E     FDDA0000 E     FDDC0000 E     FDDE0000 E
  FDE00000 E     FDE20000 E     FDE40000 E     FDE60000 E     FDE80000 E
  FDEA0000 E     FDEC0000 E     FDEE0000 E     FDF00000 E     FDF20000 E
  FDF40000 E     FDF60000 E     FDF80000 E     FDFA0000 E     FDFC0000 E
  FDFE0000 E     FE000000 E     FE020000 E     FE040000 E     FE060000 E
  FE080000 E     FE0A0000 E     FE0C0000 E     FE0E0000 E     FE100000 E
  FE120000 E     FE140000 E     FE160000 E     FE180000 E     FE1A0000 E
  FE1C0000 E     FE1E0000 E     FE200000 E     FE220000 E     FE240000 E
  FE260000 E     FE280000 E     FE2A0000 E     FE2C0000 E     FE2E0000 E
  FE300000 E     FE320000 E     FE340000 E     FE360000 E     FE380000 E
  FE3A0000 E     FE3C0000 E     FE3E0000 E     FE400000 E     FE420000 E
  FE440000 E     FE460000 E     FE480000 E     FE4A0000 E     FE4C0000 E
  FE4E0000 E     FE500000 E     FE520000 E     FE540000 E     FE560000 E
  FE580000 E     FE5A0000 E     FE5C0000 E     FE5E0000 E     FE600000 E
  FE620000 E     FE640000 E     FE660000 E     FE680000 E     FE6A0000 E
  FE6C0000 E     FE6E0000 E     FE700000 E     FE720000 E     FE740000 E
  FE760000 E     FE780000 E     FE7A0000 E     FE7C0000 E     FE7E0000 E
  FE800000 E     FE820000 E     FE840000 E     FE860000 E     FE880000 E
  FE8A0000 E     FE8C0000 E     FE8E0000 E     FE900000 E     FE920000 E
  FE940000 E     FE960000 E     FE980000 E     FE9A0000 E     FE9C0000 E
  FE9E0000 E     FEA00000 E     FEA20000 E     FEA40000 E     FEA60000 E
  FEA80000 E     FEAA0000 E     FEAC0000 E     FEAE0000 E     FEB00000 E
  FEB20000 E     FEB40000 E     FEB60000 E     FEB80000 E     FEBA0000 E
  FEBC0000 E     FEBE0000 E     FEC00000 E     FEC20000 E     FEC40000 E
  FEC60000 E     FEC80000 E     FECA0000 E     FECC0000 E     FECE0000 E
  FED00000 E     FED20000 E     FED40000 E     FED60000 E     FED80000 E
  FEDA0000 E     FEDC0000 E     FEDE0000 E     FEE00000 E     FEE20000 E
  FEE40000 E     FEE60000 E     FEE80000 E     FEEA0000 E     FEEC0000 E
  FEEE0000 E     FEF00000 E     FEF20000 E     FEF40000 E     FEF60000 E
  FEF80000 E     FEFA0000 E     FEFC0000 E     FEFE0000 E     FF000000 E
  FF020000 E     FF040000 E     FF060000 E     FF080000 E     FF0A0000 E
  FF0C0000 E     FF0E0000 E     FF100000 E     FF120000 E     FF140000 E
  FF160000 E     FF180000 E     FF1A0000 E     FF1C0000 E     FF1E0000 E
  FF200000 E     FF220000 E     FF240000 E     FF260000 E     FF280000 E
  FF2A0000 E     FF2C0000 E     FF2E0000 E     FF300000 E     FF320000 E
  FF340000 E     FF360000 E     FF380000 E     FF3A0000 E     FF3C0000 E
  FF3E0000 E     FF400000 E     FF420000 E     FF440000 E     FF460000 E
  FF480000 E     FF4A0000 E     FF4C0000 E     FF4E0000 E     FF500000 E
  FF520000 E     FF540000 E     FF560000 E     FF580000 E     FF5A0000 E
  FF5C0000 E     FF5E0000 E     FF600000 E     FF620000 E     FF640000 E
  FF660000 E     FF680000 E     FF6A0000 E     FF6C0000 E     FF6E0000 E
  FF700000 E     FF720000 E     FF740000 E     FF760000 E     FF780000 E
  FF7A0000 E     FF7C0000 E     FF7E0000 E     FF800000 E     FF820000 E
  FF840000 E     FF860000 E     FF880000 E     FF8A0000 E     FF8C0000 E
  FF8E0000 E     FF900000 E RO     FF920000 E RO     FF940000 E RO     FF960000 E RO
  FF980000 E     FF9A0000 E     FF9C0000 E     FF9E0000 E     FFA00000 E
  FFA20000 E     FFA40000 E     FFA60000 E     FFA80000 E     FFAA0000 E
  FFAC0000 E     FFAE0000 E     FFB00000 E     FFB20000 E     FFB40000 E
  FFB60000 E     FFB80000 E     FFBA0000 E     FFBC0000 E     FFBE0000 E
  FFC00000 E     FFC20000 E     FFC40000 E     FFC60000 E     FFC80000 E
  FFCA0000 E     FFCC0000 E     FFCE0000 E     FFD00000 E     FFD20000 E
  FFD40000 E     FFD60000 E     FFD80000 E     FFDA0000 E     FFDC0000 E
  FFDE0000 E     FFE00000 E     FFE20000 E     FFE40000 E     FFE60000 E
  FFE80000 E     FFEA0000 E     FFEC0000 E     FFEE0000 E     FFF00000 E
  FFF20000 E     FFF40000 E     FFF60000   RO     FFF80000   RO     FFFA0000   RO
  FFFC0000   RO     FFFE0000   RO
=> era 1:455
Erase Flash Sectors 455-455 in Bank # 1
. done
=>

ALERT! The actual level of protection depends on the flash chips used on your hardware, and on the implementation of the flash device driver for this board. In most cases U-Boot provides just a simple software-protection, i. e. it prevents you from erasing or overwriting important stuff by accident (like the U-Boot code itself or U-Boot's environment variables), but it cannot prevent you from circumventing these restrictions - a nasty user who is loading and running his own flash driver code cannot and will not be stopped by this mechanism. Also, in most cases this protection is only effective while running U-Boot, i. e. any operating system will not know about "protected" flash areas and will happily erase these if requested to do so.

5.9.3.5. mtdparts - define a Linux compatible MTD partition scheme

U-Boot implements two different approaches to define a MTD partition scheme that can be shared easily with the linux kernel.

The first one is to define a single, static partition in your board config file, for example:

#undef CONFIG_JFFS2_CMDLINE
#define CONFIG_JFFS2_DEV               "nor0"
#define CONFIG_JFFS2_PART_SIZE         0xFFFFFFFF     /* use whole device */
#define CONFIG_JFFS2_PART_SIZE         0x00100000     /* use 1MB */
#define CONFIG_JFFS2_PART_OFFSET       0x00000000
The second method uses the Linux kernel's mtdparts command line option and dynamic partitioning:
#define CONFIG_JFFS2_CMDLINE
#define MTDIDS_DEFAULT      "nor1=zuma-1,nor2=zuma-2"
#define MTDPARTS_DEFAULT   "mtdparts=zuma-1:-(jffs2),zuma-2:-(user)"
Command line of course produces bigger images, and may be inappropriate for some targets, so by default it's off.

The mtdparts command offers an easy to use and powerful interface to define the contents of the environment variable of the same name that can be passed as boot argument to the Linux kernel:

=> help mtdparts
mtdparts 
    - list partition table
mtdparts delall
    - delete all partitions
mtdparts del part-id
    - delete partition (e.g. part-id = nand0,1)
mtdparts add <mtd-dev> <size>[@<offset>] [<name>] [ro]
    - add partition
mtdparts default
    - reset partition table to defaults

-----

this command uses three environment variables:

'partition' - keeps current partition identifier

partition  := <part-id>
<part-id>  := <dev-id>,part_num

'mtdids' - linux kernel mtd device id <-> u-boot device id mapping

mtdids=<idmap>[,<idmap>,...]

<idmap>    := <dev-id>=<mtd-id>
<dev-id>   := 'nand'|'nor'<dev-num>
<dev-num>  := mtd device number, 0...
<mtd-id>   := unique device tag used by linux kernel to find mtd device (mtd->name)

'mtdparts' - partition list

mtdparts=mtdparts=<mtd-def>[;<mtd-def>...]

<mtd-def>  := <mtd-id>:<part-def>[,<part-def>...]
<mtd-id>   := unique device tag used by linux kernel to find mtd device (mtd->name)
<part-def> := <size>[@<offset>][<name>][<ro-flag>]
<size>     := standard linux memsize OR '-' to denote all remaining space
<offset>   := partition start offset within the device
<name>     := '(' NAME ')'
<ro-flag>  := when set to 'ro' makes partition read-only (not used, passed to kernel)

For example, on some target system the mtdparts command might display this information:
=> mtdparts

device nor0 <TQM5200-0>, # parts = 4
 #: name                        size            offset          mask_flags
 0: firmware            0x00100000      0x00000000      1
 1: kernel              0x00180000      0x00100000      0
 2: small-fs            0x00d80000      0x00280000      0
 3: big-fs              0x01000000      0x01000000      0

active partition: nor0,0 - (firmware) 0x00100000 @ 0x00000000

defaults:
mtdids  : nor0=TQM5200-0
mtdparts: mtdparts=TQM5200-0:1m(firmware),1536k(kernel),3584k(small-fs),2m(initrd),8m(misc),16m(big-fs)
The partition table printed here obviously differs from the default value for the mtdparts variable printed in the last line. To verify this, we can check the current content of this variable:
=> print mtdparts
mtdparts=mtdparts=TQM5200-0:1024k(firmware)ro,1536k(kernel),13824k(small-fs),16m(big-fs)
and we can see that it exactly matches the partition table printed above.

Now let's switch back to the default settings:

=> mtdparts default
=> mtdparts

device nor0 <TQM5200-0>, # parts = 6
 #: name                        size            offset          mask_flags
 0: firmware            0x00100000      0x00000000      0
 1: kernel              0x00180000      0x00100000      0
 2: small-fs            0x00380000      0x00280000      0
 3: initrd              0x00200000      0x00600000      0
 4: misc                0x00800000      0x00800000      0
 5: big-fs              0x01000000      0x01000000      0

active partition: nor0,0 - (firmware) 0x00100000 @ 0x00000000

defaults:
mtdids  : nor0=TQM5200-0
mtdparts: mtdparts=TQM5200-0:1m(firmware),1536k(kernel),3584k(small-fs),2m(initrd),8m(misc),16m(big-fs)
=> print mtdparts
mtdparts=mtdparts=TQM5200-0:1m(firmware),1536k(kernel),3584k(small-fs),2m(initrd),8m(misc),16m(big-fs)
Then we delete the last 4 partitions ("small-fs", "initrd", "misc" and "big-fs") ...
=> mtdparts del small-fs
=> mtdparts del initrd
=> mtdparts del misc  
=> mtdparts del big-fs  
=> mtdparts

device nor0 <TQM5200-0>, # parts = 2
 #: name                        size            offset          mask_flags
 0: firmware            0x00100000      0x00000000      0
 1: kernel              0x00180000      0x00100000      0

active partition: nor0,0 - (firmware) 0x00100000 @ 0x00000000

defaults:
mtdids  : nor0=TQM5200-0
mtdparts: mtdparts=TQM5200-0:1m(firmware),1536k(kernel),3584k(small-fs),2m(initrd),8m(misc),16m(big-fs)
... and combine the free space into a singe big partition:
=> mtdparts add nor0 - new-part
=> mtdparts

device nor0 <TQM5200-0>, # parts = 3
 #: name                        size            offset          mask_flags
 0: firmware            0x00100000      0x00000000      0
 1: kernel              0x00180000      0x00100000      0
 2: new-part            0x01d80000      0x00280000      0

active partition: nor0,0 - (firmware) 0x00100000 @ 0x00000000

defaults:
mtdids  : nor0=TQM5200-0
mtdparts: mtdparts=TQM5200-0:1m(firmware),1536k(kernel),3584k(small-fs),2m(initrd),8m(misc),16m(big-fs)
=> print mtdparts
mtdparts=mtdparts=TQM5200-0:1m(firmware),1536k(kernel),30208k(new-part)

5.9.4. Execution Control Commands

5.9.4.1. source - run script from memory

=> help source
source - run script from memory

Usage:
source [addr]
   - run script starting at addr
   - A valid image header must be present
=>

With the source command you can run "shell" scripts under U-Boot: You create a U-Boot script image by simply writing the commands you want to run into a text file; then you will have to use the mkimage tool to convert this text file into a U-Boot image (using the image type script).

This image can be loaded like any other image file, and with source you can run the commands in such an image. For instance, the following text file:

echo
echo Network Configuration:
echo ----------------------
echo Target:
printenv ipaddr hostname
echo
echo Server:
printenv serverip rootpath
echo

can be converted into a U-Boot script image using the mkimage command like this:

bash$ mkimage -A ppc -O linux -T script -C none -a 0 -e 0 \
> -n "autoscr example script" \
> -d ./testsystems/dulg/testcases/example.script /tftpboot/duts/canyonlands/example.scr
Image Name:   autoscr example script
Created:      Mon Feb  8 16:36:04 2010
Image Type:   PowerPC Linux Script (uncompressed)
Data Size:    157 Bytes = 0.15 kB = 0.00 MB
Load Address: 0x00000000
Entry Point:  0x00000000
Contents:
   Image 0:    149 Bytes =   0 kB = 0 MB

Now you can load and execute this script image in U-Boot:

=> tftp 0x100000 /tftpboot/duts/canyonlands/example.scr
Using ppc_4xx_eth0 device
TFTP from server 192.168.1.1; our IP address is 192.168.100.6
Filename '/tftpboot/duts/canyonlands/example.scr'.
Load address: 0x100000
Loading: #
done
Bytes transferred = 221 (dd hex)
=> imi

## Checking Image at 00100000 ...
   Legacy image found
   Image Name:    autoscr example script
   Created:    2010-02-08  15:36:04 UTC
   Image Type:    PowerPC Linux Script (uncompressed)
   Data Size:    157 Bytes =  0.2 kB
   Load Address: 00000000
   Entry Point:    00000000
   Contents:
      Image 0: 149 Bytes =  0.1 kB
   Verifying Checksum ... OK
=> source 0x100000
## Executing script at 00100000

Network Configuration:
----------------------
Target:
ipaddr=192.168.100.6
hostname=canyonlands

Server:
serverip=192.168.1.1
rootpath=/opt/eldk/ppc_4xxFP

=>

5.9.4.2. bootm - boot application image from memory

=> help bootm
bootm - boot application image from memory

Usage:
bootm [addr [arg ...]]
    - boot application image stored in memory
   passing arguments 'arg ...'; when booting a Linux kernel,
   'arg' can be the address of an initrd image
   When booting a Linux kernel which requires a flat device-tree
   a third argument is required which is the address of the
   device-tree blob. To boot that kernel without an initrd image,
   use a '-' for the second argument. If you do not pass a third
   a bd_info struct will be passed instead

Sub-commands to do part of the bootm sequence.   The sub-commands must be
issued in the order below (it's ok to not issue all sub-commands):
   start [addr [arg ...]]
   loados   - load OS image
   ramdisk - relocate initrd, set env initrd_start/initrd_end
   fdt   - relocate flat device tree
   cmdline - OS specific command line processing/setup
   bdt   - OS specific bd_t processing
   prep   - OS specific prep before relocation or go
   go   - start OS
=>

The bootm command is used to start operating system images. From the image header it gets information about the type of the operating system, the file compression method used (if any), the load and entry point addresses, etc. The command will then load the image to the required memory address, uncompressing it on the fly if necessary. Depending on the OS it will pass the required boot arguments and start the OS at it's entry point.

The first argument to bootm is the memory address (in RAM, ROM or flash memory) where the image is stored, followed by optional arguments that depend on the OS.

Linux requires the flattened device tree blob to be passed at boot time, and bootm expects its third argument to be the address of the blob in memory. Second argument to bootm depens on whether an initrd initial ramdisk image is to be used. If the kernel should be booted without the initial ramdisk, the second argument should be given as "-", otherwise it is interpreted as the start address of initrd (in RAM, ROM or flash memory).

To boot a Linux kernel image without a initrd ramdisk image, the following command can be used:

=> bootm ${kernel_addr} - ${fdt_addr}

If a ramdisk image shall be used, you can type:

=> bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}

Both examples of course imply that the variables used are set to correct addresses for a kernel, fdt blob and a initrd ramdisk image.

ALERT! When booting images that have been loaded to RAM (for instance using TFTP download) you have to be careful that the locations where the (compressed) images were stored do not overlap with the memory needed to load the uncompressed kernel. For instance, if you load a ramdisk image at a location in low memory, it may be overwritten when the Linux kernel gets loaded. This will cause undefined system crashes.

5.9.4.3. go - start application at address 'addr'

=> help go
go - start application at address 'addr'

Usage:
go addr [arg ...]
    - start application at address 'addr'
      passing 'arg' as arguments
=>

U-Boot has support for so-called standalone applications. These are programs that do not require the complex environment of an operating system to run. Instead they can be loaded and executed by U-Boot directly, utilizing U-Boot's service functions like console I/O or malloc() and free().

This can be used to dynamically load and run special extensions to U-Boot like special hardware test routines or bootstrap code to load an OS image from some filesystem.

The go command is used to start such standalone applications. The optional arguments are passed to the application without modification. For more informatoin see 5.12. U-Boot Standalone Applications.

5.9.5. Download Commands

5.9.5.1. bootp - boot image via network using BOOTP/TFTP protocol

=> help bootp
bootp - boot image via network using BOOTP/TFTP protocol

Usage:
bootp [loadAddress] [[hostIPaddr:]bootfilename]
=>

5.9.5.2. dhcp - invoke DHCP client to obtain IP/boot params

=> help dhcp
dhcp - boot image via network using DHCP/TFTP protocol

Usage:
dhcp [loadAddress] [[hostIPaddr:]bootfilename]
=>

5.9.5.3. loadb - load binary file over serial line (kermit mode)

=> help loadb
loadb - load binary file over serial line (kermit mode)

Usage:
loadb [ off ] [ baud ]
    - load binary file over serial line with offset 'off' and baudrate 'baud'
=>

With kermit you can download binary data via the serial line. Here we show how to download uImage, the Linux kernel image. Please make sure, that you have set up kermit as described in section 4.3. Configuring the "kermit" command and then type:

=> loadb 100000
## Ready for binary (kermit) download ...
Ctrl-\c
(Back at denx.denx.de)
----------------------------------------------------
C-Kermit 7.0.197, 8 Feb 2000, for Linux
 Copyright (C) 1985, 2000,
  Trustees of Columbia University in the City of New York.
Type ? or HELP for help.
Kermit> send /bin /tftpboot/pImage
...
Kermit> connect
Connecting to /dev/ttyS0, speed 115200.
The escape character is Ctrl-\ (ASCII 28, FS)
Type the escape character followed by C to get back,
or followed by ? to see other options.
----------------------------------------------------
= 550260 Bytes
## Start Addr      = 0x00100000
=> iminfo 100000

## Checking Image at 00100000 ...
   Image Name:   Linux-2.4.4
   Created:      2002-07-02  22:10:11 UTC
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    550196 Bytes = 537 kB = 0 MB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK

5.9.5.4. loads - load S-Record file over serial line

=> help loads
loads - load S-Record file over serial line

Usage:
loads [ off ] [ baud ]
    - load S-Record file over serial line with offset 'off' and baudrate 'baud'
=>

5.9.5.5. rarpboot- boot image via network using RARP/TFTP protocol

=> help rarp
rarpboot - boot image via network using RARP/TFTP protocol

Usage:
rarpboot [loadAddress] [[hostIPaddr:]bootfilename]
=>

5.9.5.6. tftpboot- boot image via network using TFTP protocol

=> help tftp
tftpboot - boot image via network using TFTP protocol

Usage:
tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
=>

5.9.6. Environment Variables Commands

5.9.6.1. printenv- print environment variables

=> help printenv
printenv - print environment variables

Usage:
printenv
    - print values of all environment variables
printenv name ...
    - print value of environment variable 'name'
=>

The printenv command prints one, several or all variables of the U-Boot environment. When arguments are given, these are interpreted as the names of environment variables which will be printed with their values:

=> printenv ipaddr hostname netmask
ipaddr=192.168.100.6
hostname=canyonlands
netmask=255.255.0.0
=>

Without arguments, printenv prints all a list with all variables in the environment and their values, plus some statistics about the current usage and the total size of the memory available for the environment.

=> printenv
bootdelay=5
baudrate=115200
loads_echo=
preboot=echo;echo Type "run flash_nfs" to mount root filesystem over NFS;echo
netdev=eth0
nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath}
ramargs=setenv bootargs root=/dev/ram rw
addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off panic=1
addtty=setenv bootargs ${bootargs} console=ttyS0,${baudrate}
addmisc=setenv bootargs ${bootargs}
initrd_high=30000000
kernel_addr_r=400000
ramdisk_addr_r=C00000
hostname=canyonlands
ramdisk_file=canyonlands/uRamdisk
rootpath=/opt/eldk/ppc_4xxFP
flash_self=run ramargs addip addtty addmisc;bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}
flash_nfs=run nfsargs addip addtty addmisc;bootm ${kernel_addr} - ${fdt_addr}
net_nfs=tftp ${kernel_addr_r} ${bootfile}; tftp ${fdt_addr_r} ${fdt_file}; run nfsargs addip addtty addmisc;bootm ${kernel_addr_r} - ${fdt_addr_r}
net_self_load=tftp ${kernel_addr_r} ${bootfile};tftp ${fdt_addr_r} ${fdt_file};tftp ${ramdisk_addr_r} ${ramdisk_file};
net_self=run net_self_load;run ramargs addip addtty addmisc;bootm ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
fdt_file=canyonlands/canyonlands.dtb
update=protect off 0xFFFA0000 FFFFFFFF;era 0xFFFA0000 FFFFFFFF;cp.b ${fileaddr} 0xFFFA0000 ${filesize};setenv filesize;saveenv
upd=run load update
nload=tftp 200000 canyonlands/u-boot-nand.bin
nupdate=nand erase 0 100000;nand write 200000 0 100000;setenv filesize;saveenv
nupd=run nload nupdate
pciconfighost=1
pcie_mode=RP:RP
ethaddr=00:10:ec:01:08:84
eth1addr=00:10:ec:81:08:84
hostname=canyonlands
sr=tftp 200000 canyonlands/u-boot.bin-sr;protect off 0xFFFA0000 FFFFFFFF;era 0xFFFA0000 FFFFFFFF;cp.b ${fileaddr} 0xFFFA0000 ${filesize};setenv filesize;saveenv
srlinux=setenv bootfile canyonlands/uImage-sr;setenv fdt_file canyonlands/canyonlands.dtb-sr;run net_nfs
bootcmd=run srlinux
fdtaddr=800000
uboot_file=canyonlands/u-boot.bin-duts
load=tftp 200000 ${u-boot}
dzu_net_nfs=setenv bootfile dzu/canyonlands/uImage;setenv fdt_file dzu/canyonlands/canyonlands.dtb;run net_nfs
bootargs=root=/dev/ram rw ip=192.168.100.6:192.168.1.1:192.168.1.254:255.255.0.0:canyonlands:eth0:off panic=1 console=ttyS0,115200
ethact=ppc_4xx_eth0
bootfile=/tftpboot/duts/canyonlands/uImage
bar=This is a new example.
cons_opts=console=tty0 console=ttyS0,${baudrate}
test=echo This is a test;printenv ipaddr;echo Done.
test2=echo This is another Test;printenv hostname;echo Done.
kernel_addr=0xFC000000
ramdisk_addr=0xFC200000
fdt_addr=0xFC1E0000
fdt_addr_r=0x00b00000
u-boot=/tftpboot/duts/canyonlands/u-boot.bin
fileaddr=200000
gatewayip=192.168.1.254
netmask=255.255.0.0
ipaddr=192.168.100.6
serverip=192.168.1.1
stdin=serial
stdout=serial
stderr=serial
ver=U-Boot 2009.11.1 (Feb 05 2010 - 08:57:12)

Environment size: 2780/16379 bytes
=>

5.9.6.2. saveenv - save environment variables to persistent storage

=> help saveenv
saveenv - save environment variables to persistent storage

Usage:
saveenv
=>

All changes you make to the U-Boot environment are made in RAM only. They are lost as soon as you reboot the system. If you want to make your changes permanent you have to use the saveenv command to write a copy of the environment settings to persistent storage, from where they are automatically loaded during startup:

=> saveenv
Saving Environment to Flash...
Un-Protected 1 sectors
Un-Protected 1 sectors
Erasing Flash...
. done
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
Protected 1 sectors
=>

5.9.6.3. setenv - set environment variables

=> help setenv
setenv - set environment variables

Usage:
setenv name value ...
    - set environment variable 'name' to 'value ...'
setenv name
    - delete environment variable 'name'
=>

To modify the U-Boot environment you have to use the setenv command. When called with exactly one argument, it will delete any variable of that name from U-Boot's environment, if such a variable exists. Any storage occupied for such a variable will be automatically reclaimed:

=> setenv foo This is an example value.
=> printenv foo
foo=This is an example value.
=> setenv foo
=> printenv foo
## Error: "foo" not defined
=>

When called with more arguments, the first one will again be the name of the variable, and all following arguments will (concatenated by single space characters) form the value that gets stored for this variable. New variables will be automatically created, existing ones overwritten.

=> printenv bar
## Error: "bar" not defined
=> setenv bar This is a new example.
=> printenv bar
bar=This is a new example.
=>

Remember standard shell quoting rules when the value of a variable shall contain characters that have a special meaning to the command line parser (like the $ character that is used for variable substitution or the semicolon which separates commands). Use the backslash (\) character to escape such special characters, or enclose the whole phrase in apstrophes ('). Use "${name}" for variable expansion (see 14.2.17. How the Command Line Parsing Works for details).

=> setenv cons_opts 'console=tty0 console=ttyS0,${baudrate}'
=> printenv cons_opts
cons_opts=console=tty0 console=ttyS0,${baudrate}
=>

TIP There is no restriction on the characters that can be used in a variable name except the restrictions imposed by the command line parser (like using backslash for quoting, space and tab characters to separate arguments, or semicolon and newline to separate commands). Even strange input like "=-/|()+=" is a perfectly legal variable name in U-Boot.

ALERT! A common mistake is to write

setenv name=value

instead of

setenv name value

There will be no error message, which lets you believe everything went OK, but it didn't: instead of setting the variable name to the value value you tried to delete a variable with the name name=value - this is probably not what you intended! Always remember that name and value have to be separated by space and/or tab characters!

5.9.6.4. run - run commands in an environment variable

=> help run
run - run commands in an environment variable

Usage:
run var [...]
    - run the commands in the environment variable(s) 'var'
=>

You can use U-Boot environment variables to store commands and even sequences of commands. To execute such a command, you use the run command:

=> setenv test echo This is a test\;printenv ipaddr\;echo Done.
=> printenv test
test=echo This is a test;printenv ipaddr;echo Done.
=> run test
This is a test
ipaddr=192.168.100.6
Done.
=>

You can call run with several variables as arguments, in which case these commands will be executed in sequence:

=> setenv test2 echo This is another Test\;printenv hostname\;echo Done.
=> printenv test test2
test=echo This is a test;printenv ipaddr;echo Done.
test2=echo This is another Test;printenv hostname;echo Done.
=> run test test2
This is a test
ipaddr=192.168.100.6
Done.
This is another Test
hostname=canyonlands
Done.
=>

TIP If a U-Boot variable contains several commands (separated by semicolon), and one of these commands fails when you "run" this variable, the remaining commands will be executed anyway.

TIP If you execute several variables with one call to run, any failing command will cause "run" to terminate, i. e. the remaining variables are not executed.

5.9.6.5. bootd - boot default, i.e., run 'bootcmd'

 
=> help boot
boot - No help available.

=> 

The bootd (short: boot) executes the default boot command, i. e. what happens when you don't interrupt the initial countdown. This is a synonym for the run bootcmd command.

5.9.7. Flattened Device Tree support

U-Boot is capable of quite comprehensive handling of the flattened device tree blob, implemented by the fdt family of commands:

=>
=> help fd

5.9.7.1. fdt addr - select FDT to work on

First, the blob that is to be operated on should be stored in memory, and U-Boot has to be informed about its location by the fdt addr command. Once this command has been issued, all subsequent fdt handling commands will use the blob stored at the given address. This address can be changed later on by issuing fdt addr or fdt move command. Here's how to load the blob into memory and tell U-Boot its location:

=> print fdt_addr_r
fdt_addr_r=0x00b00000
=> print fdt_file
fdt_file=/tftpboot/duts/canyonlands/canyonlands.dtb
=> tftp ${fdt_addr_r} ${fdt_file}
Waiting for PHY auto negotiation to complete... done
ENET Speed is 1000 Mbps - FULL duplex connection (EMAC0)
Using ppc_4xx_eth0 device
TFTP from server 192.168.1.1; our IP address is 192.168.100.6
Filename '/tftpboot/duts/canyonlands/canyonlands.dtb'.
Load address: 0xb00000
Loading: T #
done
Bytes transferred = 10190 (27ce hex)
=> fdt addr ${fdt_addr_r}
=>

5.9.7.2. fdt list - print one level

Having selected the device tree stored in the blob just loaded, we can inspect its contents. As an FDT usually is quite extensive, it is easier to get information about the structure by looking at selected levels rather than full hierarchies. fdt list allows us to do exactly this. Let's have a look at the hierarchy one level below the cpus node:

=> fdt list /cpus
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=>

5.9.7.3. fdt print - recursive print

To print a complete subtree we use fdt print. In comparison to the previous example it is obvious that the whole subtree is printed:

=> fdt print /cpus
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=>

5.9.7.4. fdt mknode - create new nodes

fdt mknode can be used to attach a new node to the tree. We will use the fdt list command to verify that the new node has been created and that it is empty:

=> fdt list /
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt mknode / testnode
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt list /
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt list /testnode
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=>

5.9.7.5. fdt set - set node properties

Now, let's create a property at the newly created node; again we'll use fdt list for verification:

=> fdt set /testnode testprop testvalue
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt list /testnode
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=>

5.9.7.6. fdt rm - remove nodes or properties

The fdt rm command is used to remove nodes and properties. Let's delete the test property created in the previous paragraph and verify the results:

=> fdt rm /testnode testprop
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt list /testnode
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt rm /testnode
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt list /
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=>

5.9.7.7. fdt move - move FDT blob to new address

To move the blob from one memory location to another we will use the fdt move command. Besides moving the blob, it makes the new address the "active" one - similar to fdt addr:

=> fdt move ${fdt_addr_r} $CFG_RAM_WS_BASE
fdt - flattened device tree utility commands

Usage:
fdt addr   <addr> [<length>]       - Set the fdt location to <addr>
fdt boardsetup             - Do board-specific set up
fdt move   <fdt> <newaddr> <length> - Copy the fdt to <addr> and make it active
fdt resize             - Resize fdt to size + padding to 4k addr
fdt print  <path> [<prop>]       - Recursive print starting at <path>
fdt list   <path> [<prop>]       - Print one level starting at <path>
fdt set      <path> <prop> [<val>]    - Set <property> [to <val>]
fdt mknode <path> <node>       - Create a new node after <path>
fdt rm      <path> [<prop>]       - Delete the node or <property>
fdt header             - Display header info
fdt bootcpu <id>          - Set boot cpuid
fdt memory <addr> <size>       - Add/Update memory node
fdt rsvmem print          - Show current mem reserves
fdt rsvmem add <addr> <size>       - Add a mem reserve
fdt rsvmem delete <index>       - Delete a mem reserves
fdt chosen [<start> <end>]       - Add/update the /chosen branch in the tree
               <start>/<end> - initrd start/end addr
NOTE: Dereference aliases by omiting the leading '/', e.g. fdt print ethernet0.
=> fdt list /
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt mknod / foobar
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt list /
libfdt fdt_path_offset() returned FDT_ERR_BADMAGIC
=> fdt addr ${fdt_addr_r}
=> fdt list /
/ {
   #address-cells = <0x2>;
   #size-cells = <0x1>;
   model = "amcc,canyonlands";
   compatible = "amcc,canyonlands";
   dcr-parent = <0x1>;
   aliases {
   };
   cpus {
   };
   memory {
   };
   interrupt-controller0 {
   };
   interrupt-controller1 {
   };
   interrupt-controller2 {
   };
   interrupt-controller3 {
   };
   sdr {
   };
   cpr {
   };
   l2c {
   };
   plb {
   };
};
=>

5.9.7.8. fdt chosen - fixup dynamic info

One of the modifications made by U-Boot to the blob before passing it to the kernel is the addition of the /chosen node. Linux 2.6 Documentation/powerpc/booting-without-of.txt says that this node is used to store "some variable environment information, like the arguments, or the default input/output devices." To force U-Boot to add the /chosen node to the current blob, fdt chosen command can be used. Let's now verify its operation:

=> fdt list /
/ {
   #address-cells = <0x2>;
   #size-cells = <0x1>;
   model = "amcc,canyonlands";
   compatible = "amcc,canyonlands";
   dcr-parent = <0x1>;
   aliases {
   };
   cpus {
   };
   memory {
   };
   interrupt-controller0 {
   };
   interrupt-controller1 {
   };
   interrupt-controller2 {
   };
   interrupt-controller3 {
   };
   sdr {
   };
   cpr {
   };
   l2c {
   };
   plb {
   };
};
=> fdt chosen
=> fdt list /
/ {
   #address-cells = <0x2>;
   #size-cells = <0x1>;
   model = "amcc,canyonlands";
   compatible = "amcc,canyonlands";
   dcr-parent = <0x1>;
   chosen {
   };
   aliases {
   };
   cpus {
   };
   memory {
   };
   interrupt-controller0 {
   };
   interrupt-controller1 {
   };
   interrupt-controller2 {
   };
   interrupt-controller3 {
   };
   sdr {
   };
   cpr {
   };
   l2c {
   };
   plb {
   };
};
=> fdt list /chosen
chosen {
   bootargs = "root=/dev/ram rw ip=192.168.100.6:192.168.1.1:192.168.1.254:255.255.0.0:canyonlands:eth0:off panic=1 console=ttyS0,115200";
};
=>

Note: fdt boardsetup performs board-specific blob updates, most commonly setting clock frequencies, etc. Discovering its operation is left as an excercise for the reader.

5.9.8. Special Commands

5.9.8.1. i2c - I2C sub-system

=> help i2c
i2c - I2C sub-system

Usage:
i2c speed [speed] - show or set I2C bus speed
i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device
i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)
i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)
i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)
i2c crc32 chip address[.0, .1, .2] count - compute CRC32 checksum
i2c probe - show devices on the I2C bus
i2c reset - re-init the I2C Controller
i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device
i2c sdram chip - print SDRAM configuration information
=>

5.9.9. Storage devices

This chapter introduces commands to work with storage devices, i.e. ATA, CF, SATA, SCSI, USB, NAND, etc. connected to the board.

5.9.10. Miscellaneous Commands

5.9.10.1. echo - echo args to console

=> help echo
echo - echo args to console

Usage:
echo [args..]
    - echo args to console; \c suppresses newline
=>

The echo command echoes the arguments to the console:

=> echo The quick brown fox jumped over the lazy dog.
The quick brown fox jumped over the lazy dog.
=>

5.9.10.2. reset - Perform RESET of the CPU

=> help reset
reset - Perform RESET of the CPU

Usage:
reset
=>

The reset command reboots the system.

=>
=> reset


U-Boot 2009.11.1 (Feb 05 2010 - 08:57:12)

CPU:   AMCC PowerPC 460EX Rev. B at 1066.667 MHz (PLB=266 OPB=88 EBC=88)
       Security/Kasumi support
       Bootstrap Option H - Boot ROM Location I2C (Addr 0x52)
       Internal PCI arbiter enabled
       32 kB I-Cache 32 kB D-Cache
Board: Canyonlands - AMCC PPC460EX Evaluation Board, 1*PCIe/1*SATA, Rev. 16
I2C:   ready
DRAM:  512 MB (ECC not enabled, 533 MHz, CL4)
FLASH: 64 MB
NAND:  128 MiB
PCI:   Bus Dev VenId DevId Class Int
PCIE1: link is not up.
DTT:   1 is 40 C
Net:   ppc_4xx_eth0, ppc_4xx_eth1

Type run flash_nfs to mount root filesystem over NFS

Hit any key to stop autoboot:  0
=>

5.9.10.3. sleep - delay execution for some time

=> help sleep
sleep - delay execution for some time

Usage:
sleep N
    - delay execution for N seconds (N is _decimal_ !!!)
=>

The sleep command pauses execution for the number of seconds given as the argument:

=> sleep 5
=>

5.9.10.4. version - print monitor version

=> help version
version - print monitor version

Usage:
version
=>

You can print the version and build date of the U-Boot image running on your system using the version command (short: vers):

=> version

U-Boot 2009.11.1 (Feb 05 2010 - 08:57:12)
=>

5.9.10.5. ? - alias for 'help'

You can use ? as a short form for the help command (see description above).

5.10. U-Boot Environment Variables

The U-Boot environment is a block of memory that is kept on persistent storage and copied to RAM when U-Boot starts. It is used to store environment variables which can be used to configure the system. The environment is protected by a CRC32 checksum.

This section lists the most important environment variables, some of which have a special meaning to U-Boot. You can use these variables to configure the behaviour of U-Boot to your liking.

=> setenv initrd_high 00c00000
     
Setting initrd_high to the highest possible address in your system (0xFFFFFFFF) prevents U-Boot from copying the image to RAM at all. This allows for faster boot times, but requires a Linux kernel with zero-copy ramdisk support.

=> setenv bootargs ${bootargs} mem=\${mem}
=> saveenv
     
This way you can tell Linux not to use this memory, either, which results in a memory region that will not be affected by reboots.

The following environment variables may be used and automatically updated by the network boot commands (bootp, dhcp, or tftp), depending the information provided by your boot server:

5.11. U-Boot Scripting Capabilities

U-Boot allows to store commands or command sequences in a plain text file. Using the mkimage tool you can then convert this file into a script image which can be executed using U-Boot's autoscr command.

For example, assume that you will have to run the following sequence of commands on many boards, so you store them in a text file, say "setenv-commands":

bash$ cat setenv-commands
setenv loadaddr 00200000
echo ===== U-Boot settings =====
setenv u-boot /tftpboot/TQM860L/u-boot.bin
setenv u-boot_addr 40000000
setenv load_u-boot 'tftp ${loadaddr} ${u-boot}'
setenv install_u-boot 'protect off ${u-boot_addr} +${filesize};era ${u-boot_addr} +${filesize};cp.b ${loadaddr} ${u-boot_addr} ${filesize};saveenv'
setenv update_u-boot run load_u-boot install_u-boot
echo ===== Linux Kernel settings =====
setenv bootfile /tftpboot/TQM860L/uImage
setenv kernel_addr 40040000
setenv load_kernel 'tftp ${loadaddr} ${bootfile};'
setenv install_kernel 'era ${kernel_addr} +${filesize};cp.b ${loadaddr} ${kernel_addr} ${filesize}'
setenv update_kernel run load_kernel install_kernel
echo ===== Ramdisk settings =====
setenv ramdisk /tftpboot/TQM860L/uRamdisk
setenv ramdisk_addr 40100000
setenv load_ramdisk 'tftp ${loadaddr} ${ramdisk};'
setenv install_ramdisk 'era ${ramdisk_addr} +${filesize};cp.b ${loadaddr} ${ramdisk_addr} ${filesize}'
setenv update_ramdisk run load_ramdisk install_ramdisk
echo ===== Save new definitions =====
saveenv
bash$ 
To convert the text file into a script image for U-Boot, you have to use the mkimage tool as follows:
bash$ mkimage -T script -C none -n 'Demo Script File' -d setenv-commands setenv.img
Image Name:   Demo Script File
Created:      Mon Jun  6 13:33:14 2005
Image Type:   PowerPC Linux Script (uncompressed)
Data Size:    1147 Bytes = 1.12 kB = 0.00 MB
Load Address: 0x00000000
Entry Point:  0x00000000
Contents:
   Image 0:     1139 Bytes =    1 kB = 0 MB
bash$ 
On the target, you can download this image as usual (for example, using the "tftp" command). Use the "autoscr" command to execute it:
=> tftp 100000 /tftpboot/TQM860L/setenv.img
Using FEC ETHERNET device
TFTP from server 192.168.3.1; our IP address is 192.168.3.80
Filename '/tftpboot/TQM860L/setenv.img'.
Load address: 0x100000
Loading: #
done
Bytes transferred = 1211 (4bb hex)
=> imi 100000

## Checking Image at 00100000 ...
   Image Name:   Demo Script File
   Created:      2005-06-06  11:33:14 UTC
   Image Type:   PowerPC Linux Script (uncompressed)
   Data Size:    1147 Bytes =  1.1 kB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
=> autoscr 100000
## Executing script at 00100000
===== U-Boot settings =====
===== Linux Kernel settings =====
===== Ramdisk settings =====
===== Save new definitions =====
Saving Environment to Flash...
Un-Protected 1 sectors
Un-Protected 1 sectors
Erasing Flash...
. done
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
Protected 1 sectors
=> 
TIP Hint: maximum flexibility can be achieved if you are using the Hush shell as command interpreter in U-Boot; see section 14.2.17. How the Command Line Parsing Works

5.12. U-Boot Standalone Applications

U-Boot supports "standalone" applications, which are loaded dynamically; these applications can have access to the U-Boot console I/O functions, memory allocation and interrupt services.

A couple of simple examples are included with the U-Boot source code:

5.12.1. "Hello World" Demo

examples/hello_world.c contains a small "Hello World" Demo application; it is automatically compiled when you build U-Boot. It's configured to run at address 0x00040004, so you can play with it like that:

=> loads
## Ready for S-Record download ...
~>examples/hello_world.srec
1 2 3 4 5 6 7 8 9 10 11 ...
[file transfer complete]
[connected]
## Start Addr = 0x00040004

=> go 40004 Hello World! This is a test.
## Starting application at 0x00040004 ...
Hello World
argc = 7
argv[0] = "40004"
argv[1] = "Hello"
argv[2] = "World!"
argv[3] = "This"
argv[4] = "is"
argv[5] = "a"
argv[6] = "test."
argv[7] = ""
Hit any key to exit ...

## Application terminated, rc = 0x0

Alternatively, you can of course use TFTP to download the image over the network. In this case the binary image (hello_world.bin) is used.

TIP Note that the entry point of the program is at offset 0x0004 from the start of file, i. e. the download address and the entry point address differ by four bytes.

=> tftp 40000 /tftpboot/hello_world.bin
...
=> go 40004 This is another test.
## Starting application at 0x00040004 ...
Hello World
argc = 5
argv[0] = "40004"
argv[1] = "This"
argv[2] = "is"
argv[3] = "another"
argv[4] = "test."
argv[5] = ""
Hit any key to exit ...

## Application terminated, rc = 0x0

5.12.2. Timer Demo

ALERT! This example is only available on MPC8xx CPUs.

TIP This example, which demonstrates how to register a CPM interrupt handler with the U-Boot code, can be found in examples/timer.c. Here, a CPM timer is set up to generate an interrupt every second. The interrupt service routine is trivial, just printing a '.' character, but this is just a demo program. The application can be controlled by the following keys:


   ? - print current values of the CPM Timer registers
   b - enable interrupts and start timer
   e - stop timer and disable interrupts
   q - quit application

 => loads
   ## Ready for S-Record download ...
   ~>examples/timer.srec
   1 2 3 4 5 6 7 8 9 10 11 ...
   [file transfer complete]
   [connected]
   ## Start Addr = 0x00040004

 => go 40004
   ## Starting application at 0x00040004 ...
   TIMERS=0xfff00980
   Using timer 1
     tgcr @ 0xfff00980, tmr @ 0xfff00990, trr @ 0xfff00994, tcr @ 0xfff00998, tcn @ 0xfff0099c, ter @ 0xfff009b0

Hit 'b':
   [q, b, e, ?] Set interval 1000000 us
   Enabling timer
Hit '?':
   [q, b, e, ?] ........
   tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0xef6, ter=0x0
Hit '?':
   [q, b, e, ?] .
   tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x2ad4, ter=0x0
Hit '?':
   [q, b, e, ?] .
   tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x1efc, ter=0x0
Hit '?':
   [q, b, e, ?] .
   tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x169d, ter=0x0
Hit 'e':
   [q, b, e, ?] ...Stopping timer
Hit 'q':
   [q, b, e, ?] ## Application terminated, rc = 0x0

5.13. U-Boot Image Formats

U-Boot operates on "image" files which can be basically anything, preceeded by a special header; see the definitions in include/image.h for details; basically, the header defines the following image properties:

The header is marked by a special Magic Number, and both the header and the data portions of the image are secured against corruption by CRC32 checksums.

5.14. U-Boot Advanced Features

5.14.1. Boot Count Limit

The Open Source Development Labs Carrier Grade Linux Requirements Definition version 2.0 (http://www.osdl.org/docs/carrier_grade_linux_requirements_definition___version_20_final_public_draft.pdf) contains the following requirement definition (ID PLT.4.0, p. 44):

CGL shall provide support for detecting a repeating reboot cycle due to recurring failures and will go to an offline state if this occurs.

This feature is available in U-Boot if you enable the CONFIG_BOOTCOUNT_LIMIT configuration option. The implementation uses the following environment variables:

bootcount:
This variable will be automatically created if it does not exist, and it will be updated at each reset of the processor. After a power-on reset, it will be initialized with 1, and each reboot will increment the value by 1.
bootlimit:
If this variable exists, its contents are taken as the maximum number of reboot cycles allowed.
altbootcmd:
If, after a reboot, the new value of bootcount exceeds the value of bootlimit, then instead of the standard boot action (executing the contents of bootcmd) an alternate boot action will be performed, and the contents of altbootcmd will be executed.

If the variable bootlimit is not defined in the environment, the Boot Count Limit feature is disabled. If it is enabled, but altbootcmd is not defined, then U-Boot will drop into interactive mode and remain there.

It is the responsibility of some application code (typically a Linux application) to reset the variable bootcount, thus allowing for more boot cycles.

ALERT! At the moment, the Boot Count Limit feature is available only for MPC8xx, MPC82xx and MPC5200 Power Architecture® processors.

6. Embedded Linux Configuration

6.1. Download and Unpack the Linux Kernel Sources

You can download the Linux Kernel Sources from our anonymous git server at http://git.denx.de/. To checkout the module for the first time, proceed as follows:

bash$ cd /opt/eldk/usr/src
bash$ git clone git://git.denx.de/linux-2.6-denx.git linux-2.6-denx
bash$ cd linux-2.6-denx
bash$ git checkout -b duts remotes/origin/44x/canyonlands
Branch duts set up to track remote branch 44x/canyonlands from origin.
Switched to a new branch 'duts'
bash$

6.2. Kernel Configuration and Compilation

The canyonlands board is fully supported by DENX Software Engineering. This means that you will always be able to build a working default configuration with just minimal interaction.

Please be aware that you will need the "powerpc" cross development tools for the following steps. Make sure that the directory which contains the binaries of your ELDK are in your PATH.

To be sure that no intermediate results of previous builds are left in your Linux kernel source tree you can clean it up as follows:

bash$ make mrproper

The following command selects a standard configuration for the canyonlands board that has been extensively tested. It is recommended to use this as a starting point for other, customized configurations:

bash$ make ARCH=powerpc CROSS_COMPILE=ppc_4xxFP- 44x/canyonlands_defconfig


TIP Note: The name of this default configuration file is arch/powerpc/configs/44x/canyonlands_defconfig . By (recursively) listing the contents of the arch/powerpc/configs/ directory you can easily find out which other default configurations are available.

If you don't want to change the default configuration you can now continue to use it to build a kernel image:

bash$ make ARCH=powerpc CROSS_COMPILE=ppc_4xxFP- uImage

Otherwise you can modify the kernel configuration as follows:

bash$ make ARCH=powerpc CROSS_COMPILE=ppc_4xxFP-  config

or

bash$ make ARCH=powerpc CROSS_COMPILE=ppc_4xxFP-  menuconfig

ALERT! Note: Because of problems (especially with some older Linux kernel versions) the use of "make xconfig" is not recommended.

bash$ make ARCH=powerpc CROSS_COMPILE=ppc_4xxFP- uImage

The make target uImage uses the tool mkimage (from the U-Boot package) to create a Linux kernel image in arch/powerpc/boot/uImage

which is immediately usable for download and booting with U-Boot.

In case you need a DTB to boot your linux kernel, you need the following step:

bash$ make canyonlands.dtb

In case you configured modules you will also need to compile the modules:

make ARCH=powerpc CROSS_COMPILE=ppc_4xxFP- modules

add install the modules (make sure to pass the correct root path for module installation):

bash$ make ARCH=powerpc CROSS_COMPILE=ppc_4xxFP- INSTALL_MOD_PATH=/opt/eldk-4.2/ppc_4xx modules_install

6.3. Installation

For now it is sufficient to copy the Linux kernel image into the directory used by your TFTP server:

bash$ cp arch/powerpc/boot/uImage /tftpboot/uImage

7. Booting Embedded Linux

7.1. Introduction

In principle, if you have a Linux kernel image and the flattened device tree blob somewhere in system memory (RAM, ROM, flash...), then all you need to boot the system is the bootm command. Assume a Linux kernel image has been stored at address 0xFC000000 and the flattened device tree blob has been stored at address 0xFC1E0000 - then you can boot this image with the following command:

=> bootm FC000000 - FC1E0000

7.2. Flattened Device Tree Blob

Linux kernel expects certain information on the hardware that it runs on. For kernels compiled with fdt support, this information has the form of a device tree, which is based on the Open Firmware specification. Bootloaders like U-Boot that do not implement the Open Firmware API, are expected to pass to the kernel a binary form of the flattened device tree, commonly referred to as FDT blob or simply the blob.

Device trees are defined in human-readable text files, which are part of the Linux 2.6 source tree. Device tree source for the canyonlands board is found in arch/powerpc/boot/dts/canyonlands.dts file. Before the device tree can be passed to the kernel, it has to be compiled to the binary form by the dtc compiler. The dtc compiler is included with the Linux kernel since 2.6.25. Since 2.6.26 there is also a simple makefile rule to generate the blob:

make ARCH=powerpc CROSS_COMPILE=ppc_4xxFP- canyonlands.dtb

After the blob has been compiled, it has to be transferred from where it was built ("arch/powerpc/boot/canyonlands.dtb") to target's memory, for example over the TFTP protocol using U-Boot's tftp command. Then, the blob is passed to the kernel by the bootm command, and its address in memory is one of the arguments to bootm - refer to the description of this command in UBootCmdGroupExec for more details. Note that U-Boot makes some automatic modifications to the blob before passing it to the kernel - mainly adding and modifying information that is learnt at run-time.

U-Boot also has provisions to alter a flattened device tree in arbitrary ways from the command line, refer to the description of the fdt commands found in UBootCmdGroupMisc.

Notes:

7.3. Passing Kernel Arguments

In nearly all cases, you will want to pass additional information to the Linux kernel; for instance, information about the root device or network configuration.

In U-Boot, this is supported using the bootargs environment variable. Its contents are automatically passed to the Linux kernel as boot arguments (or "command line" arguments). This allows the use of the same Linux kernel image in a wide range of configurations. For instance, by just changing the contents of the bootargs variable you can use the very same Linux kernel image to boot with an initrd ramdisk image, with a root filesystem over NFS, with a CompactFlash disk or from a flash filesystem.

As one example, to boot the Linux kernel image at address0x400000 using the initrd ramdisk image at address0x600000 as root filesystem, and with the flattened device tree blob at address 0x800000, and with the flattened device tree blob at address 0xFC1E0000, you can use the following commands:

=> setenv bootargs root=/dev/ram rw
=> bootm0x400000 0x600000 0x800000  0xFC1E0000 

To boot the same kernel image with a root filesystem over NFS, the following command sequence can be used. This example assumes that your NFS server has the IP address "192.168.1.1" and exports the directory "/opt/eldk-4.2/ppc_4xx" as root filesystem for the target. The target has been assigned the IP address "192.168.100.6" and the hostname "canyonlands". A netmask of "255.255.0.0" is used:

=> setenv bootargs root=/dev/nfs rw nfsroot=192.168.1.1:/opt/eldk-4.2/ppc_4xx ip=192.168.100.6:192.168.1.1:192.168.1.1:255.255.0.0:canyonlands::off
=> bootm0x400000 - 0x800000  - 0xFC1E0000 

Please see also the files Documentation/initrd.txt and Documentation/nfsroot.txt in your Linux kernel source directory for more information about which options can be passed to the Linux kernel.

ALERT! Note: Once your system is up and running, if you have a simple shell login, you can normally examine the boot arguments that were used by the kernel for the most recent boot with the command:

$ cat /proc/cmdline

7.4. Boot Arguments Unleashed

Passing command line arguments to the Linux kernel allows for very flexible and efficient configuration which is especially important in Embedded Systems. It is somewhat strange that these features are nearly undocumented everywhere else. One reason for that is certainly the very limited capabilities of other boot loaders.

It is especially U-Boot's capability to easily define, store, and use environment variables that makes it such a powerful tool in this area. In the examples above we have already seen how we can use for instance the root and ip boot arguments to pass information about the root filesystem or network configuration. The ip argument is not only useful in configurations with root filesystem over NFS; if the Linux kernel has the CONFIG_IP_PNP configuration enabled (IP kernel level autoconfiguration), this can be used to enable automatic configuration of IP addresses of devices and of the routing table during kernel boot, based on either information supplied on the kernel command line or by BOOTP or RARP protocols.

The advantage of this mechanism is that you don't have to spend precious system memory (RAM and flash) for network configuration tools like ifconfig or route - especially in Embedded Systems where you seldom have to change the network configuration while the system is running.

We can use U-Boot environment variables to store all necessary configuration parameters:

=> setenv ipaddr 192.168.100.6
=> setenv serverip 192.168.1.1
=> setenv netmask 255.255.0.0
=> setenv hostname canyonlands
=> setenv rootpath /opt/eldk-4.2/ppc_4xx
=> saveenv

Then you can use these variables to build the boot arguments to be passed to the Linux kernel:

=> setenv nfsargs 'root=/dev/nfs rw nfsroot=${serverip}:${rootpath}'

Note how apostrophes are used to delay the substitution of the referenced environment variables. This way, the current values of these variables get inserted when assigning values to the "bootargs" variable itself later, i. e. when it gets assembled from the given parts before passing it to the kernel. This allows us to simply redefine any of the variables (say, the value of "ipaddr" if it has to be changed), and the changes will automatically propagate to the Linux kernel.

ALERT! Note: You cannot use this method directly to define for example the "bootargs" environment variable, as the implicit usage of this variable by the "bootm" command will not trigger variable expansion - this happens only when using the "setenv" command.

In the next step, this can be used for a flexible method to define the "bootargs" environment variable by using a function-like approach to build the boot arguments step by step:

=> setenv ramargs setenv bootargs root=/dev/ram rw
=> setenv nfsargs 'setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath}'
=> setenv addip 'setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off'
=> setenv ram_root 'run ramargs addip;bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}  ${fdt_addr} '
=> setenv nfs_root 'run nfsargs addip;bootm ${kernel_addr} - ${fdt_addr}  - ${fdt_addr} '

In this setup we define two variables, ram_root and nfs_root, to boot with root filesystem from a ramdisk image or over NFS, respecively. The variables can be executed using U-Boot's run command. These variables make use of the run command itself:

This method can be easily extended to add more customization options when needed.

If you have used U-Boot's network commands before (and/or read the documentation), you will probably have recognized that the names of the U-Boot environment variables we used in the examples above are exactly the same as those used with the U-Boot commands to boot over a network using DHCP or BOOTP. That means that, instead of manually setting network configuration parameters like IP address, etc., these variables will be set automatically to the values retrieved with the network boot protocols. This is explained in detail in the sections about the respective U-Boot commands.

7.5. Networked Operation with Root Filesystem over NFS

This section will show how to boot the target into Linux with no more than U-Boot residing on it. For this we will use the tftp command of U-Boot to transfer a Linux kernel and boot it with the NFS rootfilesystem provided by the ELDK.

For this to work, we rely on some U-Boot environment variables to be set up correctly, i.e. the network parameters, the names of files to transfer via tftp and last but not least some scripts easing the assembly of the Linux command line. The whole process is packaged up into one script shown before we actually execute it.

Note that the Linux kernel will also output the command line used, so you can easily check if everything worked like expected. The command line in this example passes at least the following information to the:

See Documentation/nfsroot.txt in you Linux kernel source directory for more information about these parameters and other options.

7.5.1. Bootlog of tftp'd Linux kernel with Root Filesystem over NFS

=> setenv fdt_file /tftpboot/duts/canyonlands/canyonlands.dtb
=> setenv bootfile /tftpboot/duts/canyonlands/uImage
=> setenv rootpath /opt/eldk-4.2/ppc_4xxFP/
=> printenv net_nfs
net_nfs=tftp ${kernel_addr_r} ${bootfile}; tftp ${fdt_addr_r} ${fdt_file}; run nfsargs addip addtty addmisc;bootm ${kernel_addr_r} - ${fdt_addr_r}
=> run net_nfs
Using ppc_4xx_eth0 device
TFTP from server 192.168.1.1; our IP address is 192.168.100.6
Filename '/tftpboot/duts/canyonlands/uImage'.
Load address: 0x400000
Loading: #################################################################
    #################################################################
    ####
done
Bytes transferred = 1958609 (1de2d1 hex)
Using ppc_4xx_eth0 device
TFTP from server 192.168.1.1; our IP address is 192.168.100.6
Filename '/tftpboot/duts/canyonlands/canyonlands.dtb'.
Load address: 0xb00000
Loading: #
done
Bytes transferred = 10190 (27ce hex)
## Booting kernel from Legacy Image at 00400000 ...
   Image Name:    Linux-2.6.32.7-00007-g08eba26
   Created:    2010-02-04  17:54:22 UTC
   Image Type:    PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    1958545 Bytes =  1.9 MB
   Load Address: 00000000
   Entry Point:    00000000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 00b00000
   Booting using the fdt blob at 0xb00000
   Uncompressing Kernel Image ... OK
Using PowerPC 44x Platform machine description
Linux version 2.6.32.7-00007-g08eba26 (stefan@stefan-desktop) (gcc version 4.2.2) #1 Thu Feb 4 18:54:16 CET 2010
Zone PFN ranges:
  DMA      0x00000000 -> 0x00020000
  Normal   0x00020000 -> 0x00020000
  HighMem  0x00020000 -> 0x00020000
Movable zone start PFN for each node
early_node_map[1] active PFN ranges
    0: 0x00000000 -> 0x00020000
MMU: Allocated 1088 bytes of context maps for 255 contexts
Built 1 zonelists in Zone order, mobility grouping on.   Total pages: 130048
Kernel command line: root=/dev/nfs rw nfsroot=192.168.1.1:/opt/eldk-4.2/ppc_4xxFP/ ip=192.168.100.6:192.168.1.1:192.168.1.254:255.255.0.0:canyonlands:eth0:off panic=1 console=ttyS0,115200
PID hash table entries: 2048 (order: 1, 8192 bytes)
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
Memory: 515328k/524288k available (3880k kernel code, 8740k reserved, 172k data, 134k bss, 168k init)
Kernel virtual memory layout:
  * 0xfffef000..0xfffff000  : fixmap
  * 0xffc00000..0xffe00000  : highmem PTEs
  * 0xffa00000..0xffc00000  : consistent mem
  * 0xffa00000..0xffa00000  : early ioremap
  * 0xe1000000..0xffa00000  : vmalloc & ioremap
SLUB: Genslabs=11, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Hierarchical RCU implementation.
NR_IRQS:512
UIC0 (32 IRQ sources) at DCR 0xc0
UIC1 (32 IRQ sources) at DCR 0xd0
UIC2 (32 IRQ sources) at DCR 0xe0
UIC3 (32 IRQ sources) at DCR 0xf0
clocksource: timebase mult[3c0000] shift[22] registered
Mount-cache hash table entries: 512
NET: Registered protocol family 16
256k L2-cache enabled
PCIE0: Port disabled via device-tree
PCIE1: Checking link...
PCIE1: No device detected.
PCI host bridge /plb/pciex@d20000000 (primary) ranges:
 MEM 0x0000000e80000000..0x0000000effffffff -> 0x0000000080000000
 MEM 0x0000000f00100000..0x0000000f001fffff -> 0x0000000000000000
  IO 0x0000000f80010000..0x0000000f8001ffff -> 0x0000000000000000
 Removing ISA hole at 0x0000000f00100000
4xx PCI DMA offset set to 0x00000000
/plb/pciex@d20000000: Legacy ISA memory support enabled
PCIE1: successfully set as root-complex
PCI host bridge /plb/pci@c0ec00000 (primary) ranges:
 MEM 0x0000000d80000000..0x0000000dffffffff -> 0x0000000080000000
 MEM 0x0000000c0ee00000..0x0000000c0eefffff -> 0x0000000000000000
  IO 0x0000000c08000000..0x0000000c0800ffff -> 0x0000000000000000
 Removing ISA hole at 0x0000000c0ee00000
4xx PCI DMA offset set to 0x00000000
/plb/pci@c0ec00000: Legacy ISA memory support enabled
PCI: Probing PCI hardware
PCI: Hiding 4xx host bridge resources 0000:80:00.0
pci 0000:80:00.0: PCI bridge, secondary bus 0000:81
pci 0000:80:00.0:   IO window: disabled
pci 0000:80:00.0:   MEM window: disabled
pci 0000:80:00.0:   PREFETCH window: disabled
bio: create slab <bio-0> at 0
vgaarb: loaded
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Switching to clocksource timebase
NET: Registered protocol family 2
IP route cache hash table entries: 4096 (order: 2, 16384 bytes)
TCP established hash table entries: 16384 (order: 5, 131072 bytes)
TCP bind hash table entries: 16384 (order: 4, 65536 bytes)
TCP: Hash tables configured (established 16384 bind 16384)
TCP reno registered
NET: Registered protocol family 1
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
msgmni has been set to 1006
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
serial8250.0: ttyS0 at MMIO 0x4ef600300 (irq = 19) is a 16550A
console [ttyS0] enabled
serial8250.0: ttyS1 at MMIO 0x4ef600400 (irq = 20) is a 16550A
serial8250.0: ttyS2 at MMIO 0x4ef600500 (irq = 29) is a 16550A
serial8250.0: ttyS3 at MMIO 0x4ef600600 (irq = 21) is a 16550A
4ef600300.serial: ttyS0 at MMIO 0x4ef600300 (irq = 19) is a 16550
4ef600400.serial: ttyS1 at MMIO 0x4ef600400 (irq = 20) is a 16550
4ef600500.serial: ttyS2 at MMIO 0x4ef600500 (irq = 29) is a 16550
4ef600600.serial: ttyS3 at MMIO 0x4ef600600 (irq = 21) is a 16550
brd: module loaded
sata-dwc sata-dwc.0: id 0, controller version 1.82
sata-dwc sata-dwc.0: DMA initialized
sata-dwc sata-dwc.0: **** No neg speed (nothing attached?)
scsi0 : sata-dwc
ata1: SATA max UDMA/133 irq 23
4cc000000.nor_flash: Found 1 x16 devices at 0x0 in 16-bit bank
 Amd/Fujitsu Extended Query Table at 0x0040
4cc000000.nor_flash: CFI does not contain boot bank location. Assuming top.
number of CFI chips: 1
cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.
RedBoot partition parsing not available
Creating 7 MTD partitions on "4cc000000.nor_flash":
0x000000000000-0x0000001e0000 : "kernel"
0x0000001e0000-0x000000200000 : "dtb"
0x000000200000-0x000001600000 : "ramdisk"
0x000001600000-0x000001a00000 : "jffs2"
0x000001a00000-0x000003f60000 : "user"
0x000003f60000-0x000003fa0000 : "env"
0x000003fa0000-0x000004000000 : "u-boot"
NAND device: Manufacturer ID: 0x20, Chip ID: 0xf1 (ST Micro NAND 128MiB 3,3V 8-bit)
Scanning device for bad blocks
Creating 2 MTD partitions on "4e0000000.ndfc.nand":
0x000000000000-0x000000100000 : "u-boot"
0x000000000000-0x000003f00000 : "user"
e1000e: Intel(R) PRO/1000 Network Driver - 1.0.2-k2
e1000e: Copyright (c) 1999-2008 Intel Corporation.
PPC 4xx OCP EMAC driver, version 3.54
MAL v2 /plb/mcmal, 2 TX channels, 16 RX channels
ZMII /plb/opb/emac-zmii@ef600d00 initialized
RGMII /plb/opb/emac-rgmii@ef601500 initialized with MDIO support
TAH /plb/opb/emac-tah@ef601350 initialized
TAH /plb/opb/emac-tah@ef601450 initialized
/plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode
eth0: EMAC-0 /plb/opb/ethernet@ef600e00, MAC 00:10:ec:01:08:84
eth0: found Generic MII PHY (0x00)
/plb/opb/emac-rgmii@ef601500: input 1 in RGMII mode
eth1: EMAC-1 /plb/opb/ethernet@ef600f00, MAC 00:10:ec:81:08:84
eth1: found Generic MII PHY (0x01)
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ppc-of-ehci 4bffd0400.ehci: OF EHCI
ppc-of-ehci 4bffd0400.ehci: new USB bus registered, assigned bus number 1
ppc-of-ehci 4bffd0400.ehci: irq 38, io mem 0x4bffd0400
ppc-of-ehci 4bffd0400.ehci: USB 2.0 started, EHCI 1.00
usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb1: Product: OF EHCI
usb usb1: Manufacturer: Linux 2.6.32.7-00007-g08eba26 ehci_hcd
usb usb1: SerialNumber: PPC-OF USB
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
ppc-of-ohci 4bffd0000.usb: OF OHCI
ppc-of-ohci 4bffd0000.usb: new USB bus registered, assigned bus number 2
ppc-of-ohci 4bffd0000.usb: irq 39, io mem 0x4bffd0000
usb usb2: New USB device found, idVendor=1d6b, idProduct=0001
usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb2: Product: OF OHCI
usb usb2: Manufacturer: Linux 2.6.32.7-00007-g08eba26 ohci_hcd
usb usb2: SerialNumber: PPC-OF USB
usb usb2: configuration #1 chosen from 1 choice
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 1 port detected
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
usbcore: registered new interface driver libusual
dwc_otg: version 2.60a 22-NOV-2006
dwc_otg: Shared Tx FIFO mode
dwc_otg: Using DMA mode
dwc_otg dwc_otg.0: DWC OTG Controller
dwc_otg dwc_otg.0: new USB bus registered, assigned bus number 3
dwc_otg dwc_otg.0: irq 28, io mem 0x00000000
dwc_otg: Init: Port Power? op_state=4
usb usb3: New USB device found, idVendor=1d6b, idProduct=0002
usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb3: Product: DWC OTG Controller
usb usb3: Manufacturer: Linux 2.6.32.7-00007-g08eba26 dwc_otg_hcd
usb usb3: SerialNumber: dwc_otg.0
usb usb3: configuration #1 chosen from 1 choice
hub 3-0:1.0: USB hub found
hub 3-0:1.0: 1 port detected
i2c /dev entries driver
ibm-iic 4ef600700.i2c: using standard (100 kHz) mode
rtc-m41t80 0-0068: chip found, driver version 0.05
rtc-m41t80 0-0068: rtc core: registered m41t80 as rtc0
ibm-iic 4ef600800.i2c: using standard (100 kHz) mode
ad7414 0-0048: chip found
TCP cubic registered
NET: Registered protocol family 17
rtc-m41t80 0-0068: setting system clock to 2010-02-08 16:33:33 UTC (1265646813)
usb 1-1: new high speed USB device using ppc-of-ehci and address 2
usb 1-1: New USB device found, idVendor=1370, idProduct=2168
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1: Product: Memorybird P
usb 1-1: Manufacturer: FSC
usb 1-1: SerialNumber: 10005383BB000032
usb 1-1: configuration #1 chosen from 1 choice
scsi1 : SCSI emulation for USB Mass Storage devices
eth0: link is down
IP-Config: Complete:
     device=eth0, addr=192.168.100.6, mask=255.255.0.0, gw=192.168.1.254,
     host=canyonlands, domain=, nis-domain=(none),
     bootserver=192.168.1.1, rootserver=192.168.1.1, rootpath=
Looking up port of RPC 100003/2 on 192.168.1.1
eth0: link is up, 1000 FDX, pause enabled
Looking up port of RPC 100005/1 on 192.168.1.1
VFS: Mounted root (nfs filesystem) on device 0:14.
Freeing unused kernel memory: 168k init
modprobe: FATAL: Could not load /lib/modules/2.6.32.7-00007-g08eba26/modules.dep: No such file or directory

modprobe: FATAL: Could not load /lib/modules/2.6.32.7-00007-g08eba26/modules.dep: No such file or directory

INIT: version 2.86 booting
      Welcome to DENX Embedded Linux Environment
      Press 'I' to enter interactive startup.
Setting clock : Mon Feb    8 16:33:38 CET 2010 [   OK  ]
Building the cache scsi 1:0:0:0: Direct-Access      FSC       Memorybird P     2.00 PQ: 0 ANSI: 2
[  OK  ]
Setting hostname canyonlands:  [  OK  ]
Mounting local filesystems:  [   OK  ]
Enabling /etc/fstab swaps:  [  OK  ]
INIT: Entering runlevel: 3
Entering non-interactive startup
FATAL: Could not load /lib/modules/2.6.32.7-00007-g08eba26/modules.dep: No such file or directory
Bringing up loopback interface:    [  OK   ]
FATAL: Could not load /lib/modules/2.6.32.7-00007-g08eba26/modules.dep: No such file or directory
Starting system logger: [  OK  ]
Starting kernel logger: [  OK  ]
Starting rpcbind: [  OK    ]
Mounting NFS filesystems:  [  OK  ]
Mounting other filesystems:  [   OK  ]
Starting xinetd: [  OK   ]

DENX ELDK version 4.2 build 2008-04-01
Linux 2.6.32.7-00007-g08eba26 on a ppc

canyonlands login: root
Last login: Sat Jan  3 19:28:07 from pollux
-bash-3.2#

7.6. Boot from Flash Memory

The previous section described how to load the Linux kernel image over ethernet using TFTP. This is especially well suited for your development and test environment, when the kernel image is still undergoing frequent changes, for instance because you are modifying kernel code or configuration.

Later in your development cycle you will work on application code or device drivers, which can be loaded dynamically as modules. If the Linux kernel remains the same then you can save the time needed for the TFTP download and put the kernel image into the flash memory of your canyonlands board.

The U-Boot command flinfo can be used to display information about the available on-board flash on your system:

=> fli

Bank # 1: CFI conformant FLASH (16 x 16)  Size: 64 MB in 512 Sectors
  AMD Standard command set, Manufacturer ID: 0x01, Device ID: 0x227E
  Erase timeout: 16384 ms, write timeout: 2 ms
  Buffer write timeout: 5 ms, buffer size: 32 bytes

  Sector Start Addresses:
  FC000000     FC020000     FC040000     FC060000     FC080000
  FC0A0000     FC0C0000     FC0E0000     FC100000     FC120000
  FC140000     FC160000     FC180000     FC1A0000     FC1C0000 E
  FC1E0000     FC200000     FC220000     FC240000     FC260000
  FC280000     FC2A0000     FC2C0000     FC2E0000     FC300000
  FC320000     FC340000     FC360000     FC380000     FC3A0000
  FC3C0000 E     FC3E0000 E     FC400000 E     FC420000 E     FC440000 E
  FC460000 E     FC480000 E     FC4A0000 E     FC4C0000 E     FC4E0000 E
  FC500000 E     FC520000 E     FC540000 E     FC560000 E     FC580000 E
  FC5A0000 E     FC5C0000 E     FC5E0000 E     FC600000 E     FC620000 E
  FC640000 E     FC660000 E     FC680000 E     FC6A0000 E     FC6C0000 E
  FC6E0000 E     FC700000 E     FC720000 E     FC740000 E     FC760000 E
  FC780000 E     FC7A0000 E     FC7C0000 E     FC7E0000 E     FC800000 E
  FC820000 E     FC840000 E     FC860000 E     FC880000 E     FC8A0000 E
  FC8C0000 E     FC8E0000 E     FC900000 E     FC920000 E     FC940000 E
  FC960000 E     FC980000 E     FC9A0000 E     FC9C0000 E     FC9E0000 E
  FCA00000 E     FCA20000 E     FCA40000 E     FCA60000 E     FCA80000 E
  FCAA0000 E     FCAC0000 E     FCAE0000 E     FCB00000 E     FCB20000 E
  FCB40000 E     FCB60000 E     FCB80000 E     FCBA0000 E     FCBC0000 E
  FCBE0000 E     FCC00000 E     FCC20000 E     FCC40000 E     FCC60000 E
  FCC80000 E     FCCA0000 E     FCCC0000 E     FCCE0000 E     FCD00000 E
  FCD20000 E     FCD40000 E     FCD60000 E     FCD80000 E     FCDA0000 E
  FCDC0000 E     FCDE0000 E     FCE00000 E     FCE20000 E     FCE40000 E
  FCE60000 E     FCE80000 E     FCEA0000 E     FCEC0000 E     FCEE0000 E
  FCF00000 E     FCF20000 E     FCF40000 E     FCF60000 E     FCF80000 E
  FCFA0000 E     FCFC0000 E     FCFE0000 E     FD000000 E     FD020000 E
  FD040000 E     FD060000 E     FD080000 E     FD0A0000 E     FD0C0000 E
  FD0E0000 E     FD100000 E     FD120000 E     FD140000 E     FD160000 E
  FD180000 E     FD1A0000 E     FD1C0000 E     FD1E0000 E     FD200000 E
  FD220000 E     FD240000 E     FD260000 E     FD280000 E     FD2A0000 E
  FD2C0000 E     FD2E0000 E     FD300000 E     FD320000 E     FD340000 E
  FD360000 E     FD380000 E     FD3A0000 E     FD3C0000 E     FD3E0000 E
  FD400000 E     FD420000 E     FD440000 E     FD460000 E     FD480000 E
  FD4A0000 E     FD4C0000 E     FD4E0000 E     FD500000 E     FD520000 E
  FD540000 E     FD560000 E     FD580000 E     FD5A0000 E     FD5C0000 E
  FD5E0000 E     FD600000     FD620000 E     FD640000 E     FD660000 E
  FD680000 E     FD6A0000 E     FD6C0000 E     FD6E0000 E     FD700000 E
  FD720000 E     FD740000 E     FD760000 E     FD780000 E     FD7A0000 E
  FD7C0000 E     FD7E0000 E     FD800000 E     FD820000 E     FD840000 E
  FD860000 E     FD880000 E     FD8A0000 E     FD8C0000 E     FD8E0000 E
  FD900000 E     FD920000 E     FD940000 E     FD960000 E     FD980000 E
  FD9A0000 E     FD9C0000 E     FD9E0000 E     FDA00000 E     FDA20000 E
  FDA40000 E     FDA60000 E     FDA80000 E     FDAA0000 E     FDAC0000 E
  FDAE0000 E     FDB00000 E     FDB20000 E     FDB40000 E     FDB60000 E
  FDB80000 E     FDBA0000 E     FDBC0000 E     FDBE0000 E     FDC00000 E
  FDC20000 E     FDC40000 E     FDC60000 E     FDC80000 E     FDCA0000 E
  FDCC0000 E     FDCE0000 E     FDD00000 E     FDD20000 E     FDD40000 E
  FDD60000 E     FDD80000 E     FDDA0000 E     FDDC0000 E     FDDE0000 E
  FDE00000 E     FDE20000 E     FDE40000 E     FDE60000 E     FDE80000 E
  FDEA0000 E     FDEC0000 E     FDEE0000 E     FDF00000 E     FDF20000 E
  FDF40000 E     FDF60000 E     FDF80000 E     FDFA0000 E     FDFC0000 E
  FDFE0000 E     FE000000 E     FE020000 E     FE040000 E     FE060000 E
  FE080000 E     FE0A0000 E     FE0C0000 E     FE0E0000 E     FE100000 E
  FE120000 E     FE140000 E     FE160000 E     FE180000 E     FE1A0000 E
  FE1C0000 E     FE1E0000 E     FE200000 E     FE220000 E     FE240000 E
  FE260000 E     FE280000 E     FE2A0000 E     FE2C0000 E     FE2E0000 E
  FE300000 E     FE320000 E     FE340000 E     FE360000 E     FE380000 E
  FE3A0000 E     FE3C0000 E     FE3E0000 E     FE400000 E     FE420000 E
  FE440000 E     FE460000 E     FE480000 E     FE4A0000 E     FE4C0000 E
  FE4E0000 E     FE500000 E     FE520000 E     FE540000 E     FE560000 E
  FE580000 E     FE5A0000 E     FE5C0000 E     FE5E0000 E     FE600000 E
  FE620000 E     FE640000 E     FE660000 E     FE680000 E     FE6A0000 E
  FE6C0000 E     FE6E0000 E     FE700000 E     FE720000 E     FE740000 E
  FE760000 E     FE780000 E     FE7A0000 E     FE7C0000 E     FE7E0000 E
  FE800000 E     FE820000 E     FE840000 E     FE860000 E     FE880000 E
  FE8A0000 E     FE8C0000 E     FE8E0000 E     FE900000 E     FE920000 E
  FE940000 E     FE960000 E     FE980000 E     FE9A0000 E     FE9C0000 E
  FE9E0000 E     FEA00000 E     FEA20000 E     FEA40000 E     FEA60000 E
  FEA80000 E     FEAA0000 E     FEAC0000 E     FEAE0000 E     FEB00000 E
  FEB20000 E     FEB40000 E     FEB60000 E     FEB80000 E     FEBA0000 E
  FEBC0000 E     FEBE0000 E     FEC00000 E     FEC20000 E     FEC40000 E
  FEC60000 E     FEC80000 E     FECA0000 E     FECC0000 E     FECE0000 E
  FED00000 E     FED20000 E     FED40000 E     FED60000 E     FED80000 E
  FEDA0000 E     FEDC0000 E     FEDE0000 E     FEE00000 E     FEE20000 E
  FEE40000 E     FEE60000 E     FEE80000 E     FEEA0000 E     FEEC0000 E
  FEEE0000 E     FEF00000 E     FEF20000 E     FEF40000 E     FEF60000 E
  FEF80000 E     FEFA0000 E     FEFC0000 E     FEFE0000 E     FF000000 E
  FF020000 E     FF040000 E     FF060000 E     FF080000 E     FF0A0000 E
  FF0C0000 E     FF0E0000 E     FF100000 E     FF120000 E     FF140000 E
  FF160000 E     FF180000 E     FF1A0000 E     FF1C0000 E     FF1E0000 E
  FF200000 E     FF220000 E     FF240000 E     FF260000 E     FF280000 E
  FF2A0000 E     FF2C0000 E     FF2E0000 E     FF300000 E     FF320000 E
  FF340000 E     FF360000 E     FF380000 E     FF3A0000 E     FF3C0000 E
  FF3E0000 E     FF400000 E     FF420000 E     FF440000 E     FF460000 E
  FF480000 E     FF4A0000 E     FF4C0000 E     FF4E0000 E     FF500000 E
  FF520000 E     FF540000 E     FF560000 E     FF580000 E     FF5A0000 E
  FF5C0000 E     FF5E0000 E     FF600000 E     FF620000 E     FF640000 E
  FF660000 E     FF680000 E     FF6A0000 E     FF6C0000 E     FF6E0000 E
  FF700000 E     FF720000 E     FF740000 E     FF760000 E     FF780000 E
  FF7A0000 E     FF7C0000 E     FF7E0000 E     FF800000 E     FF820000 E
  FF840000 E     FF860000 E     FF880000 E     FF8A0000 E     FF8C0000 E
  FF8E0000 E     FF900000 E     FF920000 E     FF940000 E     FF960000 E
  FF980000 E     FF9A0000 E     FF9C0000 E     FF9E0000 E     FFA00000 E
  FFA20000 E     FFA40000 E     FFA60000 E     FFA80000 E     FFAA0000 E
  FFAC0000 E     FFAE0000 E     FFB00000 E     FFB20000 E     FFB40000 E
  FFB60000 E     FFB80000 E     FFBA0000 E     FFBC0000 E     FFBE0000 E
  FFC00000 E     FFC20000 E     FFC40000 E     FFC60000 E     FFC80000 E
  FFCA0000 E     FFCC0000 E     FFCE0000 E     FFD00000 E     FFD20000 E
  FFD40000 E     FFD60000 E     FFD80000 E     FFDA0000 E     FFDC0000 E
  FFDE0000 E     FFE00000 E     FFE20000 E     FFE40000 E     FFE60000 E
  FFE80000 E     FFEA0000 E     FFEC0000 E     FFEE0000 E     FFF00000 E
  FFF20000 E     FFF40000 E     FFF60000   RO     FFF80000   RO     FFFA0000   RO
  FFFC0000   RO     FFFE0000   RO
=>

From this output you can see the total amount of flash memory, and how it is divided in blocks (Erase Units or Sectors). The RO markers show blocks of flash memory that are write protected (by software) - this is the area where U-Boot is stored. The remaining flash memory is available for other use.

For instance, we can store the Linux kernel image in flash starting at the start address of the next free flash sector. Before we can do this we must make sure that the flash memory in that region is empty - a Linux kernel image is typically around 600...700 kB, so to be on the safe side we dedicate the whole area from 0xFC000000 to 0xFC17FFFF for the kernel image. Keep in mind that with flash memory only whole erase units can be cleared.

After having deleted the target flash area, you can download the Linux image and write it to flash. Below is a transcript of the complete operation with a final iminfo command to check the newly placed Linux kernel image in the flash memory.


=>  
=> setenv kernel_addr FC000000
=>  
=> prot off FC000000 FC17FFFF
Un-Protected 12 sectors
=>  
=> era FC000000 FC17FFFF

............ done
Erased 12 sectors
=>  
=> tftp 100000 /tftpboot/canyonlands/uImage-duts
ENET Speed is 1000 Mbps - FULL duplex connection (EMAC0)
Using ppc_4xx_eth0 device
TFTP from server 192.168.1.1; our IP address is 192.168.100.6
Filename '/tftpboot/canyonlands/uImage-duts'.
Load address: 0x100000
Loading: *#################################################################
    ######################################################
done
Bytes transferred = 1744326 (1a9dc6 hex)
=>  
=> imi 100000

## Checking Image at 00100000 ...
   Legacy image found
   Image Name:   Linux-2.6.25-rc8-01016-g94bf13b-
   Created:      2008-04-10   9:50:08 UTC
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    1744262 Bytes =  1.7 MB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
=>  
=> setenv ram_ws 100000
=>  
=> cp.b ${ram_ws} ${kernel_addr} ${filesize}
Copy to Flash... done
=>  
=> iminfo ${kernel_addr}

## Checking Image at fc000000 ...
   Legacy image found
   Image Name:   Linux-2.6.25-rc8-01016-g94bf13b-
   Created:      2008-04-10   9:50:08 UTC
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    1744262 Bytes =  1.7 MB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
=>  
=> saveenv
Saving Environment to Flash...
Un-Protected 1 sectors
Un-Protected 1 sectors
Erasing Flash...
. done
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
Protected 1 sectors
=> 

Note how the filesize variable (which gets set by the TFTP transfer) is used to automatically adjust for the actual image size.

Since kernel requires the flattened device tree blob to be passed at boot time, you have to also write the blob to the flash memory. Below is a transcript of this operation.

 
=>  
=> setenv fdt_addr FC1E0000
=>  
=> prot off FC1E0000 FC1FFFFF
Un-Protected 1 sectors
=>  
=> era FC1E0000 FC1FFFFF

. done
Erased 1 sectors
=>  
=> tftp 100000 /tftpboot/canyonlands/canyonlands.dtb
Waiting for PHY auto negotiation to complete... done
ENET Speed is 1000 Mbps - FULL duplex connection (EMAC0)
Using ppc_4xx_eth0 device
TFTP from server 192.168.1.1; our IP address is 192.168.100.6
Filename '/tftpboot/canyonlands/canyonlands.dtb'.
Load address: 0x100000
Loading: *T #
done
Bytes transferred = 10000 (2710 hex)
=>  
=> md 100000
00100000: d00dfeed 00002710 000000b8 00001b08    ......'.........
00100010: 00000028 00000011 00000010 00000000    ...(............
00100020: 000002f5 00001a50 00000000 00000000    .......P........
00100030: 00000000 00000000 00000000 00000000    ................
00100040: 00000000 00000000 00000000 00000000    ................
00100050: 00000000 00000000 00000000 00000000    ................
00100060: 00000000 00000000 00000000 00000000    ................
00100070: 00000000 00000000 00000000 00000000    ................
00100080: 00000000 00000000 00000000 00000000    ................
00100090: 00000000 00000000 00000000 00000000    ................
001000a0: 00000000 00000000 00000000 00000000    ................
001000b0: 00000000 00000000 00000001 00000000    ................
001000c0: 00000003 00000004 00000000 00000002    ................
001000d0: 00000003 00000004 0000000f 00000001    ................
001000e0: 00000003 00000011 0000001b 616d6363    ............amcc
001000f0: 2c63616e 796f6e6c 616e6473 00000000    ,canyonlands....
=>  
=> setenv ram_ws 100000
=>  
=> cp.b ${ram_ws} ${fdt_addr} ${filesize}
Copy to Flash... done
=>  
=> md ${fdt_addr}
fc1e0000: d00dfeed 00002710 000000b8 00001b08    ......'.........
fc1e0010: 00000028 00000011 00000010 00000000    ...(............
fc1e0020: 000002f5 00001a50 00000000 00000000    .......P........
fc1e0030: 00000000 00000000 00000000 00000000    ................
fc1e0040: 00000000 00000000 00000000 00000000    ................
fc1e0050: 00000000 00000000 00000000 00000000    ................
fc1e0060: 00000000 00000000 00000000 00000000    ................
fc1e0070: 00000000 00000000 00000000 00000000    ................
fc1e0080: 00000000 00000000 00000000 00000000    ................
fc1e0090: 00000000 00000000 00000000 00000000    ................
fc1e00a0: 00000000 00000000 00000000 00000000    ................
fc1e00b0: 00000000 00000000 00000001 00000000    ................
fc1e00c0: 00000003 00000004 00000000 00000002    ................
fc1e00d0: 00000003 00000004 0000000f 00000001    ................
fc1e00e0: 00000003 00000011 0000001b 616d6363    ............amcc
fc1e00f0: 2c63616e 796f6e6c 616e6473 00000000    ,canyonlands....
=>  
=> setenv filesize
=>  
=> saveenv
Saving Environment to Flash...
Un-Protected 1 sectors
Un-Protected 1 sectors
Erasing Flash...
. done
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
Protected 1 sectors
=> 

Now we can boot directly from flash. All we need to do is passing the in-flash address of the image (FC000000) and the in-flash address of the flattened device tree (FC1E0000) with the bootm command; we also make the definition of the bootargs variable permanent now:

=> setenv bootcmd bootm FC000000 - FC1E0000 
=> setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off

Use printenv to verify that everything is OK before you save the environment settings:

=> printenv
bootdelay=5
baudrate=115200
stdin=serial
stdout=serial
stderr=serial
bootcmd=bootm FC000000 - FC1E0000 
bootargs=root=/dev/nfs rw nfsroot=192.168.1.1:/opt/eldk-4.2/ppc_4xx
ip=192.168.100.6:192.168.1.1:192.168.1.1:255.255.0.0:canyonlands::off
....

=> saveenv

To test booting from flash you can now reset the board (either by power-cycling it, or using the U-Boot command reset), or you can manually call the boot command which will run the commands in the bootcmd variable:

=> run flash_self
## Booting kernel from Legacy Image at fc000000 ...
   Image Name:    Linux-2.6.32.7-00007-g08eba26
   Created:    2010-02-04  17:54:22 UTC
   Image Type:    PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    1958545 Bytes =  1.9 MB
   Load Address: 00000000
   Entry Point:    00000000
   Verifying Checksum ... OK
## Loading init Ramdisk from Legacy Image at fc200000 ...
   Image Name:    Simple Embedded Linux Framework
   Created:    2008-04-01  19:52:43 UTC
   Image Type:    PowerPC Linux RAMDisk Image (gzip compressed)
   Data Size:    1727937 Bytes =  1.6 MB
   Load Address: 00000000
   Entry Point:    00000000
   Verifying Checksum ... OK
## Flattened Device Tree blob at fc1e0000
   Booting using the fdt blob at 0xfc1e0000
   Uncompressing Kernel Image ... OK
   Loading Ramdisk to 1fca6000, end 1fe4bdc1 ... OK
   Loading Device Tree to 00ffa000, end 00fff7cd ... OK
Using PowerPC 44x Platform machine description
Linux version 2.6.32.7-00007-g08eba26 (stefan@stefan-desktop) (gcc version 4.2.2) #1 Thu Feb 4 18:54:16 CET 2010
Found initrd at 0xdfca6000:0xdfe4bdc1
Zone PFN ranges:
  DMA      0x00000000 -> 0x00020000
  Normal   0x00020000 -> 0x00020000
  HighMem  0x00020000 -> 0x00020000
Movable zone start PFN for each node
early_node_map[1] active PFN ranges
    0: 0x00000000 -> 0x00020000
MMU: Allocated 1088 bytes of context maps for 255 contexts
Built 1 zonelists in Zone order, mobility grouping on.   Total pages: 130048
Kernel command line: root=/dev/ram rw ip=192.168.100.6:192.168.1.1:192.168.1.254:255.255.0.0:canyonlands:eth0:off panic=1 console=ttyS0,115200
PID hash table entries: 2048 (order: 1, 8192 bytes)
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
Memory: 513536k/524288k available (3880k kernel code, 10428k reserved, 172k data, 134k bss, 168k init)
Kernel virtual memory layout:
  * 0xfffef000..0xfffff000  : fixmap
  * 0xffc00000..0xffe00000  : highmem PTEs
  * 0xffa00000..0xffc00000  : consistent mem
  * 0xffa00000..0xffa00000  : early ioremap
  * 0xe1000000..0xffa00000  : vmalloc & ioremap
SLUB: Genslabs=11, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Hierarchical RCU implementation.
NR_IRQS:512
UIC0 (32 IRQ sources) at DCR 0xc0
UIC1 (32 IRQ sources) at DCR 0xd0
UIC2 (32 IRQ sources) at DCR 0xe0
UIC3 (32 IRQ sources) at DCR 0xf0
clocksource: timebase mult[3c0000] shift[22] registered
Mount-cache hash table entries: 512
NET: Registered protocol family 16
256k L2-cache enabled
PCIE0: Port disabled via device-tree
PCIE1: Checking link...
PCIE1: No device detected.
PCI host bridge /plb/pciex@d20000000 (primary) ranges:
 MEM 0x0000000e80000000..0x0000000effffffff -> 0x0000000080000000
 MEM 0x0000000f00100000..0x0000000f001fffff -> 0x0000000000000000
  IO 0x0000000f80010000..0x0000000f8001ffff -> 0x0000000000000000
 Removing ISA hole at 0x0000000f00100000
4xx PCI DMA offset set to 0x00000000
/plb/pciex@d20000000: Legacy ISA memory support enabled
PCIE1: successfully set as root-complex
PCI host bridge /plb/pci@c0ec00000 (primary) ranges:
 MEM 0x0000000d80000000..0x0000000dffffffff -> 0x0000000080000000
 MEM 0x0000000c0ee00000..0x0000000c0eefffff -> 0x0000000000000000
  IO 0x0000000c08000000..0x0000000c0800ffff -> 0x0000000000000000
 Removing ISA hole at 0x0000000c0ee00000
4xx PCI DMA offset set to 0x00000000
/plb/pci@c0ec00000: Legacy ISA memory support enabled
PCI: Probing PCI hardware
PCI: Hiding 4xx host bridge resources 0000:80:00.0
pci 0000:80:00.0: PCI bridge, secondary bus 0000:81
pci 0000:80:00.0:   IO window: disabled
pci 0000:80:00.0:   MEM window: disabled
pci 0000:80:00.0:   PREFETCH window: disabled
bio: create slab <bio-0> at 0
vgaarb: loaded
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Switching to clocksource timebase
NET: Registered protocol family 2
IP route cache hash table entries: 4096 (order: 2, 16384 bytes)
TCP established hash table entries: 16384 (order: 5, 131072 bytes)
TCP bind hash table entries: 16384 (order: 4, 65536 bytes)
TCP: Hash tables configured (established 16384 bind 16384)
TCP reno registered
NET: Registered protocol family 1
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
Trying to unpack rootfs image as initramfs...
rootfs image is not initramfs (no cpio magic); looks like an initrd
Freeing initrd memory: 1687k freed
JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
msgmni has been set to 1006
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
serial8250.0: ttyS0 at MMIO 0x4ef600300 (irq = 19) is a 16550A
console [ttyS0] enabled
serial8250.0: ttyS1 at MMIO 0x4ef600400 (irq = 20) is a 16550A
serial8250.0: ttyS2 at MMIO 0x4ef600500 (irq = 29) is a 16550A
serial8250.0: ttyS3 at MMIO 0x4ef600600 (irq = 21) is a 16550A
4ef600300.serial: ttyS0 at MMIO 0x4ef600300 (irq = 19) is a 16550
4ef600400.serial: ttyS1 at MMIO 0x4ef600400 (irq = 20) is a 16550
4ef600500.serial: ttyS2 at MMIO 0x4ef600500 (irq = 29) is a 16550
4ef600600.serial: ttyS3 at MMIO 0x4ef600600 (irq = 21) is a 16550
brd: module loaded
sata-dwc sata-dwc.0: id 0, controller version 1.82
sata-dwc sata-dwc.0: DMA initialized
sata-dwc sata-dwc.0: **** No neg speed (nothing attached?)
scsi0 : sata-dwc
ata1: SATA max UDMA/133 irq 23
4cc000000.nor_flash: Found 1 x16 devices at 0x0 in 16-bit bank
 Amd/Fujitsu Extended Query Table at 0x0040
4cc000000.nor_flash: CFI does not contain boot bank location. Assuming top.
number of CFI chips: 1
cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.
RedBoot partition parsing not available
Creating 7 MTD partitions on "4cc000000.nor_flash":
0x000000000000-0x0000001e0000 : "kernel"
0x0000001e0000-0x000000200000 : "dtb"
0x000000200000-0x000001600000 : "ramdisk"
0x000001600000-0x000001a00000 : "jffs2"
0x000001a00000-0x000003f60000 : "user"
0x000003f60000-0x000003fa0000 : "env"
0x000003fa0000-0x000004000000 : "u-boot"
NAND device: Manufacturer ID: 0x20, Chip ID: 0xf1 (ST Micro NAND 128MiB 3,3V 8-bit)
Scanning device for bad blocks
Creating 2 MTD partitions on "4e0000000.ndfc.nand":
0x000000000000-0x000000100000 : "u-boot"
0x000000000000-0x000003f00000 : "user"
e1000e: Intel(R) PRO/1000 Network Driver - 1.0.2-k2
e1000e: Copyright (c) 1999-2008 Intel Corporation.
PPC 4xx OCP EMAC driver, version 3.54
MAL v2 /plb/mcmal, 2 TX channels, 16 RX channels
ZMII /plb/opb/emac-zmii@ef600d00 initialized
RGMII /plb/opb/emac-rgmii@ef601500 initialized with MDIO support
TAH /plb/opb/emac-tah@ef601350 initialized
TAH /plb/opb/emac-tah@ef601450 initialized
/plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode
eth0: EMAC-0 /plb/opb/ethernet@ef600e00, MAC 00:10:ec:01:08:84
eth0: found Generic MII PHY (0x00)
/plb/opb/emac-rgmii@ef601500: input 1 in RGMII mode
eth1: EMAC-1 /plb/opb/ethernet@ef600f00, MAC 00:10:ec:81:08:84
eth1: found Generic MII PHY (0x01)
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ppc-of-ehci 4bffd0400.ehci: OF EHCI
ppc-of-ehci 4bffd0400.ehci: new USB bus registered, assigned bus number 1
ppc-of-ehci 4bffd0400.ehci: irq 38, io mem 0x4bffd0400
ppc-of-ehci 4bffd0400.ehci: USB 2.0 started, EHCI 1.00
usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb1: Product: OF EHCI
usb usb1: Manufacturer: Linux 2.6.32.7-00007-g08eba26 ehci_hcd
usb usb1: SerialNumber: PPC-OF USB
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
ppc-of-ohci 4bffd0000.usb: OF OHCI
ppc-of-ohci 4bffd0000.usb: new USB bus registered, assigned bus number 2
ppc-of-ohci 4bffd0000.usb: irq 39, io mem 0x4bffd0000
usb usb2: New USB device found, idVendor=1d6b, idProduct=0001
usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb2: Product: OF OHCI
usb usb2: Manufacturer: Linux 2.6.32.7-00007-g08eba26 ohci_hcd
usb usb2: SerialNumber: PPC-OF USB
usb usb2: configuration #1 chosen from 1 choice
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 1 port detected
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
usbcore: registered new interface driver libusual
dwc_otg: version 2.60a 22-NOV-2006
dwc_otg: Shared Tx FIFO mode
dwc_otg: Using DMA mode
dwc_otg dwc_otg.0: DWC OTG Controller
dwc_otg dwc_otg.0: new USB bus registered, assigned bus number 3
dwc_otg dwc_otg.0: irq 28, io mem 0x00000000
dwc_otg: Init: Port Power? op_state=4
usb usb3: New USB device found, idVendor=1d6b, idProduct=0002
usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb3: Product: DWC OTG Controller
usb usb3: Manufacturer: Linux 2.6.32.7-00007-g08eba26 dwc_otg_hcd
usb usb3: SerialNumber: dwc_otg.0
usb usb3: configuration #1 chosen from 1 choice
hub 3-0:1.0: USB hub found
hub 3-0:1.0: 1 port detected
i2c /dev entries driver
ibm-iic 4ef600700.i2c: using standard (100 kHz) mode
rtc-m41t80 0-0068: chip found, driver version 0.05
rtc-m41t80 0-0068: rtc core: registered m41t80 as rtc0
ibm-iic 4ef600800.i2c: using standard (100 kHz) mode
ad7414 0-0048: chip found
TCP cubic registered
NET: Registered protocol family 17
rtc-m41t80 0-0068: setting system clock to 2010-02-08 16:34:03 UTC (1265646843)
usb 1-1: new high speed USB device using ppc-of-ehci and address 2
usb 1-1: New USB device found, idVendor=1370, idProduct=2168
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1: Product: Memorybird P
usb 1-1: Manufacturer: FSC
usb 1-1: SerialNumber: 10005383BB000032
usb 1-1: configuration #1 chosen from 1 choice
scsi1 : SCSI emulation for USB Mass Storage devices
eth0: link is down
IP-Config: Complete:
     device=eth0, addr=192.168.100.6, mask=255.255.0.0, gw=192.168.1.254,
     host=canyonlands, domain=, nis-domain=(none),
     bootserver=192.168.1.1, rootserver=192.168.1.1, rootpath=
RAMDISK: gzip image found at block 0
VFS: Mounted root (ext2 filesystem) on device 1:0.
Freeing unused kernel memory: 168k init
init started: BusyBox v1.7.1 (2008-04-01 21:48:01 MEST)
starting pid 944, tty '': '/etc/rc.sh'
starting pid 950, tty '': '/bin/sh'
~ # starting pid 949, tty '': '/bin/application'
### Application running ...


~ #

7.7. Standalone Operation with Ramdisk Image

When your application development is completed, you usually will want to run your Embedded System standalone, i. e. independent from external resources like NFS filesystems. Instead of mounting the root filesystem from a remote server you can use a compressed ramdisk image, which is stored in flash memory and loaded into RAM when the system boots.

Ramdisk images for tests can be found in the ftp://ftp.denx.de/pub/LinuxPPC/usr/src/SELF/images/ directories.

Load the ramdisk image into RAM and write it to flash as follows:

=> setenv ramdisk_addr 0xFC200000
=> setenv ram_ws 0x100000
=> protect off 0xFC200000 0xFC3FFFFF
Un-Protected 16 sectors
=> erase 0xFC200000 0xFC3FFFFF

................ done
Erased 16 sectors
=> tftp 0x100000 /tftpboot/duts/canyonlands/uRamdisk
Using ppc_4xx_eth0 device
TFTP from server 192.168.1.1; our IP address is 192.168.100.6
Filename '/tftpboot/duts/canyonlands/uRamdisk'.
Load address: 0x100000
Loading: #################################################################
    #####################################################
done
Bytes transferred = 1728001 (1a5e01 hex)
=> iminfo ${ram_ws}

## Checking Image at 00100000 ...
   Legacy image found
   Image Name:    Simple Embedded Linux Framework
   Created:    2008-04-01  19:52:43 UTC
   Image Type:    PowerPC Linux RAMDisk Image (gzip compressed)
   Data Size:    1727937 Bytes =  1.6 MB
   Load Address: 00000000
   Entry Point:    00000000
   Verifying Checksum ... OK
=> cp.b ${ram_ws} ${ramdisk_addr} ${filesize}
Copy to Flash... done
=> iminfo ${ramdisk_addr}

## Checking Image at fc200000 ...
   Legacy image found
   Image Name:    Simple Embedded Linux Framework
   Created:    2008-04-01  19:52:43 UTC
   Image Type:    PowerPC Linux RAMDisk Image (gzip compressed)
   Data Size:    1727937 Bytes =  1.6 MB
   Load Address: 00000000
   Entry Point:    00000000
   Verifying Checksum ... OK
=> setenv ram_ws
=> saveenv
Saving Environment to Flash...
Un-Protected 1 sectors
Un-Protected 1 sectors
Erasing Flash...
. done
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
Protected 1 sectors
=>

To tell the Linux kernel to use the ramdisk image as root filesystem you have to modify the command line arguments passed to the kernel, and pass ramdisk image address as the second argument to the bootm command (first argument is the memory address of the Linux kernel image, the third one is the memory address of the flattened device tree blob):

=> run flash_self
## Booting kernel from Legacy Image at fc000000 ...
   Image Name:    Linux-2.6.32.7-00007-g08eba26
   Created:    2010-02-04  17:54:22 UTC
   Image Type:    PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    1958545 Bytes =  1.9 MB
   Load Address: 00000000
   Entry Point:    00000000
   Verifying Checksum ... OK
## Loading init Ramdisk from Legacy Image at fc200000 ...
   Image Name:    Simple Embedded Linux Framework
   Created:    2008-04-01  19:52:43 UTC
   Image Type:    PowerPC Linux RAMDisk Image (gzip compressed)
   Data Size:    1727937 Bytes =  1.6 MB
   Load Address: 00000000
   Entry Point:    00000000
   Verifying Checksum ... OK
## Flattened Device Tree blob at fc1e0000
   Booting using the fdt blob at 0xfc1e0000
   Uncompressing Kernel Image ... OK
   Loading Ramdisk to 1fca6000, end 1fe4bdc1 ... OK
   Loading Device Tree to 00ffa000, end 00fff7cd ... OK
Using PowerPC 44x Platform machine description
Linux version 2.6.32.7-00007-g08eba26 (stefan@stefan-desktop) (gcc version 4.2.2) #1 Thu Feb 4 18:54:16 CET 2010
Found initrd at 0xdfca6000:0xdfe4bdc1
Zone PFN ranges:
  DMA      0x00000000 -> 0x00020000
  Normal   0x00020000 -> 0x00020000
  HighMem  0x00020000 -> 0x00020000
Movable zone start PFN for each node
early_node_map[1] active PFN ranges
    0: 0x00000000 -> 0x00020000
MMU: Allocated 1088 bytes of context maps for 255 contexts
Built 1 zonelists in Zone order, mobility grouping on.   Total pages: 130048
Kernel command line: root=/dev/ram rw ip=192.168.100.6:192.168.1.1:192.168.1.254:255.255.0.0:canyonlands:eth0:off panic=1 console=ttyS0,115200
PID hash table entries: 2048 (order: 1, 8192 bytes)
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
Memory: 513536k/524288k available (3880k kernel code, 10428k reserved, 172k data, 134k bss, 168k init)
Kernel virtual memory layout:
  * 0xfffef000..0xfffff000  : fixmap
  * 0xffc00000..0xffe00000  : highmem PTEs
  * 0xffa00000..0xffc00000  : consistent mem
  * 0xffa00000..0xffa00000  : early ioremap
  * 0xe1000000..0xffa00000  : vmalloc & ioremap
SLUB: Genslabs=11, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Hierarchical RCU implementation.
NR_IRQS:512
UIC0 (32 IRQ sources) at DCR 0xc0
UIC1 (32 IRQ sources) at DCR 0xd0
UIC2 (32 IRQ sources) at DCR 0xe0
UIC3 (32 IRQ sources) at DCR 0xf0
clocksource: timebase mult[3c0000] shift[22] registered
Mount-cache hash table entries: 512
NET: Registered protocol family 16
256k L2-cache enabled
PCIE0: Port disabled via device-tree
PCIE1: Checking link...
PCIE1: No device detected.
PCI host bridge /plb/pciex@d20000000 (primary) ranges:
 MEM 0x0000000e80000000..0x0000000effffffff -> 0x0000000080000000
 MEM 0x0000000f00100000..0x0000000f001fffff -> 0x0000000000000000
  IO 0x0000000f80010000..0x0000000f8001ffff -> 0x0000000000000000
 Removing ISA hole at 0x0000000f00100000
4xx PCI DMA offset set to 0x00000000
/plb/pciex@d20000000: Legacy ISA memory support enabled
PCIE1: successfully set as root-complex
PCI host bridge /plb/pci@c0ec00000 (primary) ranges:
 MEM 0x0000000d80000000..0x0000000dffffffff -> 0x0000000080000000
 MEM 0x0000000c0ee00000..0x0000000c0eefffff -> 0x0000000000000000
  IO 0x0000000c08000000..0x0000000c0800ffff -> 0x0000000000000000
 Removing ISA hole at 0x0000000c0ee00000
4xx PCI DMA offset set to 0x00000000
/plb/pci@c0ec00000: Legacy ISA memory support enabled
PCI: Probing PCI hardware
PCI: Hiding 4xx host bridge resources 0000:80:00.0
pci 0000:80:00.0: PCI bridge, secondary bus 0000:81
pci 0000:80:00.0:   IO window: disabled
pci 0000:80:00.0:   MEM window: disabled
pci 0000:80:00.0:   PREFETCH window: disabled
bio: create slab <bio-0> at 0
vgaarb: loaded
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Switching to clocksource timebase
NET: Registered protocol family 2
IP route cache hash table entries: 4096 (order: 2, 16384 bytes)
TCP established hash table entries: 16384 (order: 5, 131072 bytes)
TCP bind hash table entries: 16384 (order: 4, 65536 bytes)
TCP: Hash tables configured (established 16384 bind 16384)
TCP reno registered
NET: Registered protocol family 1
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
Trying to unpack rootfs image as initramfs...
rootfs image is not initramfs (no cpio magic); looks like an initrd
Freeing initrd memory: 1687k freed
JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
msgmni has been set to 1006
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
serial8250.0: ttyS0 at MMIO 0x4ef600300 (irq = 19) is a 16550A
console [ttyS0] enabled
serial8250.0: ttyS1 at MMIO 0x4ef600400 (irq = 20) is a 16550A
serial8250.0: ttyS2 at MMIO 0x4ef600500 (irq = 29) is a 16550A
serial8250.0: ttyS3 at MMIO 0x4ef600600 (irq = 21) is a 16550A
4ef600300.serial: ttyS0 at MMIO 0x4ef600300 (irq = 19) is a 16550
4ef600400.serial: ttyS1 at MMIO 0x4ef600400 (irq = 20) is a 16550
4ef600500.serial: ttyS2 at MMIO 0x4ef600500 (irq = 29) is a 16550
4ef600600.serial: ttyS3 at MMIO 0x4ef600600 (irq = 21) is a 16550
brd: module loaded
sata-dwc sata-dwc.0: id 0, controller version 1.82
sata-dwc sata-dwc.0: DMA initialized
sata-dwc sata-dwc.0: **** No neg speed (nothing attached?)
scsi0 : sata-dwc
ata1: SATA max UDMA/133 irq 23
4cc000000.nor_flash: Found 1 x16 devices at 0x0 in 16-bit bank
 Amd/Fujitsu Extended Query Table at 0x0040
4cc000000.nor_flash: CFI does not contain boot bank location. Assuming top.
number of CFI chips: 1
cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.
RedBoot partition parsing not available
Creating 7 MTD partitions on "4cc000000.nor_flash":
0x000000000000-0x0000001e0000 : "kernel"
0x0000001e0000-0x000000200000 : "dtb"
0x000000200000-0x000001600000 : "ramdisk"
0x000001600000-0x000001a00000 : "jffs2"
0x000001a00000-0x000003f60000 : "user"
0x000003f60000-0x000003fa0000 : "env"
0x000003fa0000-0x000004000000 : "u-boot"
NAND device: Manufacturer ID: 0x20, Chip ID: 0xf1 (ST Micro NAND 128MiB 3,3V 8-bit)
Scanning device for bad blocks
Creating 2 MTD partitions on "4e0000000.ndfc.nand":
0x000000000000-0x000000100000 : "u-boot"
0x000000000000-0x000003f00000 : "user"
e1000e: Intel(R) PRO/1000 Network Driver - 1.0.2-k2
e1000e: Copyright (c) 1999-2008 Intel Corporation.
PPC 4xx OCP EMAC driver, version 3.54
MAL v2 /plb/mcmal, 2 TX channels, 16 RX channels
ZMII /plb/opb/emac-zmii@ef600d00 initialized
RGMII /plb/opb/emac-rgmii@ef601500 initialized with MDIO support
TAH /plb/opb/emac-tah@ef601350 initialized
TAH /plb/opb/emac-tah@ef601450 initialized
/plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode
eth0: EMAC-0 /plb/opb/ethernet@ef600e00, MAC 00:10:ec:01:08:84
eth0: found Generic MII PHY (0x00)
/plb/opb/emac-rgmii@ef601500: input 1 in RGMII mode
eth1: EMAC-1 /plb/opb/ethernet@ef600f00, MAC 00:10:ec:81:08:84
eth1: found Generic MII PHY (0x01)
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ppc-of-ehci 4bffd0400.ehci: OF EHCI
ppc-of-ehci 4bffd0400.ehci: new USB bus registered, assigned bus number 1
ppc-of-ehci 4bffd0400.ehci: irq 38, io mem 0x4bffd0400
ppc-of-ehci 4bffd0400.ehci: USB 2.0 started, EHCI 1.00
usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb1: Product: OF EHCI
usb usb1: Manufacturer: Linux 2.6.32.7-00007-g08eba26 ehci_hcd
usb usb1: SerialNumber: PPC-OF USB
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
ppc-of-ohci 4bffd0000.usb: OF OHCI
ppc-of-ohci 4bffd0000.usb: new USB bus registered, assigned bus number 2
ppc-of-ohci 4bffd0000.usb: irq 39, io mem 0x4bffd0000
usb usb2: New USB device found, idVendor=1d6b, idProduct=0001
usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb2: Product: OF OHCI
usb usb2: Manufacturer: Linux 2.6.32.7-00007-g08eba26 ohci_hcd
usb usb2: SerialNumber: PPC-OF USB
usb usb2: configuration #1 chosen from 1 choice
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 1 port detected
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
usbcore: registered new interface driver libusual
dwc_otg: version 2.60a 22-NOV-2006
dwc_otg: Shared Tx FIFO mode
dwc_otg: Using DMA mode
dwc_otg dwc_otg.0: DWC OTG Controller
dwc_otg dwc_otg.0: new USB bus registered, assigned bus number 3
dwc_otg dwc_otg.0: irq 28, io mem 0x00000000
dwc_otg: Init: Port Power? op_state=4
usb usb3: New USB device found, idVendor=1d6b, idProduct=0002
usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb3: Product: DWC OTG Controller
usb usb3: Manufacturer: Linux 2.6.32.7-00007-g08eba26 dwc_otg_hcd
usb usb3: SerialNumber: dwc_otg.0
usb usb3: configuration #1 chosen from 1 choice
hub 3-0:1.0: USB hub found
hub 3-0:1.0: 1 port detected
i2c /dev entries driver
ibm-iic 4ef600700.i2c: using standard (100 kHz) mode
rtc-m41t80 0-0068: chip found, driver version 0.05
rtc-m41t80 0-0068: rtc core: registered m41t80 as rtc0
ibm-iic 4ef600800.i2c: using standard (100 kHz) mode
ad7414 0-0048: chip found
TCP cubic registered
NET: Registered protocol family 17
rtc-m41t80 0-0068: setting system clock to 2010-02-08 16:34:03 UTC (1265646843)
usb 1-1: new high speed USB device using ppc-of-ehci and address 2
usb 1-1: New USB device found, idVendor=1370, idProduct=2168
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1: Product: Memorybird P
usb 1-1: Manufacturer: FSC
usb 1-1: SerialNumber: 10005383BB000032
usb 1-1: configuration #1 chosen from 1 choice
scsi1 : SCSI emulation for USB Mass Storage devices
eth0: link is down
IP-Config: Complete:
     device=eth0, addr=192.168.100.6, mask=255.255.0.0, gw=192.168.1.254,
     host=canyonlands, domain=, nis-domain=(none),
     bootserver=192.168.1.1, rootserver=192.168.1.1, rootpath=
RAMDISK: gzip image found at block 0
VFS: Mounted root (ext2 filesystem) on device 1:0.
Freeing unused kernel memory: 168k init
init started: BusyBox v1.7.1 (2008-04-01 21:48:01 MEST)
starting pid 944, tty '': '/etc/rc.sh'
starting pid 950, tty '': '/bin/sh'
~ # starting pid 949, tty '': '/bin/application'
### Application running ...


~ #

8. Building and Using Modules

This section still needs to be written (this is a wiki, so please feel free to contribute!).

In the meantime, please refer to file Documentation/kbuild/modules.txt in the Linux source tree.

9. Advanced Topics

This section lists some advanced topics of interest to users of U-Boot and Linux.

9.1. Flash Filesystems

9.1.1. Memory Technology Devices

All currently available flash filesystems are based on the Memory Technology Devices MTD layer, so you must enable (at least) the following configuration options to get flash filesystem support in your system:

CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_GEN_PROBE=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_ROM=y
CONFIG_MTD_canyonlands=y

ALERT! Note: this configuration uses CFI conformant AMD flash chips; you may need to adjust these settings on other boards.

The partition layout of the flash devices is contained in the flat device tree for the system (see 13.1. Flat Device Tree).

Informational messages of the MTD subsystem can be found in the Linux bootlog, i.e. see section 7.5.1. Bootlog of tftp'd Linux kernel with Root Filesystem over NFS.

One can discover this information in a running system using the proc filesystem:

-bash-3.2# cat /proc/mtd
dev:   size   erasesize  name
mtd0: 001e0000 00020000 "kernel"
mtd1: 00020000 00020000 "dtb"
mtd2: 01400000 00020000 "ramdisk"
mtd3: 00400000 00020000 "jffs2"
mtd4: 02560000 00020000 "user"
mtd5: 00040000 00020000 "env"
mtd6: 00060000 00020000 "u-boot"
mtd7: 00100000 00020000 "u-boot"
mtd8: 03f00000 00020000 "user"
-bash-3.2#

Now we can run some basic tests to verify that the flash driver routines and the partitioning works as expected:

-bash-3.2# xxd /dev/mtd3 | head -4
0000000: ffff ffff ffff ffff ffff ffff ffff ffff  ................
0000010: ffff ffff ffff ffff ffff ffff ffff ffff  ................
0000020: ffff ffff ffff ffff ffff ffff ffff ffff  ................
0000030: ffff ffff ffff ffff ffff ffff ffff ffff  ................
-bash-3.2#

In the hex-dumps of the MTD devices you can identify some strings that verify that we indeed see an U-Boot environment, a Linux kernel, a ramdisk image and an empty partition to play wih.

The last output shows the partition to be empty. We can try write some data into it:

-bash-3.2# date > /tmp/tempfile
-bash-3.2# dd if=/dev/zero of=/tmp/tempfile bs=1 count=4096 seek=50
4096+0 records in
4096+0 records out
4096 bytes (4.1 kB) copied, 0.0107987 s, 379 kB/s
-bash-3.2# dd if=/tmp/tempfile of=/dev/mtd3 bs=4096 count=1
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.0179843 s, 228 kB/s
-bash-3.2# head -1 /dev/mtd3
Mon Feb    8 16:36:04 CET 2010
-bash-3.2# dd if=/tmp/tempfile of=/dev/mtd3 bs=4096 count=1
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.0179315 s, 228 kB/s
-bash-3.2#

As you can see it worked the first time. When we tried to write the (new date) again, we got an error. The reason is that the date has changed (probably at least the seconds) and flash memory cannot be simply overwritten - it has to be erased first.

You can use the eraseall Linux commands to erase a whole MTD partition:

-bash-3.2# flash_eraseall /dev/mtd3
Erasing 128 Kibyte @ 0 --  0 % complete.Erasing 128 Kibyte @ 20000 --  3 % complete.Erasing 128 Kibyte @ 40000 --  6 % complete.Erasing 128 Kibyte @ 60000 --  9 % complete.Erasing 128 Kibyte @ 80000 -- 12 % complete.Erasing 128 Kibyte @ a0000 -- 15 % complete.Erasing 128 Kibyte @ c0000 -- 18 % complete.Erasing 128 Kibyte @ e0000 -- 21 % complete.Erasing 128 Kibyte @ 100000 -- 25 % complete.Erasing 128 Kibyte @ 120000 -- 28 % complete.Erasing 128 Kibyte @ 140000 -- 31 % complete.Erasing 128 Kibyte @ 160000 -- 34 % complete.Erasing 128 Kibyte @ 180000 -- 37 % complete.Erasing 128 Kibyte @ 1a0000 -- 40 % complete.Erasing 128 Kibyte @ 1c0000 -- 43 % complete.Erasing 128 Kibyte @ 1e0000 -- 46 % complete.Erasing 128 Kibyte @ 200000 -- 50 % complete.Erasing 128 Kibyte @ 220000 -- 53 % complete.Erasing 128 Kibyte @ 240000 -- 56 % complete.Erasing 128 Kibyte @ 260000 -- 59 % complete.Erasing 128 Kibyte @ 280000 -- 62 % complete.Erasing 128 Kibyte @ 2a0000 -- 65 % complete.Erasing 128 Kibyte @ 2c0000 -- 68 % complete.Erasing 128 Kibyte @ 2e0000 -- 71 % complete.Erasing 128 Kibyte @ 300000 -- 75 % complete.Erasing 128 Kibyte @ 320000 -- 78 % complete.Erasing 128 Kibyte @ 340000 -- 81 % complete.Erasing 128 Kibyte @ 360000 -- 84 % complete.Erasing 128 Kibyte @ 380000 -- 87 % complete.Erasing 128 Kibyte @ 3a0000 -- 90 % complete.Erasing 128 Kibyte @ 3c0000 -- 93 % complete.Erasing 128 Kibyte @ 3e0000 -- 96 % complete.
-bash-3.2# date > /tmp/tempfile
-bash-3.2# dd if=/dev/zero of=/tmp/tempfile bs=1 count=4096 seek=50
4096+0 records in
4096+0 records out
4096 bytes (4.1 kB) copied, 0.01086 s, 377 kB/s
-bash-3.2# dd if=/tmp/tempfile of=/dev/mtd3 bs=4096 count=1
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.0180026 s, 228 kB/s
-bash-3.2# head -1 /dev/mtd3
Mon Feb    8 16:35:35 CET 2010
-bash-3.2#

We have now sufficient proof that the MTD layer is working as expected, so we can try creating a flash filesystem.

9.1.2. Journalling Flash File System

At the moment it seems that the Journalling Flash File System JFFS is the best choice for filesystems in flash memory of embedded devices. You must enable the following configuration options to get JFFS support in your system:

CONFIG_JFFS_FS=y
CONFIG_JFFS_FS_VERBOSE=0

If the flash device is erased, we can simply mount it, and the creation of the JFFS filesystem is performed automagically.

TIP Note: For simple accesses like direct read or write operations or erasing you use the character device interface (/dev/mtd*) of the MTD layer, while for filesystem operations like mounting we must use the block device interface (/dev/mtdblock*).

# eraseall /dev/mtd2
Erased 4096 Kibyte @ 0 -- 100% complete.       
# mount -t jffs /dev/mtdblock2 /mnt
# mount
/dev/root on / type nfs (rw,v2,rsize=4096,wsize=4096,hard,udp,nolock,addr=10.0.0.2)
proc on /proc type proc (rw)
devpts on /dev/pts type devpts (rw)
/dev/mtdblock2 on /mnt type jffs (rw)
# df
Filesystem           1k-blocks      Used Available Use% Mounted on
/dev/root              2087212   1232060    855152  60% /
/dev/mtdblock2            3584         0      3584   0% /mnt

Now you can access the files in the JFFS filesystem in the /mnt directory.

9.1.3. Second Version of JFFS

Probably even more interesting for embedded systems is the second version of JFFS, JFFS2, since it not only fixes a few design issues with JFFS, but also adds transparent compression, so that you can save a lot of precious flash memory.

The mkfs.jffs2 tool is used to create a JFFS2 filesystem image; it populates the image with files from a given directory. For instance, to create a JFFS2 image for a flash partition of 3 MB total size and to populate it with the files from the /tmp/flashtools directory you would use:

# mkfs.jffs2 --pad=3145728 --eraseblock=262144 \
--root=/tmp/flashtools/ --output image.jffs2
# eraseall /dev/mtd4
Erased 3072 Kibyte @ 0 -- 100% complete.       
\# dd if=image.jffs2 of=/dev/mtd4 bs=256k
12+0 records in
12+0 records out
# mount -t jffs2 /dev/mtdblock4 /mnt
# df /mnt
Filesystem           1k-blocks      Used Available Use% Mounted on
/dev/mtdblock4            3072      2488       584  81% /mnt

ALERT! Note: Especially when you are running time-critical applications on your system you should carefully study if the behaviour of the flash filesystem might have any negative impact on your application. After all, a flash device is not a normal harddisk. This is especially important when your flash filesystem gets full; JFFS2 acts a bit weird then:

This is especially critical when you are using the flash filesystem to store log files: when your application detects some abnormal condition and produces lots of log messages (which usually are especially important in this situation) the filesystem may fill up and cause extreme long delays - if your system crashes, the most important messages may never be logged at all.

9.1.4. Compressed ROM Filesystem

In some cases it is sufficent to have read-only access to some files, and if the files are big enough it becomes desirable to use some method of compression. The Compressed ROM Filesystem CramFs might be a solution here.

ALERT! Please note that CramFs has - beside the fact that it is a read-only filesystem - some severe limitations (like missing support for timestamps, hard links, and 16/32 bit uid/gids), but there are many situations in Embedded Systems where it's still useful.

To create a CramFs filesystem a special tool mkcramfs is used to create a file which contains the CramFs image. Note that the CramFs filesystem can be written and read only by kernels with PAGE_CACHE_SIZE == 4096, and some versions of the mkcramfs program may have other restrictions like that the filesystem must be written and read with architectures of the same endianness. Especially the endianness requirement makes it impossible to build the CramFs image on x86 PC host when you want to use it on a Power Architecture® target. The endianness problem has been fixed in the version of mkcramfs that comes with the ELDK.

In some cases you can use a target system running with root filesystem mounted over NFS to create the CramFs image on the native system and store it to flash for further use.

ALERT! Note: The normal version of the mkcramfs program tries to initialize some entries in the filesystem's superblock with random numbers by reading /dev/random; this may hang permanently on your target because there is not enough input (like mouse movement) to the entropy pool. You may want to use a modified version of mkcramfs which does not depend on /dev/random.

To create a CramFs image, you put all files you want in the filesystem into one directory, and then use the mkcramfs= program as follows:

$ mkdir /tmp/test
$ cp ... /tmp/test
$ du -sk /tmp/test
64      /tmp/test
$ mkcramfs /tmp/test test.cramfs.img
Super block: 76 bytes
  erase
  eraseall
  mkfs.jffs
  lock
  unlock
Directory data: 176 bytes
-54.96% (-4784 bytes)   erase
-55.46% (-5010 bytes)   eraseall
-51.94% (-8863 bytes)   mkfs.jffs
-58.76% (-4383 bytes)   lock
-59.68% (-4215 bytes)   unlock
Everything: 24 kilobytes
$ ls -l test.cramfs.img
-rw-r--r--    1 wd       users       24576 Nov 10 23:44 test.cramfs.img

As you can see, the CramFs image test.cramfs.img takes just 24 kB, while the input directory contained 64 kB of data. Savings of some 60% like in this case are typical CramFs.

Now we write the CramFs image to a partition in flash and test it:

# cp test.cramfs.img /dev/mtd3
# mount -t cramfs /dev/mtdblock3 /mnt
# mount
/dev/root on / type nfs (rw,v2,rsize=4096,wsize=4096,hard,udp,nolock,addr=10.0.0.2)
proc on /proc type proc (rw)
devpts on /dev/pts type devpts (rw)
/dev/mtdblock3 on /mnt type cramfs (rw)
# ls -l /mnt
total 54
-rwxr-xr-x    1 wd       users        8704 Jan  9 16:32 erase
-rwxr-xr-x    1 wd       users        9034 Jan  1 01:00 eraseall
-rwxr-xr-x    1 wd       users        7459 Jan  1 01:00 lock
-rwxr-xr-x    1 wd       users       17063 Jan  1 01:00 mkfs.jffs
-rwxr-xr-x    1 wd       users        7063 Jan  1 01:00 unlock

Note that all the timestamps in the CramFs filesyste are bogus, and so is for instance the output of the df command for such filesystems:

# df /mnt
Filesystem           1k-blocks      Used Available Use% Mounted on
/dev/mtdblock3               0         0         0   -  /mnt

9.2. The TMPFS Virtual Memory Filesystem

The tmpfs filesystem, formerly known as shmfs, is a filesystem keeping all files in virtual memory.

Everything in tmpfs is temporary in the sense that no files will be created on any device. If you unmount a tmpfs instance, everything stored therein is lost.

tmpfs puts everything into the kernel internal caches and grows and shrinks to accommodate the files it contains and is able to swap unneeded pages out to swap space. It has maximum size limits which can be adjusted on the fly via 'mount -o remount ...'

If you compare it to ramfs (which was the template to create tmpfs) you gain swapping and limit checking. Another similar thing is the RAM disk (/dev/ram*), which simulates a fixed size hard disk in physical RAM, where you have to create an ordinary filesystem on top. Ramdisks cannot swap and you do not have the possibility to resize them.

9.2.1. Mount Parameters

tmpfs has a couple of mount options:

These parameters accept a suffix k, m or g for kilo, mega and giga and can be changed on remount.

To specify the initial root directory you can use the following mount options:

These options do not have any effect on remount. You can change these parameters with chmod(1), chown(1) and chgrp(1) on a mounted filesystem.

So the following mount command will give you a tmpfs instance on /mytmpfs which can allocate 12MB of RAM/SWAP and it is only accessible by root.

mount -t tmpfs -o size=12M,mode=700 tmpfs /mytmpfs

9.2.2. Kernel Support for tmpfs

In order to use a tmpfs filesystem, the CONFIG_TMPFS option has to be enabled for your kernel configuration. It can be found in the Filesystems configuration group. You can simply check if a running kernel supports tmpfs by searching the contents of /proc/fileysystems:

bash# grep tmpfs /proc/filesystems
nodev   tmpfs
bash#

9.2.3. Usage of tmpfs in Embedded Systems

In embedded systems tmpfs is very well suited to provide read and write space (e.g. /tmp and /var) for a read-only root file system such as CramFs described in section 9.1.4. Compressed ROM Filesystem. One way to achieve this is to use symbolic links. The following code could be part of the startup file /etc/rc.sh of the read-only ramdisk:

#!/bin/sh
...
# Won't work on read-only root: mkdir /tmpfs
mount -t tmpfs tmpfs /tmpfs
mkdir /tmpfs/tmp /tmpfs/var
# Won't work on read-only root: ln -sf /tmpfs/tmp /tmpfs/var /
...

The commented out sections will of course fail on a read-only root filesystem, so you have to create the /tmpfs mount-point and the symbolic links in your root filesystem beforehand in order to successfully use this setup.

9.3. Adding Swap Space

If you are running out of system RAM, you can add virtual memory by using swap space. If you reserved a swap partition on your disk drive, you have to initialize it once using the mkswap command:

# fdisk -l /dev/hda

Disk /dev/hda: 16 heads, 63 sectors, 1575 cylinders
Units = cylinders of 1008 * 512 bytes

   Device Boot    Start       End    Blocks   Id  System
/dev/hda1             1         5      2488+  83  Linux
/dev/hda2             6        10      2520   83  Linux
/dev/hda3            11       141     66024   82  Linux swap
/dev/hda4           142      1575    722736   83  Linux
# mkswap /dev/hda3
Setting up swapspace version 1, size = 67604480 bytes

Then, to activate it, you use the swapon command like this:

# free
             total       used       free     shared    buffers     cached
Mem:         14628      14060        568       8056        100      11664
-/+ buffers/cache:       2296      12332
Swap:            0          0          0
# free
             total       used       free     shared    buffers     cached
Mem:         14628      14060        568       8056        100      11664
-/+ buffers/cache:       2296      12332
Swap:            0          0          0
# swapon /dev/hda3
Adding Swap: 66016k swap-space (priority -2)
# free
             total       used       free     shared    buffers     cached
Mem:         14628      14084        544       8056        100      11648
-/+ buffers/cache:       2336      12292
Swap:        66016          0      66016

If you forgot to reserve (sufficient) space in a separate partition on your disk, you can still use an ordinary file for swap space. You only have to create a file of appropriate size, and initialize it as follows:

# mount /dev/hda4 /mnt
# df
Filesystem           1k-blocks      Used Available Use% Mounted on
/dev/root              2087212   1378824    708388  67% /
/dev/hda4               711352        20    675196   1% /mnt
# dd if=/dev/zero of=/mnt/swapfile bs=1024k count=64
64+0 records in
64+0 records out
# mkswap /mnt/swapfile
Setting up swapspace version 1, size = 67104768 bytes

Then activate it:

# free
             total       used       free     shared    buffers     cached
Mem:         14628      14084        544       6200         96      11788
-/+ buffers/cache:       2200      12428
Swap:            0          0          0
# swapon /mnt/swapfile
Adding Swap: 65528k swap-space (priority -3)
# free
             total       used       free     shared    buffers     cached
Mem:         14628      14084        544       6200         96      11752
-/+ buffers/cache:       2236      12392
Swap:        65528          0      65528

9.4. Splash Screen Support in Linux

To complement the U-Boot Splash Screen feature the new configuration option "CONFIG_FB_PRE_INIT_FB" was added to the Linux kernel. This allows the Linux kernel to skip certain parts of the framebuffer initialization and to reuse the framebuffer contents that was set up by the U-Boot firmware. This allows to have an image displayed nearly immediately after power-on, so the delay needed to boot the Linux kernel is masked to the user.

The current implementation has some limitations:

9.5. Root File System: Design and Building

It is not an easy task to design the root file system for an embedded system. There are three major problems to be solved:

  1. what to put in it
  2. which file system type to use
  3. where to store and how to boot it

For now we will assume that the contents of the root file system is aready known; for example, it is given to us as a directory tree or a tarball which contains all the required files.

We will also assume that our system is a typical resource-limited embedded system so we will especially look for solutions where the root file system can be stored on on-board flash memory or other flash memory based devices like CompactFlash or SD cards, MMC or USB memory sticks.

A widespread approach to build a root file system is to use some Linux distribution (like the ELDK) and to remove things not needed. This approach may be pretty common, but it is almost always terribly wrong. You also don't build a family home by taking a skyscraper and removing parts. Like a house, a root file system should be built bottom up, starting from scratch and adding things you know you need. Never add anything where you don't exactly know what it's needed for.

But our focus here is on the second item: the options we have for chosing a file system type and the consequences this has.

In all cases we will base our experiments on the same content of the root filesystem; we use the images of the SELF (Simple Embedded Linux Framework) that come with the ELDK. In a first step we will transform the SELF images into a tarball to meet the requirements mentioned above:

In a ELDK installation, the SELF images can be found in the /opt/eldk/<architecture>/images/ directory. There is already a compressed ramdisk image in this directory, which we will use (ramdisk_image.gz):

  1. Uncompress ramdisk image:
    bash$ gzip -d -c -v /opt/eldk/ppc_8xx/images/ramdisk_image.gz >/tmp/ramdisk_image
    /opt/eldk/ppc_8xx/images/ramdisk_image.gz:       61.4%
    

    ALERT! Note: The following steps require root permissions!
  2. Mount ramdisk image:
    bash# mount -o loop /tmp/ramdisk_image /mnt/tmp
    
  3. Create tarball; to avoid the need for root permissions in the following steps we don't include the device files in our tarball:
    bash# cd /mnt/tmp
    bash# tar -zc --exclude='dev/*' -f /tmp/rootfs.tar.gz *
    
  4. Instead, we create a separate tarball which contains only the device entries so we can use them when necessary (with cramfs):
    bash# tar -zcf /tmp/devices.tar.gz dev/
    bash# cd /tmp
    
  5. Unmount ramdisk image:
    bash# umount /mnt/tmp
    
We will use the /tmp/rootfs.tar.gz tarball as master file in all following experiments.

9.5.1. Root File System on a Ramdisk

Ram disks are used very often to hold the root file system of embedded systems. They have several advantages:

On the other hand, there are several disadvantages, too: Actually there are only very few situations where a ramdisk image is the optimal solution. But because they are so easy to build and use we will discuss them here anyway.

In almost all cases you will use an ext2 file system in your ramdisk image. The following steps are needed to create it:

  1. Create a directory tree with the content of the target root filesystem. We do this by unpacking our master tarball:
    $ mkdir rootfs
    $ cd rootfs
    $ tar zxf /tmp/rootfs.tar.gz
    
  2. We use the genext2fs tool to create the ramdisk image as this allows to use a simple text file to describe which devices shall be created in the generated file system image. That means that no root permissions are required at all. We use the following device table rootfs_devices.tab:
    #<name>    <type> <mode> <uid> <gid> <major> <minor> <start>  <inc>  <count>
    /dev            d  755  0       0        -      -       -       -       -
    /dev/console    c  640  0       0        5      1       -       -       -
    /dev/fb0        c  640  0       0       29      0       -       -       -
    /dev/full       c  640  0       0        1      7       -       -       -
    /dev/hda        b  640  0       0        3      0       -       -       -
    /dev/hda        b  640  0       0        3      1       1       1       16
    /dev/kmem       c  640  0       0        1      2       -       -       -
    /dev/mem        c  640  0       0        1      1       -       -       -
    /dev/mtd        c  640  0       0       90      0       0       2       16
    /dev/mtdblock   b  640  0       0       31      0       0       1       16
    /dev/mtdr       c  640  0       0       90      1       0       2       16
    /dev/nftla      b  640  0       0       93      0       -       -       -
    /dev/nftla      b  640  0       0       93      1       1       1       8
    /dev/nftlb      b  640  0       0       93      16      -       -       -
    /dev/nftlb      b  640  0       0       93      17      1       1       8
    /dev/null       c  640  0       0        1      3       -       -       -
    /dev/ptyp       c  640  0       0        2      0       0       1       10
    /dev/ptypa      c  640  0       0        2      10      -       -       -
    /dev/ptypb      c  640  0       0        2      11      -       -       -
    /dev/ptypc      c  640  0       0        2      12      -       -       -
    /dev/ptypd      c  640  0       0        2      13      -       -       -
    /dev/ptype      c  640  0       0        2      14      -       -       -
    /dev/ptypf      c  640  0       0        2      15      -       -       -
    /dev/ram        b  640  0       0        1      0       0       1       2
    /dev/ram        b  640  0       0        1      1       -       -       -
    /dev/rtc        c  640  0       0       10      135     -       -       -
    /dev/tty        c  640  0       0        4      0       0       1       4
    /dev/tty        c  640  0       0        5      0       -       -       -
    /dev/ttyS       c  640  0       0        4      64      0       1       8
    /dev/ttyp       c  640  0       0        3      0       0       1       10
    /dev/ttypa      c  640  0       0        3      10      -       -       -
    /dev/ttypb      c  640  0       0        3      11      -       -       -
    /dev/ttypc      c  640  0       0        3      12      -       -       -
    /dev/ttypd      c  640  0       0        3      13      -       -       -
    /dev/ttype      c  640  0       0        3      14      -       -       -
    /dev/ttypf      c  640  0       0        3      15      -       -       -
    /dev/zero       c  640  0       0        1      5       -       -       -
    
    A description of the format of this table is part of the manual page for the genext2fs tool, genext2fs(8).
  3. We can now create an ext2 file system image using the genext2fs tool:
    $ ROOTFS_DIR=rootfs                 # directory with root file system content
    $ ROOTFS_SIZE=3700                  # size of file system image
    $ ROOTFS_FREE=100                   # free space wanted
    $ ROOTFS_INODES=380                 # number of inodes
    $ ROOTFS_DEVICES=rootfs_devices.tab # device description file
    $ ROOTFS_IMAGE=ramdisk.img          # generated file system image
    
    $ genext2fs -U \
            -d ${ROOTFS_DIR} \
            -D ${ROOTFS_DEVICES} \
            -b ${ROOTFS_SIZE} \
            -r ${ROOTFS_FREE} \
            -i ${ROOTFS_INODES} \
            ${ROOTFS_IMAGE}
    
  4. Compress the file system image:
    $ gzip -v9 ramdisk.img
    rootfs.img:      55.6% -- replaced with ramdisk.img.gz
    
  5. Create an U-Boot image file from it:
    $ mkimage -T ramdisk -C gzip -n 'Test Ramdisk Image' \
    > -d ramdisk.img.gz uRamdisk
    Image Name:   Test Ramdisk Image
    Created:      Sun Jun 12 16:58:06 2005
    Image Type:   PowerPC Linux RAMDisk Image (gzip compressed)
    Data Size:    1618547 Bytes = 1580.61 kB = 1.54 MB
    Load Address: 0x00000000
    Entry Point:  0x00000000
    

We now have a root file system image uRamdisk that can be used with U-Boot.

9.5.2. Root File System on a JFFS2 File System

JFFS2 (Journalling Flash File System version 2) was specifically designed for use on flash memory devices in embedded systems. It is a log-structured file system which means that it is robust against loss of power, crashes or other unorderly shutdowns of the system ("robust" means that data that is just being written when the system goes down may be lost, but the file system itself does not get corrupted and the system can be rebootet without need for any kind of file system check).

Some of the advantages of using JFFS2 as root file system in embedded systems are:

Disadvantages are:

Despite the aforementioned disadvantages, systems using a JFFS2 based root file system are easy to build, make efficient use of the available resources and can run pretty reliably.

To create a JFFS2 based root file system please proceed as follows:

  1. Create a directory tree with the content of the target root filesystem. We do this by unpacking our master tarball:
    $ mkdir rootfs
    $ cd rootfs
    $ tar zxf /tmp/rootfs.tar.gz
    
  2. We can now create a JFFS2 file system image using the mkfs.jffs2 tool:
    $ ROOTFS_DIR=rootfs                 # directory with root file system content
    $ ROOTFS_EBSIZE=0x20000             # erase block size of flash memory
    $ ROOTFS_ENDIAN=b                   # target system is big endian
    $ ROOTFS_DEVICES=rootfs_devices.tab # device description file
    $ ROOTFS_IMAGE=jffs2.img            # generated file system image
    
    $ mkfs.jffs2 -U \
            -d ${ROOTFS_DIR} \
            -D ${ROOTFS_DEVICES} \
            -${ROOTFS_ENDIAN} \
            -e ${ROOTFS_EBSIZE} \
            -o ${ROOTFS_IMAGE}
    mkfs.jffs2: skipping device_table entry '/dev': no parent directory!
    
ALERT! Note: When you intend to write the JFFS2 file system image to a NAND flash device, you should also add the "-n" (or "--no-cleanmarkers") option, as cleanmarkers are not needed then.

When booting the Linux kernel prints the following messages showing the default partition map which is used for the flash memory on the TQM8xxL boards:

 TQM flash bank 0: Using static image partition definition
Creating 7 MTD partitions on "TQM8xxL0":
0x00000000-0x00040000 : "u-boot"
0x00040000-0x00100000 : "kernel"
0x00100000-0x00200000 : "user"
0x00200000-0x00400000 : "initrd"
0x00400000-0x00600000 : "cramfs"
0x00600000-0x00800000 : "jffs"
0x00400000-0x00800000 : "big_fs"
We use U-Boot to load and store the JFFS2 image into the last partition and set up the Linux boot arguments to use this as root device:
  1. Erase flash:
    => era 40400000 407FFFFF
    
    ................. done
    Erased 35 sectors
    
  2. Download JFFS2 image:
    => tftp 100000 /tftpboot/TQM860L/jffs2.img
    Using FEC ETHERNET device
    TFTP from server 192.168.3.1; our IP address is 192.168.3.80
    Filename '/tftpboot/TQM860L/jffs2.img'.
    Load address: 0x100000
    Loading: #################################################################
             #################################################################
             #################################################################
             #################################################################
             #################################################################
             #################################################################
             ########
    done
    Bytes transferred = 2033888 (1f08e0 hex)
    
  3. Copy image to flash:
    => cp.b 100000 40400000 ${filesize}
    Copy to Flash... done
    
  4. set up boot arguments to use flash partition 6 as root device:
    => setenv mtd_args setenv bootargs root=/dev/mtdblock6 rw rootfstype=jffs2
    => printenv addip
    addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off panic=1
    => setenv flash_mtd 'run mtd_args addip;bootm ${kernel_addr}'
    => run flash_mtd
    Using FEC ETHERNET device
    TFTP from server 192.168.3.1; our IP address is 192.168.3.80
    Filename '/tftpboot/TQM860L/uImage'.
    Load address: 0x200000
    Loading: #################################################################
             #################################################################
             ###########
    done
    Bytes transferred = 719233 (af981 hex)
    ## Booting image at 40040000 ...
       Image Name:   Linux-2.4.25
       Created:      2005-06-12  16:32:24 UTC
       Image Type:   PowerPC Linux Kernel Image (gzip compressed)
       Data Size:    782219 Bytes = 763.9 kB
       Load Address: 00000000
       Entry Point:  00000000
       Verifying Checksum ... OK
       Uncompressing Kernel Image ... OK
    Linux version 2.4.25 (wd@xpert) (gcc version 3.3.3 (DENX ELDK 3.1.1 3.3.3-9)) #1 Sun Jun 12 18:32:18 MEST 2005
    On node 0 totalpages: 4096
    zone(0): 4096 pages.
    zone(1): 0 pages.
    zone(2): 0 pages.
    Kernel command line: root=/dev/mtdblock6 rw rootfstype=jffs2 ip=192.168.3.80:192.168.3.1::255.255.255.0:tqm860l:eth1:off panic=1
    Decrementer Frequency = 187500000/60
    Calibrating delay loop... 49.86 BogoMIPS
    ...
    NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
    VFS: Mounted root (jffs2 filesystem).
    Freeing unused kernel memory: 56k init
    
    
    BusyBox v0.60.5 (2005.03.07-06:54+0000) Built-in shell (msh)
    Enter 'help' for a list of built-in commands.
    
    # ### Application running ...
    # mount
    rootfs on / type rootfs (rw)
    /dev/mtdblock6 on / type jffs2 (rw)
    /proc on /proc type proc (rw)
    # df /
    Filesystem           1k-blocks      Used Available Use% Mounted on
    rootfs                    4096      2372      1724  58% /
    

9.5.3. Root File System on a cramfs File System

cramfs is a compressed, read-only file system.

Advantages are:

Disadvantages are:

To create a cramfs based root file system please proceed as follows:

  1. Create a directory tree with the content of the target root filesystem. We do this by unpacking our master tarball:
    $ mkdir rootfs
    $ cd rootfs
    $ tar -zxf /tmp/rootfs.tar.gz
    
  2. Create the required device files. We do this here by unpacking a special tarball which holds only the device file entries. ALERT! Note: this requires root permissions!
    # cd rootfs
    # tar -zxf /tmp/devices.tar.gz
    
  3. Many tools require some storage place in a filesystem, so we must provide at least one (small) writable filesystem. For all data which may be lost when the system goes down, a "tmpfs" filesystem is the optimal choice. To create such a writable tmpfs filesystem we add the following lines to the /etc/rc.sh script:
    # mount TMPFS because root-fs is readonly
    /bin/mount -t tmpfs -o size=2M tmpfs /tmpfs
    
    Some tools require write permissions on some device nodes (for example, to change ownership and permissions), or dynamically (re-) create such files (for example, /dev/log which is usually a Unix Domain socket). The files are placed in a writable filesystem; in the root filesystem symbolic links are used to point to their new locations:
    dev/ptyp0 /tmpfs/dev/ptyp0     dev/ttyp0 /tmpfs/dev/ttyp0
    dev/ptyp1 /tmpfs/dev/ptyp1     dev/ttyp1 /tmpfs/dev/ttyp1
    dev/ptyp2 /tmpfs/dev/ptyp2     dev/ttyp2 /tmpfs/dev/ttyp2
    dev/ptyp3 /tmpfs/dev/ptyp3     dev/ttyp3 /tmpfs/dev/ttyp3
    dev/ptyp4 /tmpfs/dev/ptyp4     dev/ttyp4 /tmpfs/dev/ttyp4
    dev/ptyp5 /tmpfs/dev/ptyp5     dev/ttyp5 /tmpfs/dev/ttyp5
    dev/ptyp6 /tmpfs/dev/ptyp6     dev/ttyp6 /tmpfs/dev/ttyp6
    dev/ptyp7 /tmpfs/dev/ptyp7     dev/ttyp7 /tmpfs/dev/ttyp7
    dev/ptyp8 /tmpfs/dev/ptyp8     dev/ttyp8 /tmpfs/dev/ttyp8
    dev/ptyp9 /tmpfs/dev/ptyp9     dev/ttyp9 /tmpfs/dev/ttyp9
    dev/ptypa /tmpfs/dev/ptypa     dev/ttypa /tmpfs/dev/ttypa
    dev/ptypb /tmpfs/dev/ptypb     dev/ttypb /tmpfs/dev/ttypb
    dev/ptypc /tmpfs/dev/ptypc     dev/ttypc /tmpfs/dev/ttypc
    dev/ptypd /tmpfs/dev/ptypd     dev/ttypd /tmpfs/dev/ttypd
    dev/ptype /tmpfs/dev/ptype     dev/ttype /tmpfs/dev/ttype
    dev/ptypf /tmpfs/dev/ptypf     dev/ttypf /tmpfs/dev/ttypf
    tmp /tmpfs/tmp     var /tmpfs/var
    dev/log /var/log/log        
    In case you use dhclient also:
    etc/dhclient.conf /tmpfs/var/lib/dhclient.conf     etc/resolv.conf /tmpfs/var/lib/resolv.conf

    To place the corresponding directories and device files in the tmpfs file system, the following code is added to the /etc/rc.sh script:
    mkdir -p /tmpfs/tmp /tmpfs/dev \
             /tmpfs/var/lib/dhcp /tmpfs/var/lock /tmpfs/var/run
    
    while read name minor
    do      
            mknod /tmpfs/dev/ptyp$name c 2 $minor
            mknod /tmpfs/dev/ttyp$name c 3 $minor
    done <<__EOD__
    0  0    
    1  1    
    2  2    
    3  3    
    4  4    
    5  5    
    6  6    
    7  7    
    8  8    
    9  9    
    a 10    
    b 11    
    c 12    
    d 13    
    e 14    
    f 15    
    __EOD__ 
    chmod 0666 /tmpfs/dev/*
    
  4. We can now create a cramfs file system image using the mkcramfs tool:
    $ ROOTFS_DIR=rootfs                 # directory with root file system content
    $ ROOTFS_ENDIAN="-r"                # target system has reversed (big) endianess
    $ ROOTFS_IMAGE=cramfs.img           # generated file system image
    
    PATH=/opt/eldk/usr/bin:$PATH
    mkcramfs ${ROOTFS_ENDIAN} ${DEVICES} ${ROOTFS_DIR} ${ROOTFS_IMAGE}
    Swapping filesystem endian-ness
      bin
      dev
      etc
    ...
    -48.78% (-86348 bytes)  in.ftpd
    -46.02% (-16280 bytes)  in.telnetd
    -45.31% (-74444 bytes)  xinetd
    Everything: 1864 kilobytes
    Super block: 76 bytes
    CRC: c166be6d
    warning: gids truncated to 8 bits.  (This may be a security concern.)
    
  5. We can use the same setup as before for the JFFS2 filesystem, just changing the bootargument to "rootfstype=cramfs"

9.5.4. Root File System on a Read-Only ext2 File System

When storing the root file system in on-board flash memory it seems only natural to look for special flash filesystems like JFFS2, or for other file system types that are designed for such environments like cramfs. It seems to be a bad idea to use a standard ext2 file system because it contains neither any type of wear leveling which is needed for writable file systems in flash memory, nor is it robust against unorderly shutdowns.

The situation changes if we use an ext2 file system which we mount read-only. Such a configuration can be very useful in some situations.

Advantages:

Disadvantages:

To create an ext2 image that can be used as a read-only root file system the following steps are necessary:

  1. Create a directory tree with the content of the target root filesystem. We do this by unpacking our master tarball:
    $ mkdir rootfs
    $ cd rootfs
    $ tar -zxf /tmp/rootfs.tar.gz
    
  2. Like with the cramfs root file system, we use "tmpfs" for cases where a writable file system is needed and add the following lines to the /etc/rc.sh script:
    # mount TMPFS because root-fs is readonly
    /bin/mount -t tmpfs -o size=2M tmpfs /tmpfs
    
    We also create the same symbolic links for device files that must be placed in a writable filesystem:
    dev/ptyp0 /tmpfs/dev/ptyp0     dev/ttyp0 /tmpfs/dev/ttyp0
    dev/ptyp1 /tmpfs/dev/ptyp1     dev/ttyp1 /tmpfs/dev/ttyp1
    dev/ptyp2 /tmpfs/dev/ptyp2     dev/ttyp2 /tmpfs/dev/ttyp2
    dev/ptyp3 /tmpfs/dev/ptyp3     dev/ttyp3 /tmpfs/dev/ttyp3
    dev/ptyp4 /tmpfs/dev/ptyp4     dev/ttyp4 /tmpfs/dev/ttyp4
    dev/ptyp5 /tmpfs/dev/ptyp5     dev/ttyp5 /tmpfs/dev/ttyp5
    dev/ptyp6 /tmpfs/dev/ptyp6     dev/ttyp6 /tmpfs/dev/ttyp6
    dev/ptyp7 /tmpfs/dev/ptyp7     dev/ttyp7 /tmpfs/dev/ttyp7
    dev/ptyp8 /tmpfs/dev/ptyp8     dev/ttyp8 /tmpfs/dev/ttyp8
    dev/ptyp9 /tmpfs/dev/ptyp9     dev/ttyp9 /tmpfs/dev/ttyp9
    dev/ptypa /tmpfs/dev/ptypa     dev/ttypa /tmpfs/dev/ttypa
    dev/ptypb /tmpfs/dev/ptypb     dev/ttypb /tmpfs/dev/ttypb
    dev/ptypc /tmpfs/dev/ptypc     dev/ttypc /tmpfs/dev/ttypc
    dev/ptypd /tmpfs/dev/ptypd     dev/ttypd /tmpfs/dev/ttypd
    dev/ptype /tmpfs/dev/ptype     dev/ttype /tmpfs/dev/ttype
    dev/ptypf /tmpfs/dev/ptypf     dev/ttypf /tmpfs/dev/ttypf
    tmp /tmpfs/tmp     var /tmpfs/var
    dev/log /var/log/log        
    In case you use dhclient also:
    etc/dhclient.conf /tmpfs/var/lib/dhclient.conf     etc/resolv.conf /tmpfs/var/lib/resolv.conf

    To place the corresponding directories and device files in the tmpfs file system, the following code is added to the /etc/rc.sh script:
    mkdir -p /tmpfs/tmp /tmpfs/dev \
             /tmpfs/var/lib/dhcp /tmpfs/var/lock /tmpfs/var/run
    
    while read name minor
    do      
            mknod /tmpfs/dev/ptyp$name c 2 $minor
            mknod /tmpfs/dev/ttyp$name c 3 $minor
    done <<__EOD__
    0  0    
    1  1    
    2  2    
    3  3    
    4  4    
    5  5    
    6  6    
    7  7    
    8  8    
    9  9    
    a 10    
    b 11    
    c 12    
    d 13    
    e 14    
    f 15    
    __EOD__ 
    chmod 0666 /tmpfs/dev/*
    
  3. Like we did for the ramdisk, we now create an ext2 file system image using the genext2fs tool:
    $ ROOTFS_DIR=rootfs                 # directory with root file system content
    $ ROOTFS_SIZE=3700                  # size of file system image
    $ ROOTFS_FREE=100                   # free space wanted
    $ ROOTFS_INODES=380                 # number of inodes
    $ ROOTFS_DEVICES=rootfs_devices.tab # device description file
    $ ROOTFS_IMAGE=ext2.img             # generated file system image
    
    $ genext2fs -U \
            -d ${ROOTFS_DIR} \
            -D ${ROOTFS_DEVICES} \
            -b ${ROOTFS_SIZE} \
            -r ${ROOTFS_FREE} \
            -i ${ROOTFS_INODES} \
            ${ROOTFS_IMAGE}
    
    
    
  4. We can again use the same setup as before for the JFFS2 filesystem, just changing the boot argument to "rootfstype=ext2" (or simply omit it completely as this is the default anyway), and we must change the "rw" argument into "ro" to mount our root file system really read-only:
    ...
    Linux version 2.4.25 (wd@xpert) (gcc version 3.3.3 (DENX ELDK 3.1.1 3.3.3-9)) #1 Sun Jun 12 18:32:18 MEST 2005
    On node 0 totalpages: 4096
    zone(0): 4096 pages.
    zone(1): 0 pages.
    zone(2): 0 pages.
    Kernel command line: root=/dev/mtdblock6 ro rootfstype=ext2 ip=192.168.3.80:192.168.3.1::255.255.255.0:tqm860l:eth1:off panic=1
    Decrementer Frequency = 187500000/60
    Calibrating delay loop... 49.86 BogoMIPS
    ...
    

9.5.5. Root File System on a Flash Card

Using an ext2 file system on a flash memory card (like CompactFlash, SD, MMC or a USB memory stick) is standard technology. To avoid unnecessary flash wear it is a good idea to mount the root file system read-only, or at least using the "noatime" mount option.

For our test we can use the "ext2.img" file from the previous step without changes:

  1. In this test we use a standard CompactFlash card which comes with a single partition on it. We use U-Boot to copy the ext2 file system image into this partition:
    => tftp 100000 /tftpboot/TQM860L/ext2.img
    Using FEC ETHERNET device
    TFTP from server 192.168.3.1; our IP address is 192.168.3.80
    Filename '/tftpboot/TQM860L/ext2.img'.
    Load address: 0x100000
    Loading: #################################################################
             #################################################################
             #################################################################
             #################################################################
             #################################################################
             #################################################################
             #################################################################
             #################################################################
             #################################################################
             #################################################################
             #################################################################
             ##########################
    done
    Bytes transferred = 3788800 (39d000 hex)
    => ide part
    
    Partition Map for IDE device 0  --   Partition Type: DOS
    
    Partition     Start Sector     Num Sectors     Type
        1                   32          500704       6
    => ide write 100000 20 1ce8
    
    IDE write: device 0 block # 32, count 7400 ... 7400 blocks written: OK
    
    Note that the "ide write" command takes parameters as hex numbers, and the write count is in terms of disk blocks of 512 bytes each. So we have to use 0x20 for the starts sector of the first partition, and 3788800 / 512 = 7400 = 0x1CE8 for the block count.
  2. We now prepare the Linux boot arguments to take this partition as read-only root device:
    => setenv cf_args setenv bootargs root=/dev/hda1 ro
    => setenv flash_cf 'run cf_args addip;bootm ${kernel_addr} - ${fdt_addr}'
    => setenv bootcmd run flash_cf
    
  3. ...and boot the system:
    ...
    Linux version 2.4.25 (wd@xpert) (gcc version 3.3.3 (DENX ELDK 3.1.1 3.3.3-9)) #1 Sun Jun 12 18:32:18 MEST 2005
    On node 0 totalpages: 4096
    zone(0): 4096 pages.
    zone(1): 0 pages.
    zone(2): 0 pages.
    Kernel command line: root=/dev/hda1 ro ip=192.168.3.80:192.168.3.1::255.255.255.0:tqm860l:eth1:off panic=1
    Decrementer Frequency = 187500000/60
    Calibrating delay loop... 49.86 BogoMIPS
    ...
    

9.5.6. Root File System in a Read-Only File in a FAT File System

This is a more complicated example that shows that - depending on project requirements - many other alternatives for chosing a root file system for your embedded system exist.

The scenario is as follows: on your embedded device you use a cheap and popular storage medium like CompactFlash, MMC or SD cards or USB memory sticks to store both the Linux kernel and your root file system. You want to distribute software updates over the internet: your customers can download the file from your web site, or you sent the images by email. Your customers may use any flash card or memory stick they happen to find, so you have no information about brand or size of the storage device.

Unfortunately most of your customers use Windows systems. And they don't want to be bothered with long instructions how to create special partitions on the storage device or how to write binary images or things like that. A simple "copy file" operation is nearly exhausting their capabilities.

What to do? Well, if copying a file is all your customers can do we should not ask for more. Storage devices like CompactFlash cards etc. typically come with a single partition on it, which holds a FAT or VFAT file system. This cannot be used as a Linux root file system directly, so we have to use some trickery.

Here is one possible solution: Your software distribution consistes of two files: The first file is the Linux kernel with a minimal ramdisk image attached (using the multi-file image format for U-Boot); U-Boot can load and boot such files from a FAT or VFAT file system. The second file is your root file system. For convenience and speed we use again an image of an ext2 file system. When Linux boots, it will initially use the attached ramdisk as root file system. The programs in this ramdisk will mount the FAT or VFAT file system - read-only. Then we can use a loop device (see losetup(8)) to associate the root file system image with a block device which can be used as a mount point. And finally we use pivot_root(8) to change the root file system to our image on the CF card.

This sounds not so complicated, and actually it is quite simple once you understand what needs to be done. Here is a more detailed description:

  1. The root file system image is easy: as mantioned before, we will use an ext2 file system image, and to avoid wearing the flash storage device we will use it in read-only mode - we did a read-only ext2 root file system image before, and here we can just re-use the existing image file.
  2. The initial ramdisk image that performs the pivot_root step must be created from scratch, but we already know how to create ramdisk images, so we just have to figure out what to put in it.

    The most important tool here is nash, a script interpreter that was specifically designed for such purposes (see nash(8)). We don't need any additional tools, and if we use static linking, then the nash binary plus a small script to control it is all we need for our initial ramdisk.

    To be precise, we need a couple of (empty) directories (bin, dev, etc, lib, loopfs, mnt, proc, and sysroot), the bin/nash binary, the linuxrc script and a symbolic link sbin pointing to bin:
    drwxr-xr-x    2 wd       users        4096 Apr 13 01:11 bin
    -rwxr-xr-x    1 wd       users      469512 Apr 11 22:47 bin/nash
    drwxr-xr-x    2 wd       users        4096 Apr 12 00:04 dev
    drwxr-xr-x    2 wd       users        4096 Apr 12 00:04 etc
    drwxr-xr-x    2 wd       users        4096 Apr 12 00:04 lib
    -rwxr-xr-x    1 wd       users         511 Apr 13 01:28 linuxrc
    drwxr-xr-x    2 wd       users        4096 Apr 12 00:04 loopfs
    drwxr-xr-x    2 wd       users        4096 Apr 12 00:09 mnt
    drwxr-xr-x    2 wd       users        4096 Apr 12 00:04 proc
    lrwxrwxrwx    1 wd       users           3 Jun 12 18:54 sbin -> bin
    drwxr-xr-x    2 wd       users        4096 Apr 12 00:04 sysroot
    
  3. We also need only a minimal device table for creating the initial ramdisk:
    #<name>    <type> <mode> <uid> <gid> <major> <minor> <start>  <inc>  <count>
    /dev            d  755  0       0       -       -       -       -       -
    /dev/console    c  640  0       0        5      1       -       -       -
    /dev/hda        b  640  0       0        3      0       -       -       -
    /dev/hda        b  640  0       0        3      1       1       1       8
    /dev/loop       b  640  0       0        7      0       0       1       4
    /dev/null       c  640  0       0        1      3       -       -       -
    /dev/ram        b  640  0       0        1      0       0       1       2
    /dev/ram        b  640  0       0        1      1       -       -       -
    /dev/tty        c  640  0       0        4      0       0       1       4
    /dev/tty        c  640  0       0        5      0       -       -       -
    /dev/ttyS       c  640  0       0        4      64      0       1       4
    /dev/zero       c  640  0       0        1      5       -       -       -
    
  4. To create the initial ramdisk we perform the usual steps:
    $ INITRD_DIR=initrd
    $ INITRD_SIZE=490
    $ INITRD_FREE=0
    $ INITRD_INODES=54
    $ INITRD_DEVICES=initrd_devices.tab
    $ INITRD_IMAGE=initrd.img
    
    $ genext2fs -U \
            -d ${INITRD_DIR} \
            -D ${INITRD_DEVICES} \
            -b ${INITRD_SIZE} \
            -r ${INITRD_FREE} \
            -i ${INITRD_INODES} \
            ${INITRD_IMAGE}
    
    $ gzip -v9 ${INITRD_IMAGE}
    
    The result is a really small (233 kB) compressed ramdisk image.
  5. Assuming you already have your Linux kernel image, you can now use mkimage to build an U-Boot multi-file image that combines the Linux kernel and the initial ramdisk:
    $ LINUX_KERNEL=linuxppc_2_4_devel/arch/ppc/boot/images/vmlinux.gz
    $ mkimage -A ppc -O Linux -T multi -C gzip \
    > -n 'Linux with Pivot Root Helper' \
    > -d ${LINUX_KERNEL}:${INITRD_IMAGE}.gz linux.img
    Image Name:   Linux with Pivot Root Helper
    Created:      Mon Jun 13 01:48:11 2005
    Image Type:   PowerPC Linux Multi-File Image (gzip compressed)
    Data Size:    1020665 Bytes = 996.74 kB = 0.97 MB
    Load Address: 0x00000000
    Entry Point:  0x00000000
    Contents:
       Image 0:   782219 Bytes =  763 kB = 0 MB
       Image 1:   238433 Bytes =  232 kB = 0 MB
    
    The newly created file linux.img is the second image we have to copy to the CF card.

    We are done.

But wait - one essential part was not mentioned yet: the linuxrc script in our initial ramdisk image which contains all the magic. This script is quite simple:

#!/bin/nash

echo Mounting /proc filesystem
mount -t proc /proc /proc

echo Creating block devices
mkdevices /dev

echo Creating root device
mkrootdev /dev/root
echo 0x0100 > /proc/sys/kernel/real-root-dev

echo Mounting flash card
mount -o noatime -t vfat /dev/hda1 /mnt

echo losetup for filesystem image
losetup /dev/loop0 /mnt/rootfs.img

echo Mounting root filesystem image
mount -o defaults --ro -t ext2 /dev/loop0 /sysroot

echo Running pivot_root
pivot_root /sysroot /sysroot/initrd
umount /initrd/proc
Let's go though it step by step: There is one tiny flaw in this method: since we mount the CF card on a directory in the ramdisk to be able to access to root file system image. This means that we cannot unmount the CF card, which in turn prevents us from freeing the space for the inital ramdisk. The consequence is that you permanently lose approx. 450 kB of RAM for the ramdisk. [We could of course re-use this ramdisk space for temporary data, but such optimization is beyond the scope of this document.]

And how does this work on our target?

  1. First we copy the two images to the CF card; we do this on the target under Linux:
    bash-2.05b# fdisk -l /dev/hda
    
    Disk /dev/hda: 256 MB, 256376832 bytes
    16 heads, 32 sectors/track, 978 cylinders
    Units = cylinders of 512 * 512 = 262144 bytes
    
       Device Boot    Start       End    Blocks   Id  System
    /dev/hda1   *         1       978    250352    6  FAT16
    bash-2.05b# mkfs.vfat /dev/hda1
    mkfs.vfat 2.8 (28 Feb 2001)
    bash-2.05b# mount -t vfat /dev/hda1 /mnt
    bash-2.05b# cp -v linux.img rootfs.img /mnt/
    `linux.img' -> `/mnt/linux.img'
    `rootfs.img' -> `/mnt/rootfs.img'
    bash-2.05b# ls -l /mnt
    total 4700
    -rwxr--r--    1 root     root      1020729 Jun 14 05:36 linux.img
    -rwxr--r--    1 root     root      3788800 Jun 14 05:36 rootfs.img
    bash-2.05b# umount /mnt
    
  2. We now prepare U-Boot to load the "uMulti" file (combined Linux kernel and initial ramdisk) from the CF card and boot it:
    => setenv fat_args setenv bootargs rw
    => setenv fat_boot 'run fat_args addip;fatload ide 0:1 200000 linux.img;bootm'
    => setenv bootcmd run fat_boot
    
  3. And finally we try it out:
    U-Boot 1.1.3 (Jun 13 2005 - 02:24:00)
    
    CPU:   XPC86xxxZPnnD4 at 50 MHz: 4 kB I-Cache 4 kB D-Cache FEC present
    Board: TQM860LDB0A3-T50.202
    DRAM:  16 MB
    FLASH:  8 MB
    In:    serial
    Out:   serial
    Err:   serial
    Net:   SCC ETHERNET, FEC ETHERNET [PRIME]
    PCMCIA: 3.3V card found: Transcend    256M
                Fixed Disk Card
                IDE interface 
                [silicon] [unique] [single] [sleep] [standby] [idle] [low power]
    Bus 0: OK 
      Device 0: Model: Transcend    256M Firm: 1.1 Ser#: SSSC256M04Z27A25906T
                Type: Removable Hard Disk
                Capacity: 244.5 MB = 0.2 GB (500736 x 512)
    
    Type "run flash_nfs" to mount root filesystem over NFS
    
    Hit any key to stop autoboot:  0 
    reading linux.img
    
    1025657 bytes read
    ## Booting image at 00200000 ...
       Image Name:   Linux with Pivot Root Helper
       Created:      2005-06-13   0:32:41 UTC
       Image Type:   PowerPC Linux Multi-File Image (gzip compressed)
       Data Size:    1025593 Bytes = 1001.6 kB
       Load Address: 00000000
       Entry Point:  00000000
       Contents:
       Image 0:   787146 Bytes = 768.7 kB
       Image 1:   238433 Bytes = 232.8 kB
       Verifying Checksum ... OK
       Uncompressing Multi-File Image ... OK
       Loading Ramdisk to 00f3d000, end 00f77361 ... OK
    Linux version 2.4.25 (wd@xpert) (gcc version 3.3.3 (DENX ELDK 3.1.1 3.3.3-9)) #1 Mon Jun 13 02:32:10 MEST 2005
    On node 0 totalpages: 4096
    zone(0): 4096 pages.
    zone(1): 0 pages.
    zone(2): 0 pages.
    Kernel command line: rw ip=192.168.3.80:192.168.3.1::255.255.255.0:tqm860l:eth1:off panic=1
    Decrementer Frequency = 187500000/60
    Calibrating delay loop... 49.86 BogoMIPS
    ...
    NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
    RAMDISK: Compressed image found at block 0
    Freeing initrd memory: 232k freed
    VFS: Mounted root (ext2 filesystem).
    Red Hat nash version 4.1.18 starting
    Mounting /proc filesystem
    Creating block devices
    Creating root device
    Mounting flash card
     hda: hda1
     hda: hda1
    losetup for filesystem image
    Mounting root filesystem image
    Running pivot_root
    Freeing unused kernel memory: 60k init
    
    
    BusyBox v0.60.5 (2005.03.07-06:54+0000) Built-in shell (msh)
    Enter 'help' for a list of built-in commands.
    
    # ### Application running ...
    

Kernel with a Flattened Device Tree Blob

When booting an arch/powerpc kernel that requires a flattened device tree blob, the above procedure must be slightly modified. Namely, the multi-image file has to include the blob as the thrid image. Here's an example of the mkimage command to create it:

mkimage -A ppc -O Linux -T multi -C gzip -n 'Kernel + Pivot Root Helper initrd + FDT blob' -d vmlinux.bin.gz:ramdisk_image.gz:canyonlands.dtb kernel+initrd+blob.img
Image Name:   Kernel + Pivot Root Helper initrd + FDT blob
Created:      Fri Sep 14 18:24:29 2007
Image Type:   PowerPC Linux Multi-File Image (gzip compressed)
Data Size:    2894576 Bytes = 2826.73 kB = 2.76 MB
Load Address: 0x00000000
Entry Point:  0x00000000
Contents:
   Image 0:  1351205 Bytes = 1319 kB = 1 MB
   Image 1:  1531063 Bytes = 1495 kB = 1 MB
   Image 2:    12288 Bytes =   12 kB = 0 MB

The newly created file kernel+initrd+blob.img needs to be copied to the CF card.

9.6. Root File System Selection

Now we know several options for file systems we can use, and know how to create the corresponding images. But how can we decide which one to chose?

For practical purposes in embedded systems the following criteria are often essential:

The following data was measured for the different configurations. All measurements were performed on the same TQM860L board (MPC860 CPU at 50 MHz, 16 MB RAM, 8 MB flash, 256 MB CompactFlash card):

File System Type Boot Time Free Mem Updates while running
ramdisk 16.3 sec 6.58 MB whole image yes
JFFS2 21.4 sec 10.3 MB per file only non-active files
cramfs 10.8 sec 10.3 MB whole image no
ext2 (ro) 9.1 sec 10.8 MB whole image no
ext2 on CF (ro) 9.3 sec 10.9 MB whole image no
File on FAT fs 11.4 sec 7.8 MB whole image yes

As you can see, the ramdisk solution is the worst of all in terms of RAM memory footprint; also it takes a pretty long time to boot. However, it is one of the few solutions that allow an in-situ update while the system is running.

JFFS2 is easy to use as it's a writable file system but it takes a long time to boot.

A read-only ext2 file system shines when boot time and RAM memory footprint are important; you pay for this with an increased flash memory footprint.

External flash memory devices like CompactFlash cards or USB memory sticks can be cheap and efficient solutions especially when lots of data need to be stored or when easy update procedures are required. -

9.7. Overlay File Systems

Introduction

Overlay File Systems provide an interesting approach to several frequent problems in Embedded Systems. For example, mini_fo is a virtual kernel file system that can make read-only file systems writable. This is done by redirecting modifying operations to a writeable location called "storage directory", and leaving the original data in the "base directory" untouched. When reading, the file system merges the modifed and original data so that only the newest versions will appear. This occurs transparently to the user, who can access the data like on any other read-write file system.

What it is good for?

In embedded systems the main use of mini_fo is to overlay the root file system. This means it is mounted on top of the regular root file system, thereby allowing applications or users to transparently make modifications to it but redirecting these to a different location.

Some examples of why this is usefull are explained in the following sections.

Making a read-only root filesystem writeable

Root file systems stored in flash are often read only, such as cramfs or read only ext2. While this offers major advantages in terms of speed and flash memory footprint, it nevertheless is often desireable to be able to modify the root file system, for example to

This can be achieved by mounting mini_fo on top of the root file system and using a (probably small) writeable partition as the storage file system. This could be either a JFFS2 flash file system, or during development even an external hard disk. This has the following advantages:

Non persistant changes

Ramdisks are often used when the root file system needs to be modified non-persistantly. This works well, but downsides are the large RAM memory footprint and the time costly operation of copying the ramdisk into RAM during startup. These can be avoided by overlaying the root file system as in the previous example but with the difference that the tmpfs file system is used as storage. Thus only modified files are stored in RAM, and can even be swapped out if neccessary. This saves boot time and RAM!

Resetable changes

Mini_fo can be easily used to implement a "reset to factory defaults" function by overlaying the default root file system. When configuration changes are made, these are automatically directed to the storage file system and take precedence over the original files. Now, to restore the system to factory defaults, all that needs to be done is delete the contents of the storage directory. This will remove all changes made to the root file system and return it to the original state.

ALERT! Note: Deleting the contents of the storage directory should only be done when the overlay file system is unmounted.

Examples

Generally, there are two different ways of overlaying the root file system, which both make sense in different scenarios.

Starting a single application in a chrooted overlayed environment

This is easy. Let's assume "/" is the read-only root file system and /dev/mtdblock5 contains a small JFFS2 flash partition that shall be used to store modifications made by application "/usr/bin/autoPilot":

# mount -t jffs2 /dev/mtdblock5 /tmp/sto
# insmod mini_fo.o
# mount -t mini_fo -o base=/,sto=/tmp/sto/ / /mnt/mini_fo/
# cd /mnt/mini_fo/
# chroot . /usr/bin/autoPilot
The mini_fo file system is mounted with "/" as base directory, "/tmp/sto/" as storage directory to the mount point "/mnt/mini_fo". After that, chroot(1) is used to start the application with the new file system root "/mnt/mini_fo". All modifications made by the application will be stored to the JFFS2 file system in /tmp/sto.

Starting the whole system system in chrooted overlayed environment

This is more interesting, and a bit trickier, as mounting needs to be done during system startup after the root file system has been mounted, but before init is started. The best way to do this is to have a script that mounts the mini_fo file system on top of root and then starts init in the chrooted overlayed environment. For example assume the following script "overlay_init", stored in /sbin/:

#!/bin/bash
#
# mount mini_fo overlay file system and execute init
#

# make sure these exist in the read-only file system
STORAGE=/tmp/sto
MOUNT_POINT=/mnt/mini_fo/

# mount tmpfs as storage file system with a maximum size of 32MB
mount -t tmpfs -o rw,size=32M none $STORAGE

/sbin/modprobe mini_fo
mount -t mini_fo -o base=/,sto=$STORAGE / $MOUNT_POINT

exec /usr/sbin/chroot $MOUNT_POINT /sbin/init

echo "exec chroot failed, bad!"
exec /bin/sh

exit 1

Now its easy to choose between a mini_fo overlayed and the regular non overlayed system just by setting the "init" kernel parameter in the boot loader to "init=/sbin/overlay_init".

Tips

Performance overhead

The mini_fo file system is inserted as an additional layer between the VFS and the native file system, and thus creates some overhead that varies strongly depending of the operation performed.

  1. modifying a regular file for the first time
    This results in a copy of the original file beeing created in the storage directory, that is then modified. Overhead depends on the size of the modified file.
  2. Reading from files, creating new files, modifying already modified files
    These operations are passed directly through to the lower native layer, and only impose an overhead of 1-2%.

Further information

This section discusses how the mini_fo overlay file system can be used in embedded systems. More general information is available at the mini_fo project page: http://www.denx.de/wiki/Know/MiniFOHome.

9.8. The Persistent RAM File system (PRAMFS)

The pramfs file system supports persistent memory devices such as SRAM. Instead of having a block emulation layer over such a memory area and using a normal file system on top of that, pramfs seeks to induce minimal overhead in this situation. Most important in this respect is that the normal block layer caching of the Linux kernel is circumvented in pramfs.

9.8.1. Mount Parameters

The most important parameters for normal usage are

9.8.2. Example

We will show a sample usage of pramfs in this section using normal DRAM on a board with at least 256MB of memory. For pramfs we reserve the upper 32MB by appending mem=224M to the kernel command line.

First off we generate some testdata on a persistent file system (/tmp) to demonstrate that pramfs survives a reboot (of course with power always applied to keep the DRAM refreshed):

bash-3.00# dd if=/dev/urandom bs=1M count=8 of=/tmp/testdata
8+0 records in
8+0 records out
bash-3.00# 

Next we mount the 32MB that we reserved and initialize it to be 32MB in size and copy the testfile. A final compare shows that the copy was indeed successful so we can reboot:

bash-3.00# mount -t pramfs -o physaddr=0xe000000,init=0x2000000 none /mnt
bash-3.00# cp /tmp/testdata /mnt
bash-3.00# cmp /tmp/testdata /mnt/testdata
bash-3.00# reboot

Having rebooted (using mem=224M on the kernel command line again of course) we mount the file system but this time without the init parameter because it is preinitialized. We then check the contents again:

bash-3.00# mount -t pramfs -o physaddr=0xe000000 none /mnt
bash-3.00# ls /mnt
testdata
bash-3.00# cmp /tmp/testdata /mnt/testdata
bash-3.00#

10. Debugging

The purpose of this document is not to provide an introduction into programming and debugging in general. We assume that you know how to use the GNU debugger gdb and probably it's graphical frontends like ddd. We also assume that you have access to adequate tools for your work, i. e. a BDI2000 BDM/JTAG debugger. The following discussion assumes that the host name of your BDI2000 is bdi.

Please note that there are several limitations in earlier versions of GDB. The version of GDB as distributed with the ELDK contains several bug fixes and extensions. If you find that your GDB behaves differently, have a look at the GDB sources and patches that come with the ELDK source.

10.1. Debugging of U-Boot

When U-Boot starts it is running from ROM space. Running from flash would make it nearly impossible to read from flash while executing code from flash not to speak of updating the U-Boot image in flash itself. To be able to do just that, U-Boot relocates itself to RAM. We therefore have two phases with different program addresses. The following sections show how to debug U-Boot in both phases.

10.1.1. Debugging of U-Boot Before Relocation

Before relocation, the addresses in the ELF file can be used without any problems, so debugging U-Boot in this phase with the BDI2000 is quite easy:

bash[0]$ ${CROSS_COMPILE}gdb u-boot
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "--host=i386-redhat-linux --target=ppc-linux"...

(gdb) target remote bdi:2001
Remote debugging using bdi:2001
0xfffffffc in ?? ()
(gdb) b cpu_init_f
Breakpoint 1 at 0xfffd3310: file cpu_init.c, line 136.
(gdb) c
Continuing.
 
Breakpoint 1, cpu_init_f () at cpu_init.c:136
136             asm volatile("  bl      0f"             ::: "lr");
(gdb) s
137             asm volatile("0:        mflr    3"              ::: "r3");
(gdb)
138             asm volatile("  addi    4, 0, 14"       ::: "r4");
(gdb)

cpu_init_f is the first C function called from the code in start.C.

10.1.2. Debugging of U-Boot After Relocation

For debugging U-Boot after relocation we need to know the address to which U-Boot relocates itself to. When no exotic features like PRAM are used, this address usually is <MAXMEM> - CONFIG_SYS_MONITOR_LEN. In our example with 16MB RAM and CONFIG_SYS_MONITOR_LEN = 192KB this yields the address 0x1000000 - 0x30000 = 0xFD0000.

In other cases, check the source code, and apply some common sense. For example, on Power Architecture® we use "r2" to hold a pointer to the "global data" structure ("struct global_data"); this structure contains a field

unsigned long   reloc_off;      /* Relocation Offset */
which is the offset between the image addresses in flash and in RAM. You can easily print this value in gdb like that:
(gdb) print/x ((gd_t *)$r2)->reloc_off
Then add this value to the value of TEXT_BASE as defined in your board's config.mk file, and you get the start address of the U-Boot image in RAM.

With this knowledge, we can instruct gdb to forget the old symbol table and reload the symbols with our calculated offset:

(gdb) symbol-file
Discard symbol table from `/home/dzu/denx/cvs-trees/u-boot/u-boot'? (y or n) y
No symbol file now.
(gdb) add-symbol-file u-boot 0xfd0000
add symbol table from file "u-boot" at
        .text_addr = 0xfd0000
(y or n) y
Reading symbols from u-boot...done.
(gdb) b board_init_r
Breakpoint 2 at 0xfd99ac: file board.c, line 533.
(gdb) c
Continuing.

Breakpoint 2, board_init_r (id=0xfbb1f0, dest_addr=16495088) at board.c:533
533     {
(gdb)
board_init_r is the first C routine running in the newly relocated C friendly RAM environment.

The simple example above relocates the symbols of only one section, .text. Other sections of the executable image (like .data, .bss, etc.) are not relocated and this prevents gdb from accessing static and global variables by name. See more sophisticated examples in section 10.3. GDB Startup File and Utility Scripts.

10.2. Linux Kernel Debugging

10.2.1. Linux Kernel and Statically Linked Device Drivers

10.2.2. Dynamically Loaded Device Drivers (Modules)

First start GDB in the root directory of your Linux kernel, using the vmlinux kernel image as file to debug:

bash$ cd <linux-root>
bash$ ${CROSS_COMPILE}gdb vmlinux 
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "--host=i386-redhat-linux --target=ppc-linux".
(gdb)

Now attach to the target and start execution with the commands:

(gdb) target remote bdi:2001
Remote debugging using bdi:2001
0x00000100 in ?? ()
(gdb) c
Continuing.

Now the target should boot Linux as usual. Next you need to load your kernel module on the target:

bash# insmod -m ex_sw.o
Sections:       Size      Address   Align
.this           00000060  cf030000  2**2
.text           000002f4  cf030060  2**2
.rodata         00000134  cf030354  2**2
.data           00000000  cf030488  2**0
.sdata          0000000c  cf030488  2**2
.kstrtab        00000085  cf030494  2**0
.bss            00000000  cf030519  2**0
.sbss           00000008  cf03051c  2**2
...

The option -m prints out the addresses of the various code and data segments ( .text, .data, .sdata, .bss, .sbss ) after relocation. GDB needs these addresses to know where all the symbols are located. We now interrupt GDB to load the symbol table of the module as follows:

(gdb) ^C
Program received signal SIGSTOP, Stopped (signal).
...
(gdb) add-symbol-file <path-to-module-dir>/ex_sw.o 0xcf030060\
 -s .rodata 0xcf030354\
 -s .data   0xcf030488\
 -s .sdata  0xcf030488\
 -s .bss    0xcf030519\
 -s .sbss   0xcf03051c
add symbol table from file "<path-to-module-dir>/ex_sw.o" at
        .text_addr = 0xcf030060
        .rodata_addr = 0xcf030354
        .data_addr = 0xcf030488
        .sdata_addr = 0xcf030488
        .bss_addr = 0xcf030519
        .sbss_addr = 0xcf03051c
(y or n) y
Reading symbols from <path-to-module-dir>/ex_sw.o...done.

Now you can list the source code of the module, set break points or inspect variables as usual:

(gdb) l fun
61      static RT_TASK *thread;
62
63      static int cpu_used[NR_RT_CPUS];
64
65      static void fun(int t)
66      {
67              unsigned int loops = LOOPS;
68              while(loops--) {
69                      cpu_used[hard_cpu_id()]++;
70                      rt_leds_set_mask(1,t);
(gdb)
(gdb) b ex_sw.c:69
Breakpoint 1 at 0xcf03007c: file ex_sw.c, line 69.
(gdb) c
Continuing.
Breakpoint 1, fun (t=1) at ex_sw.c:69
69                      cpu_used[hard_cpu_id()]++;
(gdb) p ntasks
$1 = 16
(gdb) p stack_size
$2 = 3000

The next section demonstrates a way to automate the symbol table loading procedure.

10.2.3. GDB Macros to Simplify Module Loading

The following GDB macros and scripts help you to load kernel modules into GDB in a half-automatic way. It assumes, that the module on the target has been installed with the command:

bash# insmod -m my_module.o > my_module.o.map

In your $HOME directory you need the scripts add-symbol-file.sh and the GDB startup file .gdbinit, which are listed in 10.3. GDB Startup File and Utility Scripts below.

Now you can include the symbol definition into GDB with:

bash$ ${CROSS_COMPILE}gdb vmlinux 
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "--host=i386-redhat-linux --target=ppc-linux".
0x00000100 in ?? ()
c
Continuing.
^C
Program received signal SIGSTOP, Stopped (signal).
0xcf02a91c in ?? ()
(gdb) add-module rtai4/examples/sw/ex_sw.o
add symbol table from file "/HHL/8xx/target/home/wolf/rtai4/examples/sw/ex_sw.o" at
        .text_addr = 0xcf030060
        .rodata_addr = 0xcf030340
        .data_addr = 0xcf030464
        .sdata_addr = 0xcf030464
        .bss_addr = 0xcf0304f5
        .sbss_addr = 0xcf0304f8
(gdb) b ex_sw.c:69
Breakpoint 1 at 0xcf03007c: file ex_sw.c, line 69.
(gdb) c
Continuing.

Breakpoint 1, fun (t=0x1) at ex_sw.c:69
69                      cpu_used[hard_cpu_id()]++;
(gdb) p/d loops
$2 = 999986939
(gdb) p t
$3 = 0x1
(gdb) d b
Delete all breakpoints? (y or n) y
(gdb) c
Continuing.

10.3. GDB Startup File and Utility Scripts

In addition to the add-module macro, the followin example GDB startup file contains a few other useful settings and macros, which you may want to adjust to your local environment:

set output-radix 16

target remote bdi:2001

define reset
        detach
        target remote bdi:2001
end

define add-module
        shell ~/add-symbol-file.sh $arg0
        source ~/add-symbol-file.gdb
end
document add-module
        Usage: add-module <module>

        Do add-symbol-file for module <module> automatically.
        Note: A map file with the extension ".map" must have
        been created with "insmod -m <module> > <module>.map"
        in advance.
end

The following shell script ~/add-symbol-file.sh is used to run the GDB add-symbol-file command automatically:

#!/bin/sh
#
# Constructs the GDB "add-symbol-file" command string
# from the map file of the specified kernel module.

add_sect() {
    ADDR=`awk '/^'$1' / {print $3}' $MAPFILE`
    if [ "$ADDR" != "" ]; then
        echo "-s $1 0x`awk '/^'$1' / {print $3}' $MAPFILE`"
    fi
}

[ $# == 1 ] && [ -r "$1" ] || { echo "Usage: $0 <module>" >&2 ; exit 1 ; }

MAPFILE=$1.map

ARGS="0x`awk '/^.text / {print $3}' $MAPFILE`\
 `add_sect .rodata`\
 `add_sect .data`\
 `add_sect .sdata`\
 `add_sect .bss`\
 `add_sect .sbss`\
"

echo "add-symbol-file $1 $ARGS" > ~/add-symbol-file.gdb

10.4. Tips and Tricks

10.5. Application Debugging

10.5.1. Local Debugging

In case there is a native GDB available for your target you can use it for application debugging as usual:

bash$ gcc -Wall -g -o hello hello.c 
bash$ gdb hello
...
(gdb) l
1       #include <stdio.h>
2
3       int main(int argc, char* argv[])
4       {
5               printf ("Hello world\n");
6               return 0;
7       }
(gdb) break 5
Breakpoint 1 at 0x8048466: file hello.c, line 5.
(gdb) run
Starting program: /opt/eldk/ppc_8xx/tmp/hello

Breakpoint 1, main (argc=0x1, argv=0xbffff9f4) at hello.c:5
5               printf ("Hello world\n");
(gdb) c
Continuing.
Hello world

Program exited normally.

10.5.2. Remote Debugging

gdbserver allows you to connect your program with a remote GDB using the "target remote" command. On the target machine, you need to have a copy of the program you want to debug. gdbserver does not need your program's symbol table, so you can strip the program if necessary to save space. GDB on the host system does all the symbol handling. Here is an example:

bash$ ${CROSS_COMPILE}gcc -Wall -g -o hello hello.c
bash$ cp -p hello <directory-shared-with-target>/hello-stripped
bash$ ${CROSS_COMPILE}strip <directory-shared-with-target>/hello-stripped

To use the server, you must tell it how to communicate with GDB, the name of your program, and the arguments for your program. To start a debugging session via network type on the target:

bash$ cd <directory-shared-with-host>
bash$ gdbserver 192.168.1.1:12345 hello-stripped
Process hello-stripped created; pid = 353

And then on the host:

bash$ ${CROSS_COMPILE}gdb hello
...
(gdb) set solib-absolute-prefix /opt/eldk/$CROSS_COMPILE
(gdb) dir /opt/eldk/$CROSS_COMPILE
Source directories searched:
/opt/eldk/$CROSS_COMPILE:$cdir:$cwd
(gdb) target remote 192.168.1.99:12345
Remote debugging using 192.168.1.99:12345
0x30012748 in ?? ()
...
(gdb) l
1       #include <stdio.h>
2
3       int main(int argc, char* argv[])
4       {
5               printf ("Hello world\n");
6               return 0;
7       }
(gdb) break 5
Breakpoint 1 at 0x10000498: file hello.c, line 5.
(gdb) continue
Continuing.

Breakpoint 1, main (argc=1, argv=0x7ffffbe4) at hello.c:5
5               printf ("Hello world\n");
(gdb) p argc
$1 = 1
(gdb) continue
Continuing.

Program exited normally.

ALERT! If the target program you want to debug is linked against shared libraries, you must tell GDB where the proper target libraries are located. This is done using the set solib-absolute-prefix GDB command. If this command is omitted, then, apparently, GDB loads the host versions of the libraries and gets crazy because of that.

10.6. Debugging with Graphical User Interfaces

It is convenient to use DDD, a Graphical User Interface to GDB, for debugging as it allows to define and execute frequently used commands via buttons. You can start DDD with the command:

bash$ ddd --debugger ${CROSS_COMPILE}gdb &

If DDD is not already installed on your Linux system, have a look at your distribution media.

11. Simple Embedded Linux Framework

12. Books, Mailing Lists, Links, etc.

This section provides references on where to find more information

Contents:

12.1. Application Notes

A collection of Application Notes relevant for embedded computing can be found on the DENX web server.

12.2. Further Reading

12.2.1. License Issues

Articles

12.2.2. Linux kernel

Books

Articles

12.2.3. General Linux / Unix programming

Books

Articles

Standards:

12.2.4. Network Programming

Books

Articles

12.2.5. C++ programming

Books

12.2.6. Java programming

Books

12.2.7. Power Architecture® Programming

Books

Articles

12.2.8. Embedded Topics

Articles

12.3. Mailing Lists

These are some mailing lists of interest. If you are new to mailing lists then please take the time to read at least RFC 1855.

12.4. Links

Linux Kernel Resources:

Realtime, Xenomai, RTAI:

U-Boot:

Cross Development Tools:

Miscalleneous or unsorted material:

12.5. Tools

13. Appendix

13.1. Flat Device Tree

/*
 * Device Tree Source for AMCC Canyonlands (460EX)
 *
 * Copyright 2008-2009 DENX Software Engineering, Stefan Roese <sr@denx.de>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without
 * any warranty of any kind, whether express or implied.
 */

/dts-v1/;

/ {
   #address-cells = <2>;
   #size-cells = <1>;
   model = "amcc,canyonlands";
   compatible = "amcc,canyonlands";
   dcr-parent = <&{/cpus/cpu@0}>;

   aliases {
      ethernet0 = &EMAC0;
      ethernet1 = &EMAC1;
      serial0 = &UART0;
      serial1 = &UART1;
   };

   cpus {
      #address-cells = <1>;
      #size-cells = <0>;

      cpu@0 {
         device_type = "cpu";
         model = "PowerPC,460EX";
         reg = <0x00000000>;
         clock-frequency = <0>; /* Filled in by U-Boot */
         timebase-frequency = <0>; /* Filled in by U-Boot */
         i-cache-line-size = <32>;
         d-cache-line-size = <32>;
         i-cache-size = <32768>;
         d-cache-size = <32768>;
         dcr-controller;
         dcr-access-method = "native";
         next-level-cache = <&L2C0>;
      };
   };

   memory {
      device_type = "memory";
      reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by U-Boot */
   };

   UIC0: interrupt-controller0 {
      compatible = "ibm,uic-460ex","ibm,uic";
      interrupt-controller;
      cell-index = <0>;
      dcr-reg = <0x0c0 0x009>;
      #address-cells = <0>;
      #size-cells = <0>;
      #interrupt-cells = <2>;
   };

   UIC1: interrupt-controller1 {
      compatible = "ibm,uic-460ex","ibm,uic";
      interrupt-controller;
      cell-index = <1>;
      dcr-reg = <0x0d0 0x009>;
      #address-cells = <0>;
      #size-cells = <0>;
      #interrupt-cells = <2>;
      interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
      interrupt-parent = <&UIC0>;
   };

   UIC2: interrupt-controller2 {
      compatible = "ibm,uic-460ex","ibm,uic";
      interrupt-controller;
      cell-index = <2>;
      dcr-reg = <0x0e0 0x009>;
      #address-cells = <0>;
      #size-cells = <0>;
      #interrupt-cells = <2>;
      interrupts = <0xa 0x4 0xb 0x4>; /* cascade */
      interrupt-parent = <&UIC0>;
   };

   UIC3: interrupt-controller3 {
      compatible = "ibm,uic-460ex","ibm,uic";
      interrupt-controller;
      cell-index = <3>;
      dcr-reg = <0x0f0 0x009>;
      #address-cells = <0>;
      #size-cells = <0>;
      #interrupt-cells = <2>;
      interrupts = <0x10 0x4 0x11 0x4>; /* cascade */
      interrupt-parent = <&UIC0>;
   };

   SDR0: sdr {
      compatible = "ibm,sdr-460ex";
      dcr-reg = <0x00e 0x002>;
   };

   CPR0: cpr {
      compatible = "ibm,cpr-460ex";
      dcr-reg = <0x00c 0x002>;
   };

   L2C0: l2c {
      compatible = "ibm,l2-cache-460ex", "ibm,l2-cache";
      dcr-reg = <0x020 0x008      /* Internal SRAM DCR's */
            0x030 0x008>;   /* L2 cache DCR's */
      cache-line-size = <32>;      /* 32 bytes */
      cache-size = <262144>;      /* L2, 256K */
      interrupt-parent = <&UIC1>;
      interrupts = <11 1>;
   };

   plb {
      compatible = "ibm,plb-460ex", "ibm,plb4";
      #address-cells = <2>;
      #size-cells = <1>;
      ranges;
      clock-frequency = <0>; /* Filled in by U-Boot */

      SDRAM0: sdram {
         compatible = "ibm,sdram-460ex", "ibm,sdram-405gp";
         dcr-reg = <0x010 0x002>;
      };

      CRYPTO: crypto@180000 {
         compatible = "amcc,ppc460ex-crypto", "amcc,ppc4xx-crypto";
         reg = <4 0x00180000 0x80400>;
         interrupt-parent = <&UIC0>;
         interrupts = <0x1d 0x4>;
      };

      MAL0: mcmal {
         compatible = "ibm,mcmal-460ex", "ibm,mcmal2";
         dcr-reg = <0x180 0x062>;
         num-tx-chans = <2>;
         num-rx-chans = <16>;
         #address-cells = <0>;
         #size-cells = <0>;
         interrupt-parent = <&UIC2>;
         interrupts = <   /*TXEOB*/ 0x6 0x4
               /*RXEOB*/ 0x7 0x4
               /*SERR*/  0x3 0x4
               /*TXDE*/  0x4 0x4
               /*RXDE*/  0x5 0x4>;
      };

      USB0: ehci@bffd0400 {
         compatible = "ibm,usb-ehci-460ex", "usb-ehci";
         interrupt-parent = <&UIC2>;
         interrupts = <0x1d 4>;
         reg = <4 0xbffd0400 0x90 4 0xbffd0490 0x70>;
      };

      USB1: usb@bffd0000 {
         compatible = "ohci-le";
         reg = <4 0xbffd0000 0x60>;
         interrupt-parent = <&UIC2>;
         interrupts = <0x1e 4>;
      };

      USBOTG0: usbotg@bff80000 {
         compatible = "amcc,usb-otg-460ex", "amcc,usb-otg";
         reg = <4 0xbff80000 0x10000>;
         interrupt-parent = <&USBOTG0>;
         interrupts = <0 1 2>;
         #interrupt-cells = <1>;
         #address-cells = <0>;
         #size-cells = <0>;
         interrupt-map = </* USB-OTG */ 0 &UIC2 0x1c 4
                /* HIGH-POWER */ 1 &UIC1 0x1a 8
                /* DMA */ 2 &UIC0 0xc 4>;
         interrupt-map-mask = <0xffffffff>;
      };

      SATA0: sata@bffd1000 {
         compatible = "amcc,sata-460ex";
         reg = <4 0xbffd1000 0x800   /* SATA */
                4 0xbffd0800 0x400>;   /* AHBDMA */
         interrupt-parent = <&UIC3>;
         interrupts = <0 4      /* SATA */
                  5 4>;      /* AHBDMA */
      };

      POB0: opb {
         compatible = "ibm,opb-460ex", "ibm,opb";
         #address-cells = <1>;
         #size-cells = <1>;
         ranges = <0xb0000000 0x00000004 0xb0000000 0x50000000>;
         clock-frequency = <0>; /* Filled in by U-Boot */

         EBC0: ebc {
            compatible = "ibm,ebc-460ex", "ibm,ebc";
            dcr-reg = <0x012 0x002>;
            #address-cells = <2>;
            #size-cells = <1>;
            clock-frequency = <0>; /* Filled in by U-Boot */
            /* ranges property is supplied by U-Boot */
            interrupts = <0x6 0x4>;
            interrupt-parent = <&UIC1>;

            nor_flash@0,0 {
               compatible = "amd,s29gl512n", "cfi-flash";
               bank-width = <2>;
               reg = <0x00000000 0x00000000 0x04000000>;
               #address-cells = <1>;
               #size-cells = <1>;
               partition@0 {
                  label = "kernel";
                  reg = <0x00000000 0x001e0000>;
               };
               partition@1e0000 {
                  label = "dtb";
                  reg = <0x001e0000 0x00020000>;
               };
               partition@200000 {
                  label = "ramdisk";
                  reg = <0x00200000 0x01400000>;
               };
               partition@1600000 {
                  label = "jffs2";
                  reg = <0x01600000 0x00400000>;
               };
               partition@1a00000 {
                  label = "user";
                  reg = <0x01a00000 0x02560000>;
               };
               partition@3f60000 {
                  label = "env";
                  reg = <0x03f60000 0x00040000>;
               };
               partition@3fa0000 {
                  label = "u-boot";
                  reg = <0x03fa0000 0x00060000>;
               };
            };

            ndfc@3,0 {
               compatible = "ibm,ndfc";
               reg = <0x00000003 0x00000000 0x00002000>;
               ccr = <0x00001000>;
               bank-settings = <0x80002222>;
               #address-cells = <1>;
               #size-cells = <1>;

               nand {
                  #address-cells = <1>;
                  #size-cells = <1>;

                  partition@0 {
                     label = "u-boot";
                     reg = <0x00000000 0x00100000>;
                  };
                  partition@100000 {
                     label = "user";
                     reg = <0x00000000 0x03f00000>;
                  };
               };
            };
         };

         UART0: serial@ef600300 {
            device_type = "serial";
            compatible = "ns16550";
            reg = <0xef600300 0x00000008>;
            virtual-reg = <0xef600300>;
            clock-frequency = <0>; /* Filled in by U-Boot */
            current-speed = <0>; /* Filled in by U-Boot */
            interrupt-parent = <&UIC1>;
            interrupts = <0x1 0x4>;
         };

         UART1: serial@ef600400 {
            device_type = "serial";
            compatible = "ns16550";
            reg = <0xef600400 0x00000008>;
            virtual-reg = <0xef600400>;
            clock-frequency = <0>; /* Filled in by U-Boot */
            current-speed = <0>; /* Filled in by U-Boot */
            interrupt-parent = <&UIC0>;
            interrupts = <0x1 0x4>;
         };

         UART2: serial@ef600500 {
            device_type = "serial";
            compatible = "ns16550";
            reg = <0xef600500 0x00000008>;
            virtual-reg = <0xef600500>;
            clock-frequency = <0>; /* Filled in by U-Boot */
            current-speed = <0>; /* Filled in by U-Boot */
            interrupt-parent = <&UIC1>;
            interrupts = <0x1d 0x4>;
         };

         UART3: serial@ef600600 {
            device_type = "serial";
            compatible = "ns16550";
            reg = <0xef600600 0x00000008>;
            virtual-reg = <0xef600600>;
            clock-frequency = <0>; /* Filled in by U-Boot */
            current-speed = <0>; /* Filled in by U-Boot */
            interrupt-parent = <&UIC1>;
            interrupts = <0x1e 0x4>;
         };

         IIC0: i2c@ef600700 {
            compatible = "ibm,iic-460ex", "ibm,iic";
            reg = <0xef600700 0x00000014>;
            interrupt-parent = <&UIC0>;
            interrupts = <0x2 0x4>;
            #address-cells = <1>;
            #size-cells = <0>;
            rtc@68 {
               compatible = "stm,m41t80";
               reg = <0x68>;
               interrupt-parent = <&UIC2>;
               interrupts = <0x19 0x8>;
            };
            sttm@48 {
               compatible = "ad,ad7414";
               reg = <0x48>;
               interrupt-parent = <&UIC1>;
               interrupts = <0x14 0x8>;
            };
         };

         IIC1: i2c@ef600800 {
            compatible = "ibm,iic-460ex", "ibm,iic";
            reg = <0xef600800 0x00000014>;
            interrupt-parent = <&UIC0>;
            interrupts = <0x3 0x4>;
         };

         ZMII0: emac-zmii@ef600d00 {
            compatible = "ibm,zmii-460ex", "ibm,zmii";
            reg = <0xef600d00 0x0000000c>;
         };

         RGMII0: emac-rgmii@ef601500 {
            compatible = "ibm,rgmii-460ex", "ibm,rgmii";
            reg = <0xef601500 0x00000008>;
            has-mdio;
         };

         TAH0: emac-tah@ef601350 {
            compatible = "ibm,tah-460ex", "ibm,tah";
            reg = <0xef601350 0x00000030>;
         };

         TAH1: emac-tah@ef601450 {
            compatible = "ibm,tah-460ex", "ibm,tah";
            reg = <0xef601450 0x00000030>;
         };

         EMAC0: ethernet@ef600e00 {
            device_type = "network";
            compatible = "ibm,emac-460ex", "ibm,emac4sync";
            interrupt-parent = <&EMAC0>;
            interrupts = <0x0 0x1>;
            #interrupt-cells = <1>;
            #address-cells = <0>;
            #size-cells = <0>;
            interrupt-map = </*Status*/ 0x0 &UIC2 0x10 0x4
                   /*Wake*/   0x1 &UIC2 0x14 0x4>;
            reg = <0xef600e00 0x000000c4>;
            local-mac-address = [000000000000]; /* Filled in by U-Boot */
            mal-device = <&MAL0>;
            mal-tx-channel = <0>;
            mal-rx-channel = <0>;
            cell-index = <0>;
            max-frame-size = <9000>;
            rx-fifo-size = <4096>;
            tx-fifo-size = <2048>;
            rx-fifo-size-gige = <16384>;
            phy-mode = "rgmii";
            phy-map = <0x00000000>;
            rgmii-device = <&RGMII0>;
            rgmii-channel = <0>;
            tah-device = <&TAH0>;
            tah-channel = <0>;
            has-inverted-stacr-oc;
            has-new-stacr-staopc;
         };

         EMAC1: ethernet@ef600f00 {
            device_type = "network";
            compatible = "ibm,emac-460ex", "ibm,emac4sync";
            interrupt-parent = <&EMAC1>;
            interrupts = <0x0 0x1>;
            #interrupt-cells = <1>;
            #address-cells = <0>;
            #size-cells = <0>;
            interrupt-map = </*Status*/ 0x0 &UIC2 0x11 0x4
                   /*Wake*/   0x1 &UIC2 0x15 0x4>;
            reg = <0xef600f00 0x000000c4>;
            local-mac-address = [000000000000]; /* Filled in by U-Boot */
            mal-device = <&MAL0>;
            mal-tx-channel = <1>;
            mal-rx-channel = <8>;
            cell-index = <1>;
            max-frame-size = <9000>;
            rx-fifo-size = <4096>;
            tx-fifo-size = <2048>;
            rx-fifo-size-gige = <16384>;
            phy-mode = "rgmii";
            phy-map = <0x00000000>;
            rgmii-device = <&RGMII0>;
            rgmii-channel = <1>;
            tah-device = <&TAH1>;
            tah-channel = <1>;
            has-inverted-stacr-oc;
            has-new-stacr-staopc;
            mdio-device = <&EMAC0>;
         };
      };

      PCIX0: pci@c0ec00000 {
         device_type = "pci";
         #interrupt-cells = <1>;
         #size-cells = <2>;
         #address-cells = <3>;
         compatible = "ibm,plb-pcix-460ex", "ibm,plb-pcix";
         primary;
         large-inbound-windows;
         enable-msi-hole;
         reg = <0x0000000c 0x0ec00000   0x00000008   /* Config space access */
                0x00000000 0x00000000 0x00000000      /* no IACK cycles */
                0x0000000c 0x0ed00000   0x00000004   /* Special cycles */
                0x0000000c 0x0ec80000 0x00000100 /* Internal registers */
                0x0000000c 0x0ec80100  0x000000fc>;   /* Internal messaging registers */

         /* Outbound ranges, one memory and one IO,
          * later cannot be changed
          */
         ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000
              0x02000000 0x00000000 0x00000000 0x0000000c 0x0ee00000 0x00000000 0x00100000
              0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>;

         /* Inbound 2GB range starting at 0 */
         dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;

         /* This drives busses 0 to 0x3f */
         bus-range = <0x0 0x3f>;

         /* All PCI interrupts are routed to ext IRQ 2 -> UIC1-0 */
         interrupt-map-mask = <0x0 0x0 0x0 0x0>;
         interrupt-map = < 0x0 0x0 0x0 0x0 &UIC1 0x0 0x8 >;
      };

      PCIE0: pciex@d00000000 {
         device_type = "pci";
         #interrupt-cells = <1>;
         #size-cells = <2>;
         #address-cells = <3>;
         compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex";
         primary;
         port = <0x0>; /* port number */
         reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */
                0x0000000c 0x08010000 0x00001000>;   /* Registers */
         dcr-reg = <0x100 0x020>;
         sdr-base = <0x300>;

         /* Outbound ranges, one memory and one IO,
          * later cannot be changed
          */
         ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000
              0x02000000 0x00000000 0x00000000 0x0000000f 0x00000000 0x00000000 0x00100000
              0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>;

         /* Inbound 2GB range starting at 0 */
         dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;

         /* This drives busses 40 to 0x7f */
         bus-range = <0x40 0x7f>;

         /* Legacy interrupts (note the weird polarity, the bridge seems
          * to invert PCIe legacy interrupts).
          * We are de-swizzling here because the numbers are actually for
          * port of the root complex virtual P2P bridge. But I want
          * to avoid putting a node for it in the tree, so the numbers
          * below are basically de-swizzled numbers.
          * The real slot is on idsel 0, so the swizzling is 1:1
          */
         interrupt-map-mask = <0x0 0x0 0x0 0x7>;
         interrupt-map = <
            0x0 0x0 0x0 0x1 &UIC3 0xc 0x4 /* swizzled int A */
            0x0 0x0 0x0 0x2 &UIC3 0xd 0x4 /* swizzled int B */
            0x0 0x0 0x0 0x3 &UIC3 0xe 0x4 /* swizzled int C */
            0x0 0x0 0x0 0x4 &UIC3 0xf 0x4 /* swizzled int D */>;
      };

      PCIE1: pciex@d20000000 {
         device_type = "pci";
         #interrupt-cells = <1>;
         #size-cells = <2>;
         #address-cells = <3>;
         compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex";
         primary;
         port = <0x1>; /* port number */
         reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */
                0x0000000c 0x08011000 0x00001000>;   /* Registers */
         dcr-reg = <0x120 0x020>;
         sdr-base = <0x340>;

         /* Outbound ranges, one memory and one IO,
          * later cannot be changed
          */
         ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000
              0x02000000 0x00000000 0x00000000 0x0000000f 0x00100000 0x00000000 0x00100000
              0x01000000 0x00