[U-Boot-Users] [PATCH] cmdbootz

Robert Schwebel robert at schwebel.de
Sat May 15 16:50:22 CEST 2004


Hi Wolfgang, 

I've rewritten the bootm command to recognize an ARM zImage the same way
as it already does with i368 zImages, hope that's ok with you. 

ChangeLog: 

* Patch by Robert Schwebel, 15 May 2004
  Modify the bootm command to be also able to start Linux zImages on
  ARM (x86 already works this way). Made processor detection more
  readable. Print warning when verify is switched off because of 
  faked headers (was silently droped). Make CRC vs. Checksum output
  consistent. 

Robert
-- 
 Dipl.-Ing. Robert Schwebel | http://www.pengutronix.de
 Pengutronix - Linux Solutions for Science and Industry
   Handelsregister:  Amtsgericht Hildesheim, HRA 2686
     Hornemannstraße 12,  31137 Hildesheim, Germany
    Phone: +49-5121-28619-0 |  Fax: +49-5121-28619-4
-------------- next part --------------
# 
# Author:       Robert Schwebel <r.schwebel at pengutronix.de>
# 
# Description:  Changelog Entry:
#
#               * Patch by Holger Schurig, Robert Schwebel, 13 May 2004:
#                 Add a 'bootz' command to boot normal Linux zImages in
#                 case you don't need the features of U-Boot's uImage. 
#
# State:        2004-05-13: submitted
#               
#               2004-05-13: 
#
#               WD: "The newly added code is not added to any Makefile, 
#               so it does not get compiled at all. If you add it, you 
#               will see that it is highly unportable; for example on 
#               a PowerPC system you get: cmd_bootz.c:29:17: tag.h: 
#               No such file or directory. Most of the code seems to be
#               for
#               ARM only (functions like setup_*_tag() don't exist for 
#               PowerPC or MIPS or ...). Please make this code usable
#               for 
#               other architectures as well and resubmit."
#
#               2004-05-13:
#
#               WD: "May I ask you to factor out the relevant code in 
#               lib_arm/armlinux.c so we have a set of functions which 
#               can be used by both the bootm and bootz commands?
#               And maybe we don't need to do even this - probably 
#               cmd_bootm.c can be split in a "header checking" and a 
#               "boot the image part" - so that the "bootm" command  
#               uses both, and "bootz" ignores the header checking."  
#
#               2004-05-15: rewritten, resubmit
#

diff -urN u-boot-maintainance/common/cmd_bootm.c u-boot-maintainance-bootz/common/cmd_bootm.c
--- u-boot-maintainance/common/cmd_bootm.c	2004-05-15 13:13:10.000000000 +0200
+++ u-boot-maintainance-bootz/common/cmd_bootm.c	2004-05-15 16:30:51.000000000 +0200
@@ -64,6 +64,25 @@
 #include <dataflash.h>
 #endif
 
+/* we have to find out the header architecture entry */ 
+#if   defined(__PPC__)
+#define HEADER_ARCH IH_CPU_PPC
+#elif defined(__ARM__)
+#define HEADER_ARCH IH_CPU_ARM
+#elif defined(__I386__)
+#define HEADER_ARCH IH_CPU_I386
+#elif defined(__mips__)
+#define HEADER_ARCH IH_CPU_MIPS
+#elif defined(__nios__)
+#define HEADER_ARCH IH_CPU_NIOS
+#elif defined(__M68K__)
+#define HEADER_ARCH IH_CPU_M68K
+#elif defined(__microblaze__)
+#define HEADER_ARCH IH_CPU_MICROBLAZE
+#else
+#error Unknown CPU type
+#endif
+
 /*
  * Some systems (for example LWMON) have very short watchdog periods;
  * we must make sure to split long operations like memmove() or
@@ -155,11 +174,8 @@
 	s = getenv ("verify");
 	verify = (s && (*s == 'n')) ? 0 : 1;
 
-	if (argc < 2) {
-		addr = load_addr;
-	} else {
-		addr = simple_strtoul(argv[1], NULL, 16);
-	}
+	/* use user supplied or default load address */
+	addr = (argc < 2) ? load_addr : simple_strtoul(argv[1], NULL, 16);
 
 	SHOW_BOOT_PROGRESS (1);
 	printf ("## Booting image at %08lx ...\n", addr);
@@ -171,26 +187,32 @@
 	} else
 #endif
 	memmove (&header, (char *)addr, sizeof(image_header_t));
-
+	
+	/* 
+	 * If this is no uImage, try to find out what it is and create a
+	 * faked header to start image with the normal mechanisms
+	 */ 
 	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-#ifdef __I386__	/* correct image format not implemented yet - fake it */
