[new uImage] Factor out common image_get_ramdisk() routine

Architecture specific do_bootm_linux() routines share common
ramdisk image processing code. Move this code to a common
helper routine.

Signed-off-by: Marian Balakowicz <m8@semihalf.com>
diff --git a/common/image.c b/common/image.c
index 6726f03..e4be4ca 100644
--- a/common/image.c
+++ b/common/image.c
@@ -23,10 +23,20 @@
  * MA 02111-1307 USA
  */
 #ifndef USE_HOSTCC
-# include <common.h>
-# include <watchdog.h>
+#include <common.h>
+#include <watchdog.h>
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+#include <status_led.h>
+#endif
+
+#ifdef CONFIG_HAS_DATAFLASH
+#include <dataflash.h>
+#endif
+
+extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 #else
-# include "mkimage.h"
+#include "mkimage.h"
 #endif
 
 #include <image.h>
@@ -280,4 +290,191 @@
 
 	return name;
 }
+
+/**
+ * image_get_ramdisk - get and verify ramdisk image
+ * @cmdtp: command table pointer
+ * @flag: command flag
+ * @argc: command argument count
+ * @argv: command argument list
+ * @rd_addr: ramdisk image start address
+ * @arch: expected ramdisk architecture
+ * @verify: checksum verification flag
+ *
+ * image_get_ramdisk() returns a pointer to the verified ramdisk image
+ * header. Routine receives image start address and expected architecture
+ * flag. Verification done covers data and header integrity and os/type/arch
+ * fields checking.
+ *
+ * If dataflash support is enabled routine checks for dataflash addresses
+ * and handles required dataflash reads.
+ *
+ * returns:
+ *     pointer to a ramdisk image header, if image was found and valid
+ *     otherwise, board is reset
+ */
+image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag,
+		int argc, char *argv[],
+		ulong rd_addr, uint8_t arch, int verify)
+{
+	image_header_t *rd_hdr;
+
+	show_boot_progress (9);
+
+#ifdef CONFIG_HAS_DATAFLASH
+	if (addr_dataflash (rd_addr)) {
+		rd_hdr = (image_header_t *)CFG_LOAD_ADDR;
+		debug ("   Reading Ramdisk image header from dataflash address "
+			"%08lx to %08lx\n", rd_addr, (ulong)rd_hdr);
+		read_dataflash (rd_addr, image_get_header_size (),
+				(char *)rd_hdr);
+	} else
 #endif
+	rd_hdr = (image_header_t *)rd_addr;
+
+	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 (rd_hdr)) {
+		puts ("Bad Header Checksum\n");
+		show_boot_progress (-11);
+		do_reset (cmdtp, flag, argc, argv);
+	}
+
+	show_boot_progress (10);
+	print_image_hdr (rd_hdr);
+
+#ifdef CONFIG_HAS_DATAFLASH
+	if (addr_dataflash (rd_addr)) {
+		debug ("   Reading Ramdisk image data from dataflash address "
+			"%08lx to %08lx\n", rd_addr + image_get_header_size,
+			(ulong)image_get_data (rd_hdr));
+
+		read_dataflash (rd_addr + image_get_header_size (),
+				image_get_data_size (rd_hdr),
+				(char *)image_get_data (rd_hdr));
+	}
+#endif
+
+	if (verify) {
+		puts("   Verifying Checksum ... ");
+		if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) {
+			puts ("Bad Data CRC\n");
+			show_boot_progress (-12);
+			do_reset (cmdtp, flag, argc, argv);
+		}
+		puts("OK\n");
+	}
+
+	show_boot_progress (11);
+
+	if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
+	    !image_check_arch (rd_hdr, arch) ||
+	    !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
+		printf ("No Linux %s Ramdisk Image\n",
+				image_get_arch_name(arch));
+		show_boot_progress (-13);
+		do_reset (cmdtp, flag, argc, argv);
+	}
+
+	return rd_hdr;
+}
+
+/**
+ * get_ramdisk - main ramdisk handling routine
+ * @cmdtp: command table pointer
+ * @flag: command flag
+ * @argc: command argument count
+ * @argv: command argument list
+ * @hdr: pointer to the posiibly multi componet kernel image
+ * @verify: checksum verification flag
+ * @arch: expected ramdisk architecture
+ * @rd_start: pointer to a ulong variable, will hold ramdisk start address
+ * @rd_end: pointer to a ulong variable, will hold ramdisk end
+ *
+ * get_ramdisk() is responsible for finding a valid ramdisk image.
+ * Curently supported are the following ramdisk sources:
+ *      - multicomponent kernel/ramdisk image,
+ *      - commandline provided address of decicated ramdisk image.
+ *
+ * returns:
+ *     rd_start and rd_end are set to ramdisk start/end addresses if
+ *     ramdisk image is found and valid
+ *     rd_start and rd_end are set to 0 if no ramdisk exists
+ *     board is reset if ramdisk image is found but corrupted
+ */
+void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
+		image_header_t *hdr, int verify, uint8_t arch,
+		ulong *rd_start, ulong *rd_end)
+{
+	ulong rd_addr;
+	ulong rd_data, rd_len;
+	image_header_t *rd_hdr;
+
+	if (argc >= 3) {
+		/*
+		 * Look for a '-' which indicates to ignore the
+		 * ramdisk argument
+		 */
+		if (strcmp(argv[2], "-") ==  0) {
+			debug ("## Skipping init Ramdisk\n");
+			rd_len = rd_data = 0;
+		} else {
+			/*
+			 * Check if there is an initrd image at the
+			 * address provided in the second bootm argument
+			 */
+			rd_addr = simple_strtoul (argv[2], NULL, 16);
+			printf ("## Loading init Ramdisk Image at %08lx ...\n",
+					rd_addr);
+
+			rd_hdr = image_get_ramdisk (cmdtp, flag, argc, argv,
+						rd_addr, arch, verify);
+
+			rd_data = image_get_data (rd_hdr);
+			rd_len = image_get_data_size (rd_hdr);
+
+#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)
+			/*
+			 *we need to copy the ramdisk to SRAM to let Linux boot
+			 */
+			memmove ((void *)image_get_load (rd_hdr),
+					(uchar *)rd_data, rd_len);
+
+			rd_data = image_get_load (rd_hdr);
+#endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */
+		}
+
+	} else if (image_check_type (hdr, IH_TYPE_MULTI)) {
+		/*
+		 * Now check if we have a multifile image
+		 * Get second entry data start address and len
+		 */
+		show_boot_progress (13);
+		printf ("## Loading init Ramdisk from multi component "
+				"Image at %08lx ...\n", (ulong)hdr);
+		image_multi_getimg (hdr, 1, &rd_data, &rd_len);
+	} else {
+		/*
+		 * no initrd image
+		 */
+		show_boot_progress (14);
+		rd_len = rd_data = 0;
+	}
+
+	if (!rd_data) {
+		debug ("## No init Ramdisk\n");
+		*rd_start = 0;
+		*rd_end = 0;
+	} else {
+		*rd_start = rd_data;
+		*rd_end = rd_data + rd_len;
+	}
+	debug ("   ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",
+			*rd_start, *rd_end);
+}
+#endif /* USE_HOSTCC */
+
diff --git a/include/image.h b/include/image.h
index 9ac25c9..b438564 100644
--- a/include/image.h
+++ b/include/image.h
@@ -34,6 +34,7 @@
 #define __IMAGE_H__
 
 #include <asm/byteorder.h>
