
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 --- common/cmd_bootm.c | 21 ++++++++++++--------- common/image.c | 46 +++++++++++++++++++++++++++------------------- include/image.h | 2 +- 3 files changed, 40 insertions(+), 29 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 7b07393..cac9e53 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -36,6 +36,7 @@ #include <lmb.h> #include <linux/ctype.h> #include <asm/byteorder.h> +#include <asm/io.h> #include <linux/compiler.h>
#if defined(CONFIG_CMD_USB) @@ -92,7 +93,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); #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, ulong *os_data, ulong *os_len);
@@ -192,8 +193,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[]) { - void *os_hdr; - int ret; + const void *os_hdr; + int ret;
memset((void *)&images, 0, sizeof(images)); images.verify = getenv_yesno("verify"); @@ -837,14 +838,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 * 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, ulong *os_len) { image_header_t *hdr; ulong img_addr; + const void *buf; #if defined(CONFIG_FIT) - void *fit_hdr; + const void *fit_hdr; const char *fit_uname_config = NULL; const char *fit_uname_kernel = NULL; const void *data; @@ -880,7 +882,8 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
/* check image type, for FIT images get FIT kernel node */ *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: printf("## Booting kernel from Legacy Image at %08lx ...\n", img_addr); @@ -925,7 +928,7 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - fit_hdr = (void *)img_addr; + fit_hdr = buf; printf("## Booting kernel from FIT Image at %08lx ...\n", img_addr);
@@ -1002,7 +1005,7 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
*os_len = len; *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_noffset_os = os_noffset; break; @@ -1016,7 +1019,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", *os_data, *os_len, *os_len);
- return (void *)img_addr; + return buf; }
#ifdef CONFIG_SYS_LONGHELP diff --git a/common/image.c b/common/image.c index 554f269..ed7dd7c 100644 --- a/common/image.c +++ b/common/image.c @@ -52,6 +52,7 @@
#include <u-boot/md5.h> #include <sha1.h> +#include <asm/io.h>
#ifdef CONFIG_CMD_BDI extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); @@ -91,6 +92,7 @@ static const table_entry_t uimage_arch[] = { { IH_ARCH_AVR32, "avr32", "AVR32", }, { IH_ARCH_NDS32, "nds32", "NDS32", }, { IH_ARCH_OPENRISC, "or1k", "OpenRISC 1000",}, + { IH_ARCH_SANDBOX, "sandbox", "Sandbox", }, { -1, "", "", }, };
@@ -661,7 +663,7 @@ int genimg_get_comp_id(const char *name) * returns: * 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; const image_header_t *hdr; @@ -701,6 +703,8 @@ ulong genimg_get_image(ulong img_addr) ulong h_size, d_size;
if (addr_dataflash(img_addr)) { + void *buf; + /* ger RAM address */ ram_addr = CONFIG_SYS_LOAD_ADDR;
@@ -715,20 +719,20 @@ ulong genimg_get_image(ulong img_addr) debug(" Reading image header from dataflash address " "%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 */ - switch (genimg_get_format((void *)ram_addr)) { + switch (genimg_get_format(buf)) { case IMAGE_FORMAT_LEGACY: - d_size = image_get_data_size( - (const image_header_t *)ram_addr); + d_size = image_get_data_size(buf); debug(" Legacy format image found at 0x%08lx, " "size 0x%08lx\n", ram_addr, d_size); break; #if defined(CONFIG_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, " "size 0x%08lx\n", ram_addr, d_size); @@ -746,7 +750,7 @@ ulong genimg_get_image(ulong img_addr) ram_addr + h_size);
read_dataflash(img_addr + h_size, d_size, - (char *)(ram_addr + h_size)); + (char *)(buf + h_size));
} #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_data, rd_len; const image_header_t *rd_hdr; + void *buf; #ifdef CONFIG_SUPPORT_RAW_INITRD char *end; #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 * 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; debug("* ramdisk: using config '%s' from image " "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, * 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, fit_uname_config); 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 * 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: printf("## Loading init Ramdisk from Legacy " "Image at %08lx ...\n", rd_addr); @@ -916,7 +922,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - fit_hdr = (void *)rd_addr; + fit_hdr = buf; printf("## Loading init Ramdisk from FIT " "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) { - 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);
@@ -1396,6 +1402,7 @@ int boot_get_fdt(int flag, int argc, char * const argv[], char *fdt_blob = NULL; ulong image_start, image_data, image_end; ulong load_start, load_end; + void *buf; #if defined(CONFIG_FIT) void *fit_hdr; 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 * 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; debug("* fdt: using config '%s' from image " "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, * if not quit silently. */ - fit_hdr = (void *)fdt_addr; + fit_hdr = images->fit_hdr_os; cfg_noffset = fit_conf_get_node(fit_hdr, fit_uname_config); 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 * 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: /* verify fdt_addr points to a valid image header */ 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) /* check FDT blob vs FIT blob */ - if (fit_check_format((const void *)fdt_addr)) { + if (fit_check_format(buf)) { /* * FIT image */ - fit_hdr = (void *)fdt_addr; + fit_hdr = buf; printf("## Flattened Device Tree from FIT " "Image at %08lx\n", fdt_addr); @@ -1646,10 +1654,10 @@ int boot_get_fdt(int flag, int argc, char * const argv[], /* * FDT blob */ - fdt_blob = (char *)fdt_addr; + fdt_blob = buf; debug("* fdt: raw FDT blob\n"); printf("## Flattened Device Tree blob at " - "%08lx\n", (long)fdt_blob); + "%08lx\n", (long)fdt_addr); } break; default: diff --git a/include/image.h b/include/image.h index d6993d4..bf734db 100644 --- a/include/image.h +++ b/include/image.h @@ -344,7 +344,7 @@ void genimg_print_time(time_t timestamp); #define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header 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); ulong genimg_get_image(ulong img_addr);