-		if (fake_header(hdr, (void*)addr, -1) != NULL) {
+
+#if defined(__I386__) || \
+    defined(__ARM__)
+		if (fake_header(hdr, (void*)addr, -1)) {
 			/* to compensate for the addition below */
 			addr -= sizeof(image_header_t);
-			/* turnof verify,
-			 * fake_header() does not fake the data crc
-			 */
+			printf ("Warning: no uImage, turning off verify\n");
 			verify = 0;
 		} else
-#endif	/* __I386__ */
-	    {
-		puts ("Bad Magic Number\n");
-		SHOW_BOOT_PROGRESS (-1);
-		return 1;
-	    }
+#endif
+    		{
+			puts ("Bad Magic Number\n");
+			SHOW_BOOT_PROGRESS (-1);
+			return 1;
+	    	}
 	}
+
 	SHOW_BOOT_PROGRESS (2);
 
+	/* check header CRC32 */
 	data = (ulong)&header;
 	len  = sizeof(image_header_t);
 
@@ -198,14 +220,15 @@
 	hdr->ih_hcrc = 0;
 
 	if (crc32 (0, (char *)data, len) != checksum) {
-		puts ("Bad Header Checksum\n");
+		puts ("Bad Header CRC\n");
 		SHOW_BOOT_PROGRESS (-2);
 		return 1;
 	}
+
 	SHOW_BOOT_PROGRESS (3);
 
 	/* for multi-file images we need the data part, too */
-	print_image_hdr ((image_header_t *)addr);
+	print_image_hdr (hdr);
 
 	data = addr + sizeof(image_header_t);
 	len  = ntohl(hdr->ih_size);
@@ -226,41 +249,28 @@
 		}
 		puts ("OK\n");
 	}
+
 	SHOW_BOOT_PROGRESS (4);
 
+	/* check if header was created for correct CPU type */
 	len_ptr = (ulong *)data;
 
-#if defined(__PPC__)
-	if (hdr->ih_arch != IH_CPU_PPC)
-#elif defined(__ARM__)
-	if (hdr->ih_arch != IH_CPU_ARM)
-#elif defined(__I386__)
-	if (hdr->ih_arch != IH_CPU_I386)
-#elif defined(__mips__)
-	if (hdr->ih_arch != IH_CPU_MIPS)
-#elif defined(__nios__)
-	if (hdr->ih_arch != IH_CPU_NIOS)
-#elif defined(__M68K__)
-	if (hdr->ih_arch != IH_CPU_M68K)
-#elif defined(__microblaze__)
-	if (hdr->ih_arch != IH_CPU_MICROBLAZE)
-#else
-# error Unknown CPU type
-#endif
+	if (hdr->ih_arch != HEADER_ARCH)
 	{
 		printf ("Unsupported Architecture 0x%x\n", hdr->ih_arch);
 		SHOW_BOOT_PROGRESS (-4);
 		return 1;
 	}
+
 	SHOW_BOOT_PROGRESS (5);
 
+	/* check what kind of an image we have here */
 	switch (hdr->ih_type) {
 	case IH_TYPE_STANDALONE:
 		name = "Standalone Application";
 		/* A second argument overwrites the load address */
-		if (argc > 2) {
+		if (argc > 2)
 			hdr->ih_load = simple_strtoul(argv[2], NULL, 16);
-		}
 		break;
 	case IH_TYPE_KERNEL:
 		name = "Kernel Image";
@@ -277,6 +287,7 @@
 		SHOW_BOOT_PROGRESS (-5);
 		return 1;
 	}
+
 	SHOW_BOOT_PROGRESS (6);
 
 	/*
@@ -289,7 +300,7 @@
 
 #ifdef CONFIG_AMIGAONEG3SE
 	/*
-	 * We've possible left the caches enabled during
+	 * We've possibly left the caches enabled during
 	 * bios emulation, so turn them off again
 	 */
 	icache_disable();
@@ -298,6 +309,7 @@
 	dcache_disable();
 #endif
 