+#include <command.h>
 #ifndef USE_HOSTCC
 #include <linux/string.h>
 #endif
@@ -331,6 +332,15 @@
 const char* image_get_arch_name (uint8_t arch);
 const char* image_get_type_name (uint8_t type);
 const char* image_get_comp_name (uint8_t comp);
+
+image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag,
+		int argc, char *argv[],
+		ulong rd_addr, uint8_t arch, int verify);
+
+void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
+		image_header_t *hdr, int verify, uint8_t arch,
+		ulong *rd_start, ulong *rd_end);
 #endif /* USE_HOSTCCa */
 
+
 #endif	/* __IMAGE_H__ */
diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c
index 4f9aae6..529b097 100644
--- a/lib_arm/bootm.c
+++ b/lib_arm/bootm.c
@@ -26,15 +26,9 @@
 #include <image.h>
 #include <zlib.h>
 #include <asm/byteorder.h>
-#ifdef CONFIG_HAS_DATAFLASH
-#include <dataflash.h>
-#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/*cmd_boot.c*/
-extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
-
 #if defined (CONFIG_SETUP_MEMORY_TAGS) || \
     defined (CONFIG_CMDLINE_TAG) || \
     defined (CONFIG_INITRD_TAG) || \
@@ -69,10 +63,7 @@
 void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
 		     image_header_t *hdr, int verify)
 {
-	ulong rd_addr;
-	ulong rd_data, rd_len = 0;
 	ulong initrd_start, initrd_end;
-	image_header_t *rd_hdr;
 	void (*theKernel)(int zero, int arch, uint params);
 	bd_t *bd = gd->bd;
 
@@ -82,109 +73,8 @@
 
 	theKernel = (void (*)(int, int, uint))image_get_ep (hdr);
 
-	/*
-	 * Check if there is an initrd image
-	 */
-	if (argc >= 3) {
-		show_boot_progress (9);
-
-		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 (rd_addr)) {
-			rd_hdr = (image_header_t *)CFG_LOAD_ADDR;
-			read_dataflash (rd_addr, image_get_header_size (),
-					(char *)rd_hdr);
-		} else
-#endif
-		rd_hdr = (image_header_t *)rd_addr;
-
-		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 (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);
-
-		rd_data = image_get_data (rd_hdr);
-		rd_len = image_get_data_size (rd_hdr);
-
-#ifdef CONFIG_HAS_DATAFLASH
-		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 (rd_hdr)) {
-				printf ("Bad Data CRC\n");
-				show_boot_progress (-12);
-				do_reset (cmdtp, flag, argc, argv);
-			}
-			printf ("OK\n");
-		}
-
-		show_boot_progress (11);
-
-		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);
-		}
-
-#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)
-		/*
-		 *we need to copy the ramdisk to SRAM to let Linux boot
-		 */
-		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)) {
-		/*
-		 * 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);
-
-		rd_len = rd_data = 0;
-	}
-
-#ifdef	DEBUG
-	if (!rd_data) {
-		printf ("No initrd\n");
-	}
-#endif
-
-	if (rd_data) {
-		initrd_start = rd_data;
-		initrd_end = initrd_start + rd_len;
-	} else {
-		initrd_start = 0;
-		initrd_end = 0;
-	}
+	get_ramdisk (cmdtp, flag, argc, argv, hdr, verify,
+			IH_ARCH_ARM, &initrd_start, &initrd_end);
 
 	show_boot_progress (15);
 
diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c
index 455590e..a934cae 100644
--- a/lib_avr32/bootm.c
+++ b/lib_avr32/bootm.c
@@ -31,8 +31,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
-
 /* CPU-specific hook to allow flushing of caches, etc. */
 extern void prepare_to_boot(void);
 
@@ -176,9 +174,7 @@
 void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
 		    image_header_t *hdr, int verify)
 {
-	ulong rd_data, rd_len = 0;
 	ulong initrd_start, initrd_end;
-	image_header_t *rd_hdr;
 
 	void (*theKernel)(int magic, void *tagtable);
 	struct tag *params, *params_start;
@@ -186,72 +182,8 @@
 
 	theKernel = (void *)image_get_ep (hdr);
 
-	/*
-	 * Check if there is an initrd image
-	 */
-	if (argc >= 3) {
-		show_boot_progress (9);
-
-		rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16);
-		printf ("## Loading RAMDISK image at %08lx ...\n", rd_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 (rd_hdr)) {
-			puts("Bad Header Checksum\n");
-			show_boot_progress (-11);
-			do_reset(cmdtp, flag, argc, argv);
-		}
-
-		show_boot_progress (10);
-		print_image_hdr (rd_hdr);
-
-		if (verify) {
-			puts("   Verifying Checksum ... ");
-			if (!image_check_dcrc (rd_hdr)) {
-				puts("Bad Data CRC\n");
-				show_boot_progress (-12);
-				do_reset(cmdtp, flag, argc, argv);
-			}
-			puts("OK\n");
-		}
-
-		show_boot_progress (11);
-
-		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);
-		}
-
-		rd_data = image_get_data (rd_hdr);
-		rd_len = image_get_data_size (rd_hdr);
-
-	} 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);
-		rd_len = rd_data = 0;
-	}
-
-	if (rd_data) {
-		initrd_start = rd_data;
-		initrd_end = initrd_start + rd_len;
-	} else {
-		initrd_start = 0;
-		initrd_end = 0;
-	}
+	get_ramdisk (cmdtp, flag, argc, argv, hdr, verify,
+			IH_ARCH_AVR32, &initrd_start, &initrd_end);
 
 	show_boot_progress (15);
 
diff --git a/lib_i386/bootm.c b/lib_i386/bootm.c
index 27a2b0d..ab6c2a9 100644
--- a/lib_i386/bootm.c
+++ b/lib_i386/bootm.c
@@ -37,80 +37,10 @@
 	void *base_ptr;
 
 	ulong os_data, os_len;
-	ulong rd_data, rd_len;
 	ulong initrd_start, initrd_end;
-	image_header_t *rd_hdr;
 
-	/*
-	 * Check if there is an initrd image
-	 */
-	if (argc >= 3) {
-		rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16);
-		printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr);
-
-		if (!image_check_magic (rd_hdr)) {
-			printf ("Bad Magic Number\n");
-			do_reset (cmdtp, flag, argc, argv);
-		}
-
-		if (!image_check_hcrc (rd_hdr)) {
-			printf ("Bad Header Checksum\n");
-			do_reset (cmdtp, flag, argc, argv);
-		}
-
-		print_image_hdr (rd_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 (rd_hdr)) {
-				printf ("Bad Data CRC\n");
-				do_reset (cmdtp, flag, argc, argv);
-			}
-			printf ("OK\n");
-		}
-
-		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);
-		}
-
-		/*
-		 * Now check if we have a multifile image
-		 */
-	} 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
-		 */
-		rd_data = rd_len = 0;
-	}
-
-#ifdef	DEBUG
-	if (!rd_data) {
-		printf ("No initrd\n");
-	}
-#endif
-
-	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 *)rd_data, rd_len);
-		printf ("OK\n");
-	} else {
-		initrd_start = 0;
-		initrd_end = 0;
-	}
+	get_ramdisk (cmdtp, flag, argc, argv, hdr, verify,
+			IH_ARCH_I386, &initrd_start, &initrd_end);
 
 	/* if multi-part image, we need to advance base ptr */
 	if (image_check_type (hdr, IH_TYPE_MULTI)) {
@@ -121,7 +51,7 @@
 	}
 
 	base_ptr = load_zimage ((void*)os_data, os_len,
-			initrd_start, rd_len, 0);
+			initrd_start, initrd_end - initrd_start, 0);
 
 	if (NULL == base_ptr) {
 		printf ("## Kernel loading failed ...\n");
diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c
index b135556..dac5276 100644
--- a/lib_m68k/bootm.c
+++ b/lib_m68k/bootm.c
@@ -44,18 +44,15 @@
 # define SHOW_BOOT_PROGRESS(arg)
 #endif
 
-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[],
 		    image_header_t *hdr, int verify)
 {
 	ulong sp;
 
-	ulong rd_data, rd_len;
+	ulong rd_data_start, rd_data_end, rd_len;
 	ulong initrd_high;
 	ulong initrd_start, initrd_end;
-	image_header_t *rd_hdr;
 	int initrd_copy_to_ram = 1;
 
 	ulong cmd_start, cmd_end;
@@ -132,82 +129,14 @@
 	kernel =
 	    (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr);
 
-	/*
-	 * Check if there is an initrd image
-	 */
+	get_ramdisk (cmdtp, flag, argc, argv, hdr, verify,
+			IH_ARCH_M68K, &rd_data_start, &rd_data_end);
+	rd_len = rd_data_end - rd_data_start;
 
-	if (argc >= 3) {
-		debug("Not skipping initrd\n");
-		SHOW_BOOT_PROGRESS(9);
-
-		rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16);
-		printf ("## Loading RAMDisk Image at %08lx ...\n", rd_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 (rd_hdr)) {
-			puts("Bad Header Checksum\n");
-			SHOW_BOOT_PROGRESS(-11);
-			do_reset(cmdtp, flag, argc, argv);
-		}
-
-		SHOW_BOOT_PROGRESS(10);
-
-		print_image_hdr (rd_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 (rd_hdr, CHUNKSZ)) {
-				puts("Bad Data CRC\n");
-				SHOW_BOOT_PROGRESS(-12);
-				do_reset(cmdtp, flag, argc, argv);
-			}
-			puts("OK\n");
-		}
-
-		SHOW_BOOT_PROGRESS(11);
-
-		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);
-		}
-
-		/*
-		 * Now check if we have a multifile image
-		 */
-	} 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);
-
-		rd_len = rd_data = 0;
-	}
-
-	if (!rd_data) {
-		debug("No initrd\n");
-	}
-
-	if (rd_data) {
+	if (rd_data_start) {
 		if (!initrd_copy_to_ram) {	/* zero-copy ramdisk support */
-			initrd_start = rd_data;
-			initrd_end = initrd_start + rd_len;
+			initrd_start = rd_data_start;
+			initrd_end = rd_data_end;
 		} else {
 			initrd_start = (ulong) kbd - rd_len;
 			initrd_start &= ~(4096 - 1);	/* align on page */
@@ -245,14 +174,14 @@
 
 			debug
 			    ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
-			     rd_data, rd_data + rd_len - 1, rd_len, rd_len);
+			     rd_data_start, rd_data_end - 1, rd_len, rd_len);
 
 			initrd_end = initrd_start + rd_len;
 			printf("   Loading Ramdisk to %08lx, end %08lx ... ",
 			       initrd_start, initrd_end);
 
 			memmove_wd((void *)initrd_start,
-				   (void *)rd_data, rd_len, CHUNKSZ);
+				   (void *)rd_data_start, rd_len, CHUNKSZ);
 
 			puts("OK\n");
 		}
