8devices / u-boot

U-boot for a Ralink based SoC
Other
13 stars 5 forks source link

#

(C) Copyright 2000 - 2005

Wolfgang Denk, DENX Software Engineering, wd@denx.de.

#

See file CREDITS for list of people who contributed to this

project.

#

This program is free software; you can redistribute it and/or

modify it under the terms of the GNU General Public License as

published by the Free Software Foundation; either version 2 of

the License, or (at your option) any later version.

#

This program is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

GNU General Public License for more details.

#

You should have received a copy of the GNU General Public License

along with this program; if not, write to the Free Software

Foundation, Inc., 59 Temple Place, Suite 330, Boston,

MA 02111-1307 USA

#

Summary:

This directory contains the source code for U-Boot, a boot loader for Embedded boards based on PowerPC, ARM, MIPS and several other processors, which can be installed in a boot ROM and used to initialize and test the hardware or to download and run application code.

The development of U-Boot is closely related to Linux: some parts of the source code originate in the Linux source tree, we have some header files in common, and special provision has been made to support booting of Linux images.

Some attention has been paid to make this software easily configurable and extendable. For instance, all monitor commands are implemented with the same call interface, so that it's very easy to add new commands. Also, instead of permanently adding rarely used code (for instance hardware test utilities) to the monitor, you can load and run it dynamically.

Status:

In general, all boards for which a configuration option exists in the Makefile have been tested to some extent and can be considered "working". In fact, many of them are used in production systems.

In case of problems see the CHANGELOG and CREDITS files to find out who contributed the specific port.

Where to get help:

In case you have questions about, problems with or contributions for U-Boot you should send a message to the U-Boot mailing list at u-boot-users@lists.sourceforge.net. There is also an archive of previous traffic on the mailing list - please search the archive before asking FAQ's. Please see http://lists.sourceforge.net/lists/listinfo/u-boot-users/

Where we come from:

Names and Spelling:

The "official" name of this project is "Das U-Boot". The spelling "U-Boot" shall be used in all written text (documentation, comments in source files etc.). Example:

This is the README file for the U-Boot project.

File names etc. shall be based on the string "u-boot". Examples:

include/asm-ppc/u-boot.h

#include <asm/u-boot.h>

Variable names, preprocessor constants etc. shall be either based on the string "u_boot" or on "U_BOOT". Example:

U_BOOT_VERSION      u_boot_logo
IH_OS_U_BOOT        u_boot_hush_start

Versioning:

U-Boot uses a 3 level version number containing a version, a sub-version, and a patchlevel: "U-Boot-2.34.5" means version "2", sub-version "34", and patchlevel "4".

The patchlevel is used to indicate certain stages of development between released versions, i. e. officially released versions of U-Boot will always have a patchlevel of "0".

Directory Hierarchy:

Software Configuration:

Configuration is usually done using C preprocessor defines; the rationale behind that is to avoid dead code whenever possible.

There are two classes of configuration variables:

Later we will add a configuration tool - probably similar to or even identical to what's used for the Linux kernel. Right now, we have to do the configuration by hand, which means creating some symbolic links and editing some configuration files. We use the TQM8xxL boards as an example here.

Selection of Processor Architecture and Board Type:

For all supported boards there are ready-to-use default configurations available; just type "make _config".

Example: For a TQM823L module type:

cd u-boot
make TQM823L_config

For the Cogent platform, you need to specify the cpu type as well; e.g. "make cogent_mpc8xx_config". And also configure the cogent directory according to the instructions in cogent/README.

Configuration Options:

Configuration depends on the combination of board and CPU type; all such information is kept in a configuration file "include/configs/.h".

Example: For a TQM823L module, all configuration settings are in "include/configs/TQM823L.h".

Many of the options are named exactly as the corresponding Linux kernel configuration options. The intention is to make it easier to build a config tool - later.

The following options need to be configured:

Modem Support:

[so far only for SMDK2400 and TRAB boards]

Configuration Settings:

The following definitions that deal with the placement and management of environment data (variable area); in general, we support the following configurations:

BE CAREFUL! Any changes to the flash layout, and some changes to the source code will make it necessary to adapt /u-boot.lds* accordingly!

BE CAREFUL! The first access to the environment happens quite early in U-Boot initalization (when we try to get the setting of for the console baudrate). You MUST have mappend your NVRAM area then, or U-Boot will hang.

Please note that even with NVRAM we still use a copy of the environment in RAM: we could work on NVRAM directly, but we want to keep settings there always unmodified except somebody uses "saveenv" to save the current settings.

Please note that the environment is read-only as long as the monitor has been relocated to RAM and a RAM copy of the environment has been created; also, when using EEPROM you will have to use getenv_r() until then to read environment variables.

