Patchwork [U-Boot,v2,30/45] sandbox: image: Add support for booting images in sandbox

login
register
mail settings
Submitter Simon Glass
Date March 18, 2013, 11:51 p.m.
Message ID <1363650725-30459-31-git-send-email-sjg@chromium.org>
Download mbox | patch
Permalink /patch/228868/
State Deferred
Delegated to: Tom Rini
Headers show

Comments

Simon Glass - March 18, 2013, 11:51 p.m.
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)
---
Changes in v2:
- Fix checkpatch checks about parenthesis alignment

 common/cmd_bootm.c | 21 ++++++++++++---------
 common/image.c     | 48 ++++++++++++++++++++++++++++--------------------
 include/image.h    |  2 +-
 3 files changed, 41 insertions(+), 30 deletions(-)

Patch

diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index f6eb7a6..c03e88f 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)
@@ -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);
 #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);
 
@@ -197,8 +198,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");
@@ -849,14 +850,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;
@@ -892,7 +894,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);
@@ -937,7 +940,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);
 
@@ -1014,7 +1017,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;
@@ -1028,7 +1031,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 3fbdd9b..14d1c48 100644
--- a/common/image.c
+++ b/common/image.c
@@ -51,6 +51,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[]);
@@ -90,6 +91,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,			"",		"",		},
 };
 
@@ -660,7 +662,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;
@@ -700,6 +702,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;
 
@@ -714,20 +718,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);
@@ -745,7 +749,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 */
@@ -801,6 +805,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
@@ -862,7 +867,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",
@@ -872,7 +877,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) {
@@ -897,7 +902,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);
@@ -915,7 +921,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);
 
@@ -1158,7 +1164,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);
 
@@ -1395,6 +1401,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;
@@ -1448,7 +1455,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",
@@ -1458,7 +1465,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) {
@@ -1486,7 +1493,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 "
@@ -1535,11 +1543,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);
@@ -1645,10 +1653,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);
+				printf("## Flattened Device Tree blob at %08lx\n",
+				       (long)fdt_addr);
 			}
 			break;
 		default:
diff --git a/include/image.h b/include/image.h
index 41d95f3..008aeef 100644
--- a/include/image.h
+++ b/include/image.h
@@ -351,7 +351,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);