diff --git a/lib_microblaze/bootm.c b/lib_microblaze/bootm.c
index a4fce5a..1f3e777 100644
--- a/lib_microblaze/bootm.c
+++ b/lib_microblaze/bootm.c
@@ -32,17 +32,10 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-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[],
 		     image_header_t *hdr, int verify)
 {
-	int i;
-	ulong checksum;
-
-	ulong rd_data, rd_len;
 	ulong initrd_start, initrd_end;
-	image_header_t *rd_hdr;
 
 	/* First parameter is mapped to $r5 for kernel boot args */
 	void (*theKernel) (char *);
@@ -50,82 +43,8 @@
 
 	theKernel = (void (*)(char *))image_get_ep (hdr);
 
-	/* Check if there is an initrd image */
-	if (argc >= 3) {
-		show_boot_progress (9);
-
-		rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16);
-		printf ("## Loading Ramdisk Image at %08lx ...\n", rd_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 (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);
-
-		rd_data = image_get_data (rd_hdr);
-		rd_en = image_get_data_size (rd_hdr);
-
-		if (verify) {
-			printf ("   Verifying Checksum ... ");
-			if (!image_check_dcrc (rd_hdr)) {
-				printf ("Bad Data CRC\n");
-				show_boot_progress (-12);
-				do_reset (cmdtp, flag, argc, argv);
-			}
-			printf ("OK\n");
-		}
-
-		show_boot_progress (11);
-
-		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);
-		}
-
-		/*
-		 * Now check if we have a multifile image
-		 */
-	} 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);
-
-		rd_data = rd_len = 0;
-	}
-
-#ifdef  DEBUG
-	if (!rd_data) {
-		printf ("No initrd\n");
-	}
-#endif
-
-	if (rd_data) {
-		initrd_start = rd_data;
-		initrd_end = initrd_start + rd_len;
-	} else {
-		initrd_start = 0;
-		initrd_end = 0;
-	}
+	get_ramdisk (cmdtp, flag, argc, argv, hdr, verify,
+			IH_ARCH_MICROBLAZE, &initrd_start, &initrd_end);
 
 	show_boot_progress (15);
 
