BOOT: Add "bootz" command to boot Linux zImage on ARM

This command boots Linux zImage from where the zImage is loaded to. Passing
initrd and fdt is supported.

Tested on i.MX28 based DENX M28EVK
Tested on PXA270 based Voipac PXA270.

NOTE: This currently only supports ARM, but other architectures can be easily
added by defining bootz_setup().

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Tom Warren <TWarren@nvidia.com>
Cc: albert.u.boot@aribaud.net
Cc: afleming@gmail.com,
Cc: Simon Glass <sjg@chromium.org>,
Cc: Stephen Warren <swarren@nvidia.com>
Cc: Nicolas Pitre <nico@fluxnic.net>
Cc: Wolfgang Denk <wd@denx.de>
Cc: Detlev Zundel <dzu@denx.de>
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 160ba55..1c1bee6 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -359,3 +359,33 @@
 	boot_jump_linux(images);
 	return 0;
 }
+
+#ifdef CONFIG_CMD_BOOTZ
+
+struct zimage_header {
+	uint32_t	code[9];
+	uint32_t	zi_magic;
+	uint32_t	zi_start;
+	uint32_t	zi_end;
+};
+
+#define	LINUX_ARM_ZIMAGE_MAGIC	0x016f2818
+
+int bootz_setup(void *image, void **start, void **end)
+{
+	struct zimage_header *zi = (struct zimage_header *)image;
+
+	if (zi->zi_magic != LINUX_ARM_ZIMAGE_MAGIC) {
+		puts("Bad Linux ARM zImage magic!\n");
+		return 1;
+	}
+
+	*start = (void *)zi->zi_start;
+	*end = (void *)zi->zi_end;
+
+	debug("Kernel image @ 0x%08x [ 0x%08x - 0x%08x ]\n",
+		(uint32_t)image, (uint32_t)*start, (uint32_t)*end);
+
+	return 0;
+}
+#endif	/* CONFIG_CMD_BOOTZ */