The environment is protected by a CRC32 checksum. Before the monitor is relocated into RAM, as a result of a bad CRC you will be working with the compiled-in default environment - silently!!! [This is necessary, because the first environment variable we need is the "baudrate" setting for the console - if we have a bad CRC, we don't have any device yet where we could complain.]

Note: once the monitor has been relocated, then it will complain if the default environment is used; a new CRC is computed as soon as you use the "saveenv" command to store a valid environment.

Low Level (hardware related) configuration options:

Building the Software:

Building U-Boot has been tested in native PPC environments (on a PowerBook G3 running LinuxPPC 2000) and in cross environments (running RedHat 6.x and 7.x Linux on x86, Solaris 2.6 on a SPARC, and NetBSD 1.5 on x86).

If you are not using a native PPC environment, it is assumed that you have the GNU cross compiling tools available in your path and named with a prefix of "powerpc-linux-". If this is not the case, (e.g. if you are using Monta Vista's Hard Hat Linux CDK 1.2) you must change the definition of CROSS_COMPILE in Makefile. For HHL on a 4xx CPU, change it to:

CROSS_COMPILE = ppc_4xx-

U-Boot is intended to be simple to build. After installing the sources you must configure U-Boot for one specific board type. This is done by typing:

make NAME_config

where "NAME_config" is the name of one of the existing configurations; the following names are supported:

ADCIOP_config       FPS860L_config      omap730p2_config
ADS860_config       GEN860T_config      pcu_e_config
Alaska8220_config
AR405_config        GENIETV_config      PIP405_config
at91rm9200dk_config GTH_config      QS823_config
CANBT_config        hermes_config       QS850_config
cmi_mpc5xx_config   hymod_config        QS860T_config
cogent_common_config    IP860_config        RPXlite_config
cogent_mpc8260_config   IVML24_config       RPXlite_DW_config
cogent_mpc8xx_config    IVMS8_config        RPXsuper_config
CPCI405_config      JSE_config      rsdproto_config
CPCIISER4_config    LANTEC_config       Sandpoint8240_config
csb272_config       lwmon_config        sbc8260_config
CU824_config        MBX860T_config      sbc8560_33_config
DUET_ADS_config     MBX_config      sbc8560_66_config
EBONY_config        MPC8260ADS_config   SM850_config
ELPT860_config      MPC8540ADS_config   SPD823TS_config
ESTEEM192E_config   MPC8560ADS_config   stxgp3_config
ETX094_config       NETVIA_config       SXNI855T_config
FADS823_config      omap1510inn_config  TQM823L_config
FADS850SAR_config   omap1610h2_config   TQM850L_config
FADS860T_config     omap1610inn_config  TQM855L_config
FPS850L_config      omap5912osk_config  TQM860L_config
            omap2420h4_config   WALNUT405_config
                        Yukon8220_config
                        ZPC1900_config

Note: for some board special configuration names may exist; check if additional information is available from the board vendor; for instance, the TQM823L systems are available without (standard) or with LCD support. You can select such additional "features" when chosing the configuration, i. e.

  make TQM823L_config
- will configure for a plain TQM823L, i. e. no LCD support

  make TQM823L_LCD_config
- will configure for a TQM823L with U-Boot console on LCD

  etc.

Finally, type "make all", and you should get some working U-Boot images ready for download to / installation on your system:

Please be aware that the Makefiles assume you are using GNU make, so for instance on NetBSD you might need to use "gmake" instead of native "make".

If the system board that you have is not listed, then you will need to port U-Boot to your hardware platform. To do this, follow these steps:

  1. Add a new configuration option for your board to the toplevel "Makefile" and to the "MAKEALL" script, using the existing entries as examples. Note that here and at many other places boards and other names are listed in alphabetical sort order. Please keep this order.
  2. Create a new directory to hold your board specific code. Add any files you need. In your board directory, you will need at least the "Makefile", a ".c", "flash.c" and "u-boot.lds".
  3. Create a new configuration file "include/configs/.h" for your board
  4. If you're porting U-Boot to a new CPU, then also create a new directory to hold your CPU specific code. Add any files you need.
  5. Run "make _config" with your new name.
  6. Type "make", and you should get a working "u-boot.srec" file to be installed on your target system.
  7. Debug and solve any problems that might arise. [Of course, this last step is much harder than it sounds.]

Testing of U-Boot Modifications, Ports to New Hardware, etc.:

If you have modified U-Boot sources (for instance added a new board or support for new devices, a new CPU, etc.) you are expected to provide feedback to the other developers. The feedback normally takes the form of a "patch", i. e. a context diff against a certain (latest official or latest in CVS) version of U-Boot sources.

But before you submit such a patch, please verify that your modifi- cation did not break existing code. At least make sure that ALL of the supported boards compile WITHOUT ANY compiler warnings. To do so, just run the "MAKEALL" script, which will configure and build U-Boot for ALL supported system. Be warned, this will take a while. You can select which (cross) compiler to use by passing a `CROSS_COMPILE' environment variable to the script, i. e. to use the cross tools from MontaVista's Hard Hat Linux you can type

CROSS_COMPILE=ppc_8xx- MAKEALL

or to build on a native PowerPC system you can type

CROSS_COMPILE=' ' MAKEALL

See also "U-Boot Porting Guide" below.

Monitor Commands - Overview:

go - start application at address 'addr' run - run commands in an environment variable bootm - boot application image from memory bootp - boot image via network using BootP/TFTP protocol tftpboot- boot image via network using TFTP protocol and env variables "ipaddr" and "serverip" (and eventually "gatewayip") rarpboot- boot image via network using RARP/TFTP protocol diskboot- boot from IDE devicebootd - boot default, i.e., run 'bootcmd' loads - load S-Record file over serial line loadb - load binary file over serial line (kermit mode) md - memory display mm - memory modify (auto-incrementing) nm - memory modify (constant address) mw - memory write (fill) cp - memory copy cmp - memory compare crc32 - checksum calculation imd - i2c memory display imm - i2c memory modify (auto-incrementing) inm - i2c memory modify (constant address) imw - i2c memory write (fill) icrc32 - i2c checksum calculation iprobe - probe to discover valid I2C chip addresses iloop - infinite loop on address range isdram - print SDRAM configuration information sspi - SPI utility commands base - print or set address offset printenv- print environment variables setenv - set environment variables saveenv - save environment variables to persistent storage protect - enable or disable FLASH write protection erase - erase FLASH memory flinfo - print FLASH memory information bdinfo - print Board Info structure iminfo - print header information for application image coninfo - print console devices and informations ide - IDE sub-system loop - infinite loop on address range loopw - infinite write loop on address range mtest - simple RAM test icache - enable or disable instruction cache dcache - enable or disable data cache reset - Perform RESET of the CPU echo - echo args to console version - print monitor version help - print online help ? - alias for 'help'

Monitor Commands - Detailed Description:

TODO.

For now: just type "help ".

Environment Variables:

U-Boot supports user configuration using Environment Variables which can be made persistent by saving to Flash memory.

Environment Variables are set using "setenv", printed using "printenv", and saved to Flash using "saveenv". Using "setenv" without a value can be used to delete a variable from the environment. As long as you don't save the environment you are working with an in-memory copy. In case the Flash area containing the environment is erased by accident, a default environment is provided.

Some configuration options can be set using Environment Variables:

baudrate - see CONFIG_BAUDRATE

bootdelay - see CONFIG_BOOTDELAY

bootcmd - see CONFIG_BOOTCOMMAND

bootargs - Boot arguments when booting an RTOS image

bootfile - Name of the image to load with TFTP

autoload - if set to "no" (any string beginning with 'n'), "bootp" will just load perform a lookup of the configuration from the BOOTP server, but not try to load any image using TFTP

autostart - if set to "yes", an image loaded using the "bootp", "rarpboot", "tftpboot" or "diskboot" commands will be automatically started (by internally calling "bootm")

      If set to "no", a standalone image passed to the
      "bootm" command will be copied to the load address
      (and eventually uncompressed), but NOT be started.
      This can be used to load and uncompress arbitrary
      data.

i2cfast - (PPC405GP|PPC405EP only) if set to 'y' configures Linux I2C driver for fast mode (400kHZ). This environment variable is used in initialization code. So, for changes to be effective it must be saved and board must be reset.

initrd_high - restrict positioning of initrd images: If this variable is not set, initrd images will be copied to the highest possible address in RAM; this is usually what you want since it allows for maximum initrd size. If for some reason you want to make sure that the initrd image is loaded below the CFG_BOOTMAPSZ limit, you can set this environment variable to a value of "no" or "off" or "0". Alternatively, you can set it to a maximum upper address to use (U-Boot will still check that it does not overwrite the U-Boot stack and data).

      For instance, when you have a system with 16 MB
      RAM, and want to reserve 4 MB from use by Linux,
      you can do this by adding "mem=12M" to the value of
      the "bootargs" variable. However, now you must make
      sure that the initrd image is placed in the first
      12 MB as well - this can be done with

      setenv initrd_high 00c00000

      If you set initrd_high to 0xFFFFFFFF, this is an
      indication to U-Boot that all addresses are legal
      for the Linux kernel, including addresses in flash
      memory. In this case U-Boot will NOT COPY the
      ramdisk at all. This may be useful to reduce the
      boot time on your system, but requires that this
      feature is supported by your Linux kernel.

ipaddr - IP address; needed for tftpboot command

loadaddr - Default load address for commands like "bootp", "rarpboot", "tftpboot", "loadb" or "diskboot"

loads_echo - see CONFIG_LOADS_ECHO

serverip - TFTP server IP address; needed for tftpboot command

bootretry - see CONFIG_BOOT_RETRY_TIME

bootdelaykey - see CONFIG_AUTOBOOT_DELAY_STR

bootstopkey - see CONFIG_AUTOBOOT_STOP_STR

ethprime - When CONFIG_NET_MULTI is enabled controls which interface is used first.

ethact - When CONFIG_NET_MULTI is enabled controls which interface is currently active. For example you can do the following

      => setenv ethact FEC ETHERNET
      => ping 192.168.0.1 # traffic sent on FEC ETHERNET
      => setenv ethact SCC ETHERNET
      => ping 10.0.0.1 # traffic sent on SCC ETHERNET

netretry - When set to "no" each network operation will either succeed or fail without retrying. When set to "once" the network operation will fail when all the available network interfaces are tried once without success. Useful on scripts which control the retry operation themselves.

vlan - When set to a value < 4095 the traffic over ethernet is encapsulated/received over 802.1q VLAN tagged frames.

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

bootfile - see above dnsip - IP address of your Domain Name Server dnsip2 - IP address of your secondary Domain Name Server gatewayip - IP address of the Gateway (Router) to use hostname - Target hostname ipaddr - see above netmask - Subnet Mask rootpath - Pathname of the root filesystem on the NFS server serverip - see above

There are two special Environment Variables:

serial# - contains hardware identification information such as type string and/or serial number ethaddr - Ethernet address

These variables can be set only once (usually during manufacturing of the board). U-Boot refuses to delete or overwrite these variables once they have been set once.

Further special Environment Variables:

ver - Contains the U-Boot version string as printed with the "version" command. This variable is readonly (see CONFIG_VERSION_VARIABLE).

Please note that changes to some configuration parameters may take only effect after the next boot (yes, that's just like Windoze :-).

Command Line Parsing:

There are two different command line parsers available with U-Boot: the old "simple" one, and the much more powerful "hush" shell:

Old, simple command line parser:

Hush shell:

General rules:

(1) If a command line (or an environment variable executed by a "run" command) contains several commands separated by semicolon, and one of these commands fails, then the remaining commands will be executed anyway.

(2) If you execute several variables with one call to run (i. e. calling run with a list af variables as arguments), any failing command will cause "run" to terminate, i. e. the remaining variables are not executed.

Note for Redundant Ethernet Interfaces:

Some boards come with redundant ethernet interfaces; U-Boot supports such configurations and is capable of automatic selection of a "working" interface when needed. MAC assignment works as follows:

Network interfaces are numbered eth0, eth1, eth2, ... Corresponding MAC addresses can be stored in the environment as "ethaddr" (=>eth0), "eth1addr" (=>eth1), "eth2addr", ...

If the network interface stores some valid MAC address (for instance in SROM), this is used as default address if there is NO correspon- ding setting in the environment; if the corresponding environment variable is set, this overrides the settings in the card; that means:

o If the SROM has a valid MAC address, and there is no address in the environment, the SROM's address is used.

o If there is no valid address in the SROM, and a definition in the environment exists, then the value from the environment variable is used.

o If both the SROM and the environment contain a MAC address, and both addresses are the same, this MAC address is used.

o If both the SROM and the environment contain a MAC address, and the addresses differ, the value from the environment is used and a warning is printed.

o If neither SROM nor the environment contain a MAC address, an error is raised.

Image Formats:

The "boot" commands of this monitor operate on "image" files which can be basicly anything, preceeded by a special header; see the definitions in include/image.h for details; basicly, 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.

Linux Support:

Although U-Boot should support any OS or standalone application easily, the main focus has always been on Linux during the design of U-Boot.

U-Boot includes many features that so far have been part of some special "boot loader" code within the Linux kernel. Also, any "initrd" images to be used are no longer part of one big Linux image; instead, kernel and "initrd" are separate images. This implementation serves several purposes:

Linux HOWTO:

Porting Linux to U-Boot based systems:

U-Boot cannot save you from doing all the necessary modifications to configure the Linux device drivers for use with your target hardware (no, we don't intend to provide a full virtual machine interface to Linux :-).

But now you can ignore ALL boot loader code (in arch/ppc/mbxboot).

Just make sure your machine specific header file (for instance include/asm-ppc/tqm8xx.h) includes the same definition of the Board Information structure as we define in include/u-boot.h, and make sure that your definition of IMAP_ADDR uses the same value as your U-Boot configuration in CFG_IMMR.

Configuring the Linux kernel:

No specific requirements for U-Boot. Make sure you have some root device (initial ramdisk, NFS) for your target system.

Building a Linux Image:

With U-Boot, "normal" build targets like "zImage" or "bzImage" are not used. If you use recent kernel source, a new build target "uImage" will exist which automatically builds an image usable by U-Boot. Most older kernels also have support for a "pImage" target, which was introduced for our predecessor project PPCBoot and uses a 100% compatible format.

Example:

make TQM850L_config
make oldconfig
make dep
make uImage

The "uImage" build target uses a special tool (in 'tools/mkimage') to encapsulate a compressed Linux kernel image with header information, CRC32 checksum etc. for use with U-Boot. This is what we are doing:

The "mkimage" tool can also be used to create ramdisk images for use with U-Boot, either separated from the Linux kernel image, or combined into one file. "mkimage" encapsulates the images with a 64 byte header containing information about target architecture, operating system, image type, compression method, entry points, time stamp, CRC32 checksums, etc.

"mkimage" can be called in two ways: to verify existing images and print the header information, or to build new images.

In the first form (with "-l" option) mkimage lists the information contained in the header of an existing U-Boot image; this includes checksum verification:

tools/mkimage -l image
  -l ==> list image header information

The second form (with "-d" option) is used to build a U-Boot image from a "data file" which is used as image payload:

tools/mkimage -A arch -O os -T type -C comp -a addr -e ep \
          -n name -d data_file image
  -A ==> set architecture to 'arch'
  -O ==> set operating system to 'os'
  -T ==> set image type to 'type'
  -C ==> set compression type 'comp'
  -a ==> set load address to 'addr' (hex)
  -e ==> set entry point to 'ep' (hex)
  -n ==> set image name to 'name'
  -d ==> use image data from 'datafile'

Right now, all Linux kernels for PowerPC systems use the same load address (0x00000000), but the entry point address depends on the kernel version:

So a typical call to build a U-Boot image would read:

-> tools/mkimage -n '2.4.4 kernel for TQM850L' \
> -A ppc -O linux -T kernel -C gzip -a 0 -e 0 \
> -d /opt/elsk/ppc_8xx/usr/src/linux-2.4.4/arch/ppc/coffboot/vmlinux.gz \
> examples/uImage.TQM850L
Image Name:   2.4.4 kernel for TQM850L
Created:      Wed Jul 19 02:34:59 2000
Image Type:   PowerPC Linux Kernel Image (gzip compressed)
Data Size:    335725 Bytes = 327.86 kB = 0.32 MB
Load Address: 0x00000000
Entry Point:  0x00000000

To verify the contents of the image (or check for corruption):

-> tools/mkimage -l examples/uImage.TQM850L
Image Name:   2.4.4 kernel for TQM850L
Created:      Wed Jul 19 02:34:59 2000
Image Type:   PowerPC Linux Kernel Image (gzip compressed)
Data Size:    335725 Bytes = 327.86 kB = 0.32 MB
Load Address: 0x00000000
Entry Point:  0x00000000

NOTE: for embedded systems where boot time is critical you can trade speed for memory and install an UNCOMPRESSED image instead: this needs more space in Flash, but boots much faster since it does not need to be uncompressed:

-> gunzip /opt/elsk/ppc_8xx/usr/src/linux-2.4.4/arch/ppc/coffboot/vmlinux.gz
-> tools/mkimage -n '2.4.4 kernel for TQM850L' \
> -A ppc -O linux -T kernel -C none -a 0 -e 0 \
> -d /opt/elsk/ppc_8xx/usr/src/linux-2.4.4/arch/ppc/coffboot/vmlinux \
> examples/uImage.TQM850L-uncompressed
Image Name:   2.4.4 kernel for TQM850L
Created:      Wed Jul 19 02:34:59 2000
Image Type:   PowerPC Linux Kernel Image (uncompressed)
Data Size:    792160 Bytes = 773.59 kB = 0.76 MB
Load Address: 0x00000000
Entry Point:  0x00000000

Similar you can build U-Boot images from a 'ramdisk.image.gz' file when your kernel is intended to use an initial ramdisk:

-> tools/mkimage -n 'Simple Ramdisk Image' \
> -A ppc -O linux -T ramdisk -C gzip \
> -d /LinuxPPC/images/SIMPLE-ramdisk.image.gz examples/simple-initrd
Image Name:   Simple Ramdisk Image
Created:      Wed Jan 12 14:01:50 2000
Image Type:   PowerPC Linux RAMDisk Image (gzip compressed)
Data Size:    566530 Bytes = 553.25 kB = 0.54 MB
Load Address: 0x00000000
Entry Point:  0x00000000

Installing a Linux Image:

To downloading a U-Boot image over the serial (console) interface, you must convert the image to S-Record format:

objcopy -I binary -O srec examples/image examples/image.srec

The 'objcopy' does not understand the information in the U-Boot image header, so the resulting S-Record file will be relative to address 0x00000000. To load it to a given address, you need to specify the target address as 'offset' parameter with the 'loads' command.

Example: install the image to address 0x40100000 (which on the TQM8xxL is in the first Flash bank):

=> erase 40100000 401FFFFF

.......... done
Erased 8 sectors

=> loads 40100000
## Ready for S-Record download ...
~>examples/image.srec
1 2 3 4 5 6 7 8 9 10 11 12 13 ...
...
15989 15990 15991 15992
[file transfer complete]
[connected]
## Start Addr = 0x00000000

You can check the success of the download using the 'iminfo' command; this includes a checksum verification so you can be sure no data corruption happened:

=> imi 40100000

## Checking Image at 40100000 ...
   Image Name:   2.2.13 for initrd on TQM850L
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    335725 Bytes = 327 kB = 0 MB
   Load Address: 00000000
   Entry Point:  0000000c
   Verifying Checksum ... OK

Boot Linux:

The "bootm" command is used to boot an application that is stored in memory (RAM or Flash). In case of a Linux kernel image, the contents of the "bootargs" environment variable is passed to the kernel as parameters. You can check and modify this variable using the "printenv" and "setenv" commands:

=> printenv bootargs
bootargs=root=/dev/ram

=> setenv bootargs root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2

=> printenv bootargs
bootargs=root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2

=> bootm 40020000
## Booting Linux kernel at 40020000 ...
   Image Name:   2.2.13 for NFS on TQM850L
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    381681 Bytes = 372 kB = 0 MB
   Load Address: 00000000
   Entry Point:  0000000c
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
Linux version 2.2.13 (wd@denx.local.net) (gcc version 2.95.2 19991024 (release)) #1 Wed Jul 19 02:35:17 MEST 2000
Boot arguments: root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2
time_init: decrementer frequency = 187500000/60
Calibrating delay loop... 49.77 BogoMIPS
Memory: 15208k available (700k kernel code, 444k data, 32k init) [c0000000,c1000000]
...

If you want to boot a Linux kernel with initial ram disk, you pass the memory addresses of both the kernel and the initrd image (PPBCOOT format!) to the "bootm" command:

=> imi 40100000 40200000

## Checking Image at 40100000 ...
   Image Name:   2.2.13 for initrd on TQM850L
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    335725 Bytes = 327 kB = 0 MB
   Load Address: 00000000
   Entry Point:  0000000c
   Verifying Checksum ... OK

## Checking Image at 40200000 ...
   Image Name:   Simple Ramdisk Image
   Image Type:   PowerPC Linux RAMDisk Image (gzip compressed)
   Data Size:    566530 Bytes = 553 kB = 0 MB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK

=> bootm 40100000 40200000
## Booting Linux kernel at 40100000 ...
   Image Name:   2.2.13 for initrd on TQM850L
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    335725 Bytes = 327 kB = 0 MB
   Load Address: 00000000
   Entry Point:  0000000c
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
## Loading RAMDisk Image at 40200000 ...
   Image Name:   Simple Ramdisk Image
   Image Type:   PowerPC Linux RAMDisk Image (gzip compressed)
   Data Size:    566530 Bytes = 553 kB = 0 MB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   Loading Ramdisk ... OK
Linux version 2.2.13 (wd@denx.local.net) (gcc version 2.95.2 19991024 (release)) #1 Wed Jul 19 02:32:08 MEST 2000
Boot arguments: root=/dev/ram
time_init: decrementer frequency = 187500000/60
Calibrating delay loop... 49.77 BogoMIPS
...
RAMDISK: Compressed image found at block 0
VFS: Mounted root (ext2 filesystem).

bash#

More About U-Boot Image Types:

U-Boot supports the following image types:

"Standalone Programs" are directly runnable in the environment provided by U-Boot; it is expected that (if they behave well) you can continue to work in U-Boot after return from the Standalone Program. "OS Kernel Images" are usually images of some Embedded OS which will take over control completely. Usually these programs will install their own set of exception handlers, device drivers, set up the MMU, etc. - this means, that you cannot expect to re-enter U-Boot except by resetting the CPU. "RAMDisk Images" are more or less just data blocks, and their parameters (address, size) are passed to an OS kernel that is being started. "Multi-File Images" contain several images, typically an OS (Linux) kernel image and one or more data images like RAMDisks. This construct is useful for instance when you want to boot over the network using BOOTP etc., where the boot server provides just a single image file, but you want to get for instance an OS kernel and a RAMDisk image.

"Multi-File Images" start with a list of image sizes, each
image size (in bytes) specified by an "uint32_t" in network
byte order. This list is terminated by an "(uint32_t)0".
Immediately after the terminating 0 follow the images, one by
one, all aligned on "uint32_t" boundaries (size rounded up to
a multiple of 4 bytes).

"Firmware Images" are binary images containing firmware (like U-Boot or FPGA images) which usually will be programmed to flash memory.

"Script files" are command sequences that will be executed by U-Boot's command interpreter; this feature is especially useful when you configure U-Boot to use a real shell (hush) as command interpreter.

Standalone HOWTO:

One of the features of U-Boot is that you can dynamically load and run "standalone" applications, which can use some resources of U-Boot like console I/O functions or interrupt services.

Two simple examples are included with the sources:

"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] = "<NULL>"
Hit any key to exit ...

## Application terminated, rc = 0x0

Another 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 og 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

Minicom warning:

Over time, many people have reported problems when trying to use the "minicom" terminal emulation program for serial download. I (wd) consider minicom to be broken, and recommend not to use it. Under Unix, I recommend to use C-Kermit for general purpose use (and especially for kermit binary protocol download ("loadb" command), and use "cu" for S-Record download ("loads" command).

Nevertheless, if you absolutely want to use it try adding this configuration to your "File transfer protocols" section:

   Name    Program          Name U/D FullScr IO-Red. Multi
X  kermit  /usr/bin/kermit -i -l %l -s   Y    U    Y       N      N
Y  kermit  /usr/bin/kermit -i -l %l -r   N    D    Y       N      N

NetBSD Notes:

Starting at version 0.9.2, U-Boot supports NetBSD both as host (build U-Boot) and target system (boots NetBSD/mpc8xx).

Building requires a cross environment; it is known to work on NetBSD/i386 with the cross-powerpc-netbsd-1.3 package (you will also need gmake since the Makefiles are not compatible with BSD make). Note that the cross-powerpc package does not install include files; attempting to build U-Boot will fail because <machine/ansi.h> is missing. This file has to be installed and patched manually:

# cd /usr/pkg/cross/powerpc-netbsd/include
# mkdir powerpc
# ln -s powerpc machine
# cp /usr/src/sys/arch/powerpc/include/ansi.h powerpc/ansi.h
# ${EDIT} powerpc/ansi.h    ## must remove __va_list, _BSD_VA_LIST

Native builds don't work due to incompatibilities between native and U-Boot include files.

Booting assumes that (the first part of) the image booted is a stage-2 loader which in turn loads and then invokes the kernel proper. Loader sources will eventually appear in the NetBSD source tree (probably in sys/arc/mpc8xx/stand/u-boot_stage2/); in the meantime, send mail to bruno@exet-ag.de and/or wd@denx.de for details.

Implementation Internals:

The following is not intended to be a complete description of every implementation detail. However, it should help to understand the inner workings of U-Boot and make it easier to port it to custom hardware.

Initial Stack, Global Data:

The implementation of U-Boot is complicated by the fact that U-Boot starts running out of ROM (flash memory), usually without access to system RAM (because the memory controller is not initialized yet). This means that we don't have writable Data or BSS segments, and BSS is not initialized as zero. To be able to get a C environment working at all, we have to allocate at least a minimal stack. Implementation options for this are defined and restricted by the CPU used: Some CPU models provide on-chip memory (like the IMMR area on MPC8xx and MPC826x processors), on others (parts of) the data cache can be locked as (mis-) used as memory, etc.

Chris Hallinan posted a good summary of  these  issues  to  the
u-boot-users mailing list:

Subject: RE: [U-Boot-Users] RE: More On Memory Bank x (nothingness)?
From: "Chris Hallinan" <clh@net1plus.com>
Date: Mon, 10 Feb 2003 16:43:46 -0500 (22:43 MET)
...

Correct me if I'm wrong, folks, but the way I understand it
is this: Using DCACHE as initial RAM for Stack, etc, does not
require any physical RAM backing up the cache. The cleverness
is that the cache is being used as a temporary supply of
necessary storage before the SDRAM controller is setup. It's
beyond the scope of this list to expain the details, but you
can see how this works by studying the cache architecture and
operation in the architecture and processor-specific manuals.

OCM is On Chip Memory, which I believe the 405GP has 4K. It
is another option for the system designer to use as an
initial stack/ram area prior to SDRAM being available. Either
option should work for you. Using CS 4 should be fine if your
board designers haven't used it for something that would
cause you grief during the initial boot! It is frequently not
used.

CFG_INIT_RAM_ADDR should be somewhere that won't interfere
with your processor/board/system design. The default value
you will find in any recent u-boot distribution in
Walnut405.h should work for you. I'd set it to a value larger
than your SDRAM module. If you have a 64MB SDRAM module, set
it above 400_0000. Just make sure your board has no resources
that are supposed to respond to that address! That code in
start.S has been around a while and should work as is when
you get the config right.

-Chris Hallinan
DS4.COM, Inc.

It is essential to remember this, since it has some impact on the C code for the initialization procedures:

Having only the stack as writable memory limits means we cannot use normal global data to share information beween the code. But it turned out that the implementation of U-Boot can be greatly simplified by making a global data structure (gd_t) available to all functions. We could pass a pointer to this data as argument to all functions, but this would bloat the code. Instead we use a feature of the GCC compiler (Global Register Variables) to share the data: we place a pointer (gd) to the global data into a register which we reserve for this purpose.

When choosing a register for such a purpose we are restricted by the relevant (E)ABI specifications for the current architecture, and by GCC's implementation.

For PowerPC, the following registers have specific use: R1: stack pointer R2: TOC pointer R3-R4: parameter passing and return values R5-R10: parameter passing R13: small data area pointer R30: GOT pointer R31: frame pointer

(U-Boot also uses R14 as internal GOT pointer.)

==> U-Boot will use R29 to hold a pointer to the global data

Note: on PPC, we could use a static initializer (since the
address of the global data structure is known at compile time),
but it turned out that reserving a register results in somewhat
smaller code - although the code savings are not that big (on
average for all boards 752 bytes for the whole U-Boot image,
624 text + 127 data).

On ARM, the following registers are used:

R0: function argument word/integer result
R1-R3:  function argument word
R9: GOT pointer
R10:    stack limit (used only if stack checking if enabled)
R11:    argument (frame) pointer
R12:    temporary workspace
R13:    stack pointer
R14:    link register
R15:    program counter

==> U-Boot will use R8 to hold a pointer to the global data

Memory Management:

U-Boot runs in system state and uses physical addresses, i.e. the MMU is not used either for address mapping nor for memory protection.

The available memory is mapped to fixed addresses using the memory controller. In this process, a contiguous block is formed for each memory type (Flash, SDRAM, SRAM), even when it consists of several physical memory banks.

U-Boot is installed in the first 128 kB of the first Flash bank (on TQM8xxL modules this is the range 0x40000000 ... 0x4001FFFF). After booting and sizing and initializing DRAM, the code relocates itself to the upper end of DRAM. Immediately below the U-Boot code some memory is reserved for use by malloc() [see CFG_MALLOC_LEN configuration setting]. Below that, a structure with global Board Info data is placed, followed by the stack (growing downward).

Additionally, some exception handler code is copied to the low 8 kB of DRAM (0x00000000 ... 0x00001FFF).

So a typical memory configuration with 16 MB of DRAM could look like this:

0x0000 0000 Exception Vector code
      :
0x0000 1FFF
0x0000 2000 Free for Application Use
      :
      :

      :
      :
0x00FB FF20 Monitor Stack (Growing downward)
0x00FB FFAC Board Info Data and permanent copy of global data
0x00FC 0000 Malloc Arena
      :
0x00FD FFFF
0x00FE 0000 RAM Copy of Monitor Code
...     eventually: LCD or video framebuffer
...     eventually: pRAM (Protected RAM - unchanged by reset)
0x00FF FFFF [End of RAM]

System Initialization:

In the reset configuration, U-Boot starts at the reset entry point (on most PowerPC systens at address 0x00000100). Because of the reset configuration for CS0# this is a mirror of the onboard Flash memory. To be able to re-map memory U-Boot then jumps to its link address. To be able to implement the initialization code in C, a (small!) initial stack is set up in the internal Dual Ported RAM (in case CPUs which provide such a feature like MPC8xx or MPC8260), or in a locked part of the data cache. After that, U-Boot initializes the CPU core, the caches and the SIU.

Next, all (potentially) available memory banks are mapped using a preliminary mapping. For example, we put them on 512 MB boundaries (multiples of 0x20000000: SDRAM on 0x00000000 and 0x20000000, Flash on 0x40000000 and 0x60000000, SRAM on 0x80000000). Then UPM A is programmed for SDRAM access. Using the temporary configuration, a simple memory test is run that determines the size of the SDRAM banks.

When there is more than one SDRAM bank, and the banks are of different size, the largest is mapped first. For equal size, the first bank (CS2#) is mapped first. The first mapping is always for address 0x00000000, with any additional banks following immediately to create contiguous memory starting from 0.

Then, the monitor installs itself at the upper end of the SDRAM area and allocates memory for use by malloc() and for the global Board Info data; also, the exception vector code is copied to the low RAM pages, and the final stack is set up.

Only after this relocation will you have a "normal" C environment; until that you are restricted in several ways, mostly because you are running from ROM, and because the code will have to be relocated to a new address in RAM.

U-Boot Porting Guide:

[Based on messages by Jerry Van Baren in the U-Boot-Users mailing list, October 2002]

int main (int argc, char *argv[]) { sighandler_t no_more_time;

signal (SIGALRM, no_more_time);
alarm (PROJECT_DEADLINE - toSec (3 * WEEK));

if (available_money > available_manpower) {
    pay consultant to port U-Boot;
    return 0;
}

Download latest U-Boot source;

Subscribe to u-boot-users mailing list;

if (clueless) {
    email ("Hi, I am new to U-Boot, how do I get started?");
}

while (learning) {
    Read the README file in the top level directory;
    Read http://www.denx.de/twiki/bin/view/DULG/Manual ;
    Read the source, Luke;
}

if (available_money > toLocalCurrency ($2500)) {
    Buy a BDI2000;
} else {
    Add a lot of aggravation and time;
}

Create your own board support subdirectory;

Create your own board config file;

while (!running) {
    do {
        Add / modify source code;
    } until (compiles);
    Debug;
    if (clueless)
        email ("Hi, I am having problems...");
}
Send patch file to Wolfgang;

return 0;

}

void no_more_time (int sig) { hire_a_guru(); }

Coding Standards:

All contributions to U-Boot should conform to the Linux kernel coding style; see the file "Documentation/CodingStyle" in your Linux kernel source directory.

Please note that U-Boot is implemented in C (and to some small parts in Assembler); no C++ is used, so please do not use C++ style comments (//) in your code.

Please also stick to the following formatting rules:

Submissions which do not conform to the standards may be returned with a request to reformat the changes.

Submitting Patches:

Since the number of patches for U-Boot is growing, we need to establish some rules. Submissions which do not conform to these rules may be rejected, even when they contain important and valuable stuff.

When you send a patch, please include the following information with it:

Notes: