Skip to main content.

5.12. U-Boot Standalone Applications

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

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

5.12.1. "Hello World" Demo

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

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

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

## Application terminated, rc = 0x0

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

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

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

## Application terminated, rc = 0x0

5.12.2. Timer Demo

ALERT! This example is only available on MPC8xx CPUs.

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


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

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

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

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

5.12.3. Processor cache considerations

Some processors have data and/or instruction caches. For some of these processors (e.g. MPC85xx), the operation of the cache(s) must be considered whenever data transferred to RAM is later executed as instructions. For these processors, data transferred to RAM might not be be represented correctly in the instruction cache without special treatment. This could result in incorrect execution of that data when it is considered an instruction stream. Multi core and multi processor systems with caches can also show this erroneous behaviour. To avoid this extremely difficult to debug type of problem, any instruction stream transferred to RAM as data should be flushed from any enabled data cache and the corresponding part of any enabled instruction cache should be invalidated.

In the "Hello World" example previously shown, the example program might be transferred to RAM by TFTP and then executed with the go command. While this procedure may work in most situations, it makes no provisions for cache behaviour as was just discussed. That is, obviously, there is no explicit cache management, nor does the go command do any cache management. This leaves open the possibility of malfunction.

The bootm command, which is normally used to start Linux, does implement the required cache flushes and invalidations, in ways that are appropriate for the particular processor.

To prepare an image of the "Hello World" example that is appropriate for the bootm command, the IMG target in the Makefile will wrap the executable in the appropriate U-Boot image header. An example addition to the Makefile might look like

IMG = $(BOARD)_standalone.img
IMG := $(addprefix $(obj),$(IMG))
$(IMG):
$(obj)%.img: $(BIN)
   $(MKIMAGE) -n "Hello stand alone" -A ppc -O u-boot -T standalone -C none -a $(LOAD_ADDR) -d $(BIN) -v $@

With this preparatory step added to the Makefile, the previously given "Hello World" console output example becomes

=> tftp 600000 helloworld.img
...
=> bootm 600000 Hello World! This is a test.
WARNING: adjusting available memory to 30000000
## Booting kernel from Legacy Image at 600000 ...
   Image Name:   Hello stand alone
   Image Type:   PowerPC U-Boot Standalone Program (uncompressed)
   Data Size:    25391 Bytes = 24.8 KiB
   Load Address: 00040000
   Entry Point:  00040000
   Verifying Checksum ... OK
Hello World
argc = 7
argv[0] = "600000"
argv[1] = "Hello"
argv[2] = "World!"
argv[3] = "This"
argv[4] = "is"
argv[5] = "a"
argv[6] = "test."
argv[7] = ""
Hit any key to exit ...

=> 

Of course, more is done by bootm in this example than is done by go in the original example. This additional work requires additional time, which may, or may not, be significant in any particular situation.

5.12.4. Running on core other than core 0

For Freescale PowerPC-based multi-core system, the following can be said.

U-Boot facilities are not available to stand alone applications, since U-Boot runs only on core 0

From Scott Wood (<1372799469.8183.120@snotra>):

If you have true standalone code, you can release it on other CPUs using the
"cpu  release" command.  That code will not have access to any U-Boot
functionality.  Its entry state will be as described for secondary CPUs in [the]
ePAPR [specification]. It will be the same as if an OS were spinning up its
secondary cores by writing directly to the spin table.

The ePAPR specification can be found at https://www.power.org/documentation/epapr-version-1-1/.

This implies that use of the normal stand alone stubs (e.g. stdio, I2C) will not work for stand alone applications running on any core other than core 0.

5.11. U-Boot Scripting Capabilities 1. Abstract 5.13. U-Boot Image Formats
Prev Home Next