Commit 202a674b authored by Linus Walleij's avatar Linus Walleij Committed by Tom Rini

armv8: semihosting: add a command to load semihosted images

Instead of sprinkling custom code and calls over the Vexpress64
boardfile, create a command that loads images using semihosting
just like we would load from flash memory of over the network,
using a special command:

    smhload <image> <address>

This will make it possible to remove some custom calls and
code and make the boot easier.
Signed-off-by: default avatarLinus Walleij <>
parent e769f686
......@@ -13,6 +13,7 @@
* for them.
#include <common.h>
#include <command.h>
#include <asm/semihosting.h>
#define SYSOPEN 0x01
......@@ -234,3 +235,72 @@ long smh_len(const char *fname)
/* Return the file length (or -1 error indication) */
return len;
static int smh_load_file(const char * const name, ulong load_addr,
ulong *end_addr)
long fd;
long len;
long ret;
fd = smh_open(name, "rb");
if (fd == -1)
return -1;
len = smh_len_fd(fd);
if (len < 0) {
return -1;
ret = smh_read(fd, (void *)load_addr, len);
if (ret == 0) {
*end_addr = load_addr + len - 1;
printf("loaded file %s from %08lX to %08lX, %08lX bytes\n",
} else {
printf("read failed\n");
return 0;
return 0;
static int do_smhload(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (argc == 3 || argc == 4) {
ulong load_addr;
ulong end_addr = 0;
ulong ret;
char end_str[64];
load_addr = simple_strtoul(argv[2], NULL, 16);
if (!load_addr)
return -1;
ret = smh_load_file(argv[1], load_addr, &end_addr);
if (ret < 0)
return 1;
/* Optionally save returned end to the environment */
if (argc == 4) {
sprintf(end_str, "0x%08lx", end_addr);
setenv(argv[3], end_str);
} else {
return 0;
U_BOOT_CMD(smhload, 4, 0, do_smhload, "load a file using semihosting",
"<file> 0x<address> [end var]\n"
" - load a semihosted file to the address specified\n"
" if the optional [end var] is specified, the end\n"
" address of the file will be stored in this environment\n"
" variable.\n");
......@@ -30,25 +30,10 @@ vexpress_aemv8a.h but differentiate the two models by the presence or
absence of CONFIG_BASE_FVP. This change is tested and works on both the
Foundation and Base fastmodel simulators.
The level of semihosting support is minimal, restricted to just what it
takes to load images to memory. If more semihosting functionality is
required, such as file seek, outputting strings, reading characters, etc,
then it can be easily added later.
The semihosting code adds a command:
We require that the board include file define these env variables:
- kernel_name e.g. "uImage"
- kernel_addr_r e.g. "0x80000000"
- initrd_name e.g. "ramdisk.img"
- initrd_addr_r e.g. "0x88000000"
- fdt_name e.g. "devtree.dtb"
- fdt_addr_r e.g. "0x83000000"
smhload <image> <address> [env var]
Optionally, "fdt_high" and "initrd_high" can be specified as per
their rules for allowing or preventing copying of these images.
For the "fdt chosen" startup macro, this code will then define:
- initrd_end (based on retrieving initrd_addr_r plus actual initrd_size)
We will then load the kernel, initrd, and fdt into the specified
locations in memory in a similar way that the ATF fastmodel code
uses semihosting calls to load other boot stages and u-boot itself.
That will load an image from the host filesystem into RAM at the specified
address and optionally store the load end address in the specified
environment variable.
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment