The rrload Embedded Bootloader

-- rrload --

Embedded Bootloader for DSPLinux

ver 3.8

by RidgeRun, Inc

Copyright 2001
All Rights Reserved

Contents


Introduction

The rrload bootloader was developed by RidgeRun Inc, and is shipped as a component within the DSPLinux SDK distribution. It is taylored specifically towards allowing users to manage the loading, storing, and invoking of a Linux kernel and root filesystem. At the time of this writing it had been ported to at least six Texas Instruments platforms; the C547[1|2], DSC21_EVM, DSC24_EVM, OMAP1510, OMAP710 and TI925_EVM.

In normal operation the bootloader resides in flash (at the reset vector) and is the first program run on power up, and unless intercepted, rrload will typically transfer control to the stored system (e.g. kernel + filesystem). Additionally, the bootloader will relocate either the kernel and/or the filesystem to SDRAM if necessary prior to transferring control. This behavior happens automatically in response to the user having previously configured rrload with a default boot command of "boot_auto". This is the typical command stored along with the user's other persistent bootloader settings, which among other things, can include extra command line arguments the user desires to have passed to the kernel.

If the bootloader is not configured with a default boot command, or if the boot process is intercepted, rrload will simply present its user interface and wait for user input. The bootloader offers both a menu UI, as well as a command line UI which the user may easily toggle between. Available through the UI, is the ability to download a new kernel and/or file system to either ram or flash.

The bootloader supports a variety of download formats and can accept these formats over a variety of board I/O ports such as serial, parallel and ether. The user interface communicates over the board's serial line with a host terminal session such as minicom, hyperterm, etc. Holding the [Enter] key down within the host terminal session while simultaneously applying power to the board will insure that any previously stored default boot command is temporarily intercepted and instead force the bootloader to present its user interface.


Design Objectives


Feature Set


Setting Things Up

---- If you have an C547x EVM ----

With the C547[1|2] EVM turned off, connect a serial cable between it and the host PC.

Now at the host bring up a terminal emulator such as minicom and associate it with the particular host serial port you've just connected the cable to. Also use these terminal settings:

    115200 buad
    8 data bits,
    1 stop bit.
    no start bit.
    no parity.
    no flow control
    Cable: Normal type (not a Null Modem type)
Some jumper will have to be changed.
  Use all stock board jumper settings, except....
  JP29 ROM size Select;   moved to left-middle position.
  JP27 RAM/FLASH Swap ;   moved to 1-2 position.
  JP28 FLASH WE Disable;  moved to 1-2 position.
  JP21 Big/Little Endian; moved to 2-3 position.

Assuming that the board has rrload contained within on-board flash and the board switches/jumpers are enabled for boot-from-flash, then apply power to the target board. As the board powers up you should see the rrload UI appear in the host minicom session window. The bootloader now has control of your target and is waiting for user input. Note: If you are interested in interacting with the bootloader's UI and it is not already presented to you on a power cycle, then hold down the [Enter] key within your host terminal session while simultaneously reseting the device. This should intercept the default boot command and instead force the bootloader to present its UI and allow user interaction.

---- If you have a omap1510-HelenP1 EVM ----

With the omap1510 turned off, connect a serial cable between it and the host PC. You may use any host serial port you desire, but on the target end you must use the board connector identified in table below.

Now at the host bring up a terminal emulator such as minicom and associate it with the particular host serial port you've just connected the cable to. Also use these terminal settings:

    115200 buad
    8 data bits,
    1 stop bit.
    no start bit.
    no parity.
    no flow control
    Board Connector: "Modem UART" (lower connector).
    Cable: Null Modem type
Here are the various switch settings of that dip package which pertain to omap1510-HelenP1 rrload.
  Dip Switch "S2-6" on  --- boot from eeprom
  Dip Switch "S2-6" off --- boot from flash

Assuming that the board has rrload contained within on-board flash and the board switches/jumpers are enabled for boot-from-flash, then apply power to the target board. As the board powers up you should see the rrload UI appear in the host minicom session window. The bootloader now has control of your target and is waiting for user input. Note: If you are interested in interacting with the bootloader's UI and it is not already presented to you on a power cycle, then hold down the [Enter] key within your host terminal session while simultaneously reseting the device. This should intercept the default boot command and instead force the bootloader to present its UI and allow user interaction.

---- If you have a DSC21/24 EVM ----

Like the Linux kernel, the rrload bootloader uses the board's serial port for the console. It is expected that a standard cable (not a NULL-Modem cable) will be connected between the host and JP19 board connector. The terminal settings required by rrrload are the same as those required by the DSPLinux kernel.

    115200 baud
    8 data bits
    1 stop bit
    no start bit
    no parity
    no flow control
    Board Connector: JP19
    Cable: Standard (not a Null Modem type)

Assuming that the board has rrload contained within on-board flash and the board switches and/or jumpers are enabled for boot-from-flash, then apply power to the target board. As the board powers up you should see the rrload UI appear in the host minicom session window. The bootloader now has control of your target and is waiting for user input.

Note: If you are interested in interacting with the bootloader's UI and it is not already presented to you on a power cycle, then hold down the [Enter] key within your host terminal session while simultaneously reseting the device. This should intercept the default boot command and instead force the bootloader to present its UI and allow user interaction.

---- If you have a TI925 EVM ----

With the TI925 turned off, connect a serial cable between it and the host PC. You may use any host serial port you desire, but on the target end you must use the board connector identified in table below.

Now at the host bring up a terminal emulator such as minicom and associate it with the particular host serial port you've just connected the cable to. Also use these terminal settings:

    57600 buad
    8 data bits,
    1 stop bit.
    no start bit.
    no parity.
    no flow control
    Board Connector: "uart2"
    Cable: Null Modem type
Here are the various switch settings of that dip package which pertain to TI925 rrload.
  Dip Switch "S1-1" off --- boot from flash
  Dip Switch "S1-3" off --- flash write protect disabled (valid when "S1-1" off, "S1-2" off)

Assuming that the board has rrload contained within on-board flash and the board switches/jumpers are enabled for boot-from-flash, then apply power to the target board. As the board powers up you should see the rrload UI appear in the host minicom session window. The bootloader now has control of your target and is waiting for user input. Note: If you are interested in interacting with the bootloader's UI and it is not already presented to you on a power cycle, then hold down the [Enter] key within your host terminal session while simultaneously reseting the device. This should intercept the default boot command and instead force the bootloader to present its UI and allow user interaction.


Persistent Configuration

Option 3 from the main menu will show a list of current user settings. These are the same settings that can be viewed from command line mode by issuing the "set" command. If you make changes to these settings it only effects the current session (ram based settings). If you would like your new settings to survive power cycles you will have to re-flash them by first performing an erase of the params section of flash (ram copy remains unaltered), followed by a flash store of the new params causing the current ram settings to be copied to flash. This can be performed with menu mode or command line mode. Here's an example showing the setting/storing of a new bootloader default boot command. In this case, we're using the bootloader's command line UI (as an alternative to using the menu mode UI) to asssign the bootcmd parameter. Here we assign an empty string since no value string was supplied on the first line:

  rrload> set bootcmd
  rrload> eraseflash params
  rrload> copy -c params -s ram -d flash -f na

Here are the settings that rrload lets the user customize and store persistantly.

Note: As mentioned earlier any of these SDRAM based values can be changed by the user and remain in effect only for the current session. If the user wishes the new settings to survive power cycles then he/she needs to take steps to erase the params section of flash and the re-store the params to flash. On bootup, the bootloader will always insure that the SDRAM based params start out initialized to the flashed set.


Downloading a New Kernel and/or Filesystem

One of the main reasons the bootloader exists is to give the user a means to load images onto the EVM board. Specifically, we are interested in loading a kernel and possibly a root filesystem. Without the bootloader the user would be restricted to JTAG based downloads which can be an attractive option except not all users will have the supporting tools necessary to facilitate JTAG based development. The rrload bootloader gives the user a immediate path to getting software components loaded and running on the board. Additionally, the bootloader allows the user to store the components to flash if desired.

The bootloader supports a variety of download image formats which can be streamed through the various I/O ports of the EVM. The architecture supports easily adding more modules to support additional image formats or I/O ports as necessary. Currently there are two image formats supported and three I/O ports.

Image Formats

I/O Load Ports

How to create and srec image.
The srec format is a Motorola inspired binary standard format. This is an ascii format used for downloading executables, not data files. A srec file is typically created prior to download with the following command:
  $ arm-uclinux-objcopy -S -O myprog myprog.srec
Where myprog is a standard executable file format such as ELF or a.out, etc.

How to create an rrbin image.
A RidgeRun inspired format. This is tagged image binary format use for downloading either executables or data files such as filesystems, etc. This format is very efficient and can be generated with the help of the RidgeRun supplied utility called `mkimage` which is used to prepare a file for download to the rrload bootloader.
  $ mkimage --LAddr 08e00000 linux linux.rr
   ..or..
  $ mkimage --LAddr 08c00000 romdisk.img romdisk.img.rr
  Note: The --LAddr used here is just an example, the
        actual value you use will be dependant on the
        address that you need your specific object loaded
        to. For example, in the case of a kernel, a
        command such as `arm-linux-objdump -h linux`
        could be used to find out where the image expects
        to load to. In the case of a filesystem the --LAddr
        value should match the address that your kernel
        expects to find the filesystem at during a kernel
        boot. mkimage is used to prepare both kernel images
        and filesystem images for download.
The resulting *.rr file will be a space efficient binary format with an additional header tacked on the front to allow the rrload bootloader accept the file with a minimum of coupling between the rrload source code and the software components downloaded to it. This special header is what makes it a tagged image format and it contains the following pieces of information which is used by rrload to process the enclosed pure binary data. Here is an example of the internals of a *.rr file.
  >LoadAddr :0x08e00000
  >EntryAddr:0x08e00130
  >NumBytes :0x0000a200
  (binary block here; 0xa200 bytes)
Note: In our example here, the LoadAddr was determined by the user options supplied (--LAddr), while the EntryAddr and NumBytes are computed by the mkimage script. In cases where the input image doesn't represent an executable, but rather represents a filesystem (for example), then the EntryAddr will not apply and mkimage will simply supply a default filler value. For those that are curious, there is additional usage information contained within the document header of the mkimage script.
When faced with the choice of creating an srec image or rrbin image, rrload users generally opt for the rrbin format for both the kernel and filesystem components. Once the images are created they can be downloaded to the EVM using UI menus in conjunction with the prior settings made to rrload parameters (Main menu; option 3). In particular you will want to adjust the bootloader configuration to indicate the I/O port and image format you intend on using. On the other hand, when using the bootloader's command line mode, the "copy" command contains all the information needed to direct the download. Here are some command line mode examples:
rrload> copy -c kernel -s serial -d ram -f rrbin
   This copies the kernel from the serial port to a
   ram destination using the rrbin input parser. The
   ram addresses written to are determined by the
   incoming file; remember the rrbin header shown above?
   The LoadAddr field of incoming file determined where
   in the system's memory map the image is loaded to. The
   image was built specifically to load and run at
   this address. Note: The header information is also
   acquired by rrload when processing incoming srec
   images as well. The bootloader will keep this
   information with the image so that it always knows
   where in memory it needs to reside when used. This
   will come into play if the user subsequently requests
   the bootloader to store the kernel to flash -- how
   does the bootloader know what a kernel is? It doesn't
   really, except in this command here the -c kernel
   informed the bootloader that this image is a kernel
   and hence when the user later requests a kernel
   boot, or kernel store, etc, the bootloader has a
   record of what image the term "kernel" corresponds
   to. Note: this command only loads the kernel, it
   does not cause the kernel to start running. The
   bootloader's "boot" and "boot_auto" commands are
   the only way to transfer control to a kernel.

rrload> copy -c k -s s -d r -f r
   Exactly the same as the example above.

rrload> copy -c filesys -s ether -d ram -f r
   Incoming rrbin filesystem image is copied from the
   ether port to the memory map ram locations called
   out by the image. Like kernel images, the bootloader
   will maintain a record with this image that
   indicates the location in memory that it originally
   loaded to. If the user requests the filesystem be
   moved to flash and later power cycles and requests
   the filesystem be moved to SDRAM the bootloader will
   have the necessary information to place it in the
   correct location. Note: This command requests the
   bootloader to pull in the rrbin image using the ether
   port. This will only work if the bootloader has
   previously been setup with the correct TFTP related
   user configuration. For more please see
   "A Special Note About Ethernet Downloads".

rrload> set
   Shows the current bootloader user configuration
   settings.

rrload> help
   Provides additional information regarding the "copy"
   command and others. Also shows how you can change
   the bootloader user config settings if necessary.

rrload> copy -c k -s e -d r -f r; copy -c f -s e -d r -f r; boot
   A command list requesting a kernel and filesystem
   download, followed by a boot of the kernel. The
   "boot" command transfers control to the last kernel
   downloaded, or if there wasn't one, will try and
   locate one stored in flash and transfer to the
   EntryAddr recorded with that kernel image.

rrload> copy -c f -s e -d r -f r; copy -c k -s e -d r -f r; boot
   Exactly the same as the command above. We've just
   reversed the order of the loads. Filesystem first
   this time, then the kernel, then boot the kernel.

rrload> copy -c kernel  -s flash -d ram -f na
rrload> copy -c filesys -s flash -d ram -f na
rrload> boot
   Move the kernel and filesystem stored in flash to
   SDRAM according to the LoadAddr recorded with
   it. Then boot the kernel by transferring control to
   the EntryAddr recorded with the kernel image. Note:
   We've supplied the "-f na" here since we are moving
   a pure memory image from flash to SDRAM and it
   wouldn't make sense to state "-f srec" or "-f rrbin"
   since those images are neither of those formats --
   it's just a straight memory copy.

rrload> boot_auto
   This single command is exactly the same as the three
   command set shown above. This is typically the
   command the user assigns to the bootloader's default
   boot command so that on power cycle the kernel
   automatically boots. This is the command mapped to
   menu option 4 of the main menu.

rrload> set bootcmd boot_auto
   Sets the bootloader's default boot command to a
   string that represents the command (or command list)
   the user would like the bootloader to automatically
   execute on each power cycle. This is how a user can
   set things up so that the kernel boots directly on a
   power cycle instead of presenting the bootloader's
   UI.  Yet, holding the [Enter] key down within the
   host terminal session while simultaneously applying
   power to the board will insure that any previously
   stored default boot command is temporarily
   intercepted and instead force the bootloader to
   present its user interface.
Please Note: It is really only a matter of documentation convenience that all the examples above where performed using the bootloader's command line UI. All these operations could have been performed equally well using the bootloader's menu UI.


Storing a New Kernel and/or Filesystem in Flash

As mentioned earlier a main purpose in life for the bootloader is to facilitate getting software components loaded onto the board (via I/O ports). Another main purpose for the bootloader is to facilitate the storing and retrieving of software components within on-board flash. Specifically, the rrload bootloader has been designed to manage four such component types. Each of these components has a very specific area of flash dedicated to holding it. There can only be one such instance of each component within flash at any one time and prior to replacing any content the user must explicitly erase the previous component content. The rrload UI provides the ability to individually erase and store the 4 components listed. The bootloader image area of flash is typically not something a person would fiddle with unless performing the steps associated with installing a copy of rrload on the EVM board. The bootloader's user config area of flash holds the various configuration settings available via option 3 of the main menu but the Kernel and Filesystem areas of flash are what we want to talk more about in this chapter. In the "ram based" case the user can remain unaware of the flash addresses used to store a kernel and filesystem. The bootloader takes care of tagging the stored component with enough information to allow the user to later pull this component back out of flash and into its original SDRAM location prior to use. For example, the following steps will load in a ram based image and store it to flash:
  rrload> copy -c kernel -s ether -d ram -f rrbin
  rrload> eraseflash kernel
  rrload> copy -c kernel -s ram -d flash -f na
If the current SDRAM contents are lost (e.g. by a power cycle) the user can retrieve the kernel from flash and boot it with the following commands:
  rrload> copy -c kernel -s flash -d ram -f na; boot
Notice that at no time did the user need to be aware of the specific addresses used for storing the component in either flash or SDRAM. This is true of all four component types. Of course there's always got to be an exception, and in this case it is revealed during the "flash based" image case discussed next.

XIP Images are a Special Case

As we mentioned earlier, the "flash based" case is unique in that an image is written directly to flash as a result of downloading a kernel or filesystem via an I/O port. This occurs when the image contains load addresses that fall within the flash area of the system's memory map. Those address were assigned at the time the image was produced by a linker and then prepared by mkimage into an rrbin image. This falls in the realm of advanced usage and requires some special attention as mistakes in this area can corrupt the board's flash content to the point of not permitting a boot. In this case, the user would be forced to install a new copy of rrload using the JTAG connector. The critical area pertains to the selection of load address assigned to the image. A user is not free to locate the image any where he/she chooses since areas of the flash have already been set aside for the bootloader's use. These areas are reserved. Instead the user is limited to a sub-range within the flash for placing XIP kernel images and another specific sub-range for placing XIP filesystem images. Loads performed to these specific ranges are managed by rrload by way of tagging the loaded image with the normal record keeping info normally associated with kernels and filesystems stored to flash -- just as when storing components in the normal manner (copy from SDRAM to flash). This record keeping info is stored automatically by rrload during the download and contains enough information that rrload knows this component is an XIP one. For example, the following command would not result in a copy to SDRAM since rrload can see that the stored kernel did not originate from SDRAM and instead was an XIP loaded one. The requested copy is ignored and the kernel is simply booted in place.
  rrload> copy -c k -s f -d r -f na; boot
The steps for performing an XIP download are pretty straight forward but it must be emphasized that it assumes the user had taken care to build the load image with a valid load address. If you send an image to the wrong area of flash you are most certainly corrupting data reserved for the bootloader's use. As always, we erase the component's flash area first before placing new content there. Here are the steps:
  rrload> eraseflash -c kernel
  rrload> copy -c k -s e -d r -f rrbin
  rrload> eraseflash -c filesys
  rrload> copy -c f -s e -d r -f rrbin
Note: You may have expected the -d field to be "-d flash" instead of "-d ram"; it turns out that either one will work.

Important! These steps will only be successful if you build the XIP kernel and XIP filesystem so as to be fully contained within the following special flash address ranges:

  --C547x EVM--
  XIP kernel:  Flash range 0x00040020 to 0x0011ffff (inclusive)
  XIP Filesys: Flash range 0x00120020 to 0x003fffff (inclusive)

  --DSC21 EVM--
  XIP kernel:  Flash range 0x02020020 to 0x020bffff (inclusive)
  XIP Filesys: Flash range 0x020C0020 to 0x021fffff (inclusive)

  --DSC24 EVM--
  XIP kernel:  Flash range 0x02020020 to 0x020bffff (inclusive)
  XIP Filesys: Flash range 0x020C0020 to 0x021fffff (inclusive)

  --OMAP1510 EVM (F160 Chips) --
  XIP kernel:  Flash range 0x00020020 to 0x0021ffff (inclusive)
  XIP Filesys: Flash range 0x00220020 to 0x0081ffff (inclusive)

  --OMAP1510 EVM (F128 Chips) --
  XIP kernel:  Flash range 0x00040020 to 0x0023ffff (inclusive)
  XIP Filesys: Flash range 0x00240020 to 0x0083ffff (inclusive)

  --OMAP710 EVM (F160 Chips) --
  XIP kernel:  Flash range 0x00020020 to 0x0021ffff (inclusive)
  XIP Filesys: Flash range 0x00220020 to 0x0081ffff (inclusive)

  --OMAP710 EVM (F128 Chips) --
  XIP kernel:  Flash range 0x00040020 to 0x0023ffff (inclusive)
  XIP Filesys: Flash range 0x00240020 to 0x0083ffff (inclusive)

  --TI925 EVM (F160 Chips)--
  XIP kernel:  Flash range 0x00020020 to 0x000bffff (inclusive)
  XIP Filesys: Flash range 0x000C0020 to 0x001fffff (inclusive)

  --TI925 EVM (F128 Chips)--
  XIP kernel:  Flash range 0x00040020 to 0x000dffff (inclusive)
  XIP Filesys: Flash range 0x000e0020 to 0x001fffff (inclusive)


A Special Note About Serial Downloads

Note: Recall that the serial port is used by rrload for UI interaction and serves double duty when also used during an image download to the target platform. Take the following command for example:
  rrload> copy -c kernel -s serial -d ram -f srec
This command is issued to rrload by using a terminal session running on a remote host connected over a serial port. Yet the command itself is requesting a file transfer over that same serial line. Doesn't the UI occurring over the serial line conflict with a file transfer over the same line? No it doesn't. When using the UI to request a file download rrload drops into a mode where it stops using the serial channel for anything except bringing in the file image. Only when rrload has brought in the final byte will rrload again start using the serial line for UI operations. Now it is also true that when rrload drops into "load" mode that the user must insure that only file image bytes now be transfered over the serial line since any bytes received by the target device will be interpreted as file bytes. This is something the user will need to be aware of. In the case of using `minicom` as a terminal window we find that we can issue the "copy" command and then, without typing anything else in that terminal session, go to a shell window and type:
  $ cat linux.rr > /dev/ttyS0
This streams the file to rrload. When rrload completes the file transfer the user can move the cursor back over to the minicom window and resume interacting with the rrload UI.


A Special Note About Ethernet Downloads

If you are planning to use the ethernet port for your downloads then you will have to use the UI to establish params settings that allow the internal TFTP logic to work with your remote server. Option 3 from the main menu will show a list of current user settings. These are the same settings that can viewed from command line mode by issuing the "set" command. Here are some example settings:
  ui mode [cmd|menu]  : menu
  default boot cmd    : boot_auto
  I/O load format     : rrbin
  I/O load port       : ether
  Server IP    (tftp) : 192.168.1.15
  Server MAC   (tftp) : 55:3:00:c0:00:F0
  Device IP    (tftp) : 192.168.1.50
  Device MAC   (tftp) : 11:22:33:EA:cc:00
  Kernel Path  (tftp) : linux.rr
  FileSys Path (tftp) : romdisk.img.rr
  Kernel cmdline      :
Note: Since the network stack implemented within the bootloader does not yet support the Address Resolution Protocol (ARP) it will be necessary to manually inform the remote server of your device IP/MAC mapping. The server would normally be able to use ARP at runtime to learn this mapping. Until then, do this sort of command on your server (may need to be root user):
  $ arp -s 192.168.1.29 00:e0:81:10:36:cf
Notice here that we are manually loading the server's internal ARP cache with the IP and MAC of our EVM device. It is also important that you have your system admisistrator enable TFTP on your remote server since this is often times disabled for security reasons. One final note, as the example goes above, rrload will expect to find a kernel file by the name of linux.rr which should be located on the remote server in the default TFTP directory of that machine -- in my case that was /home/skranz.


A Special Note About Passing A Command Line and Ethernet MAC to the Kernel

The DSPlinux bootloader has the ability to pass a user supplied Kernel Command Line string to the DSPLinux kernel as control is being transferred to it. Once the kernel boot process is under way, special logic in the DSPLinux kernel picks up the Command Line previously deposited by rrload and replaces whatever original default kernel command line was embedded within the kernel. The command line is then parsed in the normal way during the remaining steps of the kernel boot process. To implement this, a special SDRAM memory location is agreed upon in advance which rrload and the kernel are both built to know about. Again, this allows the bootloader to deposit a command line string at that specific SDRAM memory location and when the DSPLinux kernel is booted that string will be picked up at the same location as in the manner just described.

Note: A NULL terminated magic pattern string equal to "kcmdline-->" actually proceeds the real kernel command line string (if any) to let the kernel know that a valid string really exists (even if just a NULL string). If the pattern is found then the kernel can assume that the command line string will immediately follow the magic string. Both the magic string and the command line string (if they exist) butt up against each other, and again, are both null terminated strings. If the pattern is not found then the kernel will assume that it had been invoked by some other means than the rrload bootloader and will avoid attempting to pick up an incoming command line string. There's probably nothing valid there anyways.

