sandbox: image: Add support for booting images in sandbox

Much of the image code uses addresses as ulongs and pointers interchangeably,
casting between the two forms as needed.

This doesn't work with sandbox, which has a U-Boot RAM buffer which is
separate from the host machine's memory.

Adjust the cost so that translating from a U-Boot address to a pointer uses
map_sysmem(). This allows bootm to work correctly on sandbox.

Note that there are no exhaustive tests for this code on sandbox, so it is
possible that some dark corners remain.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Marek Vasut <marex@denx.de> (v1)
master
Simon Glass 11 years ago committed by Tom Rini
parent d8b75360ee
commit 35e7b0f179
  1. 21
      common/cmd_bootm.c
  2. 48
      common/image.c
  3. 2
      include/image.h

@ -36,6 +36,7 @@
#include <lmb.h> #include <lmb.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/io.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#if defined(CONFIG_CMD_USB) #if defined(CONFIG_CMD_USB)
@ -97,7 +98,7 @@ static image_header_t *image_get_kernel(ulong img_addr, int verify);
static int fit_check_kernel(const void *fit, int os_noffset, int verify); static int fit_check_kernel(const void *fit, int os_noffset, int verify);
#endif #endif
static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[], bootm_headers_t *images, char * const argv[], bootm_headers_t *images,
ulong *os_data, ulong *os_len); ulong *os_data, ulong *os_len);
@ -203,8 +204,8 @@ static inline void boot_start_lmb(bootm_headers_t *images) { }
static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{ {
void *os_hdr; const void *os_hdr;
int ret; int ret;
memset((void *)&images, 0, sizeof(images)); memset((void *)&images, 0, sizeof(images));
images.verify = getenv_yesno("verify"); images.verify = getenv_yesno("verify");
@ -855,14 +856,15 @@ static int fit_check_kernel(const void *fit, int os_noffset, int verify)
* pointer to image header if valid image was found, plus kernel start * pointer to image header if valid image was found, plus kernel start
* address and length, otherwise NULL * address and length, otherwise NULL
*/ */
static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[], bootm_headers_t *images, ulong *os_data, char * const argv[], bootm_headers_t *images, ulong *os_data,
ulong *os_len) ulong *os_len)
{ {
image_header_t *hdr; image_header_t *hdr;
ulong img_addr; ulong img_addr;
const void *buf;
#if defined(CONFIG_FIT) #if defined(CONFIG_FIT)
void *fit_hdr; const void *fit_hdr;
const char *fit_uname_config = NULL; const char *fit_uname_config = NULL;
const char *fit_uname_kernel = NULL; const char *fit_uname_kernel = NULL;
const void *data; const void *data;
@ -898,7 +900,8 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
/* check image type, for FIT images get FIT kernel node */ /* check image type, for FIT images get FIT kernel node */
*os_data = *os_len = 0; *os_data = *os_len = 0;
switch (genimg_get_format((void *)img_addr)) { buf = map_sysmem(img_addr, 0);
switch (genimg_get_format(buf)) {
case IMAGE_FORMAT_LEGACY: case IMAGE_FORMAT_LEGACY:
printf("## Booting kernel from Legacy Image at %08lx ...\n", printf("## Booting kernel from Legacy Image at %08lx ...\n",
img_addr); img_addr);
@ -943,7 +946,7 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
break; break;
#if defined(CONFIG_FIT) #if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT: case IMAGE_FORMAT_FIT:
fit_hdr = (void *)img_addr; fit_hdr = buf;
printf("## Booting kernel from FIT Image at %08lx ...\n", printf("## Booting kernel from FIT Image at %08lx ...\n",
img_addr); img_addr);
@ -1020,7 +1023,7 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
*os_len = len; *os_len = len;
*os_data = (ulong)data; *os_data = (ulong)data;
images->fit_hdr_os = fit_hdr; images->fit_hdr_os = (void *)fit_hdr;
images->fit_uname_os = fit_uname_kernel; images->fit_uname_os = fit_uname_kernel;
images->fit_noffset_os = os_noffset; images->fit_noffset_os = os_noffset;
break; break;
@ -1034,7 +1037,7 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n", debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
*os_data, *os_len, *os_len); *os_data, *os_len, *os_len);
return (void *)img_addr; return buf;
} }
#ifdef CONFIG_SYS_LONGHELP #ifdef CONFIG_SYS_LONGHELP