diff --git a/lib_mips/bootm.c b/lib_mips/bootm.c
index 7ea7571..fb91c76 100644
--- a/lib_mips/bootm.c
+++ b/lib_mips/bootm.c
@@ -33,8 +33,6 @@
 #define	LINUX_MAX_ENVS		256
 #define	LINUX_MAX_ARGS		256
 
-extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
-
 static int	linux_argc;
 static char **	linux_argv;
 
@@ -49,9 +47,7 @@
 void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
 		     image_header_t *hdr, int verify)
 {
-	ulong rd_data, rd_len;
 	ulong initrd_start, initrd_end;
-	image_header_t *rd_hdr;
 
 	void (*theKernel) (int, char **, char **, int *);
 	char *commandline = getenv ("bootargs");
@@ -60,84 +56,8 @@
 	theKernel =
 		(void (*)(int, char **, char **, int *))image_get_ep (hdr);
 
-	/*
-	 * Check if there is an initrd image
-	 */
-	if (argc >= 3) {
-		show_boot_progress (9);
-
-		rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16);
-		printf ("## Loading Ramdisk Image at %08lx ...\n", rd_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 (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);
-
-		rd_data = image_get_data (rd_hdr);
-		rd_len = image_get_data_size (rd_hdr);
-
-		if (verify) {
-			printf ("   Verifying Checksum ... ");
-			if (!image_check_dcrc (rd_hdr)) {
-				printf ("Bad Data CRC\n");
-				show_boot_progress (-12);
-				do_reset (cmdtp, flag, argc, argv);
-			}
-			printf ("OK\n");
-		}
-
-		show_boot_progress (11);
-
-		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);
-		}
-
-		/*
-		 * Now check if we have a multifile image
-		 */
-	} 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);
-
-		rd_data = rd_len = 0;
-	}
-
-#ifdef	DEBUG
-	if (!rd_data) {
-		printf ("No initrd\n");
-	}
-#endif
-
-	if (rd_data) {
-		initrd_start = rd_data;
-		initrd_end = initrd_start + rd_len;
-	} else {
-		initrd_start = 0;
-		initrd_end = 0;
-	}
+	get_ramdisk (cmdtp, flag, argc, argv, hdr, verify,
+			IH_ARCH_MIPS, &initrd_start, &initrd_end);
 
 	show_boot_progress (15);
 
diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c
index 36e6776..65edcdb 100644
--- a/lib_ppc/bootm.c
+++ b/lib_ppc/bootm.c
@@ -68,8 +68,7 @@
 	ulong	initrd_high;
 	int	initrd_copy_to_ram = 1;
 	ulong	initrd_start, initrd_end;
-	ulong	rd_data, rd_len;
-	image_header_t *rd_hdr;
+	ulong	rd_data_start, rd_data_end, rd_len;
 
 	ulong	cmd_start, cmd_end;
 	char    *cmdline;
@@ -171,81 +170,9 @@
 
 	kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr);
 
-	/*
-	 * Check if there is an initrd image
-	 */
-
-#if defined(CONFIG_OF_LIBFDT)
-	/* Look for a '-' which indicates to ignore the ramdisk argument */
-	if (argc >= 3 && strcmp(argv[2], "-") ==  0) {
-			debug ("Skipping initrd\n");
-			rd_len = rd_data = 0;
-		}
-	else
-#endif
-	if (argc >= 3) {
-		debug ("Not skipping initrd\n");
-		show_boot_progress (9);
-
-		rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16);
-		printf ("## Loading RAMDisk Image at %08lx ...\n", (ulong)rd_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 (rd_hdr)) {
-			puts ("Bad Header Checksum\n");
-			show_boot_progress (-11);
-			do_reset (cmdtp, flag, argc, argv);
-		}
-		show_boot_progress (10);
-
-		print_image_hdr (rd_hdr);
-
-		if (verify) {
-			puts ("   Verifying Checksum ... ");
-
-			if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) {
-				puts ("Bad Data CRC\n");
-				show_boot_progress (-12);
-				do_reset (cmdtp, flag, argc, argv);
-			}
-			puts ("OK\n");
-		}
-
-		show_boot_progress (11);
-
-		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);
-		}
-
-		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)) {
-		/*
-		 * Get second entry data start address and len
-		 */
-		image_multi_getimg (hdr, 1, &rd_data, &rd_len);
-		show_boot_progress (13);
-	} else {
-		/*
-		 * No initrd image
-		 */
-		show_boot_progress (14);
-
-		rd_len = rd_data = 0;
-	}
+	get_ramdisk (cmdtp, flag, argc, argv, hdr, verify,
+			IH_ARCH_PPC, &rd_data_start, &rd_data_end);
+	rd_len = rd_data_end - rd_data_start;
 
 #if defined(CONFIG_OF_LIBFDT)
 	if(argc > 3) {
@@ -337,14 +264,11 @@
 		}
 	}
 #endif
-	if (!rd_data) {
-		debug ("No initrd\n");
-	}
 
-	if (rd_data) {
+	if (rd_data_start) {
 	    if (!initrd_copy_to_ram) {	/* zero-copy ramdisk support */
-		initrd_start = rd_data;
-		initrd_end = initrd_start + rd_len;
+		initrd_start = rd_data_start;
+		initrd_end = rd_data_end;
 	    } else {
 		initrd_start  = (ulong)kbd - rd_len;
 		initrd_start &= ~(4096 - 1);	/* align on page */
@@ -376,14 +300,14 @@
 		show_boot_progress (12);
 
 		debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
-			rd_data, rd_data + rd_len - 1, rd_len, rd_len);
+			rd_data_start, rd_data_end - 1, rd_len, rd_len);
 
 		initrd_end    = initrd_start + rd_len;
 		printf ("   Loading Ramdisk to %08lx, end %08lx ... ",
 			initrd_start, initrd_end);
 
 		memmove_wd((void *)initrd_start,
-			   (void *)rd_data, rd_len, CHUNKSZ);
+			   (void *)rd_data_start, rd_len, CHUNKSZ);
 
 		puts ("OK\n");
 	    }