EmbLogic's Blog

U-Boot Standalone Applications

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 0×00040000, so you can play with it like that:

TIP Note that the entry point of the program is at 0×40000 for the PowerPC architecture. It may be different for other architectures. See the CONFIG_STANDALONE_LOAD_ADDR define in your U-Boot tree if problems are encountered.

=> 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 = 0×00040000

=> go 40000 Hello World! This is a test.
## Starting application at 0×00040000 …
Hello World
argc = 7
argv[0] = “40000″
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 = 0×0
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.

=> tftp 40000 /tftpboot/hello_world.bin

=> go 40000 This is another test.
## Starting application at 0×00040000 …
Hello World
argc = 5
argv[0] = “40000″
argv[1] = “This”
argv[2] = “is”
argv[3] = “another”
argv[4] = “test.”
argv[5] = “”
Hit any key to exit …

## Application terminated, rc = 0×0
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 = 0×00040000

=> go 40000
## Starting application at 0×00040000 …
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=0×1, tmr=0xff1c, trr=0x3d09, tcr=0×0, tcn=0xef6, ter=0×0
Hit ‘?’:
[q, b, e, ?] .
tgcr=0×1, tmr=0xff1c, trr=0x3d09, tcr=0×0, tcn=0x2ad4, ter=0×0
Hit ‘?’:
[q, b, e, ?] .
tgcr=0×1, tmr=0xff1c, trr=0x3d09, tcr=0×0, tcn=0x1efc, ter=0×0
Hit ‘?’:
[q, b, e, ?] .
tgcr=0×1, tmr=0xff1c, trr=0x3d09, tcr=0×0, tcn=0x169d, ter=0×0
Hit ‘e’:
[q, b, e, ?] …Stopping timer
Hit ‘q’:
[q, b, e, ?] ## Application terminated, rc = 0×0
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 ():

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>