In like manner, the Device MAC rrload param configured by the user is also deposited in a special ram location so that the Kernel can retrieve it and make use of it in ways necessary for Kernel ethernet initialization. This NULL terminated ethernet MAC string (e.g. "00:11:22:33:44:55") is deposited in the same manner as described for the Kernel Command Line with the NULL terminated magic pattern "etherMAC-->" immediately proceeding it. When the kernel boots it can use these deposited strings in ways it sees fit.

Although a user wouldn't normally need to know the exact ram addresses used for depositing the Kernel Command Line and Device MAC, it may help those trying to debug kernel boot issues. The specific ram addresses used for the kernel's incoming Command Line string and ether MAC are:

  Note: the quote ("..") characters are shown here for
        clarity only and the NULL label represents the
        byte value zero that terminates each string.

  --C547x EVM--
  Start Addr | Comment
  -----------+--------------------------------------------
  0xffc00020 | "kcmdline-->"NULL"Command Line string"NULL
  0xffc00100 | "etherMAC-->"NULL"00:11:22:33:44:55"NULL

  --DSC21 EVM--
  Start Addr | Comment
  -----------+--------------------------------------------
  0x08000000 | "kcmdline-->"NULL"Command Line string"NULL
  0x080000E0 | "etherMAC-->"NULL"00:11:22:33:44:55"NULL

  --DSC24 EVM--
  Start Addr | Comment
  -----------+--------------------------------------------
  0x00900000 | "kcmdline-->"NULL"Command Line string"NULL
  0x009000E0 | "etherMAC-->"NULL"00:11:22:33:44:55"NULL

  --OMAP1510 EVM--
  Start Addr | Comment
  -----------+--------------------------------------------
  0x10000100 | "kcmdline-->"NULL"Command Line string"NULL
  0x100001E0 | "etherMAC-->"NULL"00:11:22:33:44:55"NULL

  --TI925 EVM--
  Start Addr | Comment
  -----------+--------------------------------------------
  0x05e00000 | "kcmdline-->"NULL"Command Line string"NULL
  0x05e000E0 | "etherMAC-->"NULL"00:11:22:33:44:55"NULL

Note: The bootloader will manage these addresses for you according to the settings you have established for the kcmdline parameter and devmac parameter. These parameters are settable using the rrload menu mode interface (option 3 from main menu) or the command line mode. An example follows:
   rrload> set kcmdline root=/dev/rom0
   rrload> set devmac 00:11:22:33:44:55


Building the rrload bootloader

$ cd dsplinux/dsc21/rrload
$ cat README
$ make

This operation produces three rrload bootloader images.

1. rrload     -- This is ELF version of the
                 bootloader which can be downloaded
                 to the board's SDRAM via a JTAG
                 based emulator. Currently this is
                 the only way to get the very first
                 instance of the rrload bootloader
                 installed on the board.
2. rrload.rr  -- This is an rrbin format version of
                 the rrload bootloader as produced
                 by the Makefile using the mkimage
                 utility. It only differs from the
                 ELF version in format. This rrbin
                 format is very close to a raw binary
                 format.
                 This is used by user performing an
                 upgrade of an existing rrload
                 installation. Other areas of this
                 document discuss the process more
                 fully.
3. rrload.ForUpGrade.rr -- This is identicle to the
                 other two version of the bootloader
                 except it is built to load to a
                 different SDRAM address.
                 This is used by user performing an
                 upgrade of an existing rrload
                 installation. Other areas of this
                 document discuss the process more
                 fully.


Upgrading An Existing rrload Installation

This discussion refers to the installation of the rrload bootloader program and not the installation of a kernel and/or filesystem normally managed by the installed bootloader.

