[new uImage] Cleanup image header pointer use in bootm code

- use single image header pointer instead of a set of auxilliary variables.
- add multi component image helper routines: get component size/data address

Signed-off-by: Marian Balakowicz <m8@semihalf.com>
diff --git a/common/cmd_autoscript.c b/common/cmd_autoscript.c
index 3e68ced..53f8e83 100644
--- a/common/cmd_autoscript.c
+++ b/common/cmd_autoscript.c
@@ -54,7 +54,7 @@
 {
 	ulong len;
 	image_header_t *hdr = (image_header_t *)addr;
-	ulong *len_ptr;
+	ulong *data;
 	char *cmd;
 	int rcode = 0;
 	int verify;
@@ -84,9 +84,9 @@
 	}
 
 	/* get length of script */
-	len_ptr = (ulong *)image_get_data (hdr);
+	data = (ulong *)image_get_data (hdr);
 
-	if ((len = image_to_cpu (*len_ptr)) == 0) {
+	if ((len = image_to_cpu (*data)) == 0) {
 		puts ("Empty Script\n");
 		return 1;
 	}
@@ -97,10 +97,10 @@
 		return 1;
 	}
 
-	while (*len_ptr++);
+	while (*data++);
 
 	/* make sure cmd is null terminated */
-	memmove (cmd, (char *)len_ptr, len);
+	memmove (cmd, (char *)data, len);
 	*(cmd + len) = 0;
 
 #ifdef CFG_HUSH_PARSER /*?? */
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 2de1329..2d17bdd 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -93,14 +93,13 @@
  *  - disabled interrupts.
  */
 typedef void boot_os_fn (cmd_tbl_t *cmdtp, int flag,
-			int	argc, char *argv[],
-			ulong	addr,		/* of image to boot */
-			ulong	*len_ptr,	/* multi-file image length table */
-			int	verify);	/* getenv("verify")[0] != 'n' */
+			int argc, char *argv[],
+			image_header_t *hdr,	/* of image to boot */
+			int verify);		/* getenv("verify")[0] != 'n' */
 
 extern boot_os_fn do_bootm_linux;
 static boot_os_fn do_bootm_netbsd;
-#ifdef CONFIG_LYNXKDI
+#if defined(CONFIG_LYNXKDI)
 static boot_os_fn do_bootm_lynxkdi;
 extern void lynxkdi_boot (image_header_t *);
 #endif
@@ -116,8 +115,6 @@
 static boot_os_fn do_bootm_artos;
 #endif
 
-image_header_t header;
-
 ulong load_addr = CFG_LOAD_ADDR;	/* Default Load Address */
 
 
@@ -126,34 +123,32 @@
 /*******************************************************************/
 int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
-	ulong	iflag;
-	ulong	addr;
-	ulong	data, len;
-	ulong  *len_ptr;
-	uint	unc_len = CFG_BOOTM_LEN;
-	int	i, verify;
-	char	*name, *s;
-	int	(*appl)(int, char *[]);
-	image_header_t *hdr = &header;
+	ulong		iflag;
+	char		*name, *s;
+	int		(*appl)(int, char *[]);
+	uint		unc_len = CFG_BOOTM_LEN;
+	int		verify = getenv_verify();
 
-	verify = getenv_verify ();
+	image_header_t	*hdr;
+	ulong		img_addr;
+	ulong		os_data, os_len;
 
 	if (argc < 2) {
-		addr = load_addr;
+		img_addr = load_addr;
 	} else {
-		addr = simple_strtoul(argv[1], NULL, 16);
+		img_addr = simple_strtoul(argv[1], NULL, 16);
 	}
 
 	show_boot_progress (1);
-	printf ("## Booting image at %08lx ...\n", addr);
+	printf ("## Booting image at %08lx ...\n", img_addr);
 
-	/* Copy header so we can blank CRC field for re-calculation */
 #ifdef CONFIG_HAS_DATAFLASH