@ -51,6 +51,7 @@
#include <u-boot/md5.h> #include <u-boot/md5.h>
#include <sha1.h> #include <sha1.h>
#include <asm/io.h>
#ifdef CONFIG_CMD_BDI #ifdef CONFIG_CMD_BDI
extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
@ -90,6 +91,7 @@ static const table_entry_t uimage_arch[] = {
{ IH_ARCH_AVR32, "avr32", "AVR32", }, { IH_ARCH_AVR32, "avr32", "AVR32", },
{ IH_ARCH_NDS32, "nds32", "NDS32", }, { IH_ARCH_NDS32, "nds32", "NDS32", },
{ IH_ARCH_OPENRISC, "or1k", "OpenRISC 1000",}, { IH_ARCH_OPENRISC, "or1k", "OpenRISC 1000",},
{ IH_ARCH_SANDBOX, "sandbox", "Sandbox", },
{ -1, "", "", }, { -1, "", "", },
}; };
@ -661,7 +663,7 @@ int genimg_get_comp_id(const char *name)
* returns: * returns:
* image format type or IMAGE_FORMAT_INVALID if no image is present * image format type or IMAGE_FORMAT_INVALID if no image is present
*/ */
int genimg_get_format(void *img_addr) int genimg_get_format(const void *img_addr)
{ {
ulong format = IMAGE_FORMAT_INVALID; ulong format = IMAGE_FORMAT_INVALID;
const image_header_t *hdr; const image_header_t *hdr;
@ -701,6 +703,8 @@ ulong genimg_get_image(ulong img_addr)
ulong h_size, d_size; ulong h_size, d_size;
if (addr_dataflash(img_addr)) { if (addr_dataflash(img_addr)) {
void *buf;
/* ger RAM address */ /* ger RAM address */
ram_addr = CONFIG_SYS_LOAD_ADDR; ram_addr = CONFIG_SYS_LOAD_ADDR;
@ -715,20 +719,20 @@ ulong genimg_get_image(ulong img_addr)
debug(" Reading image header from dataflash address " debug(" Reading image header from dataflash address "
"%08lx to RAM address %08lx\n", img_addr, ram_addr); "%08lx to RAM address %08lx\n", img_addr, ram_addr);
read_dataflash(img_addr, h_size, (char *)ram_addr); buf = map_sysmem(ram_addr, 0);
read_dataflash(img_addr, h_size, buf);
/* get data size */ /* get data size */
switch (genimg_get_format((void *)ram_addr)) { switch (genimg_get_format(buf)) {
case IMAGE_FORMAT_LEGACY: case IMAGE_FORMAT_LEGACY:
d_size = image_get_data_size( d_size = image_get_data_size(buf);
(const image_header_t *)ram_addr);
debug(" Legacy format image found at 0x%08lx, " debug(" Legacy format image found at 0x%08lx, "
"size 0x%08lx\n", "size 0x%08lx\n",
ram_addr, d_size); ram_addr, d_size);
break; break;
#if defined(CONFIG_FIT) #if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT: case IMAGE_FORMAT_FIT:
d_size = fit_get_size((const void *)ram_addr) - h_size; d_size = fit_get_size(buf) - h_size;
debug(" FIT/FDT format image found at 0x%08lx, " debug(" FIT/FDT format image found at 0x%08lx, "
"size 0x%08lx\n", "size 0x%08lx\n",
ram_addr, d_size); ram_addr, d_size);
@ -746,7 +750,7 @@ ulong genimg_get_image(ulong img_addr)
ram_addr + h_size); ram_addr + h_size);
read_dataflash(img_addr + h_size, d_size, read_dataflash(img_addr + h_size, d_size,
(char *)(ram_addr + h_size)); (char *)(buf + h_size));
} }
#endif /* CONFIG_HAS_DATAFLASH */ #endif /* CONFIG_HAS_DATAFLASH */
@ -802,6 +806,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
ulong rd_addr, rd_load; ulong rd_addr, rd_load;
ulong rd_data, rd_len; ulong rd_data, rd_len;
const image_header_t *rd_hdr; const image_header_t *rd_hdr;
void *buf;
#ifdef CONFIG_SUPPORT_RAW_INITRD #ifdef CONFIG_SUPPORT_RAW_INITRD
char *end; char *end;
#endif #endif
@ -863,7 +868,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
/* use FIT configuration provided in first bootm /* use FIT configuration provided in first bootm
* command argument * command argument
*/ */
rd_addr = (ulong)images->fit_hdr_os; rd_addr = map_to_sysmem(images->fit_hdr_os);
fit_uname_config = images->fit_uname_cfg; fit_uname_config = images->fit_uname_cfg;
debug("* ramdisk: using config '%s' from image " debug("* ramdisk: using config '%s' from image "
"at 0x%08lx\n", "at 0x%08lx\n",
@ -873,7 +878,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
* Check whether configuration has ramdisk defined, * Check whether configuration has ramdisk defined,
* if not, don't try to use it, quit silently. * if not, don't try to use it, quit silently.
*/ */
fit_hdr = (void *)rd_addr; fit_hdr = images->fit_hdr_os;
cfg_noffset = fit_conf_get_node(fit_hdr, cfg_noffset = fit_conf_get_node(fit_hdr,
fit_uname_config); fit_uname_config);
if (cfg_noffset < 0) { if (cfg_noffset < 0) {
@ -898,7 +903,8 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
* address provided in the second bootm argument * address provided in the second bootm argument
* check image type, for FIT images get FIT node. * check image type, for FIT images get FIT node.
*/ */
switch (genimg_get_format((void *)rd_addr)) { buf = map_sysmem(rd_addr, 0);
switch (genimg_get_format(buf)) {
case IMAGE_FORMAT_LEGACY: case IMAGE_FORMAT_LEGACY:
printf("## Loading init Ramdisk from Legacy " printf("## Loading init Ramdisk from Legacy "
"Image at %08lx ...\n", rd_addr); "Image at %08lx ...\n", rd_addr);
@ -916,7 +922,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
break; break;
#if defined(CONFIG_FIT) #if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT: case IMAGE_FORMAT_FIT:
fit_hdr = (void *)rd_addr; fit_hdr = buf;
printf("## Loading init Ramdisk from FIT " printf("## Loading init Ramdisk from FIT "
"Image at %08lx ...\n", rd_addr); "Image at %08lx ...\n", rd_addr);
@ -1159,7 +1165,7 @@ static void fdt_error(const char *msg)
static const image_header_t *image_get_fdt(ulong fdt_addr) static const image_header_t *image_get_fdt(ulong fdt_addr)
{ {
const image_header_t *fdt_hdr = (const image_header_t *)fdt_addr; const image_header_t *fdt_hdr = map_sysmem(fdt_addr, 0);
image_print_contents(fdt_hdr); image_print_contents(fdt_hdr);
@ -1396,6 +1402,7 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
char *fdt_blob = NULL; char *fdt_blob = NULL;
ulong image_start, image_data, image_end; ulong image_start, image_data, image_end;
ulong load_start, load_end; ulong load_start, load_end;
void *buf;
#if defined(CONFIG_FIT) #if defined(CONFIG_FIT)
void *fit_hdr; void *fit_hdr;
const char *fit_uname_config = NULL; const char *fit_uname_config = NULL;
@ -1449,7 +1456,7 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
/* use FIT configuration provided in first bootm /* use FIT configuration provided in first bootm
* command argument * command argument
*/ */
fdt_addr = (ulong)images->fit_hdr_os; fdt_addr = map_to_sysmem(images->fit_hdr_os);
fit_uname_config = images->fit_uname_cfg; fit_uname_config = images->fit_uname_cfg;
debug("* fdt: using config '%s' from image " debug("* fdt: using config '%s' from image "
"at 0x%08lx\n", "at 0x%08lx\n",
@ -1459,7 +1466,7 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
* Check whether configuration has FDT blob defined, * Check whether configuration has FDT blob defined,
* if not quit silently. * if not quit silently.
*/ */
fit_hdr = (void *)fdt_addr; fit_hdr = images->fit_hdr_os;
cfg_noffset = fit_conf_get_node(fit_hdr, cfg_noffset = fit_conf_get_node(fit_hdr,
fit_uname_config); fit_uname_config);
if (cfg_noffset < 0) { if (cfg_noffset < 0) {
@ -1487,7 +1494,8 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
* address provided in the second bootm argument * address provided in the second bootm argument
* check image type, for FIT images get a FIT node. * check image type, for FIT images get a FIT node.
*/ */
switch (genimg_get_format((void *)fdt_addr)) { buf = map_sysmem(fdt_addr, 0);
switch (genimg_get_format(buf)) {
case IMAGE_FORMAT_LEGACY: case IMAGE_FORMAT_LEGACY:
/* verify fdt_addr points to a valid image header */ /* verify fdt_addr points to a valid image header */
printf("## Flattened Device Tree from Legacy Image " printf("## Flattened Device Tree from Legacy Image "
@ -1536,11 +1544,11 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
*/ */
#if defined(CONFIG_FIT) #if defined(CONFIG_FIT)
/* check FDT blob vs FIT blob */ /* check FDT blob vs FIT blob */
if (fit_check_format((const void *)fdt_addr)) { if (fit_check_format(buf)) {
/* /*
* FIT image * FIT image
*/ */
fit_hdr = (void *)fdt_addr; fit_hdr = buf;
printf("## Flattened Device Tree from FIT " printf("## Flattened Device Tree from FIT "
"Image at %08lx\n", "Image at %08lx\n",
fdt_addr); fdt_addr);
@ -1646,10 +1654,10 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
/* /*
* FDT blob * FDT blob
*/ */
fdt_blob = (char *)fdt_addr; fdt_blob = buf;
debug("* fdt: raw FDT blob\n"); debug("* fdt: raw FDT blob\n");
printf("## Flattened Device Tree blob at " printf("## Flattened Device Tree blob at %08lx\n",
"%08lx\n", (long)fdt_blob); (long)fdt_addr);
} }
break; break;
default: default:

@ -352,7 +352,7 @@ void genimg_print_time(time_t timestamp);
#define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */ #define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */
#define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */ #define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */
int genimg_get_format(void *img_addr); int genimg_get_format(const void *img_addr);
int genimg_has_config(bootm_headers_t *images); int genimg_has_config(bootm_headers_t *images);
ulong genimg_get_image(ulong img_addr); ulong genimg_get_image(ulong img_addr);

Loading…
Cancel
Save