The Makefile of the rrload project automatically creates two rrload rrbin images which are absolutely identical to one another except they are built to run at different locations within the memory map. This allows both instances of rrload to reside in memory simultaneously without conflicting with each other which is necessary for performing rrload upgrades. The main instance is called "rrload.rr" and represents the image you really want to have loaded on the board; the second instance is called "rrload.ForUpGrade". The purpose of the "rrload.ForUpGrade" object is to help provide the rrload user with the ability to upgrade an existing rrload installation without the use of JTAG. The reason this is useful is to allow the following steps to occur for the user who wishes to upgrade an old instance of rrload with a newer version (again, without using JTAG). Assuming the user has built the new version of rrload and has the current (old) running rrload in command line mode, these steps could accomplish the upgrade. Please note that in this example we are choosing to use ethernet to load the new image and hence we assume that you have the necessary bootloader params established to allow this (see menu option #3).

...Upgrading via Ethernet

Step0:
  Start a minicom window on the desktop connected
  to the targets serial port, then hold down the
  Enter key while applying power to the board. Let
  go after a second or two when you see the rrload
  main menu appear. At the main menu select option
  3 and jot down any installation specific settings
  that you may want to re-establish later after the
  upgrade process.

Step1:
  At the main menu select option 5 to get into command
  line mode, Then...
  rrload> set kpath rrload.ForUpGrade.rr
  rrload> copy -c kernel -s ether -d ram -f rrbin
  rrload> eraseflash params
  rrload> boot

    Note: We've used the "load kernel" path to sneak
    in the second instance of rrload. Then we booted it.
    At this point the second instance of rrload should
    be running and we'll use it to perform the upgrade.
    The ram location previously used for rrload is now
    available so we can now download the new version of
    rrload to fill that spot. But please note, you will
    have to reestablish your desired bootloader params
    for this new image just loaded and running. Please
    do not store these settings to flash just yet. We
    still need to get the final bootloader image into
    memory -- the next step.

Step2:
  At the main menu select option 5 to get into command
  line mode, Then...
  rrload> set kpath rrload.rr
  rrload> copy -c kernel -s ether -d ram -f rrbin
  rrload> boot

    Note: okay, now we've got the new version in memory
    and we are running it. The only thing left to do is
    to establish your final bootloader parameter values
    (menu item #3 stuff recorded earlier) and then use
    the normal rrload commands to flash itself persistently
    as well as flash the params persistently.

Step3:
  At the main menu select option 5 to get into command
  line mode, Then...
  rrload> eraseflash bootldr
  rrload> copy -c bootldr -s ram -d flash -f na
  rrload> set bootcmd boot_auto
  rrload> set loadfmt rrbin
  rrload> set loadport ether
          etc, for other desired settings, then...
  rrload> copy -c params -s ram -d flash -f na

    Note: All done. The rrload bootloader has
    been upgraded and is stored persistently with
    its new bootloader params settings.

NoteA: Although this example assumed rrload command line
       mode, it could just as well have been performed
       using rrload's menu based UI.

NoteB: Although this example performed the image
       "loads" via ether, it could just as well have
       been performed using one of the other I/O ports.
       Below is another example using the serial port.

...Upgrading via Serial

Step0:
  Start a minicom window on the desktop connected
  to the targets serial port, then hold down the
  Enter key while applying power to the board. Let
  go after a second or two when you see the rrload
  main menu appear. At the main menu select option
  3 and jot down any installation specific settings
  that you may want to re-establish later after the
  upgrade process.

Step1:
  At the main menu select option 5 to get into command
  line mode, Then...
  rrload> copy -c kernel -s serial -d ram -f rrbin

  Then immediately do the following...

  On the host system, enter the following (where ttyS1
  is the serial port connected to the EVM):

  linux$ cd dsplinux/[platform]/rrload/
  linux$ cat rrload.ForUpGrade.rr > /dev/ttyS1

  ...when the download completes, proceed with the following:

  rrload> eraseflash params
  rrload> boot

    Note: We've used the "load kernel" path to sneak
    in the second instance of rrload. Then we booted it.
    At this point the second instance of rrload should
    be running and we'll use it to perform the upgrade.
    The ram location previously used for rrload is now
    available so we can now download the new version of
    rrload to fill that spot.

Step2:
  At the main menu select option 5 to get into command
  line mode, Then...
  rrload> copy -c kernel -s serial -d ram -f rrbin

  Then immediately do the following...

  On the host system, enter the following (where ttyS1
  is the serial port connected to the EVM):

  linux$ cd dsplinux/[platform]/rrload/
  linux$ cat rrload.rr > /dev/ttyS1

  ...when the download completes, proceed with the following:

  rrload> boot

    Note: okay, now we've got the new version in memory
    and we are running it. The only thing left to do is
    to establish your final bootloader parameter values
    (menu item #3 stuff recorded earlier) and then use
    the normal rrload commands to flash itself persistently
    as well as flash the params persistently.

Step3:
  At the main menu select option 5 to get into command
  line mode, Then...
  rrload> eraseflash bootldr
  rrload> copy -c bootldr -s ram -d flash -f na
  rrload> set bootcmd boot_auto
  rrload> set loadfmt rrbin
  rrload> set loadport ether
          etc, for other desired settings, then...
  rrload> copy -c params -s ram -d flash -f na

    Note: All done. The rrload bootloader has
    been upgraded and is stored persistently with
    its new bootloader params settings.


Installing rrload into a New Flash Chip

Getting the first instance of the bootloader onto the EVM requires the use of the board's JTAG interface since there isn't yet any code running on the board to "pull" in that first instance; JTAG allows you to "push" it there. Once rrload is loaded, you can use the rrload UI to request it to store itself in the on board flash. With rrload present you now have the means to load other software components such as kernel and file system through various standard board I/O ports (as opposed to JTAG loading).

The issue of upgrading rrload with a new version of rrload can be performed without the use of JTAG and is described in the section "Upgrading An Existing rrload Installation"

More info:

For C547x: 
  Standard JTAG:
     First install jumpers on JP16, JP17, and JP18.
     Then use the emulator to download and run the setup
     program (built as part of rrload). 
     Use the setup_c5471.cmm debugger script to do
     this. This will initialize h/w so that SDRAM is
     visible. Stop the emulator after a few seconds of
     running and then download rrload and run. At this
     point you can use the rrload UI to erase and
     program the flash.
  Parallel JTAG:
     First removed jumpers from JP16, JP17, and JP18.
     Then consult the gdb documentation supplied with
     your DSPLinux distribution and look at the
     example session using the sdi-arm-gdb debugger.
     This will show how to use that debugger with the
     sdserver and the parallel jtag port to install
     the bootloader.

For omap1510: First use the emulator to download and run the setup program (built as part of rrload). You should use the Lauderbach script called setup_omap1510.cmm to perform this load/run. This will initialize h/w so that SDRAM is visible. Now stop the jtag debugger after a few seconds of running and then download rrload and run. At this point you can use the rrload UI to erase and program the flash. If you want now boot from flash make sure that the SW2-6 switch is in the "off" position.

For DSC21/24: First use the emulator to download and run the setup program (built as part of rrload). This will initialize h/w so that SDRAM is visible. Stop the emulator after a few seconds of running and then download rrload and run. Do this first with the SRAM/Flash jumper set to the SRAM mode. To burn flash you will want to hot-jumper from the SRAM mode to the Flash mode. Do this while rrload is running. At this point you can use the rrload UI to erase and program the flash.

For TI925: First use the emulator to reset the board and then run until you see the TI monitor message appear on the minicom window. At this point the h/w has been initialized correctly to allow SDRAM to written to. Stop the emulator and then download rrload and run.


Customizing rrload with new drivers

A Makefile links the following tree into a runnable bootloader image called "rrload". The individual *.o files have been pre-built at the RidgeRun factory and supplied in the rrload project directory along with the Makefile and this documentation (index.html).
                  head_*.o
                      |
                      |
                 rrload_base.o
                      |
                      |
     +-----------+----+-----+-----------+
     |           |          |           |
   sdram.h     io.h      flash.h     ether.h
   sdram_*.o   io_*.o    flash_*.o   ether_*.o
The driver modules shown at the bottom of this hierarchy have a *.h file associated with them that describes the interface of each driver. This allows a user to replace a driver with an new implementation. The new implementation of course needs to provide logic as described by the header file. The user need only rename the existing *.o to some other name such as *.o.original, and then place the new *.c or *.S file in the directory, and type "Make". The Makefile will compile the new driver source file and then link it as normal forming a new rrload image containing the replacement driver.

Here is an example:

In this example we'll replace the current sdram_dsc24.o file with a new version that supports the 4Mx32 Mobile SDRAM instead of the SDRAM that typically ships with a DSC24 EVM. For starters, since we're using the DSC24 in our example here, the specific directory structure as shipped from the RidgeRun factory would look like this:

                head_dsc24.o
                    |
                    |
               rrload_base.o
                    |
                    |
   +----------------+---------------+----------------+
   |                |               |                |
 sdram.h         io.h          flash.h           ether.h
 sdram_dsc24.o   io__dsc21.o   flash_toshiba.o   ether_cs8900.o

The steps performed to replace the current sdram_dsc24.o driver are as follows: For reference, the user supplied sdram_dsc24.S.example source file contains this logic, as an example:
  $ cat sdram_dsc24.S.example
  .text
  .align
  .global sdram_ini
  sdram_ini:
    // SDMODE Reg (0x0x000309a6)
    // =========================
    //   Bit(s) 15:    RDL select = "1 cycle"
    //   Bit(s) 14:    SDRAM bus width select = "32bits"
    //   Bit(s) 13:    DMA select = "ext mem -> SDRAM"
    //   Bit(s) 12:    Bank Number selection = "4 BANK"
    //   Bit(s) 11-10: Cas Latency selection = "3 cycle"
    //   Bit(s) 9-8:   Memory Type = "8k X 512 word"
    //   Bit(s) 7:     DQMC Control = "Normal"
    //   Bit(s) 6:     Automatic Power Down = "OFF"
    //
    // REFCTL Reg (0x0x000309a8)
    // =========================
    //   Bit(s) 8: Auto Refresh Enable = "Enabled"
    //   Bit(s) 7-0: Refresh cycle cnt = "0x10"
    //
    ldr r0,=0x000309a6
    ldr r1,=0x0000df00
    str r1,[r0]
    ldr r0,=0x000309a8
    ldr r1,=0x00000110
    str r1,[r0]
    ldr r0,=0x000309a6
    ldr r1,=0x0000df02
    str r1,[r0]
    ldr r0,=0x000309a6
    ldr r1,=0x0000df04
    str r1,[r0]
    ldr r0,=0x000309a6
    ldr r1,=0x0000df04
    str r1,[r0]
    ldr r0,=0x000309a6
    ldr r1,=0x0000df04
    str r1,[r0]
    ldr r0,=0x000309a6
    ldr r1,=0x0000df04
    str r1,[r0]
    ldr r0,=0x000309a6
    ldr r1,=0x0000df04
    str r1,[r0]
    ldr r0,=0x000309a6
    ldr r1,=0x0000df04
    str r1,[r0]
    ldr r0,=0x000309a6
    ldr r1,=0x0000df04
    str r1,[r0]
    ldr r0,=0x000309a6
    ldr r1,=0x0000df04
    str r1,[r0]
    ldr r0,=0x000309a6
    ldr r1,=0x0000df01
    str r1,[r0]
    mov pc, lr // return to caller.


Customizing the Flash Partitions

The rrload bootloader sets aside four areas of flash that it will use for storing the four components it is designed to manage; 1. the bootloader image, 2. the bootloader params, 3. the kernel image, and 4. the filesystem image.

Each of these components is given a very specific range of flash addresses that will be involved whenever a user erases/stores that component. These four ranges are fixed at the time the rrload bootloader is built and have been established in a way that will fit most user needs. However, some users will want to redefine the way the bootloader uses flash and so provisions have been made to allow a certain amount of re-configuring. Specifically, there are two control points we wanted to provide:

The default flash memory ranges used by rrload are shown below:

   C5471 EVM:
           kernel image: 0x00040000 - 0x0011ffff
       filesystem image: 0x00120000 - 0x007fffff

  *DSC21 EVM:
           kernel image: 0x00020000 - 0x000bffff
       filesystem image: 0x000c0000 - 0x001fffff

  *DSC24 EVM:
           kernel image: 0x00020000 - 0x000bffff
       filesystem image: 0x000c0000 - 0x001fffff

  OMAP1510 EVM:
       (F160 flash chips)
           kernel image: 0x00020000 - 0x0021ffff
       filesystem image: 0x00220000 - 0x0081ffff
       (F128 flash chips)
           kernel image: 0x00040000 - 0x0023ffff
       filesystem image: 0x00240000 - 0x00f40000

  OMAP710 EVM:
       (F160 flash chips)
           kernel image: 0x00020000 - 0x0021ffff
       filesystem image: 0x00220000 - 0x0081ffff
       (F128 flash chips)
           kernel image: 0x00040000 - 0x0023ffff
       filesystem image: 0x00240000 - 0x00f40000

* Note: These are flash range addresses, since the
        the DSC21 and DSC24 have flash positioned
        at physical address 0x00200000, instead of
        physical address 0x00000000, it means that
        flash address 0x00020000, for example, is
        really physical address 0x00220000.

In order to facilitate changing this partitioning the user will have to edit the rrload linker script (it is well documented there) and then rebuild the rrload bootloader to get a version that reflects your new partitioning of kernel and filesystem space.

To give one example:

Suppose you have the c5471 EVM and you have written a linux driver of some sort that wants to make use of the last 0x20000 of the board's flash range. In this case you don't want the rrload bootloader to touch that portion of flash yet you know that by default the rrload bootloader sets aside the whole flash range extending from flash address 0x00200000 all the way to the end of flash (0x007fffff) for the filesystem. And you know that even if you only use a fraction of that space to store your linux filesystem the whole area is essentially off limits to anything else since any rrload erase operation requested for the filesystem area will take out the whole range, not just the small part actually used at the moment.

What you want in this scenario is to re-configure the bootloader so that it treats the filesystem storage as extending from 0x00200000 to 0x007dffff. That will leave the remaining 0x20000 bytes untouched by the rrload filesystem store/erase operations.

To accomplish this you will want to edit the c5471 linker script:

    dsplinux/c5471/rrload/ld.c5471.script

There are two lines in that file that we can change in order to re-partition the flash is viewed by rrload. The two lines are

  FlashFileSysStart = 0x0;
  FlashFileSysEnd = 0x0;
Documentation Inside that file describes the use of both of these. In our example here, all we need to do is change the one line from this:
  FlashFileSysEnd = 0x0;
...to this instead. Then rebuild the bootloader.
  FlashFileSysEnd = 0x007dffff;

For reference the snippet of documentation from that file has been reproduced below:

+----------doc snippet from ld.c5471.script---------------+
|                                                         |
|  When a user requests that rrload erase the             |
|  filesystem component, how does it know what range of   |
|  flash to actually erase? The answer is that the        |
|  internal source code defines the flash memory range    |
|  that each of the components will occupy (components    |
|  such as the bootloader itself, the bootloader          |
|  params, the kernel and the filesystem).                |
|                                                         |
|  The filesystem storage always follows the range set    |
|  aside for the kernel image storage which means that    |
|  if the kernel you store is significantly less than     |
|  the space set aside for it you will have a large pad   |
|  between the actual stored kernel image and the start   |
|  of the filesystem image. And likewise, if you have     |
|  kernel that is too large for the space set aside       |
|  then you will collide with the space set aside for     |
|  the filesystem. So...                                  |
|                                                         |
|  -- The Controls Offered --                             |
|                                                         |
|  The rrload linker script offers the user the ability   |
|  to override the internal location of the filesystem    |
|  and move the range of address that are set aside to    |
|  store it. This then becomes the new default for all    |
|  filesystems downloaded and stored to flash and         |
|  becomes the new default used when the user requests    |
|  rrload to erase the filesystem range. The two          |
|  controls offered to the user are FlashFileSysStart     |
|  and FlashFileSysEnd.  Each can be adjusted             |
|  independently and if either is set to 0x0 then this    |
|  turns off the override for that control and allows     |
|  the system to resort to the internal factory default   |
|  for that value.                                        |
|                                                         |
|  --FlashFileSysStart--                                  |
|                                                         |
|  This setting also influences the size of the           |
|  filesystem storage area as well as the kernel          |
|  storage area. If you make the FlashFileSysStart        |
|  address lower than the internal factory default then   |
|  you will be increasing the filesystem storage area     |
|  and decreasing the kernel storage area that proceeds   |
|  it. And likewise if you increase the FlashFileSysStart |
|  address beyond the internal factory default then you   |
|  will be decreasing the filesystem storage area and     |
|  increasing the kernel storage area.                    |
|                                                         |
|  --FlashFileSysEnd--                                    |
|                                                         |
|  If you redefine the FlashFileSysEnd address then you   |
|  can control the high address of the flash range        |
|  involved in the storage set aside for the filesystem   |
|  and likewise sets the end of the range effected by a   |
|  user request to erase the flash component. Changing    |
|  this number has no effect on the amount of storage     |
|  set aside for the kernel which proceeds the filesystem |
|  storage area.                                          |
|                                                         |
|  -- Some Rules When Picking Values --                   |
|                                                         |
|  Legal values for FlashFileSysStart is any value that   |
|  begins on a flash block erase boundary.  For           |
|  this platform that would be numbers such as            |
|  0x00040000, 0x00060000, 0x00080000, etc, since the     |
|  erase unit size of our flash is 128Kbytes (2*64; two   |
|  chips interleaved).                                    |
|                                                         |
|  Legal values for FlashFileSysStart is any value that   |
|  ends on a flash chip erase block boundary.  For this   |
|  platform that would be numbers such as 0x00003fff,     |
|  0x00005fff, 0x00007fff, etc, since                     |
|                                                         |
|  -- Ramifications to your XIP Kernel/FS Builds --       |
|                                                         |
|  Don't forget that the range of address set asided      |
|  for storing filesystem images has a header reserved    |
|  at the start of the range used for rrload meta-data    |
|  meaning that the first address actually available      |
|  for the user bits of a filesystem image are            |
|  FlashFileSysStart+0x20 which is the value that you     |
|  should assign during the DSPLinux kernel `make         |
|  xconfig` session. See the FILE_SYS_START field on      |
|  the "general setup" panel of the `make xconfig`        |
|  session. This only applies however if you are          |
|  creating an XIP kernel/filesystem build since          |
|  otherwise the FILE_SYS_START will be set to a SDRAM    |
|  address and not a flash address and doesn't apply to   |
|  this discussion.                                       |
|                                                         |
|  -- Some Examples --                                    |
|                                                         |
|  If FlashFileSysStart is set to 0x00080000 then the     |
|  earliest location I could use for my downloaded XIP    |
|  filesystem is 0x00080020. This would honor the         |
|  reserved space mentioned.  This FlashFileSysStart      |
|  setting would allow the kernel images stored in        |
|  flash to extend to address 0x00080000-1.  And for      |
|  XIP Kernel/FS builds, the following applies...         |
|  e.g. `mkimage --LAddr 00080020 romdisk.img             |
|  romdisk.img.rr which is used when the xconfig          |
|  session has 0x00080020 value defined for               |
|  FILE_SYS_START (General Setup Panel; XIP).             |
|                                                         |
|  If FlashFileSysStart is set to 0x00120000 then the     |
|  earliest location I could use for my downloaded XIP    |
|  filesystem is 0x00120020. This would honor the         |
|  reserved space mentioned.  This FlashFileSysStart      |
|  setting would allow the kernel images stored in        |
|  flash to extend to address 0x00120000-1.  And for      |
|  XIP Kernel/FS builds, the following applies...         |
|  e.g. `mkimage --LAddr 00120020 romdisk.img             |
|  romdisk.img.rr which is used when the xconfig          |
|  session has 0x00120020 value defined for               |
|  FILE_SYS_START (General Setup Panel; XIP)              |
+---------------------------------------------------------+