-	if (addr_dataflash(addr)){
-		read_dataflash (addr, image_get_header_size (), (char *)&header);
+	if (addr_dataflash (img_addr)){
+		hdr = (image_header_t *)CFG_LOAD_ADDR;
+		read_dataflash (img_addr, image_get_header_size (), (char *)hdr);
 	} else
 #endif
-	memmove (&header, (char *)addr, image_get_header_size ());
+	hdr = (image_header_t *)img_addr;
 
 	if (!image_check_magic(hdr)) {
 		puts ("Bad Magic Number\n");
@@ -170,23 +165,18 @@
 	show_boot_progress (3);
 
 #ifdef CONFIG_HAS_DATAFLASH
-	if (addr_dataflash(addr)){
-		len  = image_get_image_size (hdr);
-		read_dataflash(addr, len, (char *)CFG_LOAD_ADDR);
-		addr = CFG_LOAD_ADDR;
-	}
+	if (addr_dataflash (img_addr))
+		read_dataflash (img_addr + image_get_header_size (),
+				image_get_data_size (hdr),
+				(char *)image_get_data (hdr));
 #endif
 
-	/* for multi-file images we need the data part, too */
-	print_image_hdr ((image_header_t *)addr);
-
-	len = image_get_data_size (hdr);
-	data = addr + image_get_header_size ();
-	len_ptr = (ulong *)data;
+	/* uImage is in a system RAM, pointed to by hdr */
+	print_image_hdr (hdr);
 
 	if (verify) {
 		puts ("   Verifying Checksum ... ");
-		if (!image_check_dcrc ((image_header_t *)addr)) {
+		if (!image_check_dcrc (hdr)) {
 			printf ("Bad Data CRC\n");
 			show_boot_progress (-3);
 			return 1;
@@ -212,14 +202,12 @@
 		break;
 	case IH_TYPE_KERNEL:
 		name = "Kernel Image";
+		os_data = image_get_data (hdr);
+		os_len = image_get_data_size (hdr);
 		break;
 	case IH_TYPE_MULTI:
 		name = "Multi-File Image";
-		len  = image_to_cpu (len_ptr[0]);
-		/* OS kernel is always the first image */
-		data += 8; /* kernel_len + terminator */
-		for (i=1; len_ptr[i]; ++i)
-			data += 4;
+		image_multi_getimg (hdr, 0, &os_data, &os_len);
 		break;
 	default:
 		printf ("Wrong Image Type for %s command\n", cmdtp->name);
@@ -248,13 +236,13 @@
 
 	switch (image_get_comp (hdr)) {
 	case IH_COMP_NONE:
-		if (image_get_load (hdr) == addr) {
+		if (image_get_load (hdr) == img_addr) {
 			printf ("   XIP %s ... ", name);
 		} else {
 			printf ("   Loading %s ... ", name);
 
 			memmove_wd ((void *)image_get_load (hdr),
-				   (void *)data, len, CHUNKSZ);
+				   (void *)os_data, os_len, CHUNKSZ);
 
 			puts("OK\n");
 		}
@@ -262,7 +250,7 @@
 	case IH_COMP_GZIP:
 		printf ("   Uncompressing %s ... ", name);
 		if (gunzip ((void *)image_get_load (hdr), unc_len,
-			    (uchar *)data, &len) != 0) {
+					(uchar *)os_data, &os_len) != 0) {
 			puts ("GUNZIP ERROR - must RESET board to recover\n");
 			show_boot_progress (-6);
 			do_reset (cmdtp, flag, argc, argv);
@@ -276,9 +264,9 @@
 		 * use slower decompression algorithm which requires
 		 * at most 2300 KB of memory.
 		 */
-		i = BZ2_bzBuffToBuffDecompress ((char*)image_get_load (hdr),
-						&unc_len, (char *)data, len,
-						CFG_MALLOC_LEN < (4096 * 1024), 0);
+		int i = BZ2_bzBuffToBuffDecompress ((char*)image_get_load (hdr),
+					&unc_len, (char *)os_data, os_len,
+					CFG_MALLOC_LEN < (4096 * 1024), 0);
 		if (i != BZ_OK) {
 			printf ("BUNZIP2 ERROR %d - must RESET board to recover\n", i);
 			show_boot_progress (-6);
@@ -306,7 +294,7 @@
 		 */
 		if (((s = getenv("autostart")) != NULL) && (strcmp(s,"no") == 0)) {
 			char buf[32];
-			sprintf(buf, "%lX", len);
+			sprintf(buf, "%lX", image_get_data_size(hdr));
 			setenv("filesize", buf);
 			return 0;
 		}
@@ -332,42 +320,36 @@
 #ifdef CONFIG_SILENT_CONSOLE
 	    fixup_silent_linux();
 #endif
-	    do_bootm_linux  (cmdtp, flag, argc, argv,
-			     addr, len_ptr, verify);
+	    do_bootm_linux (cmdtp, flag, argc, argv, hdr, verify);
 	    break;
 
 	case IH_OS_NETBSD:
-	    do_bootm_netbsd (cmdtp, flag, argc, argv,
-			     addr, len_ptr, verify);
+	    do_bootm_netbsd (cmdtp, flag, argc, argv, hdr, verify);
 	    break;
 
 #ifdef CONFIG_LYNXKDI
 	case IH_OS_LYNXOS:
-	    do_bootm_lynxkdi (cmdtp, flag, argc, argv,
-			     addr, len_ptr, verify);
+	    do_bootm_lynxkdi (cmdtp, flag, argc, argv, hdr, verify);
 	    break;
 #endif
 
 	case IH_OS_RTEMS:
-	    do_bootm_rtems (cmdtp, flag, argc, argv,
-			     addr, len_ptr, verify);
+	    do_bootm_rtems (cmdtp, flag, argc, argv, hdr, verify);
 	    break;
 
 #if defined(CONFIG_CMD_ELF)
 	case IH_OS_VXWORKS:
-	    do_bootm_vxworks (cmdtp, flag, argc, argv,
-			      addr, len_ptr, verify);
+	    do_bootm_vxworks (cmdtp, flag, argc, argv, hdr, verify);
 	    break;
+
 	case IH_OS_QNX:
-	    do_bootm_qnxelf (cmdtp, flag, argc, argv,
-			      addr, len_ptr, verify);
+	    do_bootm_qnxelf (cmdtp, flag, argc, argv, hdr, verify);
 	    break;
 #endif
 
 #ifdef CONFIG_ARTOS
 	case IH_OS_ARTOS:
-	    do_bootm_artos  (cmdtp, flag, argc, argv,
-			     addr, len_ptr, verify);
+	    do_bootm_artos (cmdtp, flag, argc, argv, hdr, verify);
 	    break;
 #endif
 	}
@@ -570,11 +552,12 @@
 
 	if (image_check_type (hdr, IH_TYPE_MULTI)) {
 		int i;
-		ulong len;
-		ulong *len_ptr = (ulong *)((ulong)hdr + image_get_header_size ());
+		ulong data, len;
+		ulong count = image_multi_count (hdr);
 
 		puts ("   Contents:\n");
-		for (i = 0; (len = image_to_cpu (*len_ptr)); ++i, ++len_ptr) {
+		for (i = 0; i < count; i++) {
+			image_multi_getimg (hdr, i, &data, &len);
 			printf ("   Image %d: %8ld Bytes = ", i, len);
 			print_size (len, "\n");
 		}
@@ -684,14 +667,12 @@
 /*******************************************************************/
 
 static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag,
-			     int argc, char *argv[],
-			     ulong addr, ulong *len_ptr,
-			     int verify)
+			    int argc, char *argv[],
+			    image_header_t *hdr, int verify)
 {
-	image_header_t *hdr = &header;
-
 	void (*loader)(bd_t *, image_header_t *, char *, char *);
 	image_header_t *img_addr;
+	ulong kernel_data, kernel_len;
 	char *consdev;
 	char *cmdline;
 
@@ -708,8 +689,11 @@
 	 */
 
 	img_addr = 0;
-	if ((image_check_type (hdr, IH_TYPE_MULTI)) && (len_ptr[1]))
-		img_addr = (image_header_t *)addr;
+	if (image_check_type (hdr, IH_TYPE_MULTI)) {
+		image_multi_getimg (hdr, 1, &kernel_data, &kernel_len);
+		if (kernel_len)
+			img_addr = hdr;
+	}
 
 	consdev = "";
 #if   defined (CONFIG_8xx_CONS_SMC1)
@@ -760,19 +744,16 @@
 #ifdef CONFIG_LYNXKDI
 static void do_bootm_lynxkdi (cmd_tbl_t *cmdtp, int flag,
 			     int argc, char *argv[],
-			     ulong addr, ulong *len_ptr,
-			     int verify)
+			     image_header_t *hdr, int verify)
 {
-	lynxkdi_boot (&header);
+	lynxkdi_boot (hdr);
 }
 #endif /* CONFIG_LYNXKDI */
 
 static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag,
 			   int argc, char *argv[],
-		           ulong addr, ulong *len_ptr,
-			   int verify)
+			   image_header_t *hdr, int verify)
 {
-	image_header_t *hdr = &header;
 	void (*entry_point)(bd_t *);
 
 	entry_point = (void (*)(bd_t *))image_get_ep (hdr);
@@ -792,10 +773,8 @@
 #if defined(CONFIG_CMD_ELF)
 static void do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag,
 			     int argc, char *argv[],
-			     ulong addr, ulong *len_ptr,
-			     int verify)
+			     image_header_t *hdr, int verify)
 {
-	image_header_t *hdr = &header;
 	char str[80];
 
 	sprintf(str, "%x", image_get_ep (hdr)); /* write entry-point into string */
@@ -803,12 +782,10 @@
 	do_bootvx(cmdtp, 0, 0, NULL);
 }
 
-static void do_bootm_qnxelf (cmd_tbl_t *cmdtp, int flag,
-			     int argc, char *argv[],
-			     ulong addr, ulong *len_ptr,
-			     int verify)
+static void do_bootm_qnxelf(cmd_tbl_t *cmdtp, int flag,
+			    int argc, char *argv[],
+			    image_header_t *hdr, int verify)
 {
-	image_header_t *hdr = &header;
 	char *local_args[2];
 	char str[16];
 
@@ -822,8 +799,7 @@
 #if defined(CONFIG_ARTOS) && defined(CONFIG_PPC)
 static void do_bootm_artos (cmd_tbl_t *cmdtp, int flag,
 			   int argc, char *argv[],
-			   ulong addr, ulong *len_ptr,
-			   int verify)
+			   image_header_t *hdr, int verify)
 {
 	ulong top;
 	char *s, *cmdline;
@@ -831,7 +807,6 @@
 	int i, j, nxt, len, envno, envsz;
 	bd_t *kbd;
 	void (*entry)(bd_t *bd, char *cmdline, char **fwenv, ulong top);
-	image_header_t *hdr = &header;
 
 	/*
 	 * Booting an ARTOS kernel image + application
diff --git a/common/image.c b/common/image.c
index 048b866..6eee83d 100644
--- a/common/image.c
+++ b/common/image.c
@@ -107,3 +107,89 @@
 #endif	/* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
 }
 #endif /* USE_HOSTCC */
+
+/**
+ * image_multi_count - get component (sub-image) count
+ * @hdr: pointer to the header of the multi component image
+ *
+ * image_multi_count() returns number of components in a multi
+ * component image.
+ *
+ * Note: no checking of the image type is done, caller must pass
+ * a valid multi component image.
+ *
+ * returns:
+ *     number of components
+ */
+ulong image_multi_count (image_header_t *hdr)
+{
+	ulong i, count = 0;
+	ulong *size;
+
+	/* get start of the image payload, which in case of multi
+	 * component images that points to a table of component sizes */
+	size = (ulong *)image_get_data (hdr);
+
+	/* count non empty slots */
+	for (i = 0; size[i]; ++i)
+		count++;
+
+	return count;
+}
+
+/**
+ * image_multi_getimg - get component data address and size
+ * @hdr: pointer to the header of the multi component image
+ * @idx: index of the requested component
+ * @data: pointer to a ulong variable, will hold component data address
+ * @len: pointer to a ulong variable, will hold component size
+ *
+ * image_multi_getimg() returns size and data address for the requested
+ * component in a multi component image.
+ *
+ * Note: no checking of the image type is done, caller must pass
+ * a valid multi component image.
+ *
+ * returns:
+ *     data address and size of the component, if idx is valid
+ *     0 in data and len, if idx is out of range
+ */
+void image_multi_getimg (image_header_t *hdr, ulong idx,
+			ulong *data, ulong *len)
+{
+	int i;
+	ulong *size;
+	ulong offset, tail, count, img_data;
+
+	/* get number of component */
+	count = image_multi_count (hdr);
+
+	/* get start of the image payload, which in case of multi
+	 * component images that points to a table of component sizes */
+	size = (ulong *)image_get_data (hdr);
+
+	/* get address of the proper component data start, which means
+	 * skipping sizes table (add 1 for last, null entry) */
+	img_data = image_get_data (hdr) + (count + 1) * sizeof (ulong);
+
+	if (idx < count) {
+		*len = size[idx];
+		offset = 0;
+		tail = 0;
+
+		/* go over all indices preceding requested component idx */
+		for (i = 0; i < idx; i++) {
+			/* add up i-th component size */
+			offset += size[i];
+
+			/* add up alignment for i-th component */
+			tail += (4 - size[i] % 4);
+		}
+
+		/* calculate idx-th component data address */
+		*data = img_data + offset + tail;
+	} else {
+		*len = 0;
+		*data = 0;
+	}
+}
diff --git a/include/image.h b/include/image.h
index 9dc0343..c605d66 100644
--- a/include/image.h
+++ b/include/image.h
@@ -211,13 +211,30 @@
 {
 	return image_get_size (hdr);
 }
+
+/**
+ * image_get_data - get image payload start address
+ * @hdr: image header
+ *
+ * image_get_data() returns address of the image payload. For single
+ * component images it is image data start. For multi component
+ * images it points to the null terminated table of sub-images sizes.
+ *
+ * returns:
+ *     image payload data start address
+ */
+static inline ulong image_get_data (image_header_t *hdr)
+{
+	return ((ulong)hdr + image_get_header_size ());
+}
+
 static inline uint32_t image_get_image_size (image_header_t *hdr)
 {
 	return (image_get_size (hdr) + image_get_header_size ());
 }
-static inline ulong image_get_data (image_header_t *hdr)
+static inline ulong image_get_image_end (image_header_t *hdr)
 {
-	return ((ulong)hdr + image_get_header_size ());
+	return ((ulong)hdr + image_get_image_size (hdr));
 }
 
 #define image_set_hdr_l(f) \
@@ -307,4 +324,8 @@
 }
 #endif
 
-#endif /* __IMAGE_H__ */
+ulong image_multi_count (image_header_t *hdr);
+void image_multi_getimg (image_header_t *hdr, ulong idx,
+			ulong *data, ulong *len);
+
+#endif	/* __IMAGE_H__ */
diff --git a/lib_arm/armlinux.c b/lib_arm/armlinux.c
index 09038cc..4f9aae6 100644
--- a/lib_arm/armlinux.c
+++ b/lib_arm/armlinux.c
@@ -66,17 +66,14 @@
 static struct tag *params;
 #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
 
-extern image_header_t header;	/* from cmd_bootm.c */
-
-
 void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
-		     ulong addr, ulong *len_ptr, int verify)
+		     image_header_t *hdr, int verify)
 {
-	ulong len = 0;
+	ulong rd_addr;
+	ulong rd_data, rd_len = 0;
 	ulong initrd_start, initrd_end;
-	ulong data;
+	image_header_t *rd_hdr;
 	void (*theKernel)(int zero, int arch, uint params);
-	image_header_t *hdr = &header;
 	bd_t *bd = gd->bd;
 
 #ifdef CONFIG_CMDLINE_TAG
@@ -91,27 +88,26 @@
 	if (argc >= 3) {
 		show_boot_progress (9);
 
-		addr = simple_strtoul (argv[2], NULL, 16);
-
-		printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
+		rd_addr = simple_strtoul (argv[2], NULL, 16);
+		printf ("## Loading Ramdisk Image at %08lx ...\n", rd_addr);
 
 		/* Copy header so we can blank CRC field for re-calculation */
 #ifdef CONFIG_HAS_DATAFLASH
-		if (addr_dataflash (addr)) {
-			read_dataflash (addr, image_get_header_size (),
-					(char *) &header);
+		if (addr_dataflash (rd_addr)) {
+			rd_hdr = (image_header_t *)CFG_LOAD_ADDR;
+			read_dataflash (rd_addr, image_get_header_size (),
+					(char *)rd_hdr);
 		} else
 #endif
-			memcpy (&header, (char *) addr,
-				image_get_header_size ());
+		rd_hdr = (image_header_t *)rd_addr;
 
-		if (!image_check_magic (hdr)) {
+		if (!image_check_magic (rd_hdr)) {
 			printf ("Bad Magic Number\n");
 			show_boot_progress (-10);
 			do_reset (cmdtp, flag, argc, argv);
 		}
 
-		if (!image_check_hcrc (hdr)) {
+		if (!image_check_hcrc (rd_hdr)) {
 			printf ("Bad Header Checksum\n");
 			show_boot_progress (-11);
 			do_reset (cmdtp, flag, argc, argv);
@@ -119,21 +115,20 @@
 
 		show_boot_progress (10);
 
-		print_image_hdr (hdr);
+		print_image_hdr (rd_hdr);
 
-		data = image_get_data (hdr);
-		len = image_get_data_size (hdr);
+		rd_data = image_get_data (rd_hdr);
+		rd_len = image_get_data_size (rd_hdr);
 
 #ifdef CONFIG_HAS_DATAFLASH
-		if (addr_dataflash (addr)) {
-			read_dataflash (data, len, (char *) CFG_LOAD_ADDR);
-			data = CFG_LOAD_ADDR;
-		}
+		if (addr_dataflash (rd_addr))
+			read_dataflash (rd_addr + image_get_header_size (),
+					rd_len, (char *)rd_data);
 #endif
 
 		if (verify) {
 			printf ("   Verifying Checksum ... ");
-			if (!image_get_dcrc (hdr)) {
+			if (!image_get_dcrc (rd_hdr)) {
 				printf ("Bad Data CRC\n");
 				show_boot_progress (-12);
 				do_reset (cmdtp, flag, argc, argv);
@@ -143,9 +138,9 @@
 
 		show_boot_progress (11);
 
-		if (!image_check_os (hdr, IH_OS_LINUX) ||
-		    !image_check_arch (hdr, IH_ARCH_ARM) ||
-		    !image_check_type (hdr, IH_TYPE_RAMDISK)) {
+		if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
+		    !image_check_arch (rd_hdr, IH_ARCH_ARM) ||
+		    !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
 			printf ("No Linux ARM Ramdisk Image\n");
 			show_boot_progress (-13);
 			do_reset (cmdtp, flag, argc, argv);
@@ -155,50 +150,37 @@
 		/*
 		 *we need to copy the ramdisk to SRAM to let Linux boot
 		 */
-		memmove ((void *)image_get_load (hdr), (uchar *)data, len);
-		data = image_get_load (hdr);
+		memmove ((void *)image_get_load (rd_hdr), (uchar *)rd_data, rd_len);
+		rd_data = image_get_load (rd_hdr);
 #endif /* CONFIG_B2 || CONFIG_EVB4510 */
 
 		/*
 		 * Now check if we have a multifile image
 		 */
-	} else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) {
-		ulong tail = image_to_cpu (len_ptr[0]) % 4;
-		int i;
-
+	} else if (image_check_type (hdr, IH_TYPE_MULTI)) {
+		/*
+		 * Get second entry data start address and len
+		 */
 		show_boot_progress (13);
-
-		/* skip kernel length and terminator */
-		data = (ulong) (&len_ptr[2]);
-		/* skip any additional image length fields */
-		for (i = 1; len_ptr[i]; ++i)
-			data += 4;
-		/* add kernel length, and align */
-		data += image_to_cpu (len_ptr[0]);
-		if (tail) {
-			data += 4 - tail;
-		}
-
-		len = image_to_cpu (len_ptr[1]);
-
+		image_multi_getimg (hdr, 1, &rd_data, &rd_len);
 	} else {
 		/*
 		 * no initrd image
 		 */
 		show_boot_progress (14);
 
-		len = data = 0;
+		rd_len = rd_data = 0;
 	}
 
 #ifdef	DEBUG
-	if (!data) {
+	if (!rd_data) {
 		printf ("No initrd\n");
 	}
 #endif
 
-	if (data) {
-		initrd_start = data;
-		initrd_end = initrd_start + len;
+	if (rd_data) {
+		initrd_start = rd_data;
+		initrd_end = initrd_start + rd_len;
 	} else {
 		initrd_start = 0;
 		initrd_end = 0;
diff --git a/lib_avr32/avr32_linux.c b/lib_avr32/avr32_linux.c
index 44827ec..455590e 100644
--- a/lib_avr32/avr32_linux.c
+++ b/lib_avr32/avr32_linux.c
@@ -174,20 +174,16 @@
 }
 
 void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
-		    unsigned long addr, unsigned long *len_ptr, int verify)
+		    image_header_t *hdr, int verify)
 {
-	unsigned long data, len = 0;
-	unsigned long initrd_start, initrd_end;
-	unsigned long image_start, image_end;
+	ulong rd_data, rd_len = 0;
+	ulong initrd_start, initrd_end;
+	image_header_t *rd_hdr;
+
 	void (*theKernel)(int magic, void *tagtable);
-	image_header_t *hdr;
 	struct tag *params, *params_start;
 	char *commandline = getenv("bootargs");
 
-	hdr = (image_header_t *)addr;
-	image_start = addr;
-	image_end = addr + image_get_data_size (hdr);
-
 	theKernel = (void *)image_get_ep (hdr);
 
 	/*
@@ -196,29 +192,27 @@
 	if (argc >= 3) {
 		show_boot_progress (9);
 
-		addr = simple_strtoul(argv[2], NULL, 16);
-		hdr = (image_header_t *)addr;
+		rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16);
+		printf ("## Loading RAMDISK image at %08lx ...\n", rd_hdr);
 
-		printf("## Loading RAMDISK image at %08lx ...\n", addr);
-
-		if (!image_check_magic (hdr)) {
+		if (!image_check_magic (rd_hdr)) {
 			puts("Bad Magic Number\n");
 			show_boot_progress (-10);
 			do_reset(cmdtp, flag, argc, argv);
 		}
 
-		if (!image_check_hcrc (hdr)) {
+		if (!image_check_hcrc (rd_hdr)) {
 			puts("Bad Header Checksum\n");
 			show_boot_progress (-11);
 			do_reset(cmdtp, flag, argc, argv);
 		}
 
 		show_boot_progress (10);
-		print_image_hdr (hdr);
+		print_image_hdr (rd_hdr);
 
 		if (verify) {
 			puts("   Verifying Checksum ... ");
-			if (!image_check_dcrc (hdr)) {
+			if (!image_check_dcrc (rd_hdr)) {
 				puts("Bad Data CRC\n");
 				show_boot_progress (-12);
 				do_reset(cmdtp, flag, argc, argv);
@@ -228,44 +222,32 @@
 
 		show_boot_progress (11);
 
-		if (!image_check_os (hdr, IH_OS_LINUX) ||
-		    !image_check_arch (hdr, IH_ARCH_AVR32) ||
-		    !image_check_type (hdr, IH_TYPE_RAMDISK)) {
+		if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
+		    !image_check_arch (rd_hdr, IH_ARCH_AVR32) ||
+		    !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
 			puts("Not a Linux/AVR32 RAMDISK image\n");
 			show_boot_progress (-13);
 			do_reset(cmdtp, flag, argc, argv);
 		}
 
-		data = image_get_data (hdr);
-		len = image_get_data_size (hdr);
+		rd_data = image_get_data (rd_hdr);
+		rd_len = image_get_data_size (rd_hdr);
 
-	} else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) {
-		ulong tail = image_to_cpu (len_ptr[0]) % 4;
-		int i;
-
+	} else if (image_check_type (hdr, IH_TYPE_MULTI)) {
+		/*
+		 * Get second entry data start address and len
+		 */
 		show_boot_progress (13);
-
-		/* skip kernel length and terminator */
-		data = (ulong) (&len_ptr[2]);
-		/* skip any additional image length fields */
-		for (i = 1; len_ptr[i]; ++i)
-			data += 4;
-		/* add kernel length, and align */
-		data += image_to_cpu (len_ptr[0]);
-		if (tail) {
-			data += 4 - tail;
-		}
-
-		len = image_to_cpu (len_ptr[1]);
+		image_multi_getimg (hdr, 1, &rd_data, &rd_len);
 	} else {
 		/* no initrd image */
 		show_boot_progress (14);
-		len = data = 0;
+		rd_len = rd_data = 0;
 	}
 
-	if (data) {
-		initrd_start = data;
-		initrd_end = initrd_start + len;
+	if (rd_data) {
+		initrd_start = rd_data;
+		initrd_end = initrd_start + rd_len;
 	} else {
 		initrd_start = 0;
 		initrd_end = 0;
diff --git a/lib_blackfin/bf533_linux.c b/lib_blackfin/bf533_linux.c
index 26c6534..6299415 100644
--- a/lib_blackfin/bf533_linux.c
+++ b/lib_blackfin/bf533_linux.c
@@ -42,17 +42,15 @@
 extern void swap_to(int device_id);
 #endif
 
-extern image_header_t header;
 extern void flush_instruction_cache(void);
 extern void flush_data_cache(void);
 static char *make_command_line(void);
 
 void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
-		    ulong addr, ulong * len_ptr, int verify)
+		    image_header_t *hdr, int verify)
 {
 	int (*appl) (char *cmdline);
 	char *cmdline;
-	image_header_t *hdr = &header;
 
 #ifdef SHARED_RESOURCES
 	swap_to(FLASH);
diff --git a/lib_i386/i386_linux.c b/lib_i386/i386_linux.c
index b0cf263..27a2b0d 100644
--- a/lib_i386/i386_linux.c
+++ b/lib_i386/i386_linux.c
@@ -31,54 +31,50 @@
 /*cmd_boot.c*/
 extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
-extern image_header_t header;           /* from cmd_bootm.c */
-
 void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
-		ulong addr, ulong *len_ptr, int   verify)
+		image_header_t *hdr, int verify)
 {
 	void *base_ptr;
 
-	ulong len = 0;
+	ulong os_data, os_len;
+	ulong rd_data, rd_len;
 	ulong initrd_start, initrd_end;
-	ulong data;
-	image_header_t *hdr = &header;
+	image_header_t *rd_hdr;
 
 	/*
 	 * Check if there is an initrd image
 	 */
 	if (argc >= 3) {
-		addr = simple_strtoul(argv[2], NULL, 16);
-		hdr = (image_header_t *)addr;
+		rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16);
+		printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr);
 
-		printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
-
-		if (!image_check_magic (hdr)) {
+		if (!image_check_magic (rd_hdr)) {
 			printf ("Bad Magic Number\n");
 			do_reset (cmdtp, flag, argc, argv);
 		}
 
-		if (!image_check_hcrc (hdr)) {
+		if (!image_check_hcrc (rd_hdr)) {
 			printf ("Bad Header Checksum\n");
 			do_reset (cmdtp, flag, argc, argv);
 		}
 
-		print_image_hdr (hdr);
+		print_image_hdr (rd_hdr);
 
-		data = image_get_data (hdr);
-		len = image_get_data_size (hdr);
+		rd_data = image_get_data (rd_hdr);
+		rd_len = image_get_data_size (rd_hdr);
 
 		if (verify) {
 			printf ("   Verifying Checksum ... ");
-			if (!image_check_dcrc (hdr)) {
+			if (!image_check_dcrc (rd_hdr)) {
 				printf ("Bad Data CRC\n");
 				do_reset (cmdtp, flag, argc, argv);
 			}
 			printf ("OK\n");
 		}
 
-		if (!image_check_os (hdr, IH_OS_LINUX) ||
-		    !image_check_arch (hdr, IH_ARCH_I386) ||
-		    !image_check_type (hdr, IH_TYPE_RAMDISK)) {
+		if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
+		    !image_check_arch (rd_hdr, IH_ARCH_I386) ||
+		    !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
 			printf ("No Linux i386 Ramdisk Image\n");
 			do_reset (cmdtp, flag, argc, argv);
 		}
@@ -86,42 +82,30 @@
 		/*
 		 * Now check if we have a multifile image
 		 */
-	} else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) {
-		ulong tail    = image_to_cpu (len_ptr[0]) % 4;
-		int i;
-
-		/* skip kernel length and terminator */
-		data = (ulong)(&len_ptr[2]);
-		/* skip any additional image length fields */
-		for (i=1; len_ptr[i]; ++i)
-			data += 4;
-		/* add kernel length, and align */
-		data += image_to_cpu (len_ptr[0]);
-		if (tail) {
-			data += 4 - tail;
-		}
-
-		len   = image_to_cpu (len_ptr[1]);
-
+	} else if (image_check_type (hdr, IH_TYPE_MULTI)) {
+		/*
+		 * Get second entry data start address and len
+		 */
+		image_multi_getimg (hdr, 1, &rd_data, &rd_len);
 	} else {
 		/*
 		 * no initrd image
 		 */
-		data = 0;
+		rd_data = rd_len = 0;
 	}
 
 #ifdef	DEBUG
-	if (!data) {
+	if (!rd_data) {
 		printf ("No initrd\n");
 	}
 #endif
 
-	if (data) {
-		initrd_start = data;
-		initrd_end   = initrd_start + len;
+	if (rd_data) {
+		initrd_start = rd_data;
+		initrd_end = initrd_start + rd_len;
 		printf ("   Loading Ramdisk to %08lx, end %08lx ... ",
 			initrd_start, initrd_end);
-		memmove ((void *)initrd_start, (void *)data, len);
+		memmove ((void *)initrd_start, (void *)rd_data, rd_len);
 		printf ("OK\n");
 	} else {
 		initrd_start = 0;
@@ -129,14 +113,15 @@
 	}
 
 	/* if multi-part image, we need to advance base ptr */
-	if (image_check_type (&header, IH_TYPE_MULTI) && (len_ptr[1])) {
-		int i;
-		for (i=0, addr+=sizeof(int); len_ptr[i++]; addr+=sizeof(int));
+	if (image_check_type (hdr, IH_TYPE_MULTI)) {
+		image_multi_getimg (hdr, 0, &os_data, &os_len);
+	} else {
+		os_data = image_get_data (hdr);
+		os_len = image_get_data_size (hdr);
 	}
 
-	base_ptr = load_zimage ((void*)addr + image_get_header_size (),
-			       image_get_data_size (&header),
-			       initrd_start, initrd_end-initrd_start, 0);
+	base_ptr = load_zimage ((void*)os_data, os_len,
+			initrd_start, rd_len, 0);
 
 	if (NULL == base_ptr) {
 		printf ("## Kernel loading failed ...\n");
diff --git a/lib_m68k/m68k_linux.c b/lib_m68k/m68k_linux.c
index 0af2eae..b135556 100644
--- a/lib_m68k/m68k_linux.c
+++ b/lib_m68k/m68k_linux.c
@@ -44,26 +44,25 @@
 # define SHOW_BOOT_PROGRESS(arg)
 #endif
 
-extern image_header_t header;
-
 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
 void do_bootm_linux(cmd_tbl_t * cmdtp, int flag,
 		    int argc, char *argv[],
-		    ulong addr, ulong * len_ptr, int verify)
+		    image_header_t *hdr, int verify)
 {
 	ulong sp;
-	ulong len;
-	ulong initrd_start, initrd_end;
-	ulong cmd_start, cmd_end;
+
+	ulong rd_data, rd_len;
 	ulong initrd_high;
-	ulong data;
+	ulong initrd_start, initrd_end;
+	image_header_t *rd_hdr;
 	int initrd_copy_to_ram = 1;
+
+	ulong cmd_start, cmd_end;
 	char *cmdline;
 	char *s;
 	bd_t *kbd;
 	void (*kernel) (bd_t *, ulong, ulong, ulong, ulong);
-	image_header_t *hdr = &header;
 
 	if ((s = getenv("initrd_high")) != NULL) {
 		/* a value of "no" or a similar string will act like 0,
@@ -141,18 +140,16 @@
 		debug("Not skipping initrd\n");
 		SHOW_BOOT_PROGRESS(9);
 
-		addr = simple_strtoul(argv[2], NULL, 16);
-		hdr = (image_header_t *)addr;
+		rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16);
+		printf ("## Loading RAMDisk Image at %08lx ...\n", rd_hdr);
 
-		printf("## Loading RAMDisk Image at %08lx ...\n", addr);
-
-		if (!image_check_magic (hdr)) {
+		if (!image_check_magic (rd_hdr)) {
 			puts("Bad Magic Number\n");
 			SHOW_BOOT_PROGRESS(-10);
 			do_reset(cmdtp, flag, argc, argv);
 		}
 
-		if (!image_check_hcrc (hdr)) {
+		if (!image_check_hcrc (rd_hdr)) {
 			puts("Bad Header Checksum\n");
 			SHOW_BOOT_PROGRESS(-11);
 			do_reset(cmdtp, flag, argc, argv);
@@ -160,14 +157,14 @@
 
 		SHOW_BOOT_PROGRESS(10);
 
-		print_image_hdr (hdr);
+		print_image_hdr (rd_hdr);
 
-		data = image_get_data (hdr);
-		len = image_get_data_size (hdr);
+		rd_data = image_get_data (rd_hdr);
+		rd_len = image_get_data_size (rd_hdr);
 
 		if (verify) {
 			puts("   Verifying Checksum ... ");
-			if (!image_check_dcrc_wd (hdr, CHUNKSZ)) {
+			if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) {
 				puts("Bad Data CRC\n");
 				SHOW_BOOT_PROGRESS(-12);
 				do_reset(cmdtp, flag, argc, argv);
@@ -177,9 +174,9 @@
 
 		SHOW_BOOT_PROGRESS(11);
 
-		if (!image_check_os (hdr, IH_OS_LINUX) ||
-		    !image_check_arch (hdr, IH_ARCH_M68K) ||
-		    !image_check_type (hdr, IH_TYPE_RAMDISK)) {
+		if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
+		    !image_check_arch (rd_hdr, IH_ARCH_M68K) ||
+		    !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
 			puts("No Linux ColdFire Ramdisk Image\n");
 			SHOW_BOOT_PROGRESS(-13);
 			do_reset(cmdtp, flag, argc, argv);
@@ -188,44 +185,31 @@
 		/*
 		 * Now check if we have a multifile image
 		 */
-	} else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) {
-		u_long tail = image_to_cpu (len_ptr[0]) % 4;
-		int i;
-
-		SHOW_BOOT_PROGRESS(13);
-
-		/* skip kernel length and terminator */
-		data = (ulong) (&len_ptr[2]);
-		/* skip any additional image length fields */
-		for (i = 1; len_ptr[i]; ++i)
-			data += 4;
-		/* add kernel length, and align */
-		data += image_to_cpu (len_ptr[0]);
-		if (tail) {
-			data += 4 - tail;
-		}
-
-		len = image_to_cpu (len_ptr[1]);
-
+	} else if (image_check_type (hdr, IH_TYPE_MULTI)) {
+		/*
+		 * Get second entry data start address and len
+		 */
+		SHOW_BOOT_PROGRESS (13);
+		image_multi_getimg (hdr, 1, &rd_data, &rd_len);
 	} else {
 		/*
 		 * no initrd image
 		 */
 		SHOW_BOOT_PROGRESS(14);
 
-		len = data = 0;
+		rd_len = rd_data = 0;
 	}
 
-	if (!data) {
+	if (!rd_data) {
 		debug("No initrd\n");
 	}
 
-	if (data) {
+	if (rd_data) {
 		if (!initrd_copy_to_ram) {	/* zero-copy ramdisk support */
-			initrd_start = data;
-			initrd_end = initrd_start + len;
+			initrd_start = rd_data;
+			initrd_end = initrd_start + rd_len;
 		} else {
-			initrd_start = (ulong) kbd - len;
+			initrd_start = (ulong) kbd - rd_len;
 			initrd_start &= ~(4096 - 1);	/* align on page */
 
 			if (initrd_high) {
@@ -250,7 +234,7 @@
 				if (nsp > initrd_high)	/* limit as specified */
 					nsp = initrd_high;
 
-					nsp -= len;
+					nsp -= rd_len;
 				nsp &= ~(4096 - 1);	/* align on page */
 
 				if (nsp >= sp)
@@ -261,14 +245,14 @@
 
 			debug
 			    ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
-			     data, data + len - 1, len, len);
+			     rd_data, rd_data + rd_len - 1, rd_len, rd_len);
 
-			initrd_end = initrd_start + len;
+			initrd_end = initrd_start + rd_len;
 			printf("   Loading Ramdisk to %08lx, end %08lx ... ",
 			       initrd_start, initrd_end);
 
 			memmove_wd((void *)initrd_start,
-				   (void *)data, len, CHUNKSZ);
+				   (void *)rd_data, rd_len, CHUNKSZ);
 
 			puts("OK\n");
 		}
diff --git a/lib_microblaze/microblaze_linux.c b/lib_microblaze/microblaze_linux.c
index 7cd9799..a4fce5a 100644
--- a/lib_microblaze/microblaze_linux.c
+++ b/lib_microblaze/microblaze_linux.c
@@ -32,21 +32,21 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-extern image_header_t header;	/* from cmd_bootm.c */
-/*cmd_boot.c*/
 extern int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
 
 void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
-		     ulong addr, ulong * len_ptr, int verify)
+		     image_header_t *hdr, int verify)
 {
-	ulong len = 0, checksum;
+	int i;
+	ulong checksum;
+
+	ulong rd_data, rd_len;
 	ulong initrd_start, initrd_end;
-	ulong data;
+	image_header_t *rd_hdr;
+
 	/* First parameter is mapped to $r5 for kernel boot args */
 	void (*theKernel) (char *);
-	image_header_t *hdr = &header;
 	char *commandline = getenv ("bootargs");
-	int i;
 
 	theKernel = (void (*)(char *))image_get_ep (hdr);
 
@@ -54,33 +54,30 @@
 	if (argc >= 3) {
 		show_boot_progress (9);
 
-		addr = simple_strtoul (argv[2], NULL, 16);
-		hdr = (image_header_t *)addr;
+		rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16);
+		printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr);
 
-		printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
-
-		if (!image_check_magic (hdr)) {
+		if (!image_check_magic (rd_hdr)) {
 			printf ("Bad Magic Number\n");
 			show_boot_progress (-10);
 			do_reset (cmdtp, flag, argc, argv);
 		}
 
-		if (!image_check_magic (hdr)) {
+		if (!image_check_magic (rd_hdr)) {
 			printf ("Bad Header Checksum\n");
 			show_boot_progress (-11);
 			do_reset (cmdtp, flag, argc, argv);
 		}
 
 		show_boot_progress (10);
+		print_image_hdr (rd_hdr);
 
-		print_image_hdr (hdr);
-
-		data = image_get_data (hdr);
-		len = image_get_data_size (hdr);
+		rd_data = image_get_data (rd_hdr);
+		rd_en = image_get_data_size (rd_hdr);
 
 		if (verify) {
 			printf ("   Verifying Checksum ... ");
-			if (!image_check_dcrc (hdr)) {
+			if (!image_check_dcrc (rd_hdr)) {
 				printf ("Bad Data CRC\n");
 				show_boot_progress (-12);
 				do_reset (cmdtp, flag, argc, argv);
@@ -90,9 +87,9 @@
 
 		show_boot_progress (11);
 
-		if (!image_check_os (hdr, IH_OS_LINUX) ||
-		    !image_check_arch (hdr, IH_ARCH_MICROBLAZE) ||
-		    !image_check_type (hdr, IH_TYPE_RAMDISK)) {
+		if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
+		    !image_check_arch (rd_hdr, IH_ARCH_MICROBLAZE) ||
+		    !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
 			printf ("No Linux Microblaze Ramdisk Image\n");
 			show_boot_progress (-13);
 			do_reset (cmdtp, flag, argc, argv);
@@ -101,42 +98,30 @@
 		/*
 		 * Now check if we have a multifile image
 		 */
-	} else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) {
-		ulong tail = image_to_cpu (len_ptr[0]) % 4;
-
+	} else if (image_check_type (hdr, IH_TYPE_MULTI)) {
+		/*
+		 * Get second entry data start address and len
+		 */
 		show_boot_progress (13);
-
-		/* skip kernel length and terminator */
-		data = (ulong) (&len_ptr[2]);
-		/* skip any additional image length fields */
-		for (i = 1; len_ptr[i]; ++i)
-			data += 4;
-		/* add kernel length, and align */
-		data += image_to_cpu (len_ptr[0]);
-		if (tail) {
-			data += 4 - tail;
-		}
-
-		len = image_to_cpu (len_ptr[1]);
-
+		image_multi_getimg (hdr, 1, &rd_data, &rd_len);
 	} else {
 		/*
 		 * no initrd image
 		 */
 		show_boot_progress (14);
 
-		data = 0;
+		rd_data = rd_len = 0;
 	}
 
 #ifdef  DEBUG
-	if (!data) {
+	if (!rd_data) {
 		printf ("No initrd\n");
 	}
 #endif
 
-	if (data) {
-		initrd_start = data;
-		initrd_end = initrd_start + len;
+	if (rd_data) {
+		initrd_start = rd_data;
+		initrd_end = initrd_start + rd_len;
 	} else {
 		initrd_start = 0;
 		initrd_end = 0;
diff --git a/lib_mips/mips_linux.c b/lib_mips/mips_linux.c
index 0881b6d..7ea7571 100644
--- a/lib_mips/mips_linux.c
+++ b/lib_mips/mips_linux.c
@@ -33,8 +33,6 @@
 #define	LINUX_MAX_ENVS		256
 #define	LINUX_MAX_ARGS		256
 
-extern image_header_t header;           /* from cmd_bootm.c */
-
 extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
 static int	linux_argc;
@@ -49,13 +47,13 @@
 
 
 void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
-		     ulong addr, ulong * len_ptr, int verify)
+		     image_header_t *hdr, int verify)
 {
-	ulong len = 0;
+	ulong rd_data, rd_len;
 	ulong initrd_start, initrd_end;
-	ulong data;
+	image_header_t *rd_hdr;
+
 	void (*theKernel) (int, char **, char **, int *);
-	image_header_t *hdr = &header;
 	char *commandline = getenv ("bootargs");
 	char env_buf[12];
 
@@ -68,33 +66,30 @@
 	if (argc >= 3) {
 		show_boot_progress (9);
 
-		addr = simple_strtoul (argv[2], NULL, 16);
-		hdr = (image_header_t *)addr;
+		rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16);
+		printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr);
 
-		printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
-
-		if (!image_check_magic (hdr)) {
+		if (!image_check_magic (rd_hdr)) {
 			printf ("Bad Magic Number\n");
 			show_boot_progress (-10);
 			do_reset (cmdtp, flag, argc, argv);
 		}
 
-		if (!image_check_hcrc (hdr)) {
+		if (!image_check_hcrc (rd_hdr)) {
 			printf ("Bad Header Checksum\n");
 			show_boot_progress (-11);
 			do_reset (cmdtp, flag, argc, argv);
 		}
 
 		show_boot_progress (10);
+		print_image_hdr (rd_hdr);
 
-		print_image_hdr (hdr);
-
-		data = image_get_data (hdr);
-		len = image_get_data_size (hdr);
+		rd_data = image_get_data (rd_hdr);
+		rd_len = image_get_data_size (rd_hdr);
 
 		if (verify) {
 			printf ("   Verifying Checksum ... ");
-			if (!image_check_dcrc (hdr)) {
+			if (!image_check_dcrc (rd_hdr)) {
 				printf ("Bad Data CRC\n");
 				show_boot_progress (-12);
 				do_reset (cmdtp, flag, argc, argv);
@@ -104,9 +99,9 @@
 
 		show_boot_progress (11);
 
-		if (!image_check_os (hdr, IH_OS_LINUX) ||
-		    !image_check_arch (hdr, IH_ARCH_MIPS) ||
-		    !image_check_type (hdr, IH_TYPE_RAMDISK)) {
+		if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
+		    !image_check_arch (rd_hdr, IH_ARCH_MIPS) ||
+		    !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
 			printf ("No Linux MIPS Ramdisk Image\n");
 			show_boot_progress (-13);
 			do_reset (cmdtp, flag, argc, argv);
@@ -115,43 +110,30 @@
 		/*
 		 * Now check if we have a multifile image
 		 */
-	} else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) {
-		ulong tail = image_to_cpu (len_ptr[0]) % 4;
-		int i;
-
+	} else if (image_check_type (hdr, IH_TYPE_MULTI)) {
+		/*
+		 * Get second entry data start address and len
+		 */
 		show_boot_progress (13);
-
-		/* skip kernel length and terminator */
-		data = (ulong) (&len_ptr[2]);
-		/* skip any additional image length fields */
-		for (i = 1; len_ptr[i]; ++i)
-			data += 4;
-		/* add kernel length, and align */
-		data += image_to_cpu (len_ptr[0]);
-		if (tail) {
-			data += 4 - tail;
-		}
-
-		len = image_to_cpu (len_ptr[1]);
-
+		image_multi_getimg (hdr, 1, &rd_data, &rd_len);
 	} else {
 		/*
 		 * no initrd image
 		 */
 		show_boot_progress (14);
 
-		data = 0;
+		rd_data = rd_len = 0;
 	}
 
 #ifdef	DEBUG
-	if (!data) {
+	if (!rd_data) {
 		printf ("No initrd\n");
 	}
 #endif
 
-	if (data) {
-		initrd_start = data;
-		initrd_end = initrd_start + len;
+	if (rd_data) {
+		initrd_start = rd_data;
+		initrd_end = initrd_start + rd_len;
 	} else {
 		initrd_start = 0;
 		initrd_end = 0;
diff --git a/lib_nios/nios_linux.c b/lib_nios/nios_linux.c
index eef1757..55f7e3a 100644
--- a/lib_nios/nios_linux.c
+++ b/lib_nios/nios_linux.c
@@ -29,6 +29,6 @@
  *
  */
 void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
-		ulong addr, ulong *len_ptr, int   verify)
+		image__header_t *hdr, int verify)
 {
 }
diff --git a/lib_nios2/nios_linux.c b/lib_nios2/nios_linux.c
index dea1ec1..cb84324 100644
--- a/lib_nios2/nios_linux.c
+++ b/lib_nios2/nios_linux.c
@@ -25,12 +25,9 @@
 #include <command.h>
 #include <asm/byteorder.h>
 
-extern image_header_t header;	/* common/cmd_bootm.c */
-
 void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
-		ulong addr, ulong *len_ptr, int   verify)
+		image_header_t *hdr, int verify)
 {
-	image_header_t *hdr = &header;
 	void (*kernel)(void) = (void (*)(void))image_get_ep (hdr);
 
 	/* For now we assume the Microtronix linux ... which only
diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c
index 6e2afed..0a625fc 100644
--- a/lib_ppc/ppc_linux.c
+++ b/lib_ppc/ppc_linux.c
@@ -50,9 +50,7 @@
 #endif
 
 DECLARE_GLOBAL_DATA_PTR;
-extern image_header_t header;
 
-/*cmd_boot.c*/
 extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
 #if defined(CONFIG_CMD_BDI)
@@ -60,25 +58,27 @@
 #endif
 
 void  __attribute__((noinline))
-do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
+do_bootm_linux(cmd_tbl_t *cmdtp, int flag,
 		int	argc, char *argv[],
-		ulong	addr,
-		ulong	*len_ptr,
+		image_header_t *hdr,
 		int	verify)
 {
-	ulong	sp;
-	ulong	len;
-	ulong	initrd_start, initrd_end;
-	ulong	cmd_start, cmd_end;
 	ulong	initrd_high;
-	ulong	data;
 	int	initrd_copy_to_ram = 1;
+	ulong	initrd_start, initrd_end;
+	ulong	rd_data, rd_len;
+	image_header_t *rd_hdr;
+
+	ulong	cmd_start, cmd_end;
 	char    *cmdline;
+
+	ulong	sp;
 	char	*s;
 	bd_t	*kbd;
 	void	(*kernel)(bd_t *, ulong, ulong, ulong, ulong);
-	image_header_t *hdr = &header;
+
 #if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
+	image_header_t *fdt_hdr;
 	char	*of_flat_tree = NULL;
 	ulong	of_data = 0;
 #endif
@@ -177,7 +177,7 @@
 	/* Look for a '-' which indicates to ignore the ramdisk argument */
 	if (argc >= 3 && strcmp(argv[2], "-") ==  0) {
 			debug ("Skipping initrd\n");
-			len = data = 0;
+			rd_len = rd_data = 0;
 		}
 	else
 #endif
@@ -185,30 +185,28 @@
 		debug ("Not skipping initrd\n");
 		show_boot_progress (9);
 
-		addr = simple_strtoul(argv[2], NULL, 16);
+		rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16);
+		printf ("## Loading RAMDisk Image at %08lx ...\n", (ulong)rd_hdr);
 
-		printf ("## Loading RAMDisk Image at %08lx ...\n", addr);
-		hdr = (image_header_t *)addr;
-
-		if (!image_check_magic (hdr)) {
+		if (!image_check_magic (rd_hdr)) {
 			puts ("Bad Magic Number\n");
 			show_boot_progress (-10);
 			do_reset (cmdtp, flag, argc, argv);
 		}
 
-		if (!image_check_hcrc (hdr)) {
+		if (!image_check_hcrc (rd_hdr)) {
 			puts ("Bad Header Checksum\n");
 			show_boot_progress (-11);
 			do_reset (cmdtp, flag, argc, argv);
 		}
 		show_boot_progress (10);
 
-		print_image_hdr (hdr);
+		print_image_hdr (rd_hdr);
 
 		if (verify) {
 			puts ("   Verifying Checksum ... ");
 
-			if (!image_check_dcrc_wd (hdr, CHUNKSZ)) {
+			if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) {
 				puts ("Bad Data CRC\n");
 				show_boot_progress (-12);
 				do_reset (cmdtp, flag, argc, argv);
@@ -218,52 +216,39 @@
 
 		show_boot_progress (11);
 
-		if (!image_check_os (hdr, IH_OS_LINUX) ||
-		    !image_check_arch (hdr, IH_ARCH_PPC) ||
-		    !image_check_type (hdr, IH_TYPE_RAMDISK)) {
+		if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
+		    !image_check_arch (rd_hdr, IH_ARCH_PPC) ||
+		    !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
 			puts ("No Linux PPC Ramdisk Image\n");
 			show_boot_progress (-13);
 			do_reset (cmdtp, flag, argc, argv);
 		}
 
-		data = image_get_data (hdr);
-		len = image_get_data_size (hdr);
+		rd_data = image_get_data (rd_hdr);
+		rd_len = image_get_data_size (rd_hdr);
 
 		/*
 		 * Now check if we have a multifile image
 		 */
-	} else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) {
-		u_long tail    = image_to_cpu (len_ptr[0]) % 4;
-		int i;
-
+	} else if (image_check_type (hdr, IH_TYPE_MULTI)) {
+		/*
+		 * Get second entry data start address and len
+		 */
+		image_multi_getimg (hdr, 1, &rd_data, &rd_len);
 		show_boot_progress (13);
-
-		/* skip kernel length and terminator */
-		data = (ulong)(&len_ptr[2]);
-		/* skip any additional image length fields */
-		for (i=1; len_ptr[i]; ++i)
-			data += 4;
-		/* add kernel length, and align */
-		data += image_to_cpu (len_ptr[0]);
-		if (tail) {
-			data += 4 - tail;
-		}
-
-		len   = image_to_cpu (len_ptr[1]);
-
 	} else {
 		/*
-		 * no initrd image
+		 * No initrd image
 		 */
 		show_boot_progress (14);
 
-		len = data = 0;
+		rd_len = rd_data = 0;
 	}
 
 #if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
 	if(argc > 3) {
 		of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16);
-		hdr = (image_header_t *)of_flat_tree;
+		fdt_hdr = (image_header_t *)of_flat_tree;
 #if defined(CONFIG_OF_FLAT_TREE)
 		if (*((ulong *)(of_flat_tree)) == OF_DT_HEADER) {
 #elif defined(CONFIG_OF_LIBFDT)
@@ -273,37 +258,37 @@
 			if (addr2info((ulong)of_flat_tree) != NULL)
 				of_data = (ulong)of_flat_tree;
 #endif
-		} else if (image_check_magic (hdr)) {
-			printf("## Flat Device Tree at %08lX\n", hdr);
-			print_image_hdr (hdr);
+		} else if (image_check_magic (fdt_hdr)) {
+			printf ("## Flat Device Tree at %08lX\n", fdt_hdr);
+			print_image_hdr (fdt_hdr);
 
-			if ((image_get_load (hdr) <  ((unsigned long)hdr + image_get_image_size (hdr))) &&
-			   ((image_get_load (hdr) + image_get_data_size (hdr)) > (unsigned long)hdr)) {
+			if ((image_get_load (fdt_hdr) < image_get_image_end (fdt_hdr)) &&
+			   ((image_get_load (fdt_hdr) + image_get_data_size (fdt_hdr)) > (unsigned long)fdt_hdr)) {
 				puts ("ERROR: fdt overwritten - "
 					"must RESET the board to recover.\n");
 				do_reset (cmdtp, flag, argc, argv);
 			}
 
 			puts ("   Verifying Checksum ... ");
-			if (!image_check_hcrc (hdr)) {
+			if (!image_check_hcrc (fdt_hdr)) {
 				puts ("ERROR: fdt header checksum invalid - "
 					"must RESET the board to recover.\n");
 				do_reset (cmdtp, flag, argc, argv);
 			}
 
-			if (!image_check_dcrc (hdr)) {
+			if (!image_check_dcrc (fdt_hdr)) {
 				puts ("ERROR: fdt checksum invalid - "
 					"must RESET the board to recover.\n");
 				do_reset (cmdtp, flag, argc, argv);
 			}
 			puts ("OK\n");
 
-			if (!image_check_type (hdr, IH_TYPE_FLATDT)) {
+			if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) {
 				puts ("ERROR: uImage is not a fdt - "
 					"must RESET the board to recover.\n");
 				do_reset (cmdtp, flag, argc, argv);
 			}
-			if (image_get_comp (hdr) != IH_COMP_NONE) {
+			if (image_get_comp (fdt_hdr) != IH_COMP_NONE) {
 				puts ("ERROR: uImage is compressed - "
 					"must RESET the board to recover.\n");
 				do_reset (cmdtp, flag, argc, argv);
@@ -318,11 +303,11 @@
 				do_reset (cmdtp, flag, argc, argv);
 			}
 
-			memmove ((void *)image_get_load (hdr),
+			memmove ((void *)image_get_load (fdt_hdr),
 				(void *)(of_flat_tree + image_get_header_size ()),
-				image_get_data_size (hdr));
+				image_get_data_size (fdt_hdr));
 
-			of_flat_tree = (char *)image_get_load (hdr);
+			of_flat_tree = (char *)image_get_load (fdt_hdr);
 		} else {
 			puts ("Did not find a flat Flat Device Tree.\n"
 				"Must RESET the board to recover.\n");
@@ -330,68 +315,52 @@
 		}
 		printf ("   Booting using the fdt at 0x%x\n",
 				of_flat_tree);
-	} else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1]) && (len_ptr[2])) {
-		u_long tail    = image_to_cpu (len_ptr[0]) % 4;
-		int i;
+	} else if (image_check_type (hdr, IH_TYPE_MULTI)) {
+		ulong fdt_data, fdt_len;
 
-		/* skip kernel length, initrd length, and terminator */
-		of_flat_tree = (char *)(&len_ptr[3]);
-		/* skip any additional image length fields */
-		for (i=2; len_ptr[i]; ++i)
-			of_flat_tree += 4;
-		/* add kernel length, and align */
-		of_flat_tree += image_to_cpu (len_ptr[0]);
-		if (tail) {
-			of_flat_tree += 4 - tail;
-		}
+		image_multi_getimg (hdr, 2, &fdt_data, &fdt_len);
+		if (fdt_len) {
 
-		/* add initrd length, and align */
-		tail = image_to_cpu (len_ptr[1]) % 4;
-		of_flat_tree += image_to_cpu (len_ptr[1]);
-		if (tail) {
-			of_flat_tree += 4 - tail;
-		}
+			of_flat_tree = (char *)fdt_data;
 
 #ifndef CFG_NO_FLASH
-		/* move the blob if it is in flash (set of_data to !null) */
-		if (addr2info ((ulong)of_flat_tree) != NULL)
-			of_data = (ulong)of_flat_tree;
+			/* move the blob if it is in flash (set of_data to !null) */
+			if (addr2info ((ulong)of_flat_tree) != NULL)
+				of_data = (ulong)of_flat_tree;
 #endif
 
-
 #if defined(CONFIG_OF_FLAT_TREE)
-		if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) {
+			if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) {
 #elif defined(CONFIG_OF_LIBFDT)
-		if (fdt_check_header (of_flat_tree) != 0) {
+			if (fdt_check_header (of_flat_tree) != 0) {
 #endif
-			puts ("ERROR: image is not a fdt - "
-				"must RESET the board to recover.\n");
-			do_reset (cmdtp, flag, argc, argv);
-		}
+				puts ("ERROR: image is not a fdt - "
+					"must RESET the board to recover.\n");
+				do_reset (cmdtp, flag, argc, argv);
+			}
 
 #if defined(CONFIG_OF_FLAT_TREE)
-		if (((struct boot_param_header *)of_flat_tree)->totalsize !=
-			image_to_cpu (len_ptr[2])) {
+			if (((struct boot_param_header *)of_flat_tree)->totalsize != fdt_len) {
 #elif defined(CONFIG_OF_LIBFDT)
-		if (be32_to_cpu (fdt_totalsize (of_flat_tree)) !=
-			image_to_cpu (len_ptr[2])) {
+			if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != fdt_len) {
 #endif
-			puts ("ERROR: fdt size != image size - "
-				"must RESET the board to recover.\n");
-			do_reset (cmdtp, flag, argc, argv);
+				puts ("ERROR: fdt size != image size - "
+					"must RESET the board to recover.\n");
+				do_reset (cmdtp, flag, argc, argv);
+			}
 		}
 	}
 #endif
-	if (!data) {
+	if (!rd_data) {
 		debug ("No initrd\n");
 	}
 
-	if (data) {
+	if (rd_data) {
 	    if (!initrd_copy_to_ram) {	/* zero-copy ramdisk support */
-		initrd_start = data;
-		initrd_end = initrd_start + len;
+		initrd_start = rd_data;
+		initrd_end = initrd_start + rd_len;
 	    } else {
-		initrd_start  = (ulong)kbd - len;
+		initrd_start  = (ulong)kbd - rd_len;
 		initrd_start &= ~(4096 - 1);	/* align on page */
 
 		if (initrd_high) {
@@ -412,7 +381,7 @@
 			nsp &= ~0xF;
 			if (nsp > initrd_high)	/* limit as specified */
 				nsp = initrd_high;
-			nsp -= len;
+			nsp -= rd_len;
 			nsp &= ~(4096 - 1);	/* align on page */
 			if (nsp >= sp)
 				initrd_start = nsp;
@@ -421,14 +390,14 @@
 		show_boot_progress (12);
 
 		debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
-			data, data + len - 1, len, len);
+			rd_data, rd_data + rd_len - 1, rd_len, rd_len);
 
-		initrd_end    = initrd_start + len;
+		initrd_end    = initrd_start + rd_len;
 		printf ("   Loading Ramdisk to %08lx, end %08lx ... ",
 			initrd_start, initrd_end);
 
 		memmove_wd((void *)initrd_start,
-			   (void *)data, len, CHUNKSZ);
+			   (void *)rd_data, rd_len, CHUNKSZ);
 
 		puts ("OK\n");
 	    }