+	/* find out compression type */
 	switch (hdr->ih_comp) {
 	case IH_COMP_NONE:
 		if(ntohl(hdr->ih_load) == addr) {
@@ -361,6 +373,7 @@
 	puts ("OK\n");
 	SHOW_BOOT_PROGRESS (7);
 
+	/* find out image type, handle standalone and unknown here */
 	switch (hdr->ih_type) {
 	case IH_TYPE_STANDALONE:
 		if (iflag)
@@ -391,6 +404,7 @@
 	}
 	SHOW_BOOT_PROGRESS (8);
 
+	/* image is OS kernel, find out which one */
 	switch (hdr->ih_os) {
 	default:			/* handled by (original) Linux case */
 	case IH_OS_LINUX:
@@ -436,6 +450,8 @@
 	}
 
 	SHOW_BOOT_PROGRESS (-9);
+
+	/* we should never reach this point */
 #ifdef DEBUG
 	puts ("\n## Control returned to monitor - resetting...\n");
 	do_reset (cmdtp, flag, argc, argv);
diff -urN u-boot-maintainance/lib_arm/armlinux.c u-boot-maintainance-bootz/lib_arm/armlinux.c
--- u-boot-maintainance/lib_arm/armlinux.c	2004-05-13 18:49:18.000000000 +0200
+++ u-boot-maintainance-bootz/lib_arm/armlinux.c	2004-05-15 16:32:04.000000000 +0200
@@ -71,7 +71,20 @@
 #endif
 
 extern image_header_t header;	/* from cmd_bootm.c */
+extern int fake_zimage_header (image_header_t *uimage_hdr, void *ptr, int size);
 
+/**
+ * 	fake_header - create an uImage header in case we don't have one
+ */
+image_header_t * fake_header(image_header_t * uimage_hdr, void *ptr, int size)
+{
+	/* try each supported image type in order */
+	if (fake_zimage_header(uimage_hdr, ptr, size))
+		return uimage_hdr;
+
+	/* image type is still unknown, exit */
+	return NULL;
+}
 
 void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
 		     ulong addr, ulong *len_ptr, int verify)
diff -urN u-boot-maintainance/lib_arm/Makefile u-boot-maintainance-bootz/lib_arm/Makefile
--- u-boot-maintainance/lib_arm/Makefile	2002-09-08 21:49:36.000000000 +0200
+++ u-boot-maintainance-bootz/lib_arm/Makefile	2004-05-15 15:06:48.000000000 +0200
@@ -28,7 +28,7 @@
 AOBJS	= _udivsi3.o _umodsi3.o
 
 COBJS	= armlinux.o board.o \
-	  cache.o div0.o
+	  cache.o div0.o zimage.o
 
 OBJS	= $(AOBJS) $(COBJS)
 
diff -urN u-boot-maintainance/lib_arm/zimage.c u-boot-maintainance-bootz/lib_arm/zimage.c
--- u-boot-maintainance/lib_arm/zimage.c	1970-01-01 01:00:00.000000000 +0100
+++ u-boot-maintainance-bootz/lib_arm/zimage.c	2004-05-15 16:14:04.000000000 +0200
@@ -0,0 +1,71 @@
+/*
+ * (C) Copyright 2004
+ * Robert Schwebel, Pengutronix, r.schwebel at pengutronix.de
+ *
+ * Derived from the i386 variant
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* Linux ARM zImage loading */
+
+#include <common.h>
+#include <asm/byteorder.h>
+
+/* 
+ * There is no way to know the size of a zImage ... *
+ * so we assume that 2MB will be enough for now 
+ */
+#define ZIMAGE_SIZE 0x200000
+
+image_header_t * fake_zimage_header(image_header_t * hdr, void *ptr, int size)
+{
+	ulong checksum = 0;
+
+	/* check if we really have a ARM zImage magic number */
+	if (*((unsigned long *) ((char *)ptr + 0x24)) != 0x016F2818)
+		return NULL;
+
+	printf ("## Image is zImage, creating header\n");
+
+	if (size == -1)
+		size = ZIMAGE_SIZE;
+
+	memset(hdr, 0, sizeof (image_header_t));
+
+	/* Build new header */
+	hdr->ih_magic = htonl(IH_MAGIC);
+	hdr->ih_time  = 0;
+	hdr->ih_size  = htonl(size);
+	hdr->ih_load  = htonl((unsigned long)ptr);
+	hdr->ih_ep    = htonl((unsigned long)ptr);
+	hdr->ih_dcrc  = htonl(checksum);
+	hdr->ih_os    = IH_OS_LINUX;
+	hdr->ih_arch  = IH_CPU_ARM;
+	hdr->ih_type  = IH_TYPE_KERNEL;
+	hdr->ih_comp  = IH_COMP_NONE;
+
+	strncpy((char *) hdr->ih_name, "zImage", IH_NMLEN);
+
+	checksum = crc32(0, (const char *) hdr, sizeof (image_header_t));
+
+	hdr->ih_hcrc = htonl(checksum);
+
+	return hdr;
+}


More information about the U-Boot mailing list