Browse Source

Merge branch 'master_merge_new-image' of /home/tur/git/u-boot

Wolfgang Denk 17 years ago
parent
commit
b951f8d317
82 changed files with 8126 additions and 2781 deletions
  1. 3 1
      Makefile
  2. 96 18
      README
  3. 9 2
      board/cray/L1/L1.c
  4. 52 40
      board/esd/common/auto_update.c
  5. 52 38
      board/mcc200/auto_update.c
  6. 23 23
      board/mpl/common/common_util.c
  7. 9 2
      board/pn62/cmd_pn62.c
  8. 27 21
      board/siemens/common/fpga.c
  9. 65 49
      board/trab/auto_update.c
  10. 3 0
      common/Makefile
  11. 107 46
      common/cmd_autoscript.c
  12. 603 800
      common/cmd_bootm.c
  13. 31 7
      common/cmd_doc.c
  14. 42 17
      common/cmd_fdc.c
  15. 94 15
      common/cmd_fpga.c
  16. 40 18
      common/cmd_ide.c
  17. 9 2
      common/cmd_load.c
  18. 65 15
      common/cmd_nand.c
  19. 9 2
      common/cmd_net.c
  20. 34 13
      common/cmd_scsi.c
  21. 35 15
      common/cmd_usb.c
  22. 107 61
      common/cmd_ximg.c
  23. 113 0
      common/gunzip.c
  24. 2541 0
      common/image.c
  25. 23 23
      common/lynxkdi.c
  26. 1 1
      cpu/mpc5xxx/cpu.c
  27. 1 1
      cpu/mpc8260/cpu.c
  28. 191 0
      doc/uImage.FIT/command_syntax_extensions.txt
  29. 297 0
      doc/uImage.FIT/howto.txt
  30. 34 0
      doc/uImage.FIT/kernel.its
  31. 48 0
      doc/uImage.FIT/kernel_fdt.its
  32. 124 0
      doc/uImage.FIT/multi.its
  33. 262 0
      doc/uImage.FIT/source_file_format.txt
  34. 3 2
      examples/eepro100_eeprom.c
  35. 2 18
      fs/cramfs/uncompress.c
  36. 0 1
      include/asm-i386/zimage.h
  37. 1 4
      include/common.h
  38. 6 0
      include/configs/pcs440ep.h
  39. 458 21
      include/image.h
  40. 4 0
      include/libfdt_env.h
  41. 54 0
      include/lmb.h
  42. 23 0
      include/md5.h
  43. 15 7
      lib_arm/Makefile
  44. 40 147
      lib_arm/bootm.c
  45. 6 4
      lib_avr32/Makefile
  46. 37 105
      lib_avr32/bootm.c
  47. 15 6
      lib_blackfin/Makefile
  48. 32 5
      lib_blackfin/bootm.c
  49. 2 0
      lib_generic/Makefile
  50. 4 0
      lib_generic/bzlib.c
  51. 280 0
      lib_generic/lmb.c
  52. 274 0
      lib_generic/md5.c
  53. 16 7
      lib_i386/Makefile
  54. 107 0
      lib_i386/bootm.c
  55. 0 179
      lib_i386/i386_linux.c
  56. 0 50
      lib_i386/zimage.c
  57. 9 4
      lib_m68k/Makefile
  58. 171 0
      lib_m68k/bootm.c
  59. 0 340
      lib_m68k/m68k_linux.c
  60. 7 4
      lib_microblaze/Makefile
  61. 81 0
      lib_microblaze/bootm.c
  62. 0 164
      lib_microblaze/microblaze_linux.c
  63. 6 4
      lib_mips/Makefile
  64. 37 117
      lib_mips/bootm.c
  65. 9 4
      lib_nios/Makefile
  66. 1 1
      lib_nios/bootm.c
  67. 8 4
      lib_nios2/Makefile
  68. 31 4
      lib_nios2/bootm.c
  69. 15 7
      lib_ppc/Makefile
  70. 774 0
      lib_ppc/bootm.c
  71. 6 4
      lib_sh/Makefile
  72. 33 6
      lib_sh/bootm.c
  73. 4 0
      libfdt/fdt.c
  74. 4 0
      libfdt/fdt_ro.c
  75. 4 0
      libfdt/fdt_rw.c
  76. 4 0
      libfdt/fdt_strerror.c
  77. 4 0
      libfdt/fdt_wip.c
  78. 8 0
      tools/.gitignore
  79. 62 3
      tools/Makefile
  80. 28 0
      tools/fdt_host.h
  81. 216 329
      tools/mkimage.c
  82. 75 0
      tools/mkimage.h

+ 3 - 1
Makefile

@@ -2890,7 +2890,9 @@ clobber:	clean
 	@rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS \
 	@rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS \
 		$(obj)cscope.* $(obj)*.*~
 		$(obj)cscope.* $(obj)*.*~
 	@rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL)
 	@rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL)
-	@rm -f $(obj)tools/{crc32.c,environment.c,env/crc32.c,sha1.c,inca-swap-bytes}
+	@rm -f $(obj)tools/{crc32.c,environment.c,env/crc32.c,md5.c,sha1.c,inca-swap-bytes}
+	@rm -f $(obj)tools/{image.c,fdt.c,fdt_ro.c,fdt_rw.c,fdt_strerror.c}
+	@rm -f $(obj)tools/{fdt_wip.c,libfdt_internal.h}
 	@rm -f $(obj)cpu/mpc824x/bedbug_603e.c
 	@rm -f $(obj)cpu/mpc824x/bedbug_603e.c
 	@rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
 	@rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
 	@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f
 	@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f

+ 96 - 18
README

@@ -1678,6 +1678,8 @@ The following options need to be configured:
 		example, some LED's) on your board. At the moment,
 		example, some LED's) on your board. At the moment,
 		the following checkpoints are implemented:
 		the following checkpoints are implemented:
 
 
+Legacy uImage format:
+
   Arg	Where			When
   Arg	Where			When
     1	common/cmd_bootm.c	before attempting to boot an image
     1	common/cmd_bootm.c	before attempting to boot an image
    -1	common/cmd_bootm.c	Image header has bad	 magic number
    -1	common/cmd_bootm.c	Image header has bad	 magic number
@@ -1688,25 +1690,26 @@ The following options need to be configured:
     4	common/cmd_bootm.c	Image data   has correct checksum
     4	common/cmd_bootm.c	Image data   has correct checksum
    -4	common/cmd_bootm.c	Image is for unsupported architecture
    -4	common/cmd_bootm.c	Image is for unsupported architecture
     5	common/cmd_bootm.c	Architecture check OK
     5	common/cmd_bootm.c	Architecture check OK
-   -5	common/cmd_bootm.c	Wrong Image Type (not kernel, multi, standalone)
+   -5	common/cmd_bootm.c	Wrong Image Type (not kernel, multi)
     6	common/cmd_bootm.c	Image Type check OK
     6	common/cmd_bootm.c	Image Type check OK
    -6	common/cmd_bootm.c	gunzip uncompression error
    -6	common/cmd_bootm.c	gunzip uncompression error
    -7	common/cmd_bootm.c	Unimplemented compression type
    -7	common/cmd_bootm.c	Unimplemented compression type
     7	common/cmd_bootm.c	Uncompression OK
     7	common/cmd_bootm.c	Uncompression OK
-   -8	common/cmd_bootm.c	Wrong Image Type (not kernel, multi, standalone)
-    8	common/cmd_bootm.c	Image Type check OK
+    8	common/cmd_bootm.c	No uncompress/copy overwrite error
    -9	common/cmd_bootm.c	Unsupported OS (not Linux, BSD, VxWorks, QNX)
    -9	common/cmd_bootm.c	Unsupported OS (not Linux, BSD, VxWorks, QNX)
-    9	common/cmd_bootm.c	Start initial ramdisk verification
-  -10	common/cmd_bootm.c	Ramdisk header has bad	   magic number
-  -11	common/cmd_bootm.c	Ramdisk header has bad	   checksum
-   10	common/cmd_bootm.c	Ramdisk header is OK
-  -12	common/cmd_bootm.c	Ramdisk data   has bad	   checksum
-   11	common/cmd_bootm.c	Ramdisk data   has correct checksum
-   12	common/cmd_bootm.c	Ramdisk verification complete, start loading
-  -13	common/cmd_bootm.c	Wrong Image Type (not PPC Linux Ramdisk)
-   13	common/cmd_bootm.c	Start multifile image verification
-   14	common/cmd_bootm.c	No initial ramdisk, no multifile, continue.
-   15	common/cmd_bootm.c	All preparation done, transferring control to OS
+
+    9	common/image.c		Start initial ramdisk verification
+  -10	common/image.c		Ramdisk header has bad	   magic number
+  -11	common/image.c		Ramdisk header has bad	   checksum
+   10	common/image.c		Ramdisk header is OK
+  -12	common/image.c		Ramdisk data   has bad	   checksum
+   11	common/image.c		Ramdisk data   has correct checksum
+   12	common/image.c		Ramdisk verification complete, start loading
+  -13	common/image.c		Wrong Image Type (not PPC Linux Ramdisk)
+   13	common/image.c		Start multifile image verification
+   14	common/image.c		No initial ramdisk, no multifile, continue.
+
+   15	lib_<arch>/bootm.c	All preparation done, transferring control to OS
 
 
   -30	lib_ppc/board.c		Fatal error, hang the system
   -30	lib_ppc/board.c		Fatal error, hang the system
   -31	post/post.c		POST test failed, detected by post_output_backlog()
   -31	post/post.c		POST test failed, detected by post_output_backlog()
@@ -1776,6 +1779,59 @@ The following options need to be configured:
   -83	common/cmd_net.c	some error in automatic boot or autoscript
   -83	common/cmd_net.c	some error in automatic boot or autoscript
    84	common/cmd_net.c	end without errors
    84	common/cmd_net.c	end without errors
 
 
+FIT uImage format:
+
+  Arg	Where			When
+  100	common/cmd_bootm.c	Kernel FIT Image has correct format
+ -100	common/cmd_bootm.c	Kernel FIT Image has incorrect format
+  101	common/cmd_bootm.c	No Kernel subimage unit name, using configuration
+ -101	common/cmd_bootm.c	Can't get configuration for kernel subimage
+  102	common/cmd_bootm.c	Kernel unit name specified
+ -103	common/cmd_bootm.c	Can't get kernel subimage node offset
+  103	common/cmd_bootm.c	Found configuration node
+  104	common/cmd_bootm.c	Got kernel subimage node offset
+ -104	common/cmd_bootm.c	Kernel subimage hash verification failed
+  105	common/cmd_bootm.c	Kernel subimage hash verification OK
+ -105	common/cmd_bootm.c	Kernel subimage is for unsupported architecture
+  106	common/cmd_bootm.c	Architecture check OK
+ -106	common/cmd_bootm.c	Kernel subimage has wrong typea
+  107	common/cmd_bootm.c	Kernel subimge type OK
+ -107	common/cmd_bootm.c	Can't get kernel subimage data/size
+  108	common/cmd_bootm.c	Got kernel subimage data/size
+ -108	common/cmd_bootm.c	Wrong image type (not legacy, FIT)
+ -109	common/cmd_bootm.c	Can't get kernel subimage type
+ -110	common/cmd_bootm.c	Can't get kernel subimage comp
+ -111	common/cmd_bootm.c	Can't get kernel subimage os
+ -112	common/cmd_bootm.c	Can't get kernel subimage load address
+ -113	common/cmd_bootm.c	Image uncompress/copy overwrite error
+
+  120	common/image.c		Start initial ramdisk verification
+ -120	common/image.c		Ramdisk FIT image has incorrect format
+  121	common/image.c		Ramdisk FIT image has correct format
+  122	common/image.c		No Ramdisk subimage unit name, using configuration
+ -122	common/image.c		Can't get configuration for ramdisk subimage
+  123	common/image.c		Ramdisk unit name specified
+ -124	common/image.c		Can't get ramdisk subimage node offset
+  125	common/image.c		Got ramdisk subimage node offset
+ -125	common/image.c		Ramdisk subimage hash verification failed
+  126	common/image.c		Ramdisk subimage hash verification OK
+ -126	common/image.c		Ramdisk subimage for unsupported architecture
+  127	common/image.c		Architecture check OK
+ -127	common/image.c		Can't get ramdisk subimage data/size
+  128	common/image.c		Got ramdisk subimage data/size
+  129	common/image.c		Can't get ramdisk load address
+ -129	common/image.c		Got ramdisk load address
+
+ -130	common/cmd_doc.c	Icorrect FIT image format
+  131	common/cmd_doc.c	FIT image format OK
+
+ -140	common/cmd_ide.c	Icorrect FIT image format
+  141	common/cmd_ide.c	FIT image format OK
+
+ -150	common/cmd_nand.c	Icorrect FIT image format
+  151	common/cmd_nand.c	FIT image format OK
+
+
 Modem Support:
 Modem Support:
 --------------
 --------------
 
 
@@ -2656,6 +2712,14 @@ Some configuration options can be set using Environment Variables:
 		  configuration from the BOOTP server, but not try to
 		  configuration from the BOOTP server, but not try to
 		  load any image using TFTP
 		  load any image using TFTP
 
 
+  autoscript	- if set to "yes" commands like "loadb", "loady",
+		  "bootp", "tftpb", "rarpboot" and "nfs" will attempt
+		  to automatically run script images (by internally
+		  calling "autoscript").
+
+  autoscript_uname - if script image is in a format (FIT) this
+		     variable is used to get script subimage unit name.
+
   autostart	- if set to "yes", an image loaded using the "bootp",
   autostart	- if set to "yes", an image loaded using the "bootp",
 		  "rarpboot", "tftpboot" or "diskboot" commands will
 		  "rarpboot", "tftpboot" or "diskboot" commands will
 		  be automatically started (by internally calling
 		  be automatically started (by internally calling
@@ -2870,10 +2934,24 @@ o If neither SROM nor the environment contain a MAC address, an error
 Image Formats:
 Image Formats:
 ==============
 ==============
 
 
-The "boot" commands of this monitor operate on "image" files which
-can be basicly anything, preceeded by a special header; see the
-definitions in include/image.h for details; basicly, the header
-defines the following image properties:
+U-Boot is capable of booting (and performing other auxiliary operations on)
+images in two formats:
+
+New uImage format (FIT)
+-----------------------
+
+Flexible and powerful format based on Flattened Image Tree -- FIT (similar
+to Flattened Device Tree). It allows the use of images with multiple
+components (several kernels, ramdisks, etc.), with contents protected by
+SHA1, MD5 or CRC32. More details are found in the doc/uImage.FIT directory.
+
+
+Old uImage format
+-----------------
+
+Old image format is based on binary files which can be basically anything,
+preceded by a special header; see the definitions in include/image.h for
+details; basically, the header defines the following image properties:
 
 
 * Target Operating System (Provisions for OpenBSD, NetBSD, FreeBSD,
 * Target Operating System (Provisions for OpenBSD, NetBSD, FreeBSD,
   4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks,
   4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks,

+ 9 - 2
board/cray/L1/L1.c

@@ -139,8 +139,15 @@ int misc_init_r (void)
 	struct rtc_time tm;
 	struct rtc_time tm;
 	char bootcmd[32];
 	char bootcmd[32];
 
 
-	hdr = (image_header_t *) (CFG_MONITOR_BASE - sizeof (image_header_t));
-	timestamp = (time_t) hdr->ih_time;
+	hdr = (image_header_t *) (CFG_MONITOR_BASE - image_get_header_size ());
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
+
+	timestamp = (time_t)image_get_time (hdr);
 	to_tm (timestamp, &tm);
 	to_tm (timestamp, &tm);
 	printf ("Welcome to U-Boot on Cray L1. Compiled %4d-%02d-%02d  %2d:%02d:%02d (UTC)\n", tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
 	printf ("Welcome to U-Boot on Cray L1. Compiled %4d-%02d-%02d  %2d:%02d:%02d (UTC)\n", tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
 
 

+ 52 - 40
board/esd/common/auto_update.c

@@ -89,24 +89,28 @@ extern block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE];
 int au_check_cksum_valid(int i, long nbytes)
 int au_check_cksum_valid(int i, long nbytes)
 {
 {
 	image_header_t *hdr;
 	image_header_t *hdr;
-	unsigned long checksum;
 
 
 	hdr = (image_header_t *)LOAD_ADDR;
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
 
 
-	if ((au_image[i].type == AU_FIRMWARE) && (au_image[i].size != ntohl(hdr->ih_size))) {
+	if ((au_image[i].type == AU_FIRMWARE) &&
+	    (au_image[i].size != image_get_data_size (hdr))) {
 		printf ("Image %s has wrong size\n", au_image[i].name);
 		printf ("Image %s has wrong size\n", au_image[i].name);
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) {
+	if (nbytes != (image_get_image_size (hdr))) {
 		printf ("Image %s bad total SIZE\n", au_image[i].name);
 		printf ("Image %s bad total SIZE\n", au_image[i].name);
 		return -1;
 		return -1;
 	}
 	}
-	/* check the data CRC */
-	checksum = ntohl(hdr->ih_dcrc);
 
 
-	if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size))
-		!= checksum) {
+	/* check the data CRC */
+	if (!image_check_dcrc (hdr)) {
 		printf ("Image %s bad data checksum\n", au_image[i].name);
 		printf ("Image %s bad data checksum\n", au_image[i].name);
 		return -1;
 		return -1;
 	}
 	}
@@ -120,51 +124,53 @@ int au_check_header_valid(int i, long nbytes)
 	unsigned long checksum;
 	unsigned long checksum;
 
 
 	hdr = (image_header_t *)LOAD_ADDR;
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
+
 	/* check the easy ones first */
 	/* check the easy ones first */
 #undef CHECK_VALID_DEBUG
 #undef CHECK_VALID_DEBUG
 #ifdef CHECK_VALID_DEBUG
 #ifdef CHECK_VALID_DEBUG
-	printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC);
-	printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_PPC);
-	printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes);
-	printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL);
+	printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC);
+	printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_PPC);
+	printf("size %#x %#lx ", image_get_data_size (hdr), nbytes);
+	printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL);
 #endif
 #endif
-	if (nbytes < sizeof(*hdr))
+	if (nbytes < image_get_header_size ())
 	{
 	{
 		printf ("Image %s bad header SIZE\n", au_image[i].name);
 		printf ("Image %s bad header SIZE\n", au_image[i].name);
 		return -1;
 		return -1;
 	}
 	}
-	if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_PPC)
+	if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC))
 	{
 	{
 		printf ("Image %s bad MAGIC or ARCH\n", au_image[i].name);
 		printf ("Image %s bad MAGIC or ARCH\n", au_image[i].name);
 		return -1;
 		return -1;
 	}
 	}
-	/* check the hdr CRC */
-	checksum = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
-
-	if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) {
+	if (!image_check_hcrc (hdr)) {
 		printf ("Image %s bad header checksum\n", au_image[i].name);
 		printf ("Image %s bad header checksum\n", au_image[i].name);
 		return -1;
 		return -1;
 	}
 	}
-	hdr->ih_hcrc = htonl(checksum);
 
 
 	/* check the type - could do this all in one gigantic if() */
 	/* check the type - could do this all in one gigantic if() */
-	if ((au_image[i].type == AU_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) {
+	if ((au_image[i].type == AU_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) {
 		printf ("Image %s wrong type\n", au_image[i].name);
 		printf ("Image %s wrong type\n", au_image[i].name);
 		return -1;
 		return -1;
 	}
 	}
-	if ((au_image[i].type == AU_SCRIPT) && (hdr->ih_type != IH_TYPE_SCRIPT)) {
+	if ((au_image[i].type == AU_SCRIPT) && !image_check_type (hdr, IH_TYPE_SCRIPT)) {
 		printf ("Image %s wrong type\n", au_image[i].name);
 		printf ("Image %s wrong type\n", au_image[i].name);
 		return -1;
 		return -1;
 	}
 	}
 
 
 	/* recycle checksum */
 	/* recycle checksum */
-	checksum = ntohl(hdr->ih_size);
+	checksum = image_get_data_size (hdr);
 
 
 #if 0 /* test-only */
 #if 0 /* test-only */
 	/* for kernel and app the image header must also fit into flash */
 	/* for kernel and app the image header must also fit into flash */
 	if (idx != IDX_DISK)
 	if (idx != IDX_DISK)
-		checksum += sizeof(*hdr);
+		checksum += image_get_header_size ();
 	/* check the size does not exceed space in flash. HUSH scripts */
 	/* check the size does not exceed space in flash. HUSH scripts */
 	/* all have ausize[] set to 0 */
 	/* all have ausize[] set to 0 */
 	if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
 	if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
@@ -190,17 +196,23 @@ int au_do_update(int i, long sz)
 #endif
 #endif
 
 
 	hdr = (image_header_t *)LOAD_ADDR;
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
 
 
 	switch (au_image[i].type) {
 	switch (au_image[i].type) {
 	case AU_SCRIPT:
 	case AU_SCRIPT:
 		printf("Executing script %s\n", au_image[i].name);
 		printf("Executing script %s\n", au_image[i].name);
 
 
 		/* execute a script */
 		/* execute a script */
-		if (hdr->ih_type == IH_TYPE_SCRIPT) {
-			addr = (char *)((char *)hdr + sizeof(*hdr));
+		if (image_check_type (hdr, IH_TYPE_SCRIPT)) {
+			addr = (char *)((char *)hdr + image_get_header_size ());
 			/* stick a NULL at the end of the script, otherwise */
 			/* stick a NULL at the end of the script, otherwise */
 			/* parse_string_outer() runs off the end. */
 			/* parse_string_outer() runs off the end. */
-			addr[ntohl(hdr->ih_size)] = 0;
+			addr[image_get_data_size (hdr)] = 0;
 			addr += 8;
 			addr += 8;
 
 
 			/*
 			/*
@@ -231,8 +243,8 @@ int au_do_update(int i, long sz)
 		 */
 		 */
 		if (au_image[i].type == AU_FIRMWARE) {
 		if (au_image[i].type == AU_FIRMWARE) {
 			char *orig = (char*)start;
 			char *orig = (char*)start;
-			char *new  = (char *)((char *)hdr + sizeof(*hdr));
-			nbytes = ntohl(hdr->ih_size);
+			char *new  = (char *)((char *)hdr + image_get_header_size ());
+			nbytes = image_get_data_size (hdr);
 
 
 			while(--nbytes) {
 			while(--nbytes) {
 				if (*orig++ != *new++) {
 				if (*orig++ != *new++) {
@@ -272,12 +284,12 @@ int au_do_update(int i, long sz)
 		/* strip the header - except for the kernel and ramdisk */
 		/* strip the header - except for the kernel and ramdisk */
 		if (au_image[i].type != AU_FIRMWARE) {
 		if (au_image[i].type != AU_FIRMWARE) {
 			addr = (char *)hdr;
 			addr = (char *)hdr;
-			off = sizeof(*hdr);
-			nbytes = sizeof(*hdr) + ntohl(hdr->ih_size);
+			off = image_get_header_size ();
+			nbytes = image_get_image_size (hdr);
 		} else {
 		} else {
-			addr = (char *)((char *)hdr + sizeof(*hdr));
+			addr = (char *)((char *)hdr + image_get_header_size ());
 			off = 0;
 			off = 0;
-			nbytes = ntohl(hdr->ih_size);
+			nbytes = image_get_data_size (hdr);
 		}
 		}
 
 
 		/*
 		/*
@@ -305,15 +317,15 @@ int au_do_update(int i, long sz)
 		 * check the dcrc of the copy
 		 * check the dcrc of the copy
 		 */
 		 */
 		if (au_image[i].type != AU_NAND) {
 		if (au_image[i].type != AU_NAND) {
-			rc = crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size));
+			rc = crc32 (0, (uchar *)(start + off), image_get_data_size (hdr));
 		} else {
 		} else {
 #if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
 #if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
 			rc = nand_legacy_rw(nand_dev_desc, NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP,
 			rc = nand_legacy_rw(nand_dev_desc, NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP,
 				     start, nbytes, (size_t *)&total, (uchar *)addr);
 				     start, nbytes, (size_t *)&total, (uchar *)addr);
-			rc = crc32 (0, (uchar *)(addr + off), ntohl(hdr->ih_size));
+			rc = crc32 (0, (uchar *)(addr + off), image_get_data_size (hdr));
 #endif
 #endif
 		}
 		}
-		if (rc != ntohl(hdr->ih_dcrc)) {
+		if (rc != image_get_dcrc (hdr)) {
 			printf ("Image %s Bad Data Checksum After COPY\n", au_image[i].name);
 			printf ("Image %s Bad Data Checksum After COPY\n", au_image[i].name);
 			return -1;
 			return -1;
 		}
 		}
@@ -497,10 +509,10 @@ int do_auto_update(void)
 
 
 		printf("Reading %s ...", au_image[i].name);
 		printf("Reading %s ...", au_image[i].name);
 		/* just read the header */
 		/* just read the header */
-		sz = do_fat_read(au_image[i].name, LOAD_ADDR, sizeof(image_header_t), LS_NO);
+		sz = do_fat_read(au_image[i].name, LOAD_ADDR, image_get_header_size (), LS_NO);
 		debug ("read %s sz %ld hdr %d\n",
 		debug ("read %s sz %ld hdr %d\n",
-			au_image[i].name, sz, sizeof(image_header_t));
-		if (sz <= 0 || sz < sizeof(image_header_t)) {
+			au_image[i].name, sz, image_get_header_size ());
+		if (sz <= 0 || sz < image_get_header_size ()) {
 			puts(" not found\n");
 			puts(" not found\n");
 			continue;
 			continue;
 		}
 		}
@@ -510,8 +522,8 @@ int do_auto_update(void)
 		}
 		}
 		sz = do_fat_read(au_image[i].name, LOAD_ADDR, MAX_LOADSZ, LS_NO);
 		sz = do_fat_read(au_image[i].name, LOAD_ADDR, MAX_LOADSZ, LS_NO);
 		debug ("read %s sz %ld hdr %d\n",
 		debug ("read %s sz %ld hdr %d\n",
-			au_image[i].name, sz, sizeof(image_header_t));
-		if (sz <= 0 || sz <= sizeof(image_header_t)) {
+			au_image[i].name, sz, image_get_header_size ());
+		if (sz <= 0 || sz <= image_get_header_size ()) {
 			puts(" not found\n");
 			puts(" not found\n");
 			continue;
 			continue;
 		}
 		}

+ 52 - 38
board/mcc200/auto_update.c

@@ -141,18 +141,21 @@ extern void lcd_enable(void);
 int au_check_cksum_valid(int idx, long nbytes)
 int au_check_cksum_valid(int idx, long nbytes)
 {
 {
 	image_header_t *hdr;
 	image_header_t *hdr;
-	unsigned long checksum;
 
 
 	hdr = (image_header_t *)LOAD_ADDR;
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
 
 
-	if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) {
+	if (nbytes != image_get_image_size (hdr)) {
 		printf ("Image %s bad total SIZE\n", aufile[idx]);
 		printf ("Image %s bad total SIZE\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
 	/* check the data CRC */
 	/* check the data CRC */
-	checksum = ntohl(hdr->ih_dcrc);
-
-	if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size)) != checksum) {
+	if (!image_check_dcrc (hdr)) {
 		printf ("Image %s bad data checksum\n", aufile[idx]);
 		printf ("Image %s bad data checksum\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
@@ -165,59 +168,62 @@ int au_check_header_valid(int idx, long nbytes)
 	unsigned long checksum, fsize;
 	unsigned long checksum, fsize;
 
 
 	hdr = (image_header_t *)LOAD_ADDR;
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
+
 	/* check the easy ones first */
 	/* check the easy ones first */
 #undef CHECK_VALID_DEBUG
 #undef CHECK_VALID_DEBUG
 #ifdef CHECK_VALID_DEBUG
 #ifdef CHECK_VALID_DEBUG
-	printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC);
-	printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_ARM);
-	printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes);
-	printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL);
+	printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC);
+	printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_ARM);
+	printf("size %#x %#lx ", image_get_data_size (hdr), nbytes);
+	printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL);
 #endif
 #endif
-	if (nbytes < sizeof(*hdr)) {
+	if (nbytes < image_get_header_size ()) {
 		printf ("Image %s bad header SIZE\n", aufile[idx]);
 		printf ("Image %s bad header SIZE\n", aufile[idx]);
 		ausize[idx] = 0;
 		ausize[idx] = 0;
 		return -1;
 		return -1;
 	}
 	}
-	if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_PPC) {
+	if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC)) {
 		printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]);
 		printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]);
 		ausize[idx] = 0;
 		ausize[idx] = 0;
 		return -1;
 		return -1;
 	}
 	}
 	/* check the hdr CRC */
 	/* check the hdr CRC */
-	checksum = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
-
-	if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) {
+	if (!image_check_hcrc (hdr)) {
 		printf ("Image %s bad header checksum\n", aufile[idx]);
 		printf ("Image %s bad header checksum\n", aufile[idx]);
 		ausize[idx] = 0;
 		ausize[idx] = 0;
 		return -1;
 		return -1;
 	}
 	}
-	hdr->ih_hcrc = htonl(checksum);
 	/* check the type - could do this all in one gigantic if() */
 	/* check the type - could do this all in one gigantic if() */
-	if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) {
+	if ((idx == IDX_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		printf ("Image %s wrong type\n", aufile[idx]);
 		ausize[idx] = 0;
 		ausize[idx] = 0;
 		return -1;
 		return -1;
 	}
 	}
-	if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) {
+	if ((idx == IDX_KERNEL) && !image_check_type (hdr, IH_TYPE_KERNEL)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		printf ("Image %s wrong type\n", aufile[idx]);
 		ausize[idx] = 0;
 		ausize[idx] = 0;
 		return -1;
 		return -1;
 	}
 	}
 	if ((idx == IDX_ROOTFS) &&
 	if ((idx == IDX_ROOTFS) &&
-		( (hdr->ih_type != IH_TYPE_RAMDISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM) )
-	   ) {
+			(!image_check_type (hdr, IH_TYPE_RAMDISK) &&
+			!image_check_type (hdr, IH_TYPE_FILESYSTEM))) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		printf ("Image %s wrong type\n", aufile[idx]);
 		ausize[idx] = 0;
 		ausize[idx] = 0;
 		return -1;
 		return -1;
 	}
 	}
 	/* recycle checksum */
 	/* recycle checksum */
-	checksum = ntohl(hdr->ih_size);
+	checksum = image_get_data_size (hdr);
 
 
-	fsize = checksum + sizeof(*hdr);
+	fsize = checksum + image_get_header_size ();
 	/* for kernel and ramdisk the image header must also fit into flash */
 	/* for kernel and ramdisk the image header must also fit into flash */
-	if (idx == IDX_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK)
-		checksum += sizeof(*hdr);
+	if (idx == IDX_KERNEL || image_check_type (hdr, IH_TYPE_RAMDISK))
+		checksum += image_get_header_size ();
 
 
 	/* check the size does not exceed space in flash. HUSH scripts */
 	/* check the size does not exceed space in flash. HUSH scripts */
 	if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
 	if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
@@ -240,13 +246,19 @@ int au_do_update(int idx, long sz)
 	uint nbytes;
 	uint nbytes;
 
 
 	hdr = (image_header_t *)LOAD_ADDR;
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
 
 
 	/* execute a script */
 	/* execute a script */
-	if (hdr->ih_type == IH_TYPE_SCRIPT) {
-		addr = (char *)((char *)hdr + sizeof(*hdr));
+	if (image_check_type (hdr, IH_TYPE_SCRIPT)) {
+		addr = (char *)((char *)hdr + image_get_header_size ());
 		/* stick a NULL at the end of the script, otherwise */
 		/* stick a NULL at the end of the script, otherwise */
 		/* parse_string_outer() runs off the end. */
 		/* parse_string_outer() runs off the end. */
-		addr[ntohl(hdr->ih_size)] = 0;
+		addr[image_get_data_size (hdr)] = 0;
 		addr += 8;
 		addr += 8;
 		parse_string_outer(addr, FLAG_PARSE_SEMICOLON);
 		parse_string_outer(addr, FLAG_PARSE_SEMICOLON);
 		return 0;
 		return 0;
@@ -278,19 +290,20 @@ int au_do_update(int idx, long sz)
 #endif
 #endif
 
 
 	/* strip the header - except for the kernel and ramdisk */
 	/* strip the header - except for the kernel and ramdisk */
-	if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) {
+	if (image_check_type (hdr, IH_TYPE_KERNEL) ||
+			image_check_type (hdr, IH_TYPE_RAMDISK)) {
 		addr = (char *)hdr;
 		addr = (char *)hdr;
-		off = sizeof(*hdr);
-		nbytes = sizeof(*hdr) + ntohl(hdr->ih_size);
+		off = image_get_header_size ();
+		nbytes = image_get_image_size (hdr);
 	} else {
 	} else {
-		addr = (char *)((char *)hdr + sizeof(*hdr));
+		addr = (char *)((char *)hdr + image_get_header_size ());
 #ifdef AU_UPDATE_TEST
 #ifdef AU_UPDATE_TEST
 		/* copy it to where Linux goes */
 		/* copy it to where Linux goes */
 		if (idx == IDX_FIRMWARE)
 		if (idx == IDX_FIRMWARE)
 			start = aufl_layout[1].start;
 			start = aufl_layout[1].start;
 #endif
 #endif
 		off = 0;
 		off = 0;
-		nbytes = ntohl(hdr->ih_size);
+		nbytes = image_get_data_size (hdr);
 	}
 	}
 
 
 	/* copy the data from RAM to FLASH */
 	/* copy the data from RAM to FLASH */
@@ -306,7 +319,8 @@ int au_do_update(int idx, long sz)
 #endif
 #endif
 
 
 	/* check the data CRC of the copy */
 	/* check the data CRC of the copy */
-	if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) {
+	if (crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)) !=
+	    image_get_dcrc (hdr)) {
 		printf ("Image %s Bad Data Checksum after COPY\n", aufile[idx]);
 		printf ("Image %s Bad Data Checksum after COPY\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
@@ -442,10 +456,10 @@ int do_auto_update(void)
 	for (i = 0; i < AU_MAXFILES; i++) {
 	for (i = 0; i < AU_MAXFILES; i++) {
 		ulong imsize;
 		ulong imsize;
 		/* just read the header */
 		/* just read the header */
-		sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t));
+		sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ());
 		debug ("read %s sz %ld hdr %d\n",
 		debug ("read %s sz %ld hdr %d\n",
-			aufile[i], sz, sizeof(image_header_t));
-		if (sz <= 0 || sz < sizeof(image_header_t)) {
+			aufile[i], sz, image_get_header_size ());
+		if (sz <= 0 || sz < image_get_header_size ()) {
 			debug ("%s not found\n", aufile[i]);
 			debug ("%s not found\n", aufile[i]);
 			ausize[i] = 0;
 			ausize[i] = 0;
 			continue;
 			continue;
@@ -474,14 +488,14 @@ int do_auto_update(void)
 		sz = file_fat_read(aufile[i], LOAD_ADDR, ausize[i]);
 		sz = file_fat_read(aufile[i], LOAD_ADDR, ausize[i]);
 
 
 		debug ("read %s sz %ld hdr %d\n",
 		debug ("read %s sz %ld hdr %d\n",
-			aufile[i], sz, sizeof(image_header_t));
+			aufile[i], sz, image_get_header_size ());
 
 
 		if (sz != ausize[i]) {
 		if (sz != ausize[i]) {
 			printf ("%s: size %d read %d?\n", aufile[i], ausize[i], sz);
 			printf ("%s: size %d read %d?\n", aufile[i], ausize[i], sz);
 			continue;
 			continue;
 		}
 		}
 
 
-		if (sz <= 0 || sz <= sizeof(image_header_t)) {
+		if (sz <= 0 || sz <= image_get_header_size ()) {
 			debug ("%s not found\n", aufile[i]);
 			debug ("%s not found\n", aufile[i]);
 			continue;
 			continue;
 		}
 		}

+ 23 - 23
board/mpl/common/common_util.c

@@ -57,9 +57,6 @@ extern int mem_test(ulong start, ulong ramsize, int quiet);
 
 
 extern flash_info_t flash_info[];	/* info for FLASH chips */
 extern flash_info_t flash_info[];	/* info for FLASH chips */
 
 
-static image_header_t header;
-
-
 static int
 static int
 mpl_prg(uchar *src, ulong size)
 mpl_prg(uchar *src, ulong size)
 {
 {
@@ -77,7 +74,7 @@ mpl_prg(uchar *src, ulong size)
 	info = &flash_info[0];
 	info = &flash_info[0];
 
 
 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)
 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)
-	if (ntohl(magic[0]) != IH_MAGIC) {
+	if (uimage_to_cpu (magic[0]) != IH_MAGIC) {
 		puts("Bad Magic number\n");
 		puts("Bad Magic number\n");
 		return -1;
 		return -1;
 	}
 	}
@@ -179,44 +176,46 @@ mpl_prg(uchar *src, ulong size)
 static int
 static int
 mpl_prg_image(uchar *ld_addr)
 mpl_prg_image(uchar *ld_addr)
 {
 {
-	unsigned long len, checksum;
+	unsigned long len;
 	uchar *data;
 	uchar *data;
-	image_header_t *hdr = &header;
+	image_header_t *hdr = (image_header_t *)ld_addr;
 	int rc;
 	int rc;
 
 
-	/* Copy header so we can blank CRC field for re-calculation */
-	memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
-	if (ntohl(hdr->ih_magic)  != IH_MAGIC) {
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
+
+	if (!image_check_magic (hdr)) {
 		puts("Bad Magic Number\n");
 		puts("Bad Magic Number\n");
 		return 1;
 		return 1;
 	}
 	}
-	print_image_hdr(hdr);
-	if (hdr->ih_os  != IH_OS_U_BOOT) {
+	image_print_contents (hdr);
+	if (!image_check_os (hdr, IH_OS_U_BOOT)) {
 		puts("No U-Boot Image\n");
 		puts("No U-Boot Image\n");
 		return 1;
 		return 1;
 	}
 	}
-	if (hdr->ih_type  != IH_TYPE_FIRMWARE) {
+	if (!image_check_type (hdr, IH_TYPE_FIRMWARE)) {
 		puts("No Firmware Image\n");
 		puts("No Firmware Image\n");
 		return 1;
 		return 1;
 	}
 	}
-	data = (uchar *)&header;
-	len  = sizeof(image_header_t);
-	checksum = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
-	if (crc32 (0, (uchar *)data, len) != checksum) {
+	if (!image_check_hcrc (hdr)) {
 		puts("Bad Header Checksum\n");
 		puts("Bad Header Checksum\n");
 		return 1;
 		return 1;
 	}
 	}
-	data = ld_addr + sizeof(image_header_t);
-	len  = ntohl(hdr->ih_size);
 	puts("Verifying Checksum ... ");
 	puts("Verifying Checksum ... ");
-	if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) {
+	if (!image_check_dcrc (hdr)) {
 		puts("Bad Data CRC\n");
 		puts("Bad Data CRC\n");
 		return 1;
 		return 1;
 	}
 	}
 	puts("OK\n");
 	puts("OK\n");
 
 
-	if (hdr->ih_comp != IH_COMP_NONE) {
+	data = (uchar *)image_get_data (hdr);
+	len = image_get_data_size (hdr);
+
+	if (image_get_comp (hdr) != IH_COMP_NONE) {
 		uchar *buf;
 		uchar *buf;
 		/* reserve space for uncompressed image */
 		/* reserve space for uncompressed image */
 		if ((buf = malloc(IMAGE_SIZE)) == NULL) {
 		if ((buf = malloc(IMAGE_SIZE)) == NULL) {
@@ -224,7 +223,7 @@ mpl_prg_image(uchar *ld_addr)
 			return 1;
 			return 1;
 		}
 		}
 
 
-		switch (hdr->ih_comp) {
+		switch (image_get_comp (hdr)) {
 		case IH_COMP_GZIP:
 		case IH_COMP_GZIP:
 			puts("Uncompressing (GZIP) ... ");
 			puts("Uncompressing (GZIP) ... ");
 			rc = gunzip ((void *)(buf), IMAGE_SIZE, data, &len);
 			rc = gunzip ((void *)(buf), IMAGE_SIZE, data, &len);
@@ -253,7 +252,8 @@ mpl_prg_image(uchar *ld_addr)
 			break;
 			break;
 #endif
 #endif
 		default:
 		default:
-			printf ("Unimplemented compression type %d\n", hdr->ih_comp);
+			printf ("Unimplemented compression type %d\n",
+				image_get_comp (hdr));
 			free(buf);
 			free(buf);
 			return 1;
 			return 1;
 		}
 		}

+ 9 - 2
board/pn62/cmd_pn62.c

@@ -157,8 +157,15 @@ int do_loadpci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	char *s;
 	char *s;
 
 
 	if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
 	if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
-	    printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
-	    rcode = autoscript (bd, load_addr);
+		printf ("Running autoscript at addr 0x%08lX", load_addr);
+
+		s = getenv ("autoscript_uname");
+		if (s)
+			printf (":%s ...\n", s);
+		else
+			puts (" ...\n");
+
+		rcode = autoscript (load_addr, s);
 	}
 	}
     }
     }
 #endif
 #endif

+ 27 - 21
board/siemens/common/fpga.c

@@ -131,45 +131,44 @@ static int fpga_reset (fpga_t* fpga)
 static int fpga_load (fpga_t* fpga, ulong addr, int checkall)
 static int fpga_load (fpga_t* fpga, ulong addr, int checkall)
 {
 {
     volatile uchar *fpga_addr = (volatile uchar *)fpga->conf_base;
     volatile uchar *fpga_addr = (volatile uchar *)fpga->conf_base;
-    image_header_t hdr;
-    ulong len, checksum;
-    uchar *data = (uchar *)&hdr;
-    char *s, msg[32];
+    image_header_t *hdr = (image_header_t *)addr;
+    ulong len;
+    uchar *data;
+    char msg[32];
     int verify, i;
     int verify, i;
 
 
+#if defined(CONFIG_FIT)
+    if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+	puts ("Non legacy image format not supported\n");
+	return -1;
+    }
+#endif
+
     /*
     /*
      * Check the image header and data of the net-list
      * Check the image header and data of the net-list
      */
      */
-    memcpy (&hdr, (char *)addr, sizeof(image_header_t));
-
-    if (hdr.ih_magic != IH_MAGIC) {
+    if (!image_check_magic (hdr)) {
 	strcpy (msg, "Bad Image Magic Number");
 	strcpy (msg, "Bad Image Magic Number");
 	goto failure;
 	goto failure;
     }
     }
 
 
-    len  = sizeof(image_header_t);
-
-    checksum = hdr.ih_hcrc;
-    hdr.ih_hcrc = 0;
-
-    if (crc32 (0, data, len) != checksum) {
+    if (!image_check_hcrc (hdr)) {
 	strcpy (msg, "Bad Image Header CRC");
 	strcpy (msg, "Bad Image Header CRC");
 	goto failure;
 	goto failure;
     }
     }
 
 
-    data = (uchar*)(addr + sizeof(image_header_t));
-    len  = hdr.ih_size;
+    data = (uchar*)image_get_data (hdr);
+    len  = image_get_data_size (hdr);
 
 
-    s = getenv ("verify");
-    verify = (s && (*s == 'n')) ? 0 : 1;
+    verify = getenv_verify ();
     if (verify) {
     if (verify) {
-	if (crc32 (0, data, len) != hdr.ih_dcrc) {
+	if (!image_check_dcrc (hdr)) {
 	    strcpy (msg, "Bad Image Data CRC");
 	    strcpy (msg, "Bad Image Data CRC");
 	    goto failure;
 	    goto failure;
 	}
 	}
     }
     }
 
 
-    if (checkall && fpga_get_version(fpga, (char *)(hdr.ih_name)) < 0)
+    if (checkall && fpga_get_version(fpga, image_get_name (hdr)) < 0)
 	return 1;
 	return 1;
 
 
     /* align length */
     /* align length */
@@ -184,7 +183,7 @@ static int fpga_load (fpga_t* fpga, ulong addr, int checkall)
 	goto failure;
 	goto failure;
     }
     }
 
 
-    printf ("(%s)... ", hdr.ih_name);
+    printf ("(%s)... ", image_get_name (hdr));
     /*
     /*
      * Copy data to FPGA
      * Copy data to FPGA
      */
      */
@@ -341,7 +340,14 @@ int fpga_init (void)
 	}
 	}
 
 
 	hdr = (image_header_t *)addr;
 	hdr = (image_header_t *)addr;
-	if ((new_id = fpga_get_version(fpga, (char *)(hdr->ih_name))) == -1)
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+	   puts ("Non legacy image format not supported\n");
+	   return -1;
+	}
+#endif
+
+	if ((new_id = fpga_get_version(fpga, image_get_name (hdr))) == -1)
 	    return 1;
 	    return 1;
 
 
 	do_load = 1;
 	do_load = 1;

+ 65 - 49
board/trab/auto_update.c

@@ -209,21 +209,21 @@ int
 au_check_cksum_valid(int idx, long nbytes)
 au_check_cksum_valid(int idx, long nbytes)
 {
 {
 	image_header_t *hdr;
 	image_header_t *hdr;
-	unsigned long checksum;
 
 
 	hdr = (image_header_t *)LOAD_ADDR;
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
 
 
-	if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size)))
-	{
+	if (nbytes != image_get_image_size (hdr)) {
 		printf ("Image %s bad total SIZE\n", aufile[idx]);
 		printf ("Image %s bad total SIZE\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
 	/* check the data CRC */
 	/* check the data CRC */
-	checksum = ntohl(hdr->ih_dcrc);
-
-	if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size))
-		!= checksum)
-	{
+	if (!image_check_dcrc (hdr)) {
 		printf ("Image %s bad data checksum\n", aufile[idx]);
 		printf ("Image %s bad data checksum\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
@@ -238,54 +238,55 @@ au_check_header_valid(int idx, long nbytes)
 	unsigned char buf[4];
 	unsigned char buf[4];
 
 
 	hdr = (image_header_t *)LOAD_ADDR;
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
+
 	/* check the easy ones first */
 	/* check the easy ones first */
 #undef CHECK_VALID_DEBUG
 #undef CHECK_VALID_DEBUG
 #ifdef CHECK_VALID_DEBUG
 #ifdef CHECK_VALID_DEBUG
-	printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC);
-	printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_ARM);
-	printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes);
-	printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL);
+	printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC);
+	printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_ARM);
+	printf("size %#x %#lx ", image_get_data_size (hdr), nbytes);
+	printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL);
 #endif
 #endif
-	if (nbytes < sizeof(*hdr))
-	{
+	if (nbytes < image_get_header_size ()) {
 		printf ("Image %s bad header SIZE\n", aufile[idx]);
 		printf ("Image %s bad header SIZE\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
-	if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_ARM)
-	{
+	if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_ARM)) {
 		printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]);
 		printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
 	/* check the hdr CRC */
 	/* check the hdr CRC */
-	checksum = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
-
-	if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) {
+	if (!image_check_hcrc (hdr)) {
 		printf ("Image %s bad header checksum\n", aufile[idx]);
 		printf ("Image %s bad header checksum\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
-	hdr->ih_hcrc = htonl(checksum);
 	/* check the type - could do this all in one gigantic if() */
 	/* check the type - could do this all in one gigantic if() */
-	if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) {
+	if ((idx == IDX_FIRMWARE) &&
+		!image_check_type (hdr, IH_TYPE_FIRMWARE)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		printf ("Image %s wrong type\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
-	if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) {
+	if ((idx == IDX_KERNEL) && !image_check_type (hdr, IH_TYPE_KERNEL)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		printf ("Image %s wrong type\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
-	if ((idx == IDX_DISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM)) {
+	if ((idx == IDX_DISK) && !image_check_type (hdr, IH_TYPE_FILESYSTEM)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		printf ("Image %s wrong type\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
-	if ((idx == IDX_APP) && (hdr->ih_type != IH_TYPE_RAMDISK)
-	    && (hdr->ih_type != IH_TYPE_FILESYSTEM)) {
+	if ((idx == IDX_APP) && !image_check_type (hdr, IH_TYPE_RAMDISK)
+		&& !image_check_type (hdr, IH_TYPE_FILESYSTEM)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		printf ("Image %s wrong type\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
 	if ((idx == IDX_PREPARE || idx == IDX_PREINST || idx == IDX_POSTINST)
 	if ((idx == IDX_PREPARE || idx == IDX_PREINST || idx == IDX_POSTINST)
-		&& (hdr->ih_type != IH_TYPE_SCRIPT))
-	{
+		&& !image_check_type (hdr, IH_TYPE_SCRIPT)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		printf ("Image %s wrong type\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
@@ -293,10 +294,10 @@ au_check_header_valid(int idx, long nbytes)
 	if (idx == IDX_PREPARE)
 	if (idx == IDX_PREPARE)
 		return 0;
 		return 0;
 	/* recycle checksum */
 	/* recycle checksum */
-	checksum = ntohl(hdr->ih_size);
+	checksum = image_get_data_size (hdr);
 	/* for kernel and app the image header must also fit into flash */
 	/* for kernel and app the image header must also fit into flash */
 	if ((idx != IDX_DISK) && (idx != IDX_FIRMWARE))
 	if ((idx != IDX_DISK) && (idx != IDX_FIRMWARE))
-		checksum += sizeof(*hdr);
+		checksum += image_get_header_size ();
 	/* check the size does not exceed space in flash. HUSH scripts */
 	/* check the size does not exceed space in flash. HUSH scripts */
 	/* all have ausize[] set to 0 */
 	/* all have ausize[] set to 0 */
 	if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
 	if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
@@ -310,10 +311,10 @@ au_check_header_valid(int idx, long nbytes)
 	printf ("buf[0] %#x buf[1] %#x buf[2] %#x buf[3] %#x "
 	printf ("buf[0] %#x buf[1] %#x buf[2] %#x buf[3] %#x "
 		"as int %#x time %#x\n",
 		"as int %#x time %#x\n",
 		buf[0], buf[1], buf[2], buf[3],
 		buf[0], buf[1], buf[2], buf[3],
-		*((unsigned int *)buf), ntohl(hdr->ih_time));
+		*((unsigned int *)buf), image_get_time (hdr));
 #endif
 #endif
 	/* check it */
 	/* check it */
-	if (*((unsigned int *)buf) >= ntohl(hdr->ih_time)) {
+	if (*((unsigned int *)buf) >= image_get_time (hdr)) {
 		printf ("Image %s is too old\n", aufile[idx]);
 		printf ("Image %s is too old\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
@@ -335,16 +336,22 @@ au_do_update(int idx, long sz)
 	uint nbytes;
 	uint nbytes;
 
 
 	hdr = (image_header_t *)LOAD_ADDR;
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
 
 
 	/* disable the power switch */
 	/* disable the power switch */
 	*CPLD_VFD_BK |= POWER_OFF;
 	*CPLD_VFD_BK |= POWER_OFF;
 
 
 	/* execute a script */
 	/* execute a script */
-	if (hdr->ih_type == IH_TYPE_SCRIPT) {
-		addr = (char *)((char *)hdr + sizeof(*hdr));
+	if (image_check_type (hdr, IH_TYPE_SCRIPT)) {
+		addr = (char *)((char *)hdr + image_get_header_size ());
 		/* stick a NULL at the end of the script, otherwise */
 		/* stick a NULL at the end of the script, otherwise */
 		/* parse_string_outer() runs off the end. */
 		/* parse_string_outer() runs off the end. */
-		addr[ntohl(hdr->ih_size)] = 0;
+		addr[image_get_data_size (hdr)] = 0;
 		addr += 8;
 		addr += 8;
 		parse_string_outer(addr, FLAG_PARSE_SEMICOLON);
 		parse_string_outer(addr, FLAG_PARSE_SEMICOLON);
 		return 0;
 		return 0;
@@ -372,19 +379,20 @@ au_do_update(int idx, long sz)
 	flash_sect_erase(start, end);
 	flash_sect_erase(start, end);
 	wait_ms(100);
 	wait_ms(100);
 	/* strip the header - except for the kernel and ramdisk */
 	/* strip the header - except for the kernel and ramdisk */
-	if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) {
+	if (image_check_type (hdr, IH_TYPE_KERNEL) ||
+			image_check_type (hdr, IH_TYPE_RAMDISK)) {
 		addr = (char *)hdr;
 		addr = (char *)hdr;
-		off = sizeof(*hdr);
-		nbytes = sizeof(*hdr) + ntohl(hdr->ih_size);
+		off = image_get_header_size ();
+		nbytes = image_get_image_size (hdr);
 	} else {
 	} else {
-		addr = (char *)((char *)hdr + sizeof(*hdr));
+		addr = (char *)((char *)hdr + image_get_header_size ());
 #ifdef AU_UPDATE_TEST
 #ifdef AU_UPDATE_TEST
 		/* copy it to where Linux goes */
 		/* copy it to where Linux goes */
 		if (idx == IDX_FIRMWARE)
 		if (idx == IDX_FIRMWARE)
 			start = aufl_layout[1].start;
 			start = aufl_layout[1].start;
 #endif
 #endif
 		off = 0;
 		off = 0;
-		nbytes = ntohl(hdr->ih_size);
+		nbytes = image_get_data_size (hdr);
 	}
 	}
 
 
 	/* copy the data from RAM to FLASH */
 	/* copy the data from RAM to FLASH */
@@ -396,7 +404,8 @@ au_do_update(int idx, long sz)
 	}
 	}
 
 
 	/* check the dcrc of the copy */
 	/* check the dcrc of the copy */
-	if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) {
+	if (crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)) !=
+	    image_get_dcrc (hdr)) {
 		printf ("Image %s Bad Data Checksum After COPY\n", aufile[idx]);
 		printf ("Image %s Bad Data Checksum After COPY\n", aufile[idx]);
 		return -1;
 		return -1;
 	}
 	}
@@ -423,17 +432,24 @@ au_update_eeprom(int idx)
 	}
 	}
 
 
 	hdr = (image_header_t *)LOAD_ADDR;
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
+
 	/* write the time field into EEPROM */
 	/* write the time field into EEPROM */
 	off = auee_off[idx].time;
 	off = auee_off[idx].time;
-	val = ntohl(hdr->ih_time);
+	val = image_get_time (hdr);
 	i2c_write_multiple(0x54, off, 1, &val, sizeof(val));
 	i2c_write_multiple(0x54, off, 1, &val, sizeof(val));
 	/* write the size field into EEPROM */
 	/* write the size field into EEPROM */
 	off = auee_off[idx].size;
 	off = auee_off[idx].size;
-	val = ntohl(hdr->ih_size);
+	val = image_get_data_size (hdr);
 	i2c_write_multiple(0x54, off, 1, &val, sizeof(val));
 	i2c_write_multiple(0x54, off, 1, &val, sizeof(val));
 	/* write the dcrc field into EEPROM */
 	/* write the dcrc field into EEPROM */
 	off = auee_off[idx].dcrc;
 	off = auee_off[idx].dcrc;
-	val = ntohl(hdr->ih_dcrc);
+	val = image_get_dcrc (hdr);
 	i2c_write_multiple(0x54, off, 1, &val, sizeof(val));
 	i2c_write_multiple(0x54, off, 1, &val, sizeof(val));
 	/* enable the power switch */
 	/* enable the power switch */
 	*CPLD_VFD_BK &= ~POWER_OFF;
 	*CPLD_VFD_BK &= ~POWER_OFF;
@@ -577,10 +593,10 @@ do_auto_update(void)
 	/* just loop thru all the possible files */
 	/* just loop thru all the possible files */
 	for (i = 0; i < AU_MAXFILES; i++) {
 	for (i = 0; i < AU_MAXFILES; i++) {
 		/* just read the header */
 		/* just read the header */
-		sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t));
+		sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ());
 		debug ("read %s sz %ld hdr %d\n",
 		debug ("read %s sz %ld hdr %d\n",
-			aufile[i], sz, sizeof(image_header_t));
-		if (sz <= 0 || sz < sizeof(image_header_t)) {
+			aufile[i], sz, image_get_header_size ());
+		if (sz <= 0 || sz < image_get_header_size ()) {
 			debug ("%s not found\n", aufile[i]);
 			debug ("%s not found\n", aufile[i]);
 			continue;
 			continue;
 		}
 		}
@@ -590,8 +606,8 @@ do_auto_update(void)
 		}
 		}
 		sz = file_fat_read(aufile[i], LOAD_ADDR, MAX_LOADSZ);
 		sz = file_fat_read(aufile[i], LOAD_ADDR, MAX_LOADSZ);
 		debug ("read %s sz %ld hdr %d\n",
 		debug ("read %s sz %ld hdr %d\n",
-			aufile[i], sz, sizeof(image_header_t));
-		if (sz <= 0 || sz <= sizeof(image_header_t)) {
+			aufile[i], sz, image_get_header_size ());
+		if (sz <= 0 || sz <= image_get_header_size ()) {
 			debug ("%s not found\n", aufile[i]);
 			debug ("%s not found\n", aufile[i]);
 			continue;
 			continue;
 		}
 		}

+ 3 - 0
common/Makefile

@@ -36,6 +36,8 @@ COBJS-y += cmd_autoscript.o
 COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
 COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
 COBJS-$(CONFIG_CMD_BEDBUG) += cmd_bedbug.o
 COBJS-$(CONFIG_CMD_BEDBUG) += cmd_bedbug.o
 COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
 COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
+COBJS-y += image.o
+COBJS-y += gunzip.o
 COBJS-y += cmd_boot.o
 COBJS-y += cmd_boot.o
 COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
 COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
 COBJS-y += cmd_bootm.o
 COBJS-y += cmd_bootm.o
@@ -94,6 +96,7 @@ COBJS-$(CONFIG_CMD_STRINGS) += cmd_strings.o
 COBJS-$(CONFIG_CMD_TERMINAL) += cmd_terminal.o
 COBJS-$(CONFIG_CMD_TERMINAL) += cmd_terminal.o
 COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o
 COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o
 COBJS-$(CONFIG_CMD_USB) += cmd_usb.o
 COBJS-$(CONFIG_CMD_USB) += cmd_usb.o
+COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o
 COBJS-y += cmd_vfd.o
 COBJS-y += cmd_vfd.o
 COBJS-y += command.o
 COBJS-y += command.o
 COBJS-y += console.o
 COBJS-y += console.o

+ 107 - 46
common/cmd_autoscript.c

@@ -49,57 +49,110 @@
 
 
 #if defined(CONFIG_AUTOSCRIPT) || defined(CONFIG_CMD_AUTOSCRIPT)
 #if defined(CONFIG_AUTOSCRIPT) || defined(CONFIG_CMD_AUTOSCRIPT)
 
 
-extern image_header_t header;		/* from cmd_bootm.c */
 int
 int
-autoscript (ulong addr)
+autoscript (ulong addr, const char *fit_uname)
 {
 {
-	ulong crc, data, len;
-	image_header_t *hdr = &header;
-	ulong *len_ptr;
-	char *cmd;
-	int rcode = 0;
-	int verify;
+	ulong 		len;
+	image_header_t	*hdr;
+	ulong		*data;
+	char		*cmd;
+	int		rcode = 0;
+	int		verify;
+#if defined(CONFIG_FIT)
+	const void*	fit_hdr;
+	int		noffset;
+	const void	*fit_data;
+	size_t		fit_len;
+#endif
 
 
-	cmd = getenv ("verify");
-	verify = (cmd && (*cmd == 'n')) ? 0 : 1;
+	verify = getenv_verify ();
 
 
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
 
 
-	memmove (hdr, (char *)addr, sizeof(image_header_t));
+		if (!image_check_magic (hdr)) {
+			puts ("Bad magic number\n");
+			return 1;
+		}
 
 
-	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-		puts ("Bad magic number\n");
-		return 1;
-	}
+		if (!image_check_hcrc (hdr)) {
+			puts ("Bad header crc\n");
+			return 1;
+		}
 
 
-	crc = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
-	len = sizeof (image_header_t);
-	data = (ulong)hdr;
-	if (crc32(0, (uchar *)data, len) != crc) {
-		puts ("Bad header crc\n");
-		return 1;
-	}
+		if (verify) {
+			if (!image_check_dcrc (hdr)) {
+				puts ("Bad data crc\n");
+				return 1;
+			}
+		}
 
 
-	data = addr + sizeof(image_header_t);
-	len = ntohl(hdr->ih_size);
+		if (!image_check_type (hdr, IH_TYPE_SCRIPT)) {
+			puts ("Bad image type\n");
+			return 1;
+		}
+
+		/* get length of script */
+		data = (ulong *)image_get_data (hdr);
 
 
-	if (verify) {
-		if (crc32(0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) {
-			puts ("Bad data crc\n");
+		if ((len = uimage_to_cpu (*data)) == 0) {
+			puts ("Empty Script\n");
 			return 1;
 			return 1;
 		}
 		}
-	}
 
 
-	if (hdr->ih_type != IH_TYPE_SCRIPT) {
-		puts ("Bad image type\n");
-		return 1;
-	}
+		/*
+		 * scripts are just multi-image files with one component, seek
+		 * past the zero-terminated sequence of image lengths to get
+		 * to the actual image data
+		 */
+		while (*data++);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		if (fit_uname == NULL) {
+			puts ("No FIT subimage unit name\n");
+			return 1;
+		}
 
 
-	/* get length of script */
-	len_ptr = (ulong *)data;
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			puts ("Bad FIT image format\n");
+			return 1;
+		}
+
+		/* get script component image node offset */
+		noffset = fit_image_get_node (fit_hdr, fit_uname);
+		if (noffset < 0) {
+			printf ("Can't find '%s' FIT subimage\n", fit_uname);
+			return 1;
+		}
+
+		if (!fit_image_check_type (fit_hdr, noffset, IH_TYPE_SCRIPT)) {
+			puts ("Not a image image\n");
+			return 1;
+		}
+
+		/* verify integrity */
+		if (verify) {
+			if (!fit_image_check_hashes (fit_hdr, noffset)) {
+				puts ("Bad Data Hash\n");
+				return 1;
+			}
+		}
 
 
-	if ((len = ntohl(*len_ptr)) == 0) {
-		puts ("Empty Script\n");
+		/* get script subimage data address and length */
+		if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) {
+			puts ("Could not find script subimage data\n");
+			return 1;
+		}
+
+		data = (ulong *)fit_data;
+		len = (ulong)fit_len;
+		break;
+#endif
+	default:
+		puts ("Wrong image format for autoscript\n");
 		return 1;
 		return 1;
 	}
 	}
 
 
@@ -109,10 +162,8 @@ autoscript (ulong addr)
 		return 1;
 		return 1;
 	}
 	}
 
 
-	while (*len_ptr++);
-
 	/* make sure cmd is null terminated */
 	/* make sure cmd is null terminated */
-	memmove (cmd, (char *)len_ptr, len);
+	memmove (cmd, (char *)data, len);
 	*(cmd + len) = 0;
 	*(cmd + len) = 0;
 
 
 #ifdef CFG_HUSH_PARSER /*?? */
 #ifdef CFG_HUSH_PARSER /*?? */
@@ -158,25 +209,35 @@ do_autoscript (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 {
 	ulong addr;
 	ulong addr;
 	int rcode;
 	int rcode;
+	const char *fit_uname = NULL;
 
 
+	/* Find script image */
 	if (argc < 2) {
 	if (argc < 2) {
 		addr = CFG_LOAD_ADDR;
 		addr = CFG_LOAD_ADDR;
+		debug ("*  autoscr: default load address = 0x%08lx\n", addr);
+#if defined(CONFIG_FIT)
+	} else if (fit_parse_subimage (argv[1], load_addr, &addr, &fit_uname)) {
+		debug ("*  autoscr: subimage '%s' from FIT image at 0x%08lx\n",
+				fit_uname, addr);
+#endif
 	} else {
 	} else {
-		addr = simple_strtoul (argv[1],0,16);
+		addr = simple_strtoul(argv[1], NULL, 16);
+		debug ("*  autoscr: cmdline image address = 0x%08lx\n", addr);
 	}
 	}
 
 
-	printf ("## Executing script at %08lx\n",addr);
-	rcode = autoscript (addr);
+	printf ("## Executing script at %08lx\n", addr);
+	rcode = autoscript (addr, fit_uname);
 	return rcode;
 	return rcode;
 }
 }
 
 
-#if defined(CONFIG_CMD_AUTOSCRIPT)
 U_BOOT_CMD(
 U_BOOT_CMD(
 	autoscr, 2, 0,	do_autoscript,
 	autoscr, 2, 0,	do_autoscript,
 	"autoscr - run script from memory\n",
 	"autoscr - run script from memory\n",
 	"[addr] - run script starting at addr"
 	"[addr] - run script starting at addr"
 	" - A valid autoscr header must be present\n"
 	" - A valid autoscr header must be present\n"
-);
+#if defined(CONFIG_FIT)
+	"For FIT format uImage addr must include subimage\n"
+	"unit name in the form of addr:<subimg_uname>\n"
 #endif
 #endif
-
+);
 #endif
 #endif

File diff suppressed because it is too large
+ 603 - 800
common/cmd_bootm.c


+ 31 - 7
common/cmd_doc.c

@@ -205,6 +205,9 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	ulong offset = 0;
 	ulong offset = 0;
 	image_header_t *hdr;
 	image_header_t *hdr;
 	int rcode = 0;
 	int rcode = 0;
+#if defined(CONFIG_FIT)
+	const void *fit_hdr;
+#endif
 
 
 	show_boot_progress (34);
 	show_boot_progress (34);
 	switch (argc) {
 	switch (argc) {
@@ -261,21 +264,36 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	}
 	}
 	show_boot_progress (38);
 	show_boot_progress (38);
 
 
-	hdr = (image_header_t *)addr;
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
 
 
-	if (hdr->ih_magic == IH_MAGIC) {
+		image_print_contents (hdr);
 
 
-		print_image_hdr (hdr);
+		cnt = image_get_image_size (hdr);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			show_boot_progress (-130);
+			puts ("** Bad FIT image format\n");
+			return 1;
+		}
+		show_boot_progress (131);
+		puts ("Fit image detected...\n");
 
 
-		cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
-		cnt -= SECTORSIZE;
-	} else {
-		puts ("\n** Bad Magic Number **\n");
+		cnt = fit_get_size (fit_hdr);
+		break;
+#endif
+	default:
 		show_boot_progress (-39);
 		show_boot_progress (-39);
+		puts ("** Unknown image type\n");
 		return 1;
 		return 1;
 	}
 	}
 	show_boot_progress (39);
 	show_boot_progress (39);
 
 
+	cnt -= SECTORSIZE;
 	if (doc_rw (doc_dev_desc + dev, 1, offset + SECTORSIZE, cnt,
 	if (doc_rw (doc_dev_desc + dev, 1, offset + SECTORSIZE, cnt,
 		    NULL, (u_char *)(addr+SECTORSIZE))) {
 		    NULL, (u_char *)(addr+SECTORSIZE))) {
 		printf ("** Read error on %d\n", dev);
 		printf ("** Read error on %d\n", dev);
@@ -284,6 +302,12 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	}
 	}
 	show_boot_progress (40);
 	show_boot_progress (40);
 
 
+#if defined(CONFIG_FIT)
+	/* This cannot be done earlier, we need complete FIT image in RAM first */
+	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
+		fit_print_contents ((const void *)addr);
+#endif
+
 	/* Loading ok, update default load address */
 	/* Loading ok, update default load address */
 
 
 	load_addr = addr;
 	load_addr = addr;

+ 42 - 17
common/cmd_fdc.c

@@ -788,6 +788,9 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	int i,nrofblk;
 	int i,nrofblk;
 	char *ep;
 	char *ep;
 	int rcode = 0;
 	int rcode = 0;
+#if defined(CONFIG_FIT)
+	const void *fit_hdr;
+#endif
 
 
 	switch (argc) {
 	switch (argc) {
 	case 1:
 	case 1:
@@ -835,14 +838,31 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 			printf("result%d: 0x%02X\n",i,pCMD->result[i]);
 			printf("result%d: 0x%02X\n",i,pCMD->result[i]);
 		return 1;
 		return 1;
 	}
 	}
-	hdr = (image_header_t *)addr;
-	if (ntohl(hdr->ih_magic)  != IH_MAGIC) {
-		printf ("Bad Magic Number\n");
+
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
+		image_print_contents (hdr);
+
+		imsize = image_get_image_size (hdr);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			puts ("** Bad FIT image format\n");
+			return 1;
+		}
+		puts ("Fit image detected...\n");
+
+		imsize = fit_get_size (fit_hdr);
+		break;
+#endif
+	default:
+		puts ("** Unknown image type\n");
 		return 1;
 		return 1;
 	}
 	}
-	print_image_hdr(hdr);
 
 
-	imsize= ntohl(hdr->ih_size)+sizeof(image_header_t);
 	nrofblk=imsize/512;
 	nrofblk=imsize/512;
 	if((imsize%512)>0)
 	if((imsize%512)>0)
 		nrofblk++;
 		nrofblk++;
@@ -858,23 +878,28 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	printf("OK %ld Bytes loaded.\n",imsize);
 	printf("OK %ld Bytes loaded.\n",imsize);
 
 
 	flush_cache (addr, imsize);
 	flush_cache (addr, imsize);
-	/* Loading ok, update default load address */
 
 
+#if defined(CONFIG_FIT)
+	/* This cannot be done earlier, we need complete FIT image in RAM first */
+	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
+		fit_print_contents ((const void *)addr);
+#endif
+
+	/* Loading ok, update default load address */
 	load_addr = addr;
 	load_addr = addr;
-	if(hdr->ih_type  == IH_TYPE_KERNEL) {
-		/* Check if we should attempt an auto-start */
-		if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
-			char *local_args[2];
-			extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
 
 
-			local_args[0] = argv[0];
-			local_args[1] = NULL;
+	/* Check if we should attempt an auto-start */
+	if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
+		char *local_args[2];
+		extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
 
 
-			printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
+		local_args[0] = argv[0];
+		local_args[1] = NULL;
 
 
-			do_bootm (cmdtp, 0, 1, local_args);
-			rcode ++;
-		}
+		printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
+
+		do_bootm (cmdtp, 0, 1, local_args);
+		rcode ++;
 	}
 	}
 	return rcode;
 	return rcode;
 }
 }

+ 94 - 15
common/cmd_fpga.c

@@ -164,6 +164,10 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 	char *devstr = getenv ("fpga");
 	char *devstr = getenv ("fpga");
 	char *datastr = getenv ("fpgadata");
 	char *datastr = getenv ("fpgadata");
 	int rc = FPGA_FAIL;
 	int rc = FPGA_FAIL;
+#if defined (CONFIG_FIT)
+	const char *fit_uname = NULL;
+	ulong fit_addr;
+#endif
 
 
 	if (devstr)
 	if (devstr)
 		dev = (int) simple_strtoul (devstr, NULL, 16);
 		dev = (int) simple_strtoul (devstr, NULL, 16);
@@ -173,9 +177,22 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 	switch (argc) {
 	switch (argc) {
 	case 5:		/* fpga <op> <dev> <data> <datasize> */
 	case 5:		/* fpga <op> <dev> <data> <datasize> */
 		data_size = simple_strtoul (argv[4], NULL, 16);
 		data_size = simple_strtoul (argv[4], NULL, 16);
+
 	case 4:		/* fpga <op> <dev> <data> */
 	case 4:		/* fpga <op> <dev> <data> */
-		fpga_data = (void *) simple_strtoul (argv[3], NULL, 16);
+#if defined(CONFIG_FIT)
+		if (fit_parse_subimage (argv[3], (ulong)fpga_data,
+					&fit_addr, &fit_uname)) {
+			fpga_data = (void *)fit_addr;
+			debug ("*  fpga: subimage '%s' from FIT image at 0x%08lx\n",
+					fit_uname, fit_addr);
+		} else
+#endif
+		{
+			fpga_data = (void *) simple_strtoul (argv[3], NULL, 16);
+			debug ("*  fpga: cmdline image address = 0x%08lx\n", (ulong)fpga_data);
+		}
 		PRINTF ("%s: fpga_data = 0x%x\n", __FUNCTION__, (uint) fpga_data);
 		PRINTF ("%s: fpga_data = 0x%x\n", __FUNCTION__, (uint) fpga_data);
+
 	case 3:		/* fpga <op> <dev | data addr> */
 	case 3:		/* fpga <op> <dev | data addr> */
 		dev = (int) simple_strtoul (argv[2], NULL, 16);
 		dev = (int) simple_strtoul (argv[2], NULL, 16);
 		PRINTF ("%s: device = %d\n", __FUNCTION__, dev);
 		PRINTF ("%s: device = %d\n", __FUNCTION__, dev);
@@ -183,14 +200,29 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 		if ((argc == 3) && (dev > fpga_count ())) {	/* must be buffer ptr */
 		if ((argc == 3) && (dev > fpga_count ())) {	/* must be buffer ptr */
 			PRINTF ("%s: Assuming buffer pointer in arg 3\n",
 			PRINTF ("%s: Assuming buffer pointer in arg 3\n",
 				__FUNCTION__);
 				__FUNCTION__);
-			fpga_data = (void *) dev;
+
+#if defined(CONFIG_FIT)
+			if (fit_parse_subimage (argv[2], (ulong)fpga_data,
+						&fit_addr, &fit_uname)) {
+				fpga_data = (void *)fit_addr;
+				debug ("*  fpga: subimage '%s' from FIT image at 0x%08lx\n",
+						fit_uname, fit_addr);
+			} else
+#endif
+			{
+				fpga_data = (void *) dev;
+				debug ("*  fpga: cmdline image address = 0x%08lx\n", (ulong)fpga_data);
+			}
+
 			PRINTF ("%s: fpga_data = 0x%x\n",
 			PRINTF ("%s: fpga_data = 0x%x\n",
 				__FUNCTION__, (uint) fpga_data);
 				__FUNCTION__, (uint) fpga_data);
 			dev = FPGA_INVALID_DEVICE;	/* reset device num */
 			dev = FPGA_INVALID_DEVICE;	/* reset device num */
 		}
 		}
+
 	case 2:		/* fpga <op> */
 	case 2:		/* fpga <op> */
 		op = (int) fpga_get_op (argv[1]);
 		op = (int) fpga_get_op (argv[1]);
 		break;
 		break;
+
 	default:
 	default:
 		PRINTF ("%s: Too many or too few args (%d)\n",
 		PRINTF ("%s: Too many or too few args (%d)\n",
 			__FUNCTION__, argc);
 			__FUNCTION__, argc);
@@ -216,19 +248,61 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 		break;
 		break;
 
 
 	case FPGA_LOADMK:
 	case FPGA_LOADMK:
-		{
-			image_header_t header;
-			image_header_t *hdr = &header;
-			ulong	data;
-
-			memmove (&header, (char *)fpga_data, sizeof(image_header_t));
-			if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-				puts ("Bad Magic Number\n");
-				return 1;
+		switch (genimg_get_format (fpga_data)) {
+		case IMAGE_FORMAT_LEGACY:
+			{
+				image_header_t *hdr = (image_header_t *)fpga_data;
+				ulong	data;
+
+				data = (ulong)image_get_data (hdr);
+				data_size = image_get_data_size (hdr);
+				rc = fpga_load (dev, (void *)data, data_size);
+			}
+			break;
+#if defined(CONFIG_FIT)
+		case IMAGE_FORMAT_FIT:
+			{
+				const void *fit_hdr = (const void *)fpga_data;
+				int noffset;
+				void *fit_data;
+
+				if (fit_uname == NULL) {
+					puts ("No FIT subimage unit name\n");
+					return 1;
+				}
+
+				if (!fit_check_format (fit_hdr)) {
+					puts ("Bad FIT image format\n");
+					return 1;
+				}
+
+				/* get fpga component image node offset */
+				noffset = fit_image_get_node (fit_hdr, fit_uname);
+				if (noffset < 0) {
+					printf ("Can't find '%s' FIT subimage\n", fit_uname);
+					return 1;
+				}
+
+				/* verify integrity */
+				if (!fit_image_check_hashes (fit_hdr, noffset)) {
+					puts ("Bad Data Hash\n");
+					return 1;
+				}
+
+				/* get fpga subimage data address and length */
+				if (fit_image_get_data (fit_hdr, noffset, &fit_data, &data_size)) {
+					puts ("Could not find fpga subimage data\n");
+					return 1;
+				}
+
+				rc = fpga_load (dev, fit_data, data_size);
 			}
 			}
-			data = ((ulong)fpga_data + sizeof(image_header_t));
-			data_size  = ntohl(hdr->ih_size);
-			rc = fpga_load (dev, (void *)data, data_size);
+			break;
+#endif
+		default:
+			puts ("** Unknown image type\n");
+			rc = FPGA_FAIL;
+			break;
 		}
 		}
 		break;
 		break;
 
 
@@ -283,4 +357,9 @@ U_BOOT_CMD (fpga, 6, 1, do_fpga,
 	    "\tload\tLoad device from memory buffer\n"
 	    "\tload\tLoad device from memory buffer\n"
 	    "\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n"
 	    "\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n"
 	    "\tloadmk\tLoad device generated with mkimage\n"
 	    "\tloadmk\tLoad device generated with mkimage\n"
-	    "\tdump\tLoad device to memory buffer\n");
+	    "\tdump\tLoad device to memory buffer\n"
+#if defined(CONFIG_FIT)
+	    "\tFor loadmk operating on FIT format uImage address must include\n"
+	    "\tsubimage unit name in the form of addr:<subimg_uname>\n"
+#endif
+);

+ 40 - 18
common/cmd_ide.c

@@ -366,10 +366,13 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	char *boot_device = NULL;
 	char *boot_device = NULL;
 	char *ep;
 	char *ep;
 	int dev, part = 0;
 	int dev, part = 0;
-	ulong addr, cnt, checksum;
+	ulong addr, cnt;
 	disk_partition_t info;
 	disk_partition_t info;
 	image_header_t *hdr;
 	image_header_t *hdr;
 	int rcode = 0;
 	int rcode = 0;
+#if defined(CONFIG_FIT)
+	const void *fit_hdr;
+#endif
 
 
 	show_boot_progress (41);
 	show_boot_progress (41);
 	switch (argc) {
 	switch (argc) {
@@ -446,29 +449,43 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	}
 	}
 	show_boot_progress (48);
 	show_boot_progress (48);
 
 
-	hdr = (image_header_t *)addr;
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
 
 
-	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-		printf("\n** Bad Magic Number **\n");
-		show_boot_progress (-49);
-		return 1;
-	}
-	show_boot_progress (49);
+		show_boot_progress (49);
 
 
-	checksum = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
+		if (!image_check_hcrc (hdr)) {
+			puts ("\n** Bad Header Checksum **\n");
+			show_boot_progress (-50);
+			return 1;
+		}
+		show_boot_progress (50);
+
+		image_print_contents (hdr);
 
 
-	if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) {
-		puts ("\n** Bad Header Checksum **\n");
-		show_boot_progress (-50);
+		cnt = image_get_image_size (hdr);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			show_boot_progress (-140);
+			puts ("** Bad FIT image format\n");
+			return 1;
+		}
+		show_boot_progress (141);
+		puts ("Fit image detected...\n");
+
+		cnt = fit_get_size (fit_hdr);
+		break;
+#endif
+	default:
+		show_boot_progress (-49);
+		puts ("** Unknown image type\n");
 		return 1;
 		return 1;
 	}
 	}
-	show_boot_progress (50);
-	hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */
 
 
-	print_image_hdr (hdr);
-
-	cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
 	cnt += info.blksz - 1;
 	cnt += info.blksz - 1;
 	cnt /= info.blksz;
 	cnt /= info.blksz;
 	cnt -= 1;
 	cnt -= 1;
@@ -481,6 +498,11 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	}
 	}
 	show_boot_progress (51);
 	show_boot_progress (51);
 
 
+#if defined(CONFIG_FIT)
+	/* This cannot be done earlier, we need complete FIT image in RAM first */
+	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
+		fit_print_contents ((const void *)addr);
+#endif
 
 
 	/* Loading ok, update default load address */
 	/* Loading ok, update default load address */
 
 

+ 9 - 2
common/cmd_load.c

@@ -521,8 +521,15 @@ int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		char *s;
 		char *s;
 
 
 		if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
 		if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
-			printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
-			rcode = autoscript (load_addr);
+			printf ("Running autoscript at addr 0x%08lX", load_addr);
+
+			s = getenv ("autoscript_uname");
+			if (s)
+				printf (":%s ...\n", s);
+			else
+				puts (" ...\n");
+
+			rcode = autoscript (load_addr, s);
 		}
 		}
 	}
 	}
 #endif
 #endif

+ 65 - 15
common/cmd_nand.c

@@ -484,6 +484,9 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
 	ulong cnt;
 	ulong cnt;
 	image_header_t *hdr;
 	image_header_t *hdr;
 	int jffs2 = 0;
 	int jffs2 = 0;
+#if defined(CONFIG_FIT)
+	const void *fit_hdr;
+#endif
 
 
 	s = strchr(cmd, '.');
 	s = strchr(cmd, '.');
 	if (s != NULL &&
 	if (s != NULL &&
@@ -512,18 +515,35 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
 	}
 	}
 	show_boot_progress (56);
 	show_boot_progress (56);
 
 
-	hdr = (image_header_t *) addr;
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
+
+		show_boot_progress (57);
+		image_print_contents (hdr);
 
 
-	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-		printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic);
+		cnt = image_get_image_size (hdr);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			show_boot_progress (-150);
+			puts ("** Bad FIT image format\n");
+			return 1;
+		}
+		show_boot_progress (151);
+		puts ("Fit image detected...\n");
+
+		cnt = fit_get_size (fit_hdr);
+		break;
+#endif
+	default:
 		show_boot_progress (-57);
 		show_boot_progress (-57);
+		puts ("** Unknown image type\n");
 		return 1;
 		return 1;
 	}
 	}
-	show_boot_progress (57);
-
-	print_image_hdr(hdr);
 
 
-	cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t));
 	if (jffs2) {
 	if (jffs2) {
 		nand_read_options_t opts;
 		nand_read_options_t opts;
 		memset(&opts, 0, sizeof(opts));
 		memset(&opts, 0, sizeof(opts));
@@ -543,6 +563,12 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
 	}
 	}
 	show_boot_progress (58);
 	show_boot_progress (58);
 
 
+#if defined(CONFIG_FIT)
+	/* This cannot be done earlier, we need complete FIT image in RAM first */
+	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
+		fit_print_contents ((const void *)addr);
+#endif
+
 	/* Loading ok, update default load address */
 	/* Loading ok, update default load address */
 
 
 	load_addr = addr;
 	load_addr = addr;
@@ -925,6 +951,10 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	ulong offset = 0;
 	ulong offset = 0;
 	image_header_t *hdr;
 	image_header_t *hdr;
 	int rcode = 0;
 	int rcode = 0;
+#if defined(CONFIG_FIT)
+	const void *fit_hdr;
+#endif
+
 	show_boot_progress (52);
 	show_boot_progress (52);
 	switch (argc) {
 	switch (argc) {
 	case 1:
 	case 1:
@@ -980,17 +1010,31 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	}
 	}
 	show_boot_progress (56);
 	show_boot_progress (56);
 
 
-	hdr = (image_header_t *)addr;
-
-	if (ntohl(hdr->ih_magic) == IH_MAGIC) {
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
+		image_print_contents (hdr);
 
 
-		print_image_hdr (hdr);
-
-		cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
+		cnt = image_get_image_size (hdr);
 		cnt -= SECTORSIZE;
 		cnt -= SECTORSIZE;
-	} else {
-		printf ("\n** Bad Magic Number 0x%x **\n", ntohl(hdr->ih_magic));
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			show_boot_progress (-150);
+			puts ("** Bad FIT image format\n");
+			return 1;
+		}
+		show_boot_progress (151);
+		puts ("Fit image detected...\n");
+
+		cnt = fit_get_size (fit_hdr);
+		break;
+#endif
+	default:
 		show_boot_progress (-57);
 		show_boot_progress (-57);
+		puts ("** Unknown image type\n");
 		return 1;
 		return 1;
 	}
 	}
 	show_boot_progress (57);
 	show_boot_progress (57);
@@ -1004,6 +1048,12 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	}
 	}
 	show_boot_progress (58);
 	show_boot_progress (58);
 
 
+#if defined(CONFIG_FIT)
+	/* This cannot be done earlier, we need complete FIT image in RAM first */
+	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
+		fit_print_contents ((const void *)addr);
+#endif
+
 	/* Loading ok, update default load address */
 	/* Loading ok, update default load address */
 
 
 	load_addr = addr;
 	load_addr = addr;

+ 9 - 2
common/cmd_net.c

@@ -220,9 +220,16 @@ netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
 
 
 #ifdef CONFIG_AUTOSCRIPT
 #ifdef CONFIG_AUTOSCRIPT
 	if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
 	if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
-		printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
+		printf ("Running autoscript at addr 0x%08lX", load_addr);
+
+		s = getenv ("autoscript_uname");
+		if (s)
+			printf (":%s ...\n", s);
+		else
+			puts (" ...\n");
+
 		show_boot_progress (83);
 		show_boot_progress (83);
-		rcode = autoscript (load_addr);
+		rcode = autoscript (load_addr, s);
 	}
 	}
 #endif
 #endif
 	if (rcode < 0)
 	if (rcode < 0)

+ 34 - 13
common/cmd_scsi.c

@@ -207,10 +207,13 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	char *boot_device = NULL;
 	char *boot_device = NULL;
 	char *ep;
 	char *ep;
 	int dev, part = 0;
 	int dev, part = 0;
-	ulong addr, cnt, checksum;
+	ulong addr, cnt;
 	disk_partition_t info;
 	disk_partition_t info;
 	image_header_t *hdr;
 	image_header_t *hdr;
 	int rcode = 0;
 	int rcode = 0;
+#if defined(CONFIG_FIT)
+	const void *fit_hdr;
+#endif
 
 
 	switch (argc) {
 	switch (argc) {
 	case 1:
 	case 1:
@@ -273,24 +276,35 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		return 1;
 		return 1;
 	}
 	}
 
 
-	hdr = (image_header_t *)addr;
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
 
 
-	if (ntohl(hdr->ih_magic) == IH_MAGIC) {
-		printf("\n** Bad Magic Number **\n");
-		return 1;
-	}
+		if (!image_check_hcrc (hdr)) {
+			puts ("\n** Bad Header Checksum **\n");
+			return 1;
+		}
 
 
-	checksum = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
+		image_print_contents (hdr);
+		cnt = image_get_image_size (hdr);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			puts ("** Bad FIT image format\n");
+			return 1;
+		}
+		puts ("Fit image detected...\n");
 
 
-	if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) {
-		puts ("\n** Bad Header Checksum **\n");
+		cnt = fit_get_size (fit_hdr);
+		break;
+#endif
+	default:
+		puts ("** Unknown image type\n");
 		return 1;
 		return 1;
 	}
 	}
-	hdr->ih_hcrc = htonl(checksum);	/* restore checksum for later use */
 
 
-	print_image_hdr (hdr);
-	cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
 	cnt += info.blksz - 1;
 	cnt += info.blksz - 1;
 	cnt /= info.blksz;
 	cnt /= info.blksz;
 	cnt -= 1;
 	cnt -= 1;
@@ -300,6 +314,13 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		printf ("** Read error on %d:%d\n", dev, part);
 		printf ("** Read error on %d:%d\n", dev, part);
 		return 1;
 		return 1;
 	}
 	}
+
+#if defined(CONFIG_FIT)
+	/* This cannot be done earlier, we need complete FIT image in RAM first */
+	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
+		fit_print_contents ((const void *)addr);
+#endif
+
 	/* Loading ok, update default load address */
 	/* Loading ok, update default load address */
 	load_addr = addr;
 	load_addr = addr;
 
 

+ 35 - 15
common/cmd_usb.c

@@ -311,11 +311,13 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	char *boot_device = NULL;
 	char *boot_device = NULL;
 	char *ep;
 	char *ep;
 	int dev, part=1, rcode;
 	int dev, part=1, rcode;
-	ulong addr, cnt, checksum;
+	ulong addr, cnt;
 	disk_partition_t info;
 	disk_partition_t info;
 	image_header_t *hdr;
 	image_header_t *hdr;
 	block_dev_desc_t *stor_dev;
 	block_dev_desc_t *stor_dev;
-
+#if defined(CONFIG_FIT)
+	const void *fit_hdr;
+#endif
 
 
 	switch (argc) {
 	switch (argc) {
 	case 1:
 	case 1:
@@ -386,25 +388,36 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		return 1;
 		return 1;
 	}
 	}
 
 
-	hdr = (image_header_t *)addr;
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
 
 
-	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-		printf("\n** Bad Magic Number **\n");
-		return 1;
-	}
+		if (!image_check_hcrc (hdr)) {
+			puts ("\n** Bad Header Checksum **\n");
+			return 1;
+		}
 
 
-	checksum = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
+		image_print_contents (hdr);
 
 
-	if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) {
-		puts ("\n** Bad Header Checksum **\n");
+		cnt = image_get_image_size (hdr);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			puts ("** Bad FIT image format\n");
+			return 1;
+		}
+		puts ("Fit image detected...\n");
+
+		cnt = fit_get_size (fit_hdr);
+		break;
+#endif
+	default:
+		puts ("** Unknown image type\n");
 		return 1;
 		return 1;
 	}
 	}
-	hdr->ih_hcrc = htonl(checksum);	/* restore checksum for later use */
 
 
-	print_image_hdr (hdr);
-
-	cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
 	cnt += info.blksz - 1;
 	cnt += info.blksz - 1;
 	cnt /= info.blksz;
 	cnt /= info.blksz;
 	cnt -= 1;
 	cnt -= 1;
@@ -414,6 +427,13 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		printf ("\n** Read error on %d:%d\n", dev, part);
 		printf ("\n** Read error on %d:%d\n", dev, part);
 		return 1;
 		return 1;
 	}
 	}
+
+#if defined(CONFIG_FIT)
+	/* This cannot be done earlier, we need complete FIT image in RAM first */
+	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
+		fit_print_contents ((const void *)addr);
+#endif
+
 	/* Loading ok, update default load address */
 	/* Loading ok, update default load address */
 	load_addr = addr;
 	load_addr = addr;
 
 

+ 107 - 61
common/cmd_ximg.c

@@ -24,7 +24,6 @@
  * MA 02111-1307 USA
  * MA 02111-1307 USA
  */
  */
 
 
-#if defined(CONFIG_CMD_XIMG)
 
 
 /*
 /*
  * Multi Image extract
  * Multi Image extract
@@ -37,92 +36,136 @@
 int
 int
 do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 {
 {
-	ulong addr = load_addr, dest = 0;
-	ulong data, len, checksum;
-	ulong *len_ptr;
-	int i, verify, part = 0;
-	char pbuf[10], *s;
-	image_header_t header;
+	ulong		addr = load_addr;
+	ulong		dest = 0;
+	ulong		data, len, count;
+	int		verify;
+	int		part = 0;
+	char		pbuf[10];
+	image_header_t	*hdr;
+#if defined(CONFIG_FIT)
+	const char	*uname = NULL;
+	const void*	fit_hdr;
+	int		noffset;
+	const void	*fit_data;
+	size_t		fit_len;
+#endif
 
 
-	s = getenv("verify");
-	verify = (s && (*s == 'n')) ? 0 : 1;
+	verify = getenv_verify ();
 
 
 	if (argc > 1) {
 	if (argc > 1) {
 		addr = simple_strtoul(argv[1], NULL, 16);
 		addr = simple_strtoul(argv[1], NULL, 16);
 	}
 	}
 	if (argc > 2) {
 	if (argc > 2) {
 		part = simple_strtoul(argv[2], NULL, 16);
 		part = simple_strtoul(argv[2], NULL, 16);
+#if defined(CONFIG_FIT)
+		uname = argv[2];
+#endif
 	}
 	}
 	if (argc > 3) {
 	if (argc > 3) {
 		dest = simple_strtoul(argv[3], NULL, 16);
 		dest = simple_strtoul(argv[3], NULL, 16);
 	}
 	}
 
 
-	printf("## Copying from image at %08lx ...\n", addr);
-
-	/* Copy header so we can blank CRC field for re-calculation */
-	memmove(&header, (char *) addr, sizeof (image_header_t));
-
-	if (ntohl(header.ih_magic) != IH_MAGIC) {
-		printf("Bad Magic Number\n");
-		return 1;
-	}
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
 
 
-	data = (ulong) & header;
-	len = sizeof (image_header_t);
+		printf("## Copying part %d from legacy image "
+			"at %08lx ...\n", part, addr);
 
 
-	checksum = ntohl(header.ih_hcrc);
-	header.ih_hcrc = 0;
+		hdr = (image_header_t *)addr;
+		if (!image_check_magic (hdr)) {
+			printf("Bad Magic Number\n");
+			return 1;
+		}
 
 
-	if (crc32(0, (char *) data, len) != checksum) {
-		printf("Bad Header Checksum\n");
-		return 1;
-	}
+		if (!image_check_hcrc (hdr)) {
+			printf("Bad Header Checksum\n");
+			return 1;
+		}
 #ifdef DEBUG
 #ifdef DEBUG
-	print_image_hdr((image_header_t *) addr);
+		image_print_contents (hdr);
 #endif
 #endif
 
 
-	data = addr + sizeof (image_header_t);
-	len = ntohl(header.ih_size);
+		if (!image_check_type (hdr, IH_TYPE_MULTI)) {
+			printf("Wrong Image Type for %s command\n",
+					cmdtp->name);
+			return 1;
+		}
 
 
-	if (header.ih_type != IH_TYPE_MULTI) {
-		printf("Wrong Image Type for %s command\n", cmdtp->name);
-		return 1;
-	}
+		if (image_get_comp (hdr) != IH_COMP_NONE) {
+			printf("Wrong Compression Type for %s command\n",
+					cmdtp->name);
+			return 1;
+		}
 
 
-	if (header.ih_comp != IH_COMP_NONE) {
-		printf("Wrong Compression Type for %s command\n", cmdtp->name);
-		return 1;
-	}
+		if (verify) {
+			printf("   Verifying Checksum ... ");
+			if (!image_check_dcrc (hdr)) {
+				printf("Bad Data CRC\n");
+				return 1;
+			}
+			printf("OK\n");
+		}
 
 
-	if (verify) {
-		printf("   Verifying Checksum ... ");
-		if (crc32(0, (char *) data, len) != ntohl(header.ih_dcrc)) {
-			printf("Bad Data CRC\n");
+		count = image_multi_count (hdr);
+		if (part >= count) {
+			printf("Bad Image Part\n");
+			return 1;
+		}
+
+		image_multi_getimg (hdr, part, &data, &len);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		if (uname == NULL) {
+			puts ("No FIT subimage unit name\n");
+			return 1;
+		}
+
+		printf("## Copying '%s' subimage from FIT image "
+			"at %08lx ...\n", uname, addr);
+
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			puts ("Bad FIT image format\n");
+			return 1;
+		}
+
+		/* get subimage node offset */
+		noffset = fit_image_get_node (fit_hdr, uname);
+		if (noffset < 0) {
+			printf ("Can't find '%s' FIT subimage\n", uname);
 			return 1;
 			return 1;
 		}
 		}
-		printf("OK\n");
-	}
 
 
-	len_ptr = (ulong *) data;
-
-	data += 4;		/* terminator */
-	for (i = 0; len_ptr[i]; ++i) {
-		data += 4;
-		if (argc > 2 && part > i) {
-			u_long tail;
-			len = ntohl(len_ptr[i]);
-			tail = len % 4;
-			data += len;
-			if (tail) {
-				data += 4 - tail;
+		if (fit_image_check_comp (fit_hdr, noffset, IH_COMP_NONE)) {
+			printf("Wrong Compression Type for %s command\n",
+					cmdtp->name);
+			return 1;
+		}
+
+		/* verify integrity */
+		if (verify) {
+			if (!fit_image_check_hashes (fit_hdr, noffset)) {
+				puts ("Bad Data Hash\n");
+				return 1;
 			}
 			}
 		}
 		}
-	}
-	if (argc > 2 && part >= i) {
-		printf("Bad Image Part\n");
+
+		/* get subimage data address and length */
+		if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) {
+			puts ("Could not find script subimage data\n");
+			return 1;
+		}
+
+		data = (ulong)fit_data;
+		len = (ulong)fit_len;
+		break;
+#endif
+	default:
+		puts ("Invalid image type for imxtract\n");
 		return 1;
 		return 1;
 	}
 	}
-	len = ntohl(len_ptr[part]);
 
 
 	if (argc > 3) {
 	if (argc > 3) {
 		memcpy((char *) dest, (char *) data, len);
 		memcpy((char *) dest, (char *) data, len);
@@ -139,6 +182,9 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 U_BOOT_CMD(imxtract, 4, 1, do_imgextract,
 U_BOOT_CMD(imxtract, 4, 1, do_imgextract,
 	   "imxtract- extract a part of a multi-image\n",
 	   "imxtract- extract a part of a multi-image\n",
 	   "addr part [dest]\n"
 	   "addr part [dest]\n"
-	   "    - extract <part> from image at <addr> and copy to <dest>\n");
-
+	   "    - extract <part> from legacy image at <addr> and copy to <dest>\n"
+#if defined(CONFIG_FIT)
+	   "addr uname [dest]\n"
+	   "    - extract <uname> subimage from FIT image at <addr> and copy to <dest>\n"
 #endif
 #endif
+);

+ 113 - 0
common/gunzip.c

@@ -0,0 +1,113 @@
+/*
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <image.h>
+#include <malloc.h>
+#include <zlib.h>
+
+#define	ZALLOC_ALIGNMENT	16
+#define HEAD_CRC		2
+#define EXTRA_FIELD		4
+#define ORIG_NAME		8
+#define COMMENT			0x10
+#define RESERVED		0xe0
+#define DEFLATED		8
+
+int gunzip(void *, int, unsigned char *, unsigned long *);
+void *zalloc(void *, unsigned, unsigned);
+void zfree(void *, void *, unsigned);
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+	void *p;
+
+	size *= items;
+	size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
+
+	p = malloc (size);
+
+	return (p);
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+	free (addr);
+}
+
+int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp)
+{
+	z_stream s;
+	int r, i, flags;
+
+	/* skip header */
+	i = 10;
+	flags = src[3];
+	if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+		puts ("Error: Bad gzipped data\n");
+		return (-1);
+	}
+	if ((flags & EXTRA_FIELD) != 0)
+		i = 12 + src[10] + (src[11] << 8);
+	if ((flags & ORIG_NAME) != 0)
+		while (src[i++] != 0)
+			;
+	if ((flags & COMMENT) != 0)
+		while (src[i++] != 0)
+			;
+	if ((flags & HEAD_CRC) != 0)
+		i += 2;
+	if (i >= *lenp) {
+		puts ("Error: gunzip out of data in header\n");
+		return (-1);
+	}
+
+	s.zalloc = zalloc;
+	s.zfree = zfree;
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	s.outcb = (cb_func)WATCHDOG_RESET;
+#else
+	s.outcb = Z_NULL;
+#endif	/* CONFIG_HW_WATCHDOG */
+
+	r = inflateInit2(&s, -MAX_WBITS);
+	if (r != Z_OK) {
+		printf ("Error: inflateInit2() returned %d\n", r);
+		return (-1);
+	}
+	s.next_in = src + i;
+	s.avail_in = *lenp - i;
+	s.next_out = dst;
+	s.avail_out = dstlen;
+	r = inflate(&s, Z_FINISH);
+	if (r != Z_OK && r != Z_STREAM_END) {
+		printf ("Error: inflate() returned %d\n", r);
+		return (-1);
+	}
+	*lenp = s.next_out - (unsigned char *) dst;
+	inflateEnd(&s);
+
+	return (0);
+}

+ 2541 - 0
common/image.c

@@ -0,0 +1,2541 @@
+/*
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ */
+
+
+#ifndef USE_HOSTCC
+#include <common.h>
+#include <watchdog.h>
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+#include <status_led.h>
+#endif
+
+#ifdef CONFIG_HAS_DATAFLASH
+#include <dataflash.h>
+#endif
+
+#ifdef CONFIG_LOGBUFFER
+#include <logbuff.h>
+#endif
+
+#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE)
+#include <rtc.h>
+#endif
+
+#include <image.h>
+
+#if defined(CONFIG_FIT) || defined (CONFIG_OF_LIBFDT)
+#include <fdt.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#endif
+
+#if defined(CONFIG_FIT)
+#include <md5.h>
+#include <sha1.h>
+
+static int fit_check_ramdisk (const void *fit, int os_noffset,
+		uint8_t arch, int verify);
+#endif
+
+#ifdef CONFIG_CMD_BDI
+extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
+						int verify);
+#else
+#include "mkimage.h"
+#include <md5.h>
+#include <time.h>
+#include <image.h>
+#endif /* !USE_HOSTCC*/
+
+typedef struct table_entry {
+	int	id;		/* as defined in image.h	*/
+	char	*sname;		/* short (input) name		*/
+	char	*lname;		/* long (output) name		*/
+} table_entry_t;
+
+static table_entry_t uimage_arch[] = {
+	{	IH_ARCH_INVALID,	NULL,		"Invalid ARCH",	},
+	{	IH_ARCH_ALPHA,		"alpha",	"Alpha",	},
+	{	IH_ARCH_ARM,		"arm",		"ARM",		},
+	{	IH_ARCH_I386,		"x86",		"Intel x86",	},
+	{	IH_ARCH_IA64,		"ia64",		"IA64",		},
+	{	IH_ARCH_M68K,		"m68k",		"M68K",		},
+	{	IH_ARCH_MICROBLAZE,	"microblaze",	"MicroBlaze",	},
+	{	IH_ARCH_MIPS,		"mips",		"MIPS",		},
+	{	IH_ARCH_MIPS64,		"mips64",	"MIPS 64 Bit",	},
+	{	IH_ARCH_NIOS,		"nios",		"NIOS",		},
+	{	IH_ARCH_NIOS2,		"nios2",	"NIOS II",	},
+	{	IH_ARCH_PPC,		"ppc",		"PowerPC",	},
+	{	IH_ARCH_S390,		"s390",		"IBM S390",	},
+	{	IH_ARCH_SH,		"sh",		"SuperH",	},
+	{	IH_ARCH_SPARC,		"sparc",	"SPARC",	},
+	{	IH_ARCH_SPARC64,	"sparc64",	"SPARC 64 Bit",	},
+	{	IH_ARCH_BLACKFIN,	"blackfin",	"Blackfin",	},
+	{	IH_ARCH_AVR32,		"avr32",	"AVR32",	},
+	{	-1,			"",		"",		},
+};
+
+static table_entry_t uimage_os[] = {
+	{	IH_OS_INVALID,	NULL,		"Invalid OS",		},
+#if defined(CONFIG_ARTOS) || defined(USE_HOSTCC)
+	{	IH_OS_ARTOS,	"artos",	"ARTOS",		},
+#endif
+	{	IH_OS_LINUX,	"linux",	"Linux",		},
+#if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC)
+	{	IH_OS_LYNXOS,	"lynxos",	"LynxOS",		},
+#endif
+	{	IH_OS_NETBSD,	"netbsd",	"NetBSD",		},
+	{	IH_OS_RTEMS,	"rtems",	"RTEMS",		},
+	{	IH_OS_U_BOOT,	"u-boot",	"U-Boot",		},
+#if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
+	{	IH_OS_QNX,	"qnx",		"QNX",			},
+	{	IH_OS_VXWORKS,	"vxworks",	"VxWorks",		},
+#endif
+#ifdef USE_HOSTCC
+	{	IH_OS_4_4BSD,	"4_4bsd",	"4_4BSD",		},
+	{	IH_OS_DELL,	"dell",		"Dell",			},
+	{	IH_OS_ESIX,	"esix",		"Esix",			},
+	{	IH_OS_FREEBSD,	"freebsd",	"FreeBSD",		},
+	{	IH_OS_IRIX,	"irix",		"Irix",			},
+	{	IH_OS_NCR,	"ncr",		"NCR",			},
+	{	IH_OS_OPENBSD,	"openbsd",	"OpenBSD",		},
+	{	IH_OS_PSOS,	"psos",		"pSOS",			},
+	{	IH_OS_SCO,	"sco",		"SCO",			},
+	{	IH_OS_SOLARIS,	"solaris",	"Solaris",		},
+	{	IH_OS_SVR4,	"svr4",		"SVR4",			},
+#endif
+	{	-1,		"",		"",			},
+};
+
+static table_entry_t uimage_type[] = {
+	{	IH_TYPE_INVALID,    NULL,	  "Invalid Image",	},
+	{	IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image",	},
+	{	IH_TYPE_FIRMWARE,   "firmware",	  "Firmware",		},
+	{	IH_TYPE_KERNEL,	    "kernel",	  "Kernel Image",	},
+	{	IH_TYPE_MULTI,	    "multi",	  "Multi-File Image",	},
+	{	IH_TYPE_RAMDISK,    "ramdisk",	  "RAMDisk Image",	},
+	{	IH_TYPE_SCRIPT,     "script",	  "Script",		},
+	{	IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
+	{	IH_TYPE_FLATDT,     "flat_dt",    "Flat Device Tree",	},
+	{	-1,		    "",		  "",			},
+};
+
+static table_entry_t uimage_comp[] = {
+	{	IH_COMP_NONE,	"none",		"uncompressed",		},
+	{	IH_COMP_BZIP2,	"bzip2",	"bzip2 compressed",	},
+	{	IH_COMP_GZIP,	"gzip",		"gzip compressed",	},
+	{	-1,		"",		"",			},
+};
+
+unsigned long crc32 (unsigned long, const unsigned char *, unsigned int);
+static void genimg_print_size (uint32_t size);
+#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
+static void genimg_print_time (time_t timestamp);
+#endif
+
+/*****************************************************************************/
+/* Legacy format routines */
+/*****************************************************************************/
+int image_check_hcrc (image_header_t *hdr)
+{
+	ulong hcrc;
+	ulong len = image_get_header_size ();
+	image_header_t header;
+
+	/* Copy header so we can blank CRC field for re-calculation */
+	memmove (&header, (char *)hdr, image_get_header_size ());
+	image_set_hcrc (&header, 0);
+
+	hcrc = crc32 (0, (unsigned char *)&header, len);
+
+	return (hcrc == image_get_hcrc (hdr));
+}
+
+int image_check_dcrc (image_header_t *hdr)
+{
+	ulong data = image_get_data (hdr);
+	ulong len = image_get_data_size (hdr);
+	ulong dcrc = crc32 (0, (unsigned char *)data, len);
+
+	return (dcrc == image_get_dcrc (hdr));
+}
+
+#ifndef USE_HOSTCC
+int image_check_dcrc_wd (image_header_t *hdr, ulong chunksz)
+{
+	ulong dcrc = 0;
+	ulong len = image_get_data_size (hdr);
+	ulong data = image_get_data (hdr);
+
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	ulong cdata = data;
+	ulong edata = cdata + len;
+
+	while (cdata < edata) {
+		ulong chunk = edata - cdata;
+
+		if (chunk > chunksz)
+			chunk = chunksz;
+		dcrc = crc32 (dcrc, (unsigned char *)cdata, chunk);
+		cdata += chunk;
+
+		WATCHDOG_RESET ();
+	}
+#else
+	dcrc = crc32 (0, (unsigned char *)data, len);
+#endif
+
+	return (dcrc == image_get_dcrc (hdr));
+}
+#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;
+	uint32_t *size;
+
+	/* get start of the image payload, which in case of multi
+	 * component images that points to a table of component sizes */
+	size = (uint32_t *)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;
+	uint32_t *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 = (uint32_t *)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 (uint32_t);
+
+	if (idx < count) {
+		*len = uimage_to_cpu (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 += uimage_to_cpu (size[i]);
+
+			/* add up alignment for i-th component */
+			tail += (4 - uimage_to_cpu (size[i]) % 4);
+		}
+
+		/* calculate idx-th component data address */
+		*data = img_data + offset + tail;
+	} else {
+		*len = 0;
+		*data = 0;
+	}
+}
+
+static void image_print_type (image_header_t *hdr)
+{
+	const char *os, *arch, *type, *comp;
+
+	os = genimg_get_os_name (image_get_os (hdr));
+	arch = genimg_get_arch_name (image_get_arch (hdr));
+	type = genimg_get_type_name (image_get_type (hdr));
+	comp = genimg_get_comp_name (image_get_comp (hdr));
+
+	printf ("%s %s %s (%s)\n", arch, os, type, comp);
+}
+
+/**
+ * __image_print_contents - prints out the contents of the legacy format image
+ * @hdr: pointer to the legacy format image header
+ * @p: pointer to prefix string
+ *
+ * __image_print_contents() formats a multi line legacy image contents description.
+ * The routine prints out all header fields followed by the size/offset data
+ * for MULTI/SCRIPT images.
+ *
+ * returns:
+ *     no returned results
+ */
+static void __image_print_contents (image_header_t *hdr, const char *p)
+{
+	printf ("%sImage Name:   %.*s\n", p, IH_NMLEN, image_get_name (hdr));
+#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
+	printf ("%sCreated:      ", p);
+	genimg_print_time ((time_t)image_get_time (hdr));
+#endif
+	printf ("%sImage Type:   ", p);
+	image_print_type (hdr);
+	printf ("%sData Size:    ", p);
+	genimg_print_size (image_get_data_size (hdr));
+	printf ("%sLoad Address: %08x\n", p, image_get_load (hdr));
+	printf ("%sEntry Point:  %08x\n", p, image_get_ep (hdr));
+
+	if (image_check_type (hdr, IH_TYPE_MULTI) ||
+			image_check_type (hdr, IH_TYPE_SCRIPT)) {
+		int i;
+		ulong data, len;
+		ulong count = image_multi_count (hdr);
+
+		printf ("%sContents:\n", p);
+		for (i = 0; i < count; i++) {
+			image_multi_getimg (hdr, i, &data, &len);
+
+			printf ("%s   Image %d: ", p, i);
+			genimg_print_size (len);
+
+			if (image_check_type (hdr, IH_TYPE_SCRIPT) && i > 0) {
+				/*
+				 * the user may need to know offsets
+				 * if planning to do something with
+				 * multiple files
+				 */
+				printf ("%s    Offset = 0x%08lx\n", p, data);
+			}
+		}
+	}
+}
+
+inline void image_print_contents (image_header_t *hdr)
+{
+	__image_print_contents (hdr, "   ");
+}
+
+inline void image_print_contents_noindent (image_header_t *hdr)
+{
+	__image_print_contents (hdr, "");
+}
+
+#ifndef USE_HOSTCC
+/**
+ * image_get_ramdisk - get and verify ramdisk image
+ * @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, return NULL
+ */
+static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
+						int verify)
+{
+	image_header_t *rd_hdr = (image_header_t *)rd_addr;
+
+	if (!image_check_magic (rd_hdr)) {
+		puts ("Bad Magic Number\n");
+		show_boot_progress (-10);
+		return NULL;
+	}
+
+	if (!image_check_hcrc (rd_hdr)) {
+		puts ("Bad Header Checksum\n");
+		show_boot_progress (-11);
+		return NULL;
+	}
+
+	show_boot_progress (10);
+	image_print_contents (rd_hdr);
+
+	if (verify) {
+		puts("   Verifying Checksum ... ");
+		if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) {
+			puts ("Bad Data CRC\n");
+			show_boot_progress (-12);
+			return NULL;
+		}
+		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",
+				genimg_get_arch_name(arch));
+		show_boot_progress (-13);
+		return NULL;
+	}
+
+	return rd_hdr;
+}
+#endif /* !USE_HOSTCC */
+
+/*****************************************************************************/
+/* Shared dual-format routines */
+/*****************************************************************************/
+#ifndef USE_HOSTCC
+int getenv_verify (void)
+{
+	char *s = getenv ("verify");
+	return (s && (*s == 'n')) ? 0 : 1;
+}
+
+int getenv_autostart (void)
+{
+	char *s = getenv ("autostart");
+	return (s && (*s == 'n')) ? 0 : 1;
+}
+
+ulong getenv_bootm_low(void)
+{
+	char *s = getenv ("bootm_low");
+	if (s) {
+		ulong tmp = simple_strtoul (s, NULL, 16);
+		return tmp;
+	}
+
+#if defined(CFG_SDRAM_BASE)
+	return CFG_SDRAM_BASE;
+#elif defined(CONFIG_ARM)
+	return gd->bd->bi_dram[0].start;
+#else
+	return 0;
+#endif
+}
+
+ulong getenv_bootm_size(void)
+{
+	char *s = getenv ("bootm_size");
+	if (s) {
+		ulong tmp = simple_strtoul (s, NULL, 16);
+		return tmp;
+	}
+
+#if defined(CONFIG_ARM)
+	return gd->bd->bi_dram[0].size;
+#else
+	return gd->bd->bi_memsize;
+#endif
+}
+
+void memmove_wd (void *to, void *from, size_t len, ulong chunksz)
+{
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	while (len > 0) {
+		size_t tail = (len > chunksz) ? chunksz : len;
+		WATCHDOG_RESET ();
+		memmove (to, from, tail);
+		to += tail;
+		from += tail;
+		len -= tail;
+	}
+#else	/* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
+	memmove (to, from, len);
+#endif	/* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
+}
+#endif /* !USE_HOSTCC */
+
+static void genimg_print_size (uint32_t size)
+{
+#ifndef USE_HOSTCC
+	printf ("%d Bytes = ", size);
+	print_size (size, "\n");
+#else
+	printf ("%d Bytes = %.2f kB = %.2f MB\n",
+			size, (double)size / 1.024e3,
+			(double)size / 1.048576e6);
+#endif
+}
+
+#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
+static void genimg_print_time (time_t timestamp)
+{
+#ifndef USE_HOSTCC
+	struct rtc_time tm;
+
+	to_tm (timestamp, &tm);
+	printf ("%4d-%02d-%02d  %2d:%02d:%02d UTC\n",
+			tm.tm_year, tm.tm_mon, tm.tm_mday,
+			tm.tm_hour, tm.tm_min, tm.tm_sec);
+#else
+	printf ("%s", ctime(&timestamp));
+#endif
+}
+#endif /* CONFIG_TIMESTAMP || CONFIG_CMD_DATE || USE_HOSTCC */
+
+/**
+ * get_table_entry_name - translate entry id to long name
+ * @table: pointer to a translation table for entries of a specific type
+ * @msg: message to be returned when translation fails
+ * @id: entry id to be translated
+ *
+ * get_table_entry_name() will go over translation table trying to find
+ * entry that matches given id. If matching entry is found, its long
+ * name is returned to the caller.
+ *
+ * returns:
+ *     long entry name if translation succeeds
+ *     msg otherwise
+ */
+static char *get_table_entry_name (table_entry_t *table, char *msg, int id)
+{
+	for (; table->id >= 0; ++table) {
+		if (table->id == id)
+			return (table->lname);
+	}
+	return (msg);
+}
+
+const char *genimg_get_os_name (uint8_t os)
+{
+	return (get_table_entry_name (uimage_os, "Unknown OS", os));
+}
+
+const char *genimg_get_arch_name (uint8_t arch)
+{
+	return (get_table_entry_name (uimage_arch, "Unknown Architecture", arch));
+}
+
+const char *genimg_get_type_name (uint8_t type)
+{
+	return (get_table_entry_name (uimage_type, "Unknown Image", type));
+}
+
+const char *genimg_get_comp_name (uint8_t comp)
+{
+	return (get_table_entry_name (uimage_comp, "Unknown Compression", comp));
+}
+
+/**
+ * get_table_entry_id - translate short entry name to id
+ * @table: pointer to a translation table for entries of a specific type
+ * @table_name: to be used in case of error
+ * @name: entry short name to be translated
+ *
+ * get_table_entry_id() will go over translation table trying to find
+ * entry that matches given short name. If matching entry is found,
+ * its id returned to the caller.
+ *
+ * returns:
+ *     entry id if translation succeeds
+ *     -1 otherwise
+ */
+static int get_table_entry_id (table_entry_t *table,
+		const char *table_name, const char *name)
+{
+	table_entry_t *t;
+#ifdef USE_HOSTCC
+	int first = 1;
+
+	for (t = table; t->id >= 0; ++t) {
+		if (t->sname && strcasecmp(t->sname, name) == 0)
+			return (t->id);
+	}
+
+	fprintf (stderr, "\nInvalid %s Type - valid names are", table_name);
+	for (t = table; t->id >= 0; ++t) {
+		if (t->sname == NULL)
+			continue;
+		fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname);
+		first = 0;
+	}
+	fprintf (stderr, "\n");
+#else
+	for (t = table; t->id >= 0; ++t) {
+		if (t->sname && strcmp(t->sname, name) == 0)
+			return (t->id);
+	}
+	debug ("Invalid %s Type: %s\n", table_name, name);
+#endif /* USE_HOSTCC */
+	return (-1);
+}
+
+int genimg_get_os_id (const char *name)
+{
+	return (get_table_entry_id (uimage_os, "OS", name));
+}
+
+int genimg_get_arch_id (const char *name)
+{
+	return (get_table_entry_id (uimage_arch, "CPU", name));
+}
+
+int genimg_get_type_id (const char *name)
+{
+	return (get_table_entry_id (uimage_type, "Image", name));
+}
+
+int genimg_get_comp_id (const char *name)
+{
+	return (get_table_entry_id (uimage_comp, "Compression", name));
+}
+
+#ifndef USE_HOSTCC
+/**
+ * genimg_get_format - get image format type
+ * @img_addr: image start address
+ *
+ * genimg_get_format() checks whether provided address points to a valid
+ * legacy or FIT image.
+ *
+ * New uImage format and FDT blob are based on a libfdt. FDT blob
+ * may be passed directly or embedded in a FIT image. In both situations
+ * genimg_get_format() must be able to dectect libfdt header.
+ *
+ * returns:
+ *     image format type or IMAGE_FORMAT_INVALID if no image is present
+ */
+int genimg_get_format (void *img_addr)
+{
+	ulong		format = IMAGE_FORMAT_INVALID;
+	image_header_t	*hdr;
+#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
+	char		*fit_hdr;
+#endif
+
+	hdr = (image_header_t *)img_addr;
+	if (image_check_magic(hdr))
+		format = IMAGE_FORMAT_LEGACY;
+#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
+	else {
+		fit_hdr = (char *)img_addr;
+		if (fdt_check_header (fit_hdr) == 0)
+			format = IMAGE_FORMAT_FIT;
+	}
+#endif
+
+	return format;
+}
+
+/**
+ * genimg_get_image - get image from special storage (if necessary)
+ * @img_addr: image start address
+ *
+ * genimg_get_image() checks if provided image start adddress is located
+ * in a dataflash storage. If so, image is moved to a system RAM memory.
+ *
+ * returns:
+ *     image start address after possible relocation from special storage
+ */
+ulong genimg_get_image (ulong img_addr)
+{
+	ulong ram_addr = img_addr;
+
+#ifdef CONFIG_HAS_DATAFLASH
+	ulong h_size, d_size;
+
+	if (addr_dataflash (img_addr)){
+		/* ger RAM address */
+		ram_addr = CFG_LOAD_ADDR;
+
+		/* get header size */
+		h_size = image_get_header_size ();
+#if defined(CONFIG_FIT)
+		if (sizeof(struct fdt_header) > h_size)
+			h_size = sizeof(struct fdt_header);
+#endif
+
+		/* read in header */
+		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);
+
+		/* get data size */
+		switch (genimg_get_format ((void *)ram_addr)) {
+		case IMAGE_FORMAT_LEGACY:
+			d_size = image_get_data_size ((image_header_t *)ram_addr);
+			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;
+			debug ("   FIT/FDT format image found at 0x%08lx, size 0x%08lx\n",
+					ram_addr, d_size);
+			break;
+#endif
+		default:
+			printf ("   No valid image found at 0x%08lx\n", img_addr);
+			return ram_addr;
+		}
+
+		/* read in image data */
+		debug ("   Reading image remaining data from dataflash address "
+			"%08lx to RAM address %08lx\n", img_addr + h_size,
+			ram_addr + h_size);
+
+		read_dataflash (img_addr + h_size, d_size,
+				(char *)(ram_addr + h_size));
+
+	}
+#endif /* CONFIG_HAS_DATAFLASH */
+
+	return ram_addr;
+}
+
+/**
+ * fit_has_config - check if there is a valid FIT configuration
+ * @images: pointer to the bootm command headers structure
+ *
+ * fit_has_config() checks if there is a FIT configuration in use
+ * (if FTI support is present).
+ *
+ * returns:
+ *     0, no FIT support or no configuration found
+ *     1, configuration found
+ */
+int genimg_has_config (bootm_headers_t *images)
+{
+#if defined(CONFIG_FIT)
+	if (images->fit_uname_cfg)
+		return 1;
+#endif
+	return 0;
+}
+
+/**
+ * boot_get_ramdisk - main ramdisk handling routine
+ * @argc: command argument count
+ * @argv: command argument list
+ * @images: pointer to the bootm images structure
+ * @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
+ *
+ * boot_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:
+ *     0, if ramdisk image was found and valid, or skiped
+ *     rd_start and rd_end are set to ramdisk start/end addresses if
+ *     ramdisk image is found and valid
+ *
+ *     1, if ramdisk image is found but corrupted
+ *     rd_start and rd_end are set to 0 if no ramdisk exists
+ */
+int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
+		uint8_t arch, ulong *rd_start, ulong *rd_end)
+{
+	ulong rd_addr, rd_load;
+	ulong rd_data, rd_len;
+	image_header_t *rd_hdr;
+#if defined(CONFIG_FIT)
+	void		*fit_hdr;
+	const char	*fit_uname_config = NULL;
+	const char	*fit_uname_ramdisk = NULL;
+	ulong		default_addr;
+	int		rd_noffset;
+	int		cfg_noffset;
+	const void	*data;
+	size_t		size;
+#endif
+
+	*rd_start = 0;
+	*rd_end = 0;
+
+	/*
+	 * Look for a '-' which indicates to ignore the
+	 * ramdisk argument
+	 */
+	if ((argc >= 3) && (strcmp(argv[2], "-") ==  0)) {
+		debug ("## Skipping init Ramdisk\n");
+		rd_len = rd_data = 0;
+	} else if (argc >= 3 || genimg_has_config (images)) {
+#if defined(CONFIG_FIT)
+		if (argc >= 3) {
+			/*
+			 * If the init ramdisk comes from the FIT image and
+			 * the FIT image address is omitted in the command
+			 * line argument, try to use os FIT image address or
+			 * default load address.
+			 */
+			if (images->fit_uname_os)
+				default_addr = (ulong)images->fit_hdr_os;
+			else
+				default_addr = load_addr;
+
+			if (fit_parse_conf (argv[2], default_addr,
+						&rd_addr, &fit_uname_config)) {
+				debug ("*  ramdisk: config '%s' from image at 0x%08lx\n",
+						fit_uname_config, rd_addr);
+			} else if (fit_parse_subimage (argv[2], default_addr,
+						&rd_addr, &fit_uname_ramdisk)) {
+				debug ("*  ramdisk: subimage '%s' from image at 0x%08lx\n",
+						fit_uname_ramdisk, rd_addr);
+			} else
+#endif
+			{
+				rd_addr = simple_strtoul(argv[2], NULL, 16);
+				debug ("*  ramdisk: cmdline image address = 0x%08lx\n",
+						rd_addr);
+			}
+#if defined(CONFIG_FIT)
+		} else {
+			/* use FIT configuration provided in first bootm
+			 * command argument
+			 */
+			rd_addr = (ulong)images->fit_hdr_os;
+			fit_uname_config = images->fit_uname_cfg;
+			debug ("*  ramdisk: using config '%s' from image at 0x%08lx\n",
+					fit_uname_config, rd_addr);
+
+			/*
+			 * Check whether configuration has ramdisk defined,
+			 * if not, don't try to use it, quit silently.
+			 */
+			fit_hdr = (void *)rd_addr;
+			cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
+			if (cfg_noffset < 0) {
+				debug ("*  ramdisk: no such config\n");
+				return 0;
+			}
+
+			rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);
+			if (rd_noffset < 0) {
+				debug ("*  ramdisk: no ramdisk in config\n");
+				return 0;
+			}
+		}
+#endif
+
+		/* copy from dataflash if needed */
+		rd_addr = genimg_get_image (rd_addr);
+
+		/*
+		 * Check if there is an initrd image at the
+		 * address provided in the second bootm argument
+		 * check image type, for FIT images get FIT node.
+		 */
+		switch (genimg_get_format ((void *)rd_addr)) {
+		case IMAGE_FORMAT_LEGACY:
+			printf ("## Loading init Ramdisk from Legacy "
+					"Image at %08lx ...\n", rd_addr);
+
+			show_boot_progress (9);
+			rd_hdr = image_get_ramdisk (rd_addr, arch,
+							images->verify);
+
+			if (rd_hdr == NULL)
+				return 1;
+
+			rd_data = image_get_data (rd_hdr);
+			rd_len = image_get_data_size (rd_hdr);
+			rd_load = image_get_load (rd_hdr);
+			break;
+#if defined(CONFIG_FIT)
+		case IMAGE_FORMAT_FIT:
+			fit_hdr = (void *)rd_addr;
+			printf ("## Loading init Ramdisk from FIT "
+					"Image at %08lx ...\n", rd_addr);
+
+			show_boot_progress (120);
+			if (!fit_check_format (fit_hdr)) {
+				puts ("Bad FIT ramdisk image format!\n");
+				show_boot_progress (-120);
+				return 0;
+			}
+			show_boot_progress (121);
+
+			if (!fit_uname_ramdisk) {
+				/*
+				 * no ramdisk image node unit name, try to get config
+				 * node first. If config unit node name is NULL
+				 * fit_conf_get_node() will try to find default config node
+				 */
+				show_boot_progress (122);
+				cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
+				if (cfg_noffset < 0) {
+					puts ("Could not find configuration node\n");
+					show_boot_progress (-122);
+					return 0;
+				}
+				fit_uname_config = fdt_get_name (fit_hdr, cfg_noffset, NULL);
+				printf ("   Using '%s' configuration\n", fit_uname_config);
+
+				rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);
+				fit_uname_ramdisk = fit_get_name (fit_hdr, rd_noffset, NULL);
+			} else {
+				/* get ramdisk component image node offset */
+				show_boot_progress (123);
+				rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk);
+			}
+			if (rd_noffset < 0) {
+				puts ("Could not find subimage node\n");
+				show_boot_progress (-124);
+				return 0;
+			}
+
+			printf ("   Trying '%s' ramdisk subimage\n", fit_uname_ramdisk);
+
+			show_boot_progress (125);
+			if (!fit_check_ramdisk (fit_hdr, rd_noffset, arch, images->verify))
+				return 0;
+
+			/* get ramdisk image data address and length */
+			if (fit_image_get_data (fit_hdr, rd_noffset, &data, &size)) {
+				puts ("Could not find ramdisk subimage data!\n");
+				show_boot_progress (-127);
+				return 0;
+			}
+			show_boot_progress (128);
+
+			rd_data = (ulong)data;
+			rd_len = size;
+
+			if (fit_image_get_load (fit_hdr, rd_noffset, &rd_load)) {
+				puts ("Can't get ramdisk subimage load address!\n");
+				show_boot_progress (-129);
+				return 0;
+			}
+			show_boot_progress (129);
+
+			images->fit_hdr_rd = fit_hdr;
+			images->fit_uname_rd = fit_uname_ramdisk;
+			images->fit_noffset_rd = rd_noffset;
+			break;
+#endif
+		default:
+			puts ("Wrong Ramdisk Image Format\n");
+			rd_data = rd_len = rd_load = 0;
+		}
+
+#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)
+		/*
+		 * We need to copy the ramdisk to SRAM to let Linux boot
+		 */
+		if (rd_data) {
+			memmove ((void *)rd_load, (uchar *)rd_data, rd_len);
+			rd_data = rd_load;
+		}
+#endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */
+
+	} else if (images->legacy_hdr_valid &&
+			image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) {
+		/*
+		 * Now check if we have a legacy mult-component image,
+		 * get second entry data start address and len.
+		 */
+		show_boot_progress (13);
+		printf ("## Loading init Ramdisk from multi component "
+				"Legacy Image at %08lx ...\n",
+				(ulong)images->legacy_hdr_os);
+
+		image_multi_getimg (images->legacy_hdr_os, 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");
+	} 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);
+
+	return 0;
+}
+
+#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
+/**
+ * boot_ramdisk_high - relocate init ramdisk
+ * @lmb: pointer to lmb handle, will be used for memory mgmt
+ * @rd_data: ramdisk data start address
+ * @rd_len: ramdisk data length
+ * @initrd_start: pointer to a ulong variable, will hold final init ramdisk
+ *      start address (after possible relocation)
+ * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
+ *      end address (after possible relocation)
+ *
+ * boot_ramdisk_high() takes a relocation hint from "initrd_high" environement
+ * variable and if requested ramdisk data is moved to a specified location.
+ *
+ * Initrd_start and initrd_end are set to final (after relocation) ramdisk
+ * start/end addresses if ramdisk image start and len were provided,
+ * otherwise set initrd_start and initrd_end set to zeros.
+ *
+ * returns:
+ *      0 - success
+ *     -1 - failure
+ */
+int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
+		  ulong *initrd_start, ulong *initrd_end)
+{
+	char	*s;
+	ulong	initrd_high;
+	int	initrd_copy_to_ram = 1;
+
+	if ((s = getenv ("initrd_high")) != NULL) {
+		/* a value of "no" or a similar string will act like 0,
+		 * turning the "load high" feature off. This is intentional.
+		 */
+		initrd_high = simple_strtoul (s, NULL, 16);
+		if (initrd_high == ~0)
+			initrd_copy_to_ram = 0;
+	} else {
+		/* not set, no restrictions to load high */
+		initrd_high = ~0;
+	}
+
+	debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
+			initrd_high, initrd_copy_to_ram);
+
+	if (rd_data) {
+		if (!initrd_copy_to_ram) {	/* zero-copy ramdisk support */
+			debug ("   in-place initrd\n");
+			*initrd_start = rd_data;
+			*initrd_end = rd_data + rd_len;
+			lmb_reserve(lmb, rd_data, rd_len);
+		} else {
+			if (initrd_high)
+				*initrd_start = lmb_alloc_base (lmb, rd_len, 0x1000, initrd_high);
+			else
+				*initrd_start = lmb_alloc (lmb, rd_len, 0x1000);
+
+			if (*initrd_start == 0) {
+				puts ("ramdisk - allocation error\n");
+				goto error;
+			}
+			show_boot_progress (12);
+
+			*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);
+
+			puts ("OK\n");
+		}
+	} else {
+		*initrd_start = 0;
+		*initrd_end = 0;
+	}
+	debug ("   ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
+			*initrd_start, *initrd_end);
+
+	return 0;
+
+error:
+	return -1;
+}
+
+/**
+ * boot_get_cmdline - allocate and initialize kernel cmdline
+ * @lmb: pointer to lmb handle, will be used for memory mgmt
+ * @cmd_start: pointer to a ulong variable, will hold cmdline start
+ * @cmd_end: pointer to a ulong variable, will hold cmdline end
+ * @bootmap_base: ulong variable, holds offset in physical memory to
+ * base of bootmap
+ *
+ * boot_get_cmdline() allocates space for kernel command line below
+ * BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt
+ * variable is present its contents is copied to allocated kernel
+ * command line.
+ *
+ * returns:
+ *      0 - success
+ *     -1 - failure
+ */
+int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
+			ulong bootmap_base)
+{
+	char *cmdline;
+	char *s;
+
+	cmdline = (char *)lmb_alloc_base(lmb, CFG_BARGSIZE, 0xf,
+					 CFG_BOOTMAPSZ + bootmap_base);
+
+	if (cmdline == NULL)
+		return -1;
+
+	if ((s = getenv("bootargs")) == NULL)
+		s = "";
+
+	strcpy(cmdline, s);
+
+	*cmd_start = (ulong) & cmdline[0];
+	*cmd_end = *cmd_start + strlen(cmdline);
+
+	debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
+
+	return 0;
+}
+
+/**
+ * boot_get_kbd - allocate and initialize kernel copy of board info
+ * @lmb: pointer to lmb handle, will be used for memory mgmt
+ * @kbd: double pointer to board info data
+ * @bootmap_base: ulong variable, holds offset in physical memory to
+ * base of bootmap
+ *
+ * boot_get_kbd() allocates space for kernel copy of board info data below
+ * BOOTMAPSZ + bootmap_base address and kernel board info is initialized with
+ * the current u-boot board info data.
+ *
+ * returns:
+ *      0 - success
+ *     -1 - failure
+ */
+int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base)
+{
+	*kbd = (bd_t *)lmb_alloc_base(lmb, sizeof(bd_t), 0xf,
+				      CFG_BOOTMAPSZ + bootmap_base);
+	if (*kbd == NULL)
+		return -1;
+
+	**kbd = *(gd->bd);
+
+	debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd);
+
+#if defined(DEBUG) && defined(CONFIG_CMD_BDI)
+	do_bdinfo(NULL, 0, 0, NULL);
+#endif
+
+	return 0;
+}
+#endif /* CONFIG_PPC || CONFIG_M68K */
+#endif /* !USE_HOSTCC */
+
+#if defined(CONFIG_FIT)
+/*****************************************************************************/
+/* New uImage format routines */
+/*****************************************************************************/
+#ifndef USE_HOSTCC
+static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr,
+		ulong *addr, const char **name)
+{
+	const char *sep;
+
+	*addr = addr_curr;
+	*name = NULL;
+
+	sep = strchr (spec, sepc);
+	if (sep) {
+		if (sep - spec > 0)
+			*addr = simple_strtoul (spec, NULL, 16);
+
+		*name = sep + 1;
+		return 1;
+	}
+
+	return 0;
+}
+
+/**
+ * fit_parse_conf - parse FIT configuration spec
+ * @spec: input string, containing configuration spec
+ * @add_curr: current image address (to be used as a possible default)
+ * @addr: pointer to a ulong variable, will hold FIT image address of a given
+ * configuration
+ * @conf_name double pointer to a char, will hold pointer to a configuration
+ * unit name
+ *
+ * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>,
+ * where <addr> is a FIT image address that contains configuration
+ * with a <conf> unit name.
+ *
+ * Address part is optional, and if omitted default add_curr will
+ * be used instead.
+ *
+ * returns:
+ *     1 if spec is a valid configuration string,
+ *     addr and conf_name are set accordingly
+ *     0 otherwise
+ */
+inline int fit_parse_conf (const char *spec, ulong addr_curr,
+		ulong *addr, const char **conf_name)
+{
+	return fit_parse_spec (spec, '#', addr_curr, addr, conf_name);
+}
+
+/**
+ * fit_parse_subimage - parse FIT subimage spec
+ * @spec: input string, containing subimage spec
+ * @add_curr: current image address (to be used as a possible default)
+ * @addr: pointer to a ulong variable, will hold FIT image address of a given
+ * subimage
+ * @image_name: double pointer to a char, will hold pointer to a subimage name
+ *
+ * fit_parse_subimage() expects subimage spec in the for of
+ * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
+ * subimage with a <subimg> unit name.
+ *
+ * Address part is optional, and if omitted default add_curr will
+ * be used instead.
+ *
+ * returns:
+ *     1 if spec is a valid subimage string,
+ *     addr and image_name are set accordingly
+ *     0 otherwise
+ */
+inline int fit_parse_subimage (const char *spec, ulong addr_curr,
+		ulong *addr, const char **image_name)
+{
+	return fit_parse_spec (spec, ':', addr_curr, addr, image_name);
+}
+#endif /* !USE_HOSTCC */
+
+static void fit_get_debug (const void *fit, int noffset,
+		char *prop_name, int err)
+{
+	debug ("Can't get '%s' property from FIT 0x%08lx, "
+		"node: offset %d, name %s (%s)\n",
+		prop_name, (ulong)fit, noffset,
+		fit_get_name (fit, noffset, NULL),
+		fdt_strerror (err));
+}
+
+/**
+ * __fit_print_contents - prints out the contents of the FIT format image
+ * @fit: pointer to the FIT format image header
+ * @p: pointer to prefix string
+ *
+ * __fit_print_contents() formats a multi line FIT image contents description.
+ * The routine prints out FIT image properties (root node level) follwed by
+ * the details of each component image.
+ *
+ * returns:
+ *     no returned results
+ */
+static void __fit_print_contents (const void *fit, const char *p)
+{
+	char *desc;
+	char *uname;
+	int images_noffset;
+	int confs_noffset;
+	int noffset;
+	int ndepth;
+	int count = 0;
+	int ret;
+#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
+	time_t timestamp;
+#endif
+
+	/* Root node properties */
+	ret = fit_get_desc (fit, 0, &desc);
+	printf ("%sFIT description: ", p);
+	if (ret)
+		printf ("unavailable\n");
+	else
+		printf ("%s\n", desc);
+
+#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
+	ret = fit_get_timestamp (fit, 0, &timestamp);
+	printf ("%sCreated:         ", p);
+	if (ret)
+		printf ("unavailable\n");
+	else
+		genimg_print_time (timestamp);
+#endif
+
+	/* Find images parent node offset */
+	images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
+	if (images_noffset < 0) {
+		printf ("Can't find images parent node '%s' (%s)\n",
+			FIT_IMAGES_PATH, fdt_strerror (images_noffset));
+		return;
+	}
+
+	/* Process its subnodes, print out component images details */
+	for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);
+	     (noffset >= 0) && (ndepth > 0);
+	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
+		if (ndepth == 1) {
+			/*
+			 * Direct child node of the images parent node,
+			 * i.e. component image node.
+			 */
+			printf ("%s Image %u (%s)\n", p, count++,
+					fit_get_name(fit, noffset, NULL));
+
+			fit_image_print (fit, noffset, p);
+		}
+	}
+
+	/* Find configurations parent node offset */
+	confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);
+	if (confs_noffset < 0) {
+		debug ("Can't get configurations parent node '%s' (%s)\n",
+			FIT_CONFS_PATH, fdt_strerror (confs_noffset));
+		return;
+	}
+
+	/* get default configuration unit name from default property */
+	uname = (char *)fdt_getprop (fit, noffset, FIT_DEFAULT_PROP, NULL);
+	if (uname)
+		printf ("%s Default Configuration: '%s'\n", p, uname);
+
+	/* Process its subnodes, print out configurations details */
+	for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, confs_noffset, &ndepth);
+	     (noffset >= 0) && (ndepth > 0);
+	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
+		if (ndepth == 1) {
+			/*
+			 * Direct child node of the configurations parent node,
+			 * i.e. configuration node.
+			 */
+			printf ("%s Configuration %u (%s)\n", p, count++,
+					fit_get_name(fit, noffset, NULL));
+
+			fit_conf_print (fit, noffset, p);
+		}
+	}
+}
+
+inline void fit_print_contents (const void *fit)
+{
+	__fit_print_contents (fit, "   ");
+}
+
+inline void fit_print_contents_noindent (const void *fit)
+{
+	__fit_print_contents (fit, "");
+}
+
+/**
+ * fit_image_print - prints out the FIT component image details
+ * @fit: pointer to the FIT format image header
+ * @image_noffset: offset of the component image node
+ * @p: pointer to prefix string
+ *
+ * fit_image_print() lists all mandatory properies for the processed component
+ * image. If present, hash nodes are printed out as well.
+ *
+ * returns:
+ *     no returned results
+ */
+void fit_image_print (const void *fit, int image_noffset, const char *p)
+{
+	char *desc;
+	uint8_t type, arch, os, comp;
+	size_t size;
+	ulong load, entry;
+	const void *data;
+	int noffset;
+	int ndepth;
+	int ret;
+
+	/* Mandatory properties */
+	ret = fit_get_desc (fit, image_noffset, &desc);
+	printf ("%s  Description:  ", p);
+	if (ret)
+		printf ("unavailable\n");
+	else
+		printf ("%s\n", desc);
+
+	fit_image_get_type (fit, image_noffset, &type);
+	printf ("%s  Type:         %s\n", p, genimg_get_type_name (type));
+
+	fit_image_get_comp (fit, image_noffset, &comp);
+	printf ("%s  Compression:  %s\n", p, genimg_get_comp_name (comp));
+
+	ret = fit_image_get_data (fit, image_noffset, &data, &size);
+
+#ifndef USE_HOSTCC
+	printf ("%s  Data Start:   ", p);
+	if (ret)
+		printf ("unavailable\n");
+	else
+		printf ("0x%08lx\n", (ulong)data);
+#endif
+
+	printf ("%s  Data Size:    ", p);
+	if (ret)
+		printf ("unavailable\n");
+	else
+		genimg_print_size (size);
+
+	/* Remaining, type dependent properties */
+	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
+	    (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
+	    (type == IH_TYPE_FLATDT)) {
+		fit_image_get_arch (fit, image_noffset, &arch);
+		printf ("%s  Architecture: %s\n", p, genimg_get_arch_name (arch));
+	}
+
+	if (type == IH_TYPE_KERNEL) {
+		fit_image_get_os (fit, image_noffset, &os);
+		printf ("%s  OS:           %s\n", p, genimg_get_os_name (os));
+	}
+
+	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE)) {
+		ret = fit_image_get_load (fit, image_noffset, &load);
+		printf ("%s  Load Address: ", p);
+		if (ret)
+			printf ("unavailable\n");
+		else
+			printf ("0x%08lx\n", load);
+
+		fit_image_get_entry (fit, image_noffset, &entry);
+		printf ("%s  Entry Point:  ", p);
+		if (ret)
+			printf ("unavailable\n");
+		else
+			printf ("0x%08lx\n", entry);
+	}
+
+	/* Process all hash subnodes of the component image node */
+	for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
+	     (noffset >= 0) && (ndepth > 0);
+	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
+		if (ndepth == 1) {
+			/* Direct child node of the component image node */
+			fit_image_print_hash (fit, noffset, p);
+		}
+	}
+}
+
+/**
+ * fit_image_print_hash - prints out the hash node details
+ * @fit: pointer to the FIT format image header
+ * @noffset: offset of the hash node
+ * @p: pointer to prefix string
+ *
+ * fit_image_print_hash() lists properies for the processed hash node
+ *
+ * returns:
+ *     no returned results
+ */
+void fit_image_print_hash (const void *fit, int noffset, const char *p)
+{
+	char *algo;
+	uint8_t *value;
+	int value_len;
+	int i, ret;
+
+	/*
+	 * Check subnode name, must be equal to "hash".
+	 * Multiple hash nodes require unique unit node
+	 * names, e.g. hash@1, hash@2, etc.
+	 */
+	if (strncmp (fit_get_name(fit, noffset, NULL),
+			FIT_HASH_NODENAME,
+			strlen(FIT_HASH_NODENAME)) != 0)
+		return;
+
+	debug ("%s  Hash node:    '%s'\n", p,
+			fit_get_name (fit, noffset, NULL));
+
+	printf ("%s  Hash algo:    ", p);
+	if (fit_image_hash_get_algo (fit, noffset, &algo)) {
+		printf ("invalid/unsupported\n");
+		return;
+	}
+	printf ("%s\n", algo);
+
+	ret = fit_image_hash_get_value (fit, noffset, &value,
+					&value_len);
+	printf ("%s  Hash value:   ", p);
+	if (ret) {
+		printf ("unavailable\n");
+	} else {
+		for (i = 0; i < value_len; i++)
+			printf ("%02x", value[i]);
+		printf ("\n");
+	}
+
+	debug  ("%s  Hash len:     %d\n", p, value_len);
+}
+
+/**
+ * fit_get_desc - get node description property
+ * @fit: pointer to the FIT format image header
+ * @noffset: node offset
+ * @desc: double pointer to the char, will hold pointer to the descrption
+ *
+ * fit_get_desc() reads description property from a given node, if
+ * description is found pointer to it is returened in third call argument.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_get_desc (const void *fit, int noffset, char **desc)
+{
+	int len;
+
+	*desc = (char *)fdt_getprop (fit, noffset, FIT_DESC_PROP, &len);
+	if (*desc == NULL) {
+		fit_get_debug (fit, noffset, FIT_DESC_PROP, len);
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * fit_get_timestamp - get node timestamp property
+ * @fit: pointer to the FIT format image header
+ * @noffset: node offset
+ * @timestamp: pointer to the time_t, will hold read timestamp
+ *
+ * fit_get_timestamp() reads timestamp poperty from given node, if timestamp
+ * is found and has a correct size its value is retured in third call
+ * argument.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on property read failure
+ *     -2, on wrong timestamp size
+ */
+int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp)
+{
+	int len;
+	const void *data;
+
+	data = fdt_getprop (fit, noffset, FIT_TIMESTAMP_PROP, &len);
+	if (data == NULL) {
+		fit_get_debug (fit, noffset, FIT_TIMESTAMP_PROP, len);
+		return -1;
+	}
+	if (len != sizeof (uint32_t)) {
+		debug ("FIT timestamp with incorrect size of (%u)\n", len);
+		return -2;
+	}
+
+	*timestamp = uimage_to_cpu (*((uint32_t *)data));
+	return 0;
+}
+
+/**
+ * fit_image_get_node - get node offset for component image of a given unit name
+ * @fit: pointer to the FIT format image header
+ * @image_uname: component image node unit name
+ *
+ * fit_image_get_node() finds a component image (withing the '/images'
+ * node) of a provided unit name. If image is found its node offset is
+ * returned to the caller.
+ *
+ * returns:
+ *     image node offset when found (>=0)
+ *     negative number on failure (FDT_ERR_* code)
+ */
+int fit_image_get_node (const void *fit, const char *image_uname)
+{
+	int noffset, images_noffset;
+
+	images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
+	if (images_noffset < 0) {
+		debug ("Can't find images parent node '%s' (%s)\n",
+			FIT_IMAGES_PATH, fdt_strerror (images_noffset));
+		return images_noffset;
+	}
+
+	noffset = fdt_subnode_offset (fit, images_noffset, image_uname);
+	if (noffset < 0) {
+		debug ("Can't get node offset for image unit name: '%s' (%s)\n",
+			image_uname, fdt_strerror (noffset));
+	}
+
+	return noffset;
+}
+
+/**
+ * fit_image_get_os - get os id for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @os: pointer to the uint8_t, will hold os numeric id
+ *
+ * fit_image_get_os() finds os property in a given component image node.
+ * If the property is found, its (string) value is translated to the numeric
+ * id which is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_os (const void *fit, int noffset, uint8_t *os)
+{
+	int len;
+	const void *data;
+
+	/* Get OS name from property data */
+	data = fdt_getprop (fit, noffset, FIT_OS_PROP, &len);
+	if (data == NULL) {
+		fit_get_debug (fit, noffset, FIT_OS_PROP, len);
+		*os = -1;
+		return -1;
+	}
+
+	/* Translate OS name to id */
+	*os = genimg_get_os_id (data);
+	return 0;
+}
+
+/**
+ * fit_image_get_arch - get arch id for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @arch: pointer to the uint8_t, will hold arch numeric id
+ *
+ * fit_image_get_arch() finds arch property in a given component image node.
+ * If the property is found, its (string) value is translated to the numeric
+ * id which is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch)
+{
+	int len;
+	const void *data;
+
+	/* Get architecture name from property data */
+	data = fdt_getprop (fit, noffset, FIT_ARCH_PROP, &len);
+	if (data == NULL) {
+		fit_get_debug (fit, noffset, FIT_ARCH_PROP, len);
+		*arch = -1;
+		return -1;
+	}
+
+	/* Translate architecture name to id */
+	*arch = genimg_get_arch_id (data);
+	return 0;
+}
+
+/**
+ * fit_image_get_type - get type id for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @type: pointer to the uint8_t, will hold type numeric id
+ *
+ * fit_image_get_type() finds type property in a given component image node.
+ * If the property is found, its (string) value is translated to the numeric
+ * id which is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_type (const void *fit, int noffset, uint8_t *type)
+{
+	int len;
+	const void *data;
+
+	/* Get image type name from property data */
+	data = fdt_getprop (fit, noffset, FIT_TYPE_PROP, &len);
+	if (data == NULL) {
+		fit_get_debug (fit, noffset, FIT_TYPE_PROP, len);
+		*type = -1;
+		return -1;
+	}
+
+	/* Translate image type name to id */
+	*type = genimg_get_type_id (data);
+	return 0;
+}
+
+/**
+ * fit_image_get_comp - get comp id for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @comp: pointer to the uint8_t, will hold comp numeric id
+ *
+ * fit_image_get_comp() finds comp property in a given component image node.
+ * If the property is found, its (string) value is translated to the numeric
+ * id which is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp)
+{
+	int len;
+	const void *data;
+
+	/* Get compression name from property data */
+	data = fdt_getprop (fit, noffset, FIT_COMP_PROP, &len);
+	if (data == NULL) {
+		fit_get_debug (fit, noffset, FIT_COMP_PROP, len);
+		*comp = -1;
+		return -1;
+	}
+
+	/* Translate compression name to id */
+	*comp = genimg_get_comp_id (data);
+	return 0;
+}
+
+/**
+ * fit_image_get_load - get load address property for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @load: pointer to the uint32_t, will hold load address
+ *
+ * fit_image_get_load() finds load address property in a given component image node.
+ * If the property is found, its value is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_load (const void *fit, int noffset, ulong *load)
+{
+	int len;
+	const uint32_t *data;
+
+	data = fdt_getprop (fit, noffset, FIT_LOAD_PROP, &len);
+	if (data == NULL) {
+		fit_get_debug (fit, noffset, FIT_LOAD_PROP, len);
+		return -1;
+	}
+
+	*load = uimage_to_cpu (*data);
+	return 0;
+}
+
+/**
+ * fit_image_get_entry - get entry point address property for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @entry: pointer to the uint32_t, will hold entry point address
+ *
+ * fit_image_get_entry() finds entry point address property in a given component image node.
+ * If the property is found, its value is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_entry (const void *fit, int noffset, ulong *entry)
+{
+	int len;
+	const uint32_t *data;
+
+	data = fdt_getprop (fit, noffset, FIT_ENTRY_PROP, &len);
+	if (data == NULL) {
+		fit_get_debug (fit, noffset, FIT_ENTRY_PROP, len);
+		return -1;
+	}
+
+	*entry = uimage_to_cpu (*data);
+	return 0;
+}
+
+/**
+ * fit_image_get_data - get data property and its size for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @data: double pointer to void, will hold data property's data address
+ * @size: pointer to size_t, will hold data property's data size
+ *
+ * fit_image_get_data() finds data property in a given component image node.
+ * If the property is found its data start address and size are returned to
+ * the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_data (const void *fit, int noffset,
+		const void **data, size_t *size)
+{
+	int len;
+
+	*data = fdt_getprop (fit, noffset, FIT_DATA_PROP, &len);
+	if (*data == NULL) {
+		fit_get_debug (fit, noffset, FIT_DATA_PROP, len);
+		*size = 0;
+		return -1;
+	}
+
+	*size = len;
+	return 0;
+}
+
+/**
+ * fit_image_hash_get_algo - get hash algorithm name
+ * @fit: pointer to the FIT format image header
+ * @noffset: hash node offset
+ * @algo: double pointer to char, will hold pointer to the algorithm name
+ *
+ * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
+ * If the property is found its data start address is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_hash_get_algo (const void *fit, int noffset, char **algo)
+{
+	int len;
+
+	*algo = (char *)fdt_getprop (fit, noffset, FIT_ALGO_PROP, &len);
+	if (*algo == NULL) {
+		fit_get_debug (fit, noffset, FIT_ALGO_PROP, len);
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * fit_image_hash_get_value - get hash value and length
+ * @fit: pointer to the FIT format image header
+ * @noffset: hash node offset
+ * @value: double pointer to uint8_t, will hold address of a hash value data
+ * @value_len: pointer to an int, will hold hash data length
+ *
+ * fit_image_hash_get_value() finds hash value property in a given hash node.
+ * If the property is found its data start address and size are returned to
+ * the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value,
+				int *value_len)
+{
+	int len;
+
+	*value = (uint8_t *)fdt_getprop (fit, noffset, FIT_VALUE_PROP, &len);
+	if (*value == NULL) {
+		fit_get_debug (fit, noffset, FIT_VALUE_PROP, len);
+		*value_len = 0;
+		return -1;
+	}
+
+	*value_len = len;
+	return 0;
+}
+
+/**
+ * fit_set_timestamp - set node timestamp property
+ * @fit: pointer to the FIT format image header
+ * @noffset: node offset
+ * @timestamp: timestamp value to be set
+ *
+ * fit_set_timestamp() attempts to set timestamp property in the requested
+ * node and returns operation status to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on property read failure
+ */
+int fit_set_timestamp (void *fit, int noffset, time_t timestamp)
+{
+	uint32_t t;
+	int ret;
+
+	t = cpu_to_uimage (timestamp);
+	ret = fdt_setprop (fit, noffset, FIT_TIMESTAMP_PROP, &t,
+				sizeof (uint32_t));
+	if (ret) {
+		printf ("Can't set '%s' property for '%s' node (%s)\n",
+			FIT_TIMESTAMP_PROP, fit_get_name (fit, noffset, NULL),
+			fdt_strerror (ret));
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * calculate_hash - calculate and return hash for provided input data
+ * @data: pointer to the input data
+ * @data_len: data length
+ * @algo: requested hash algorithm
+ * @value: pointer to the char, will hold hash value data (caller must
+ * allocate enough free space)
+ * value_len: length of the calculated hash
+ *
+ * calculate_hash() computes input data hash according to the requested algorithm.
+ * Resulting hash value is placed in caller provided 'value' buffer, length
+ * of the calculated hash is returned via value_len pointer argument.
+ *
+ * returns:
+ *     0, on success
+ *    -1, when algo is unsupported
+ */
+static int calculate_hash (const void *data, int data_len, const char *algo,
+			uint8_t *value, int *value_len)
+{
+	if (strcmp (algo, "crc32") == 0 ) {
+		*((uint32_t *)value) = crc32 (0, data, data_len);
+		*((uint32_t *)value) = cpu_to_uimage (*((uint32_t *)value));
+		*value_len = 4;
+	} else if (strcmp (algo, "sha1") == 0 ) {
+		sha1_csum ((unsigned char *) data, data_len,
+				(unsigned char *) value);
+		*value_len = 20;
+	} else if (strcmp (algo, "md5") == 0 ) {
+		md5 ((unsigned char *)data, data_len, value);
+		*value_len = 16;
+	} else {
+		debug ("Unsupported hash alogrithm\n");
+		return -1;
+	}
+	return 0;
+}
+
+#ifdef USE_HOSTCC
+/**
+ * fit_set_hashes - process FIT component image nodes and calculate hashes
+ * @fit: pointer to the FIT format image header
+ *
+ * fit_set_hashes() adds hash values for all component images in the FIT blob.
+ * Hashes are calculated for all component images which have hash subnodes
+ * with algorithm property set to one of the supported hash algorithms.
+ *
+ * returns
+ *     0, on success
+ *     libfdt error code, on failure
+ */
+int fit_set_hashes (void *fit)
+{
+	int images_noffset;
+	int noffset;
+	int ndepth;
+	int ret;
+
+	/* Find images parent node offset */
+	images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
+	if (images_noffset < 0) {
+		printf ("Can't find images parent node '%s' (%s)\n",
+			FIT_IMAGES_PATH, fdt_strerror (images_noffset));
+		return images_noffset;
+	}
+
+	/* Process its subnodes, print out component images details */
+	for (ndepth = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);
+	     (noffset >= 0) && (ndepth > 0);
+	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
+		if (ndepth == 1) {
+			/*
+			 * Direct child node of the images parent node,
+			 * i.e. component image node.
+			 */
+			ret = fit_image_set_hashes (fit, noffset);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * fit_image_set_hashes - calculate/set hashes for given component image node
+ * @fit: pointer to the FIT format image header
+ * @image_noffset: requested component image node
+ *
+ * fit_image_set_hashes() adds hash values for an component image node. All
+ * existing hash subnodes are checked, if algorithm property is set to one of
+ * the supported hash algorithms, hash value is computed and corresponding
+ * hash node property is set, for example:
+ *
+ * Input component image node structure:
+ *
+ * o image@1 (at image_noffset)
+ *   | - data = [binary data]
+ *   o hash@1
+ *     |- algo = "sha1"
+ *
+ * Output component image node structure:
+ *
+ * o image@1 (at image_noffset)
+ *   | - data = [binary data]
+ *   o hash@1
+ *     |- algo = "sha1"
+ *     |- value = sha1(data)
+ *
+ * returns:
+ *     0 on sucess
+ *    <0 on failure
+ */
+int fit_image_set_hashes (void *fit, int image_noffset)
+{
+	const void *data;
+	size_t size;
+	char *algo;
+	uint8_t value[FIT_MAX_HASH_LEN];
+	int value_len;
+	int noffset;
+	int ndepth;
+
+	/* Get image data and data length */
+	if (fit_image_get_data (fit, image_noffset, &data, &size)) {
+		printf ("Can't get image data/size\n");
+		return -1;
+	}
+
+	/* Process all hash subnodes of the component image node */
+	for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
+	     (noffset >= 0) && (ndepth > 0);
+	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
+		if (ndepth == 1) {
+			/* Direct child node of the component image node */
+
+			/*
+			 * Check subnode name, must be equal to "hash".
+			 * Multiple hash nodes require unique unit node
+			 * names, e.g. hash@1, hash@2, etc.
+			 */
+			if (strncmp (fit_get_name(fit, noffset, NULL),
+						FIT_HASH_NODENAME,
+						strlen(FIT_HASH_NODENAME)) != 0) {
+				/* Not a hash subnode, skip it */
+				continue;
+			}
+
+			if (fit_image_hash_get_algo (fit, noffset, &algo)) {
+				printf ("Can't get hash algo property for "
+					"'%s' hash node in '%s' image node\n",
+					fit_get_name (fit, noffset, NULL),
+					fit_get_name (fit, image_noffset, NULL));
+				return -1;
+			}
+
+			if (calculate_hash (data, size, algo, value, &value_len)) {
+				printf ("Unsupported hash algorithm (%s) for "
+					"'%s' hash node in '%s' image node\n",
+					algo, fit_get_name (fit, noffset, NULL),
+					fit_get_name (fit, image_noffset, NULL));
+				return -1;
+			}
+
+			if (fit_image_hash_set_value (fit, noffset, value,
+							value_len)) {
+				printf ("Can't set hash value for "
+					"'%s' hash node in '%s' image node\n",
+					fit_get_name (fit, noffset, NULL),
+					fit_get_name (fit, image_noffset, NULL));
+				return -1;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * fit_image_hash_set_value - set hash value in requested has node
+ * @fit: pointer to the FIT format image header
+ * @noffset: hash node offset
+ * @value: hash value to be set
+ * @value_len: hash value length
+ *
+ * fit_image_hash_set_value() attempts to set hash value in a node at offset
+ * given and returns operation status to the caller.
+ *
+ * returns
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value,
+				int value_len)
+{
+	int ret;
+
+	ret = fdt_setprop (fit, noffset, FIT_VALUE_PROP, value, value_len);
+	if (ret) {
+		printf ("Can't set hash '%s' property for '%s' node (%s)\n",
+			FIT_VALUE_PROP, fit_get_name (fit, noffset, NULL),
+			fdt_strerror (ret));
+		return -1;
+	}
+
+	return 0;
+}
+#endif /* USE_HOSTCC */
+
+/**
+ * fit_image_check_hashes - verify data intergity
+ * @fit: pointer to the FIT format image header
+ * @image_noffset: component image node offset
+ *
+ * fit_image_check_hashes() goes over component image hash nodes,
+ * re-calculates each data hash and compares with the value stored in hash
+ * node.
+ *
+ * returns:
+ *     1, if all hashes are valid
+ *     0, otherwise (or on error)
+ */
+int fit_image_check_hashes (const void *fit, int image_noffset)
+{
+	const void	*data;
+	size_t		size;
+	char		*algo;
+	uint8_t		*fit_value;
+	int		fit_value_len;
+	uint8_t		value[FIT_MAX_HASH_LEN];
+	int		value_len;
+	int		noffset;
+	int		ndepth;
+	char		*err_msg = "";
+
+	/* Get image data and data length */
+	if (fit_image_get_data (fit, image_noffset, &data, &size)) {
+		printf ("Can't get image data/size\n");
+		return 0;
+	}
+
+	/* Process all hash subnodes of the component image node */
+	for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
+	     (noffset >= 0) && (ndepth > 0);
+	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
+		if (ndepth == 1) {
+			/* Direct child node of the component image node */
+
+			/*
+			 * Check subnode name, must be equal to "hash".
+			 * Multiple hash nodes require unique unit node
+			 * names, e.g. hash@1, hash@2, etc.
+			 */
+			if (strncmp (fit_get_name(fit, noffset, NULL),
+					FIT_HASH_NODENAME,
+					strlen(FIT_HASH_NODENAME)) != 0)
+				continue;
+
+			if (fit_image_hash_get_algo (fit, noffset, &algo)) {
+				err_msg = "Can't get hash algo property";
+				goto error;
+			}
+			printf ("%s", algo);
+
+			if (fit_image_hash_get_value (fit, noffset, &fit_value,
+							&fit_value_len)) {
+				err_msg = "Can't get hash value property";
+				goto error;
+			}
+
+			if (calculate_hash (data, size, algo, value, &value_len)) {
+				err_msg = "Unsupported hash algorithm";
+				goto error;
+			}
+
+			if (value_len != fit_value_len) {
+				err_msg = "Bad hash value len";
+				goto error;
+			} else if (memcmp (value, fit_value, value_len) != 0) {
+				err_msg = "Bad hash value";
+				goto error;
+			}
+			printf ("+ ");
+		}
+	}
+
+	return 1;
+
+error:
+	printf ("%s for '%s' hash node in '%s' image node\n",
+			err_msg, fit_get_name (fit, noffset, NULL),
+			fit_get_name (fit, image_noffset, NULL));
+	return 0;
+}
+
+/**
+ * fit_image_check_os - check whether image node is of a given os type
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @os: requested image os
+ *
+ * fit_image_check_os() reads image os property and compares its numeric
+ * id with the requested os. Comparison result is returned to the caller.
+ *
+ * returns:
+ *     1 if image is of given os type
+ *     0 otherwise (or on error)
+ */
+int fit_image_check_os (const void *fit, int noffset, uint8_t os)
+{
+	uint8_t image_os;
+
+	if (fit_image_get_os (fit, noffset, &image_os))
+		return 0;
+	return (os == image_os);
+}
+
+/**
+ * fit_image_check_arch - check whether image node is of a given arch
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @arch: requested imagearch
+ *
+ * fit_image_check_arch() reads image arch property and compares its numeric
+ * id with the requested arch. Comparison result is returned to the caller.
+ *
+ * returns:
+ *     1 if image is of given arch
+ *     0 otherwise (or on error)
+ */
+int fit_image_check_arch (const void *fit, int noffset, uint8_t arch)
+{
+	uint8_t image_arch;
+
+	if (fit_image_get_arch (fit, noffset, &image_arch))
+		return 0;
+	return (arch == image_arch);
+}
+
+/**
+ * fit_image_check_type - check whether image node is of a given type
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @type: requested image type
+ *
+ * fit_image_check_type() reads image type property and compares its numeric
+ * id with the requested type. Comparison result is returned to the caller.
+ *
+ * returns:
+ *     1 if image is of given type
+ *     0 otherwise (or on error)
+ */
+int fit_image_check_type (const void *fit, int noffset, uint8_t type)
+{
+	uint8_t image_type;
+
+	if (fit_image_get_type (fit, noffset, &image_type))
+		return 0;
+	return (type == image_type);
+}
+
+/**
+ * fit_image_check_comp - check whether image node uses given compression
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @comp: requested image compression type
+ *
+ * fit_image_check_comp() reads image compression property and compares its
+ * numeric id with the requested compression type. Comparison result is
+ * returned to the caller.
+ *
+ * returns:
+ *     1 if image uses requested compression
+ *     0 otherwise (or on error)
+ */
+int fit_image_check_comp (const void *fit, int noffset, uint8_t comp)
+{
+	uint8_t image_comp;
+
+	if (fit_image_get_comp (fit, noffset, &image_comp))
+		return 0;
+	return (comp == image_comp);
+}
+
+/**
+ * fit_check_format - sanity check FIT image format
+ * @fit: pointer to the FIT format image header
+ *
+ * fit_check_format() runs a basic sanity FIT image verification.
+ * Routine checks for mandatory properties, nodes, etc.
+ *
+ * returns:
+ *     1, on success
+ *     0, on failure
+ */
+int fit_check_format (const void *fit)
+{
+	/* mandatory / node 'description' property */
+	if (fdt_getprop (fit, 0, FIT_DESC_PROP, NULL) == NULL) {
+		debug ("Wrong FIT format: no description\n");
+		return 0;
+	}
+
+#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
+	/* mandatory / node 'timestamp' property */
+	if (fdt_getprop (fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) {
+		debug ("Wrong FIT format: no description\n");
+		return 0;
+	}
+#endif
+
+	/* mandatory subimages parent '/images' node */
+	if (fdt_path_offset (fit, FIT_IMAGES_PATH) < 0) {
+		debug ("Wrong FIT format: no images parent node\n");
+		return 0;
+	}
+
+	return 1;
+}
+
+/**
+ * fit_conf_get_node - get node offset for configuration of a given unit name
+ * @fit: pointer to the FIT format image header
+ * @conf_uname: configuration node unit name
+ *
+ * fit_conf_get_node() finds a configuration (withing the '/configurations'
+ * parant node) of a provided unit name. If configuration is found its node offset
+ * is returned to the caller.
+ *
+ * When NULL is provided in second argument fit_conf_get_node() will search
+ * for a default configuration node instead. Default configuration node unit name
+ * is retrived from FIT_DEFAULT_PROP property of the '/configurations' node.
+ *
+ * returns:
+ *     configuration node offset when found (>=0)
+ *     negative number on failure (FDT_ERR_* code)
+ */
+int fit_conf_get_node (const void *fit, const char *conf_uname)
+{
+	int noffset, confs_noffset;
+	int len;
+
+	confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);
+	if (confs_noffset < 0) {
+		debug ("Can't find configurations parent node '%s' (%s)\n",
+			FIT_CONFS_PATH, fdt_strerror (confs_noffset));
+		return confs_noffset;
+	}
+
+	if (conf_uname == NULL) {
+		/* get configuration unit name from the default property */
+		debug ("No configuration specified, trying default...\n");
+		conf_uname = (char *)fdt_getprop (fit, confs_noffset, FIT_DEFAULT_PROP, &len);
+		if (conf_uname == NULL) {
+			fit_get_debug (fit, confs_noffset, FIT_DEFAULT_PROP, len);
+			return len;
+		}
+		debug ("Found default configuration: '%s'\n", conf_uname);
+	}
+
+	noffset = fdt_subnode_offset (fit, confs_noffset, conf_uname);
+	if (noffset < 0) {
+		debug ("Can't get node offset for configuration unit name: '%s' (%s)\n",
+			conf_uname, fdt_strerror (noffset));
+	}
+
+	return noffset;
+}
+
+static int __fit_conf_get_prop_node (const void *fit, int noffset,
+		const char *prop_name)
+{
+	char *uname;
+	int len;
+
+	/* get kernel image unit name from configuration kernel property */
+	uname = (char *)fdt_getprop (fit, noffset, prop_name, &len);
+	if (uname == NULL)
+		return len;
+
+	return fit_image_get_node (fit, uname);
+}
+
+/**
+ * fit_conf_get_kernel_node - get kernel image node offset that corresponds to
+ * a given configuration
+ * @fit: pointer to the FIT format image header
+ * @noffset: configuration node offset
+ *
+ * fit_conf_get_kernel_node() retrives kernel image node unit name from
+ * configuration FIT_KERNEL_PROP property and translates it to the node
+ * offset.
+ *
+ * returns:
+ *     image node offset when found (>=0)
+ *     negative number on failure (FDT_ERR_* code)
+ */
+int fit_conf_get_kernel_node (const void *fit, int noffset)
+{
+	return __fit_conf_get_prop_node (fit, noffset, FIT_KERNEL_PROP);
+}
+
+/**
+ * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to
+ * a given configuration
+ * @fit: pointer to the FIT format image header
+ * @noffset: configuration node offset
+ *
+ * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from
+ * configuration FIT_KERNEL_PROP property and translates it to the node
+ * offset.
+ *
+ * returns:
+ *     image node offset when found (>=0)
+ *     negative number on failure (FDT_ERR_* code)
+ */
+int fit_conf_get_ramdisk_node (const void *fit, int noffset)
+{
+	return __fit_conf_get_prop_node (fit, noffset, FIT_RAMDISK_PROP);
+}
+
+/**
+ * fit_conf_get_fdt_node - get fdt image node offset that corresponds to
+ * a given configuration
+ * @fit: pointer to the FIT format image header
+ * @noffset: configuration node offset
+ *
+ * fit_conf_get_fdt_node() retrives fdt image node unit name from
+ * configuration FIT_KERNEL_PROP property and translates it to the node
+ * offset.
+ *
+ * returns:
+ *     image node offset when found (>=0)
+ *     negative number on failure (FDT_ERR_* code)
+ */
+int fit_conf_get_fdt_node (const void *fit, int noffset)
+{
+	return __fit_conf_get_prop_node (fit, noffset, FIT_FDT_PROP);
+}
+
+/**
+ * fit_conf_print - prints out the FIT configuration details
+ * @fit: pointer to the FIT format image header
+ * @noffset: offset of the configuration node
+ * @p: pointer to prefix string
+ *
+ * fit_conf_print() lists all mandatory properies for the processed
+ * configuration node.
+ *
+ * returns:
+ *     no returned results
+ */
+void fit_conf_print (const void *fit, int noffset, const char *p)
+{
+	char *desc;
+	char *uname;
+	int ret;
+
+	/* Mandatory properties */
+	ret = fit_get_desc (fit, noffset, &desc);
+	printf ("%s  Description:  ", p);
+	if (ret)
+		printf ("unavailable\n");
+	else
+		printf ("%s\n", desc);
+
+	uname = (char *)fdt_getprop (fit, noffset, FIT_KERNEL_PROP, NULL);
+	printf ("%s  Kernel:       ", p);
+	if (uname == NULL)
+		printf ("unavailable\n");
+	else
+		printf ("%s\n", uname);
+
+	/* Optional properties */
+	uname = (char *)fdt_getprop (fit, noffset, FIT_RAMDISK_PROP, NULL);
+	if (uname)
+		printf ("%s  Init Ramdisk: %s\n", p, uname);
+
+	uname = (char *)fdt_getprop (fit, noffset, FIT_FDT_PROP, NULL);
+	if (uname)
+		printf ("%s  FDT:          %s\n", p, uname);
+}
+
+/**
+ * fit_check_ramdisk - verify FIT format ramdisk subimage
+ * @fit_hdr: pointer to the FIT ramdisk header
+ * @rd_noffset: ramdisk subimage node offset within FIT image
+ * @arch: requested ramdisk image architecture type
+ * @verify: data CRC verification flag
+ *
+ * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from
+ * specified FIT image.
+ *
+ * returns:
+ *     1, on success
+ *     0, on failure
+ */
+#ifndef USE_HOSTCC
+static int fit_check_ramdisk (const void *fit, int rd_noffset, uint8_t arch, int verify)
+{
+	fit_image_print (fit, rd_noffset, "   ");
+
+	if (verify) {
+		puts ("   Verifying Hash Integrity ... ");
+		if (!fit_image_check_hashes (fit, rd_noffset)) {
+			puts ("Bad Data Hash\n");
+			show_boot_progress (-125);
+			return 0;
+		}
+		puts ("OK\n");
+	}
+
+	show_boot_progress (126);
+	if (!fit_image_check_os (fit, rd_noffset, IH_OS_LINUX) ||
+	    !fit_image_check_arch (fit, rd_noffset, arch) ||
+	    !fit_image_check_type (fit, rd_noffset, IH_TYPE_RAMDISK)) {
+		printf ("No Linux %s Ramdisk Image\n",
+				genimg_get_arch_name(arch));
+		show_boot_progress (-126);
+		return 0;
+	}
+
+	show_boot_progress (127);
+	return 1;
+}
+#endif /* USE_HOSTCC */
+#endif /* CONFIG_FIT */

+ 23 - 23
common/lynxkdi.c

@@ -23,45 +23,45 @@
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
 #if defined(CONFIG_MPC8260) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
 #if defined(CONFIG_MPC8260) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
-void lynxkdi_boot ( image_header_t *hdr )
+void lynxkdi_boot (image_header_t *hdr)
 {
 {
-	void (*lynxkdi)(void) = (void(*)(void)) ntohl(hdr->ih_ep);
+	void (*lynxkdi)(void) = (void(*)(void))image_get_ep (hdr);
 	lynxos_bootparms_t *parms = (lynxos_bootparms_t *)0x0020;
 	lynxos_bootparms_t *parms = (lynxos_bootparms_t *)0x0020;
 	bd_t *kbd;
 	bd_t *kbd;
-	u32 *psz = (u32 *)(ntohl(hdr->ih_load) + 0x0204);
+	u32 *psz = (u32 *)(image_get_load (hdr) + 0x0204);
 
 
-	memset( parms, 0, sizeof(*parms));
+	memset (parms, 0, sizeof(*parms));
 	kbd = gd->bd;
 	kbd = gd->bd;
 	parms->clock_ref = kbd->bi_busfreq;
 	parms->clock_ref = kbd->bi_busfreq;
 	parms->dramsz = kbd->bi_memsize;
 	parms->dramsz = kbd->bi_memsize;
-	memcpy(parms->ethaddr, kbd->bi_enetaddr, 6);
-	mtspr(SPRN_SPRG2, 0x0020);
+	memcpy (parms->ethaddr, kbd->bi_enetaddr, 6);
+	mtspr (SPRN_SPRG2, 0x0020);
 
 
 	/* Do a simple check for Bluecat so we can pass the
 	/* Do a simple check for Bluecat so we can pass the
 	 * kernel command line parameters.
 	 * kernel command line parameters.
 	 */
 	 */
-	if( le32_to_cpu(*psz) == ntohl(hdr->ih_size) ){	/* FIXME: NOT SURE HERE ! */
-	    char *args;
-	    char *cmdline = (char *)(ntohl(hdr->ih_load) + 0x020c);
-	    int len;
+	if (le32_to_cpu (*psz) == image_get_data_size (hdr)) {	/* FIXME: NOT SURE HERE ! */
+		char *args;
+		char *cmdline = (char *)(image_get_load (hdr) + 0x020c);
+		int len;
 
 
-	    printf("Booting Bluecat KDI ...\n");
-	    udelay(200*1000); /* Allow serial port to flush */
-	    if ((args = getenv("bootargs")) == NULL)
-		    args = "";
-	    /* Prepend the cmdline */
-	    len = strlen(args);
-	    if( len && (len + strlen(cmdline) + 2 < (0x0400 - 0x020c))) {
-		memmove( cmdline + strlen(args) + 1, cmdline, strlen(cmdline) );
-		strcpy( cmdline, args );
-		cmdline[len] = ' ';
-	    }
+		printf ("Booting Bluecat KDI ...\n");
+		udelay (200*1000); /* Allow serial port to flush */
+		if ((args = getenv ("bootargs")) == NULL)
+			args = "";
+		/* Prepend the cmdline */
+		len = strlen (args);
+		if (len && (len + strlen (cmdline) + 2 < (0x0400 - 0x020c))) {
+			memmove (cmdline + strlen (args) + 1, cmdline, strlen (cmdline));
+			strcpy (cmdline, args);
+			cmdline[len] = ' ';
+		}
 	}
 	}
 	else {
 	else {
-	    printf("Booting LynxOS KDI ...\n");
+		printf ("Booting LynxOS KDI ...\n");
 	}
 	}
 
 
-	lynxkdi();
+	lynxkdi ();
 }
 }
 #else
 #else
 #error "Lynx KDI support not implemented for configured CPU"
 #error "Lynx KDI support not implemented for configured CPU"

+ 1 - 1
cpu/mpc5xxx/cpu.c

@@ -114,7 +114,7 @@ unsigned long get_tbclk (void)
 
 
 /* ------------------------------------------------------------------------- */
 /* ------------------------------------------------------------------------- */
 
 
-#ifdef CONFIG_OF_LIBFDT
+#if defined(CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP)
 void ft_cpu_setup(void *blob, bd_t *bd)
 void ft_cpu_setup(void *blob, bd_t *bd)
 {
 {
 	int div = in_8((void*)CFG_MBAR + 0x204) & 0x0020 ? 8 : 4;
 	int div = in_8((void*)CFG_MBAR + 0x204) & 0x0020 ? 8 : 4;

+ 1 - 1
cpu/mpc8260/cpu.c

@@ -300,7 +300,7 @@ void watchdog_reset (void)
 #endif /* CONFIG_WATCHDOG */
 #endif /* CONFIG_WATCHDOG */
 
 
 /* ------------------------------------------------------------------------- */
 /* ------------------------------------------------------------------------- */
-#if defined(CONFIG_OF_LIBFDT)
+#if defined(CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP)
 void ft_cpu_setup (void *blob, bd_t *bd)
 void ft_cpu_setup (void *blob, bd_t *bd)
 {
 {
 	char * cpu_path = "/cpus/" OF_CPU;
 	char * cpu_path = "/cpus/" OF_CPU;

+ 191 - 0
doc/uImage.FIT/command_syntax_extensions.txt

@@ -0,0 +1,191 @@
+Command syntax extensions for the new uImage format
+===================================================
+
+Author: Bartlomiej Sieka <tur@semihalf.com>
+
+With the introduction of the new uImage format, bootm command (and other
+commands as well) have to understand new syntax of the arguments. This is
+necessary in order to specify objects contained in the new uImage, on which
+bootm has to operate. This note attempts to first summarize bootm usage
+scenarios, and then introduces new argument syntax.
+
+
+bootm usage scenarios
+---------------------
+
+Below is a summary of bootm usage scenarios, focused on booting a PowerPC
+Linux kernel. The purpose of the following list is to document a complete list
+of supported bootm usages.
+
+Note: U-Boot supports two methods of booting a PowerPC Linux kernel: old way,
+i.e., without passing the Flattened Device Tree (FDT), and new way, where the
+kernel is passed a pointer to the FDT. The boot method is indicated for each
+scenario.
+
+
+1.  bootm               boot image at the current address, equivalent to 2,3,8
+
+Old uImage:
+2.  bootm <addr1>                   /* single image at <addr1> */
+3.  bootm <addr1>                   /* multi-image at <addr1>  */
+4.  bootm <addr1> -                 /* multi-image at <addr1>  */
+5.  bootm <addr1> <addr2>           /* single image at <addr1> */
+6.  bootm <addr1> <addr2> <addr3>   /* single image at <addr1> */
+7.  bootm <addr1> -       <addr3>   /* single image at <addr1> */
+
+New uImage:
+8.  bootm <addr1>
+9.  bootm [<addr1>]:<subimg1>
+10. bootm [<addr1>]#<conf>
+11. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2>
+12. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2> [<addr3>]:<subimg3>
+13. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2> <addr3>
+14. bootm [<addr1>]:<subimg1> -                   [<addr3>]:<subimg3>
+15. bootm [<addr1>]:<subimg1> -                   <addr3>
+
+
+Ad. 1. This is equivalent to cases 2,3,8, depending on the type of image at
+the current image address.
+- boot method: see cases 2,3,8
+
+Ad. 2. Boot kernel image located at <addr1>.
+- boot method: non-FDT
+
+Ad. 3. First and second components of the image at <addr1> are assumed to be a
+kernel and a ramdisk, respectively. The kernel is booted with initrd loaded
+with the ramdisk from the image.
+- boot method: depends on the number of components at <addr1>, and on whether
+  U-Boot is compiled with OF support:
+
+                    |          2 components |          3 components |
+                    |      (kernel, initrd) | (kernel, initrd, fdt) |
+---------------------------------------------------------------------
+#ifdef CONFIG_OF_*  |               non-FDT |                   FDT |
+#ifndef CONFIG_OF_* |               non-FDT |               non-FDT |
+
+Ad. 4. Similar to case 3, but the kernel is booted without initrd.  Second
+component of the multi-image is irrelevant (it can be a dummy, 1-byte file).
+- boot method: see case 3
+
+Ad. 5. Boot kernel image located at <addr1> with initrd loaded with ramdisk
+from the image at <addr2>.
+- boot method: non-FDT
+
+Ad. 6. <addr1> is the address of a kernel image, <addr2> is the address of a
+ramdisk image, and <addr3> is the address of a FDT binary blob.  Kernel is
+booted with initrd loaded with ramdisk from the image at <addr2>.
+- boot method: FDT
+
+Ad. 7. <addr1> is the address of a kernel image and <addr3> is the address of
+a FDT binary blob. Kernel is booted without initrd.
+- boot method: FDT
+
+Ad. 8. Image at <addr1> is assumed to contain a default configuration, which
+is booted.
+- boot method: FDT or non-FDT, depending on whether the default configuration
+  defines FDT
+
+Ad. 9. Similar to case 2: boot kernel stored in <subimg1> from the image at
+address <addr1>.
+- boot method: non-FDT
+
+Ad. 10. Boot configuration <conf> from the image at <addr1>.
+- boot method: FDT or non-FDT, depending on whether the configuration given
+  defines FDT
+
+Ad. 11. Equivalent to case 5: boot kernel stored in <subimg1> from the image
+at <addr1> with initrd loaded with ramdisk <subimg2> from the image at
+<addr2>.
+- boot method: non-FDT
+
+Ad. 12. Equivalent to case 6: boot kernel stored in <subimg1> from the image
+at <addr1> with initrd loaded with ramdisk <subimg2> from the image at
+<addr2>, and pass FDT blob <subimg3> from the image at <addr3>.
+- boot method: FDT
+
+Ad. 13. Similar to case 12, the difference being that <addr3> is the address
+of FDT binary blob that is to be passed to the kernel.
+- boot method: FDT
+
+Ad. 14. Equivalent to case 7: boot kernel stored in <subimg1> from the image
+at <addr1>, without initrd, and pass FDT blob <subimg3> from the image at
+<addr3>.
+- boot method: FDT
+
+Ad. 15. Similar to case 14, the difference being that <addr3> is the address
+of the FDT binary blob that is to be passed to the kernel.
+- boot method: FDT
+
+
+New uImage argument syntax
+--------------------------
+
+New uImage support introduces two new forms for bootm arguments, with the
+following syntax:
+
+- new uImage sub-image specification
+<addr>:<sub-image unit_name>
+
+- new uImage configuration specification
+<addr>#<configuration unit_name>
+
+
+Examples:
+
+- boot kernel "kernel@1" stored in a new uImage located at 200000:
+bootm 200000:kernel@1
+
+- boot configuration "cfg@1" from a new uImage located at 200000:
+bootm 200000#cfg@1
+
+- boot "kernel@1" from a new uImage at 200000 with initrd "ramdisk@2" found in
+  some other new uImage stored at address 800000:
+bootm 200000:kernel@1 800000:ramdisk@2
+
+- boot "kernel@2" from a new uImage at 200000, with initrd "ramdisk@1" and FDT
+  "fdt@1", both stored in some other new uImage located at 800000:
+bootm 200000:kernel@1 800000:ramdisk@1 800000:fdt@1
+
+- boot kernel "kernel@2" with initrd "ramdisk@2", both stored in a new uImage
+  at address 200000, with a raw FDT blob stored at address 600000:
+bootm 200000:kernel@2 200000:ramdisk@2 600000
+
+- boot kernel "kernel@2" from new uImage at 200000 with FDT "fdt@1" from the
+  same new uImage:
+bootm 200000:kernel@2 - 200000:fdt@1
+
+
+Note on current image address
+-----------------------------
+
+When bootm is called without arguments, the image at current image address is
+booted. The current image address is the address set most recently by a load
+command, etc, and is by default equal to CFG_LOAD_ADDR. For example, consider
+the following commands:
+
+tftp 200000 /tftpboot/kernel
+bootm
+Last command is equivalent to:
+bootm 200000
+
+In case of the new uImage argument syntax, the address portion of any argument
+can be omitted. If <addr3> is omitted, then it is assumed that image at
+<addr2> should be used. Similarly, when <addr2> is omitted, is is assumed that
+image at <addr1> should be used. If <addr1> is omitted, it is assumed that the
+current image address is to be used. For example, consider the following
+commands:
+
+tftp 200000 /tftpboot/uImage
+bootm :kernel@1
+Last command is equivalent to:
+bootm 200000:kernel@1
+
+tftp 200000 /tftpboot/uImage
+bootm 400000:kernel@1 :ramdisk@1
+Last command is equivalent to:
+bootm 400000:kernel@1 400000:ramdisk@1
+
+tftp 200000 /tftpboot/uImage
+bootm :kernel@1 400000:ramdisk@1 :fdt@1
+Last command is equivalent to:
+bootm 200000:kernel@1 400000:ramdisk@1 400000:fdt@1

+ 297 - 0
doc/uImage.FIT/howto.txt

@@ -0,0 +1,297 @@
+How to use images in the new image format
+=========================================
+
+Author: Bartlomiej Sieka <tur@semihalf.com>
+
+
+Overview
+--------
+
+The new uImage format allows more flexibility in handling images of various
+types (kernel, ramdisk, etc.), it also enhances integrity protection of images
+with sha1 and md5 checksums.
+
+Two auxiliary tools are needed on the development host system in order to
+create an uImage in the new format: mkimage and dtc, although only one
+(mkimage) is invoked directly. dtc is called from within mkimage and operates
+behind the scenes, but needs to be present in the $PATH nevertheless. It is
+important that the dtc used has support for binary includes -- refer to
+www.jdl.com for its latest version. mkimage (together with dtc) takes as input
+an image source file, which describes the contents of the image and defines
+its various properties used during booting. By convention, image source file
+has the ".its" extension, also, the details of its format are given in
+doc/source_file_format.txt. The actual data that is to be included in the
+uImage (kernel, ramdisk, etc.) is specified in the image source file in the
+form of paths to appropriate data files. The outcome of the image creation
+process is a binary file (by convention with the ".itb" extension) that
+contains all the referenced data (kernel, ramdisk, etc.) and other information
+needed by U-Boot to handle the uImage properly. The uImage file is then
+transferred to the target (e.g., via tftp) and booted using the bootm command.
+
+To summarize the prerequisites needed for new uImage creation:
+- mkimage
+- dtc (with support for binary includes)
+- image source file (*.its)
+- image data file(s)
+
+
+Here's a graphical overview of the image creation and booting process:
+
+image source file     mkimage + dtc               transfer to target
+        +            ---------------> image file --------------------> bootm
+image data files(s)
+
+
+Example 1 -- old-style (non-FDT) kernel booting
+-----------------------------------------------
+
+Consider a simple scenario, where a PPC Linux kernel built from sources on the
+development host is to be booted old-style (non-FDT) by U-Boot on an embedded
+target. Assume that the outcome of the build is vmlinux.bin.gz, a file which
+contains a gzip-compressed PPC Linux kernel (the only data file in this case).
+The uImage can be produced using the image source file
+doc/uImage.FIT/kernel.its (note that kernel.its assumes that vmlinux.bin.gz is
+in the current working directory; if desired, an alternative path can be
+specified in the kernel.its file). Here's how to create the image and inspect
+its contents:
+
+[on the host system]
+$ mkimage -f kernel.its kernel.itb
+DTC: dts->dtb  on file "kernel.its"
+$
+$ mkimage -l kernel.itb
+FIT description: Simple image with single Linux kernel
+Created:         Tue Mar 11 17:26:15 2008
+ Image 0 (kernel@1)
+  Description:  Vanilla Linux kernel
+  Type:         Kernel Image
+  Compression:  gzip compressed
+  Data Size:    943347 Bytes = 921.24 kB = 0.90 MB
+  Architecture: PowerPC
+  OS:           Linux
+  Load Address: 0x00000000
+  Entry Point:  0x00000000
+  Hash algo:    crc32
+  Hash value:   2ae2bb40
+  Hash algo:    sha1
+  Hash value:   3c200f34e2c226ddc789240cca0c59fc54a67cf4
+ Default Configuration: 'config@1'
+ Configuration 0 (config@1)
+  Description:  Boot Linux kernel
+  Kernel:       kernel@1
+
+
+The resulting image file kernel.itb can be now transferred to the target,
+inspected and booted (note that first three U-Boot commands below are shown
+for completeness -- they are part of the standard booting procedure and not
+specific to the new image format).
+
+[on the target system]
+=> print nfsargs
+nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath}
+=> print addip
+addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off panic=1
+=> run nfsargs addip
+=> tftp 900000 /path/to/tftp/location/kernel.itb
+Using FEC ETHERNET device
+TFTP from server 192.168.1.1; our IP address is 192.168.160.5
+Filename '/path/to/tftp/location/kernel.itb'.
+Load address: 0x900000
+Loading: #################################################################
+done
+Bytes transferred = 944464 (e6950 hex)
+=> iminfo
+
+## Checking Image at 00900000 ...
+   FIT image found
+   FIT description: Simple image with single Linux kernel
+   Created:         2008-03-11  16:26:15 UTC
+    Image 0 (kernel@1)
+     Description:  Vanilla Linux kernel
+     Type:         Kernel Image
+     Compression:  gzip compressed
+     Data Start:   0x009000e0
+     Data Size:    943347 Bytes = 921.2 kB
+     Architecture: PowerPC
+     OS:           Linux
+     Load Address: 0x00000000
+     Entry Point:  0x00000000
+     Hash algo:    crc32
+     Hash value:   2ae2bb40
+     Hash algo:    sha1
+     Hash value:   3c200f34e2c226ddc789240cca0c59fc54a67cf4
+    Default Configuration: 'config@1'
+    Configuration 0 (config@1)
+     Description:  Boot Linux kernel
+     Kernel:       kernel@1
+
+=> bootm
+## Booting kernel from FIT Image at 00900000 ...
+   Using 'config@1' configuration
+   Trying 'kernel@1' kernel subimage
+     Description:  Vanilla Linux kernel
+     Type:         Kernel Image
+     Compression:  gzip compressed
+     Data Start:   0x009000e0
+     Data Size:    943347 Bytes = 921.2 kB
+     Architecture: PowerPC
+     OS:           Linux
+     Load Address: 0x00000000
+     Entry Point:  0x00000000
+     Hash algo:    crc32
+     Hash value:   2ae2bb40
+     Hash algo:    sha1
+     Hash value:   3c200f34e2c226ddc789240cca0c59fc54a67cf4
+   Verifying Hash Integrity ... crc32+ sha1+ OK
+   Uncompressing Kernel Image ... OK
+Memory BAT mapping: BAT2=256Mb, BAT3=0Mb, residual: 0Mb
+Linux version 2.4.25 (m8@hekate) (gcc version 4.0.0 (DENX ELDK 4.0 4.0.0)) #2 czw lip 5 17:56:18 CEST 2007
+On node 0 totalpages: 65536
+zone(0): 65536 pages.
+zone(1): 0 pages.
+zone(2): 0 pages.
+Kernel command line: root=/dev/nfs rw nfsroot=192.168.1.1:/opt/eldk-4.1/ppc_6xx ip=192.168.160.5:192.168.1.1::255.255.0.0:lite5200b:eth0:off panic=1
+Calibrating delay loop... 307.20 BogoMIPS
+
+
+Example 2 -- new-style (FDT) kernel booting
+-------------------------------------------
+
+Consider another simple scenario, where a PPC Linux kernel is to be booted
+new-style, i.e., with a FDT blob. In this case there are two prerequisite data
+files: vmlinux.bin.gz (Linux kernel) and target.dtb (FDT blob). The uImage can
+be produced using image source file doc/uImage.FIT/kernel_fdt.its like this
+(note again, that both prerequisite data files are assumed to be present in
+the current working directory -- image source file kernel_fdt.its can be
+modified to take the files from some other location if needed):
+
+[on the host system]
+$ mkimage -f kernel_fdt.its kernel_fdt.itb
+DTC: dts->dtb  on file "kernel_fdt.its"
+$
+$ mkimage -l kernel_fdt.itb
+FIT description: Simple image with single Linux kernel and FDT blob
+Created:         Tue Mar 11 16:29:22 2008
+ Image 0 (kernel@1)
+  Description:  Vanilla Linux kernel
+  Type:         Kernel Image
+  Compression:  gzip compressed
+  Data Size:    1092037 Bytes = 1066.44 kB = 1.04 MB
+  Architecture: PowerPC
+  OS:           Linux
+  Load Address: 0x00000000
+  Entry Point:  0x00000000
+  Hash algo:    crc32
+  Hash value:   2c0cc807
+  Hash algo:    sha1
+  Hash value:   264b59935470e42c418744f83935d44cdf59a3bb
+ Image 1 (fdt@1)
+  Description:  Flattened Device Tree blob
+  Type:         Flat Device Tree
+  Compression:  uncompressed
+  Data Size:    16384 Bytes = 16.00 kB = 0.02 MB
+  Architecture: PowerPC
+  Hash algo:    crc32
+  Hash value:   0d655d71
+  Hash algo:    sha1
+  Hash value:   25ab4e15cd4b8a5144610394560d9c318ce52def
+ Default Configuration: 'conf@1'
+ Configuration 0 (conf@1)
+  Description:  Boot Linux kernel with FDT blob
+  Kernel:       kernel@1
+  FDT:          fdt@1
+
+
+The resulting image file kernel_fdt.itb can be now transferred to the target,
+inspected and booted:
+
+[on the target system]
+=> tftp 900000 /path/to/tftp/location/kernel_fdt.itb
+Using FEC ETHERNET device
+TFTP from server 192.168.1.1; our IP address is 192.168.160.5
+Filename '/path/to/tftp/location/kernel_fdt.itb'.
+Load address: 0x900000
+Loading: #################################################################
+         ###########
+done
+Bytes transferred = 1109776 (10ef10 hex)
+=> iminfo
+
+## Checking Image at 00900000 ...
+   FIT image found
+   FIT description: Simple image with single Linux kernel and FDT blob
+   Created:         2008-03-11  15:29:22 UTC
+    Image 0 (kernel@1)
+     Description:  Vanilla Linux kernel
+     Type:         Kernel Image
+     Compression:  gzip compressed
+     Data Start:   0x009000ec
+     Data Size:    1092037 Bytes =  1 MB
+     Architecture: PowerPC
+     OS:           Linux
+     Load Address: 0x00000000
+     Entry Point:  0x00000000
+     Hash algo:    crc32
+     Hash value:   2c0cc807
+     Hash algo:    sha1
+     Hash value:   264b59935470e42c418744f83935d44cdf59a3bb
+    Image 1 (fdt@1)
+     Description:  Flattened Device Tree blob
+     Type:         Flat Device Tree
+     Compression:  uncompressed
+     Data Start:   0x00a0abdc
+     Data Size:    16384 Bytes = 16 kB
+     Architecture: PowerPC
+     Hash algo:    crc32
+     Hash value:   0d655d71
+     Hash algo:    sha1
+     Hash value:   25ab4e15cd4b8a5144610394560d9c318ce52def
+    Default Configuration: 'conf@1'
+    Configuration 0 (conf@1)
+     Description:  Boot Linux kernel with FDT blob
+     Kernel:       kernel@1
+     FDT:          fdt@1
+=> bootm
+## Booting kernel from FIT Image at 00900000 ...
+   Using 'conf@1' configuration
+   Trying 'kernel@1' kernel subimage
+     Description:  Vanilla Linux kernel
+     Type:         Kernel Image
+     Compression:  gzip compressed
+     Data Start:   0x009000ec
+     Data Size:    1092037 Bytes =  1 MB
+     Architecture: PowerPC
+     OS:           Linux
+     Load Address: 0x00000000
+     Entry Point:  0x00000000
+     Hash algo:    crc32
+     Hash value:   2c0cc807
+     Hash algo:    sha1
+     Hash value:   264b59935470e42c418744f83935d44cdf59a3bb
+   Verifying Hash Integrity ... crc32+ sha1+ OK
+   Uncompressing Kernel Image ... OK
+## Flattened Device Tree from FIT Image at 00900000
+   Using 'conf@1' configuration
+   Trying 'fdt@1' FDT blob subimage
+     Description:  Flattened Device Tree blob
+     Type:         Flat Device Tree
+     Compression:  uncompressed
+     Data Start:   0x00a0abdc
+     Data Size:    16384 Bytes = 16 kB
+     Architecture: PowerPC
+     Hash algo:    crc32
+     Hash value:   0d655d71
+     Hash algo:    sha1
+     Hash value:   25ab4e15cd4b8a5144610394560d9c318ce52def
+   Verifying Hash Integrity ... crc32+ sha1+ OK
+   Booting using the fdt blob at 0xa0abdc
+   Loading Device Tree to 007fc000, end 007fffff ... OK
+[    0.000000] Using lite5200 machine description
+[    0.000000] Linux version 2.6.24-rc6-gaebecdfc (m8@hekate) (gcc version 4.0.0 (DENX ELDK 4.1 4.0.0)) #1 Sat Jan 12 15:38:48 CET 2008
+
+
+Example 3 -- advanced booting
+-----------------------------
+
+Refer to doc/uImage.FIT/multi.its for an image source file that allows more
+sophisticated booting scenarios (multiple kernels, ramdisks and fdt blobs).

+ 34 - 0
doc/uImage.FIT/kernel.its

@@ -0,0 +1,34 @@
+/*
+ * Simple U-boot uImage source file containing a single kernel
+ */
+/ {
+	description = "Simple image with single Linux kernel";
+	#address-cells = <1>;
+
+	images {
+		kernel@1 {
+			description = "Vanilla Linux kernel";
+			data = /incbin/("./vmlinux.bin.gz");
+			type = "kernel";
+			arch = "ppc";
+			os = "linux";
+			compression = "gzip";
+			load = <00000000>;
+			entry = <00000000>;
+			hash@1 {
+				algo = "crc32";
+			};
+			hash@2 {
+				algo = "sha1";
+			};
+		};
+	};
+
+	configurations {
+		default = "config@1";
+		config@1 {
+			description = "Boot Linux kernel";
+			kernel = "kernel@1";
+		};
+	};
+};

+ 48 - 0
doc/uImage.FIT/kernel_fdt.its

@@ -0,0 +1,48 @@
+/*
+ * Simple U-boot uImage source file containing a single kernel and FDT blob
+ */
+/ {
+	description = "Simple image with single Linux kernel and FDT blob";
+	#address-cells = <1>;
+
+	images {
+		kernel@1 {
+			description = "Vanilla Linux kernel";
+			data = /incbin/("./vmlinux.bin.gz");
+			type = "kernel";
+			arch = "ppc";
+			os = "linux";
+			compression = "gzip";
+			load = <00000000>;
+			entry = <00000000>;
+			hash@1 {
+				algo = "crc32";
+			};
+			hash@2 {
+				algo = "sha1";
+			};
+		};
+		fdt@1 {
+			description = "Flattened Device Tree blob";
+			data = /incbin/("./target.dtb");
+			type = "flat_dt";
+			arch = "ppc";
+			compression = "none";
+			hash@1 {
+				algo = "crc32";
+			};
+			hash@2 {
+				algo = "sha1";
+			};
+		};
+	};
+
+	configurations {
+		default = "conf@1";
+		conf@1 {
+			description = "Boot Linux kernel with FDT blob";
+			kernel = "kernel@1";
+			fdt = "fdt@1";
+		};
+	};
+};

+ 124 - 0
doc/uImage.FIT/multi.its

@@ -0,0 +1,124 @@
+/*
+ * U-boot uImage source file with multiple kernels, ramdisks and FDT blobs
+ */
+/ {
+	description = "Various kernels, ramdisks and FDT blobs";
+	#address-cells = <1>;
+
+	images {
+		kernel@1 {
+			description = "vanilla-2.6.23";
+			data = /incbin/("./vmlinux.bin.gz");
+			type = "kernel";
+			arch = "ppc";
+			os = "linux";
+			compression = "gzip";
+			load = <00000000>;
+			entry = <00000000>;
+			hash@1 {
+				algo = "md5";
+			};
+			hash@2 {
+				algo = "sha1";
+			};
+		};
+
+		kernel@2 {
+			description = "2.6.23-denx";
+			data = /incbin/("./2.6.23-denx.bin.gz");
+			type = "kernel";
+			arch = "ppc";
+			os = "linux";
+			compression = "gzip";
+			load = <00000000>;
+			entry = <00000000>;
+			hash@1 {
+				algo = "sha1";
+			};
+		};
+
+		kernel@3 {
+			description = "2.4.25-denx";
+			data = /incbin/("./2.4.25-denx.bin.gz");
+			type = "kernel";
+			arch = "ppc";
+			os = "linux";
+			compression = "gzip";
+			load = <00000000>;
+			entry = <00000000>;
+			hash@1 {
+				algo = "md5";
+			};
+		};
+
+		ramdisk@1 {
+			description = "eldk-4.2-ramdisk";
+			data = /incbin/("./eldk-4.2-ramdisk");
+			type = "ramdisk";
+			arch = "ppc";
+			compression = "gzip";
+			hash@1 {
+				algo = "sha1";
+			};
+		};
+
+		ramdisk@2 {
+			description = "eldk-3.1-ramdisk";
+			data = /incbin/("./eldk-3.1-ramdisk");
+			type = "ramdisk";
+			arch = "ppc";
+			compression = "gzip";
+			hash@1 {
+				algo = "crc32";
+			};
+		};
+
+		fdt@1 {
+			description = "tqm5200-fdt";
+			data = /incbin/("./tqm5200.dtb");
+			type = "flat_dt";
+			arch = "ppc";
+			compression = "none";
+			hash@1 {
+				algo = "crc32";
+			};
+		};
+
+		fdt@2 {
+			description = "tqm5200s-fdt";
+			data = /incbin/("./tqm5200s.dtb");
+			type = "flat_dt";
+			arch = "ppc";
+			compression = "none";
+			load = <00700000>;
+			hash@1 {
+				algo = "sha1";
+			};
+		};
+
+	};
+
+	configurations {
+		default = "config@1";
+
+		config@1 {
+			description = "tqm5200 vanilla-2.6.23 configuration";
+			kernel = "kernel@1";
+			ramdisk = "ramdisk@1";
+			fdt = "fdt@1";
+		};
+
+		config@2 {
+			description = "tqm5200s denx-2.6.23 configuration";
+			kernel = "kernel@2";
+			ramdisk = "ramdisk@1";
+			fdt = "fdt@2";
+		};
+
+		config@3 {
+			description = "tqm5200s denx-2.4.25 configuration";
+			kernel = "kernel@3";
+			ramdisk = "ramdisk@2";
+		};
+	};
+};

+ 262 - 0
doc/uImage.FIT/source_file_format.txt

@@ -0,0 +1,262 @@
+U-boot new uImage source file format (bindings definition)
+==========================================================
+
+Author: Marian Balakowicz <m8@semihalf.com>
+
+1) Introduction
+---------------
+
+Evolution of the 2.6 Linux kernel for embedded PowerPC systems introduced new
+booting method which requires that hardware description is available to the
+kernel in the form of Flattened Device Tree.
+
+Booting with a Flattened Device Tree is much more flexible and is intended to
+replace direct passing of 'struct bd_info' which was used to boot pre-FDT
+kernels.
+
+However, U-boot needs to support both techniques to provide backward
+compatibility for platforms which are not FDT ready. Number of elements
+playing role in the booting process has increased and now includes the FDT
+blob. Kernel image, FDT blob and possibly ramdisk image - all must be placed
+in the system memory and passed to bootm as a arguments. Some of them may be
+missing: FDT is not present for legacy platforms, ramdisk is always optional.
+Additionally, old uImage format has been extended to support multi sub-images
+but the support is limited by simple format of the legacy uImage structure.
+Single binary header 'struct image_header' is not flexible enough to cover all
+possible scenarios.
+
+All those factors combined clearly show that there is a need for new, more
+flexible, multi component uImage format.
+
+
+2) New uImage format assumptions
+--------------------------------
+
+a) Implementation
+
+Libfdt has been selected for the new uImage format implementation as (1) it
+provides needed functionality, (2) is actively maintained and developed and
+(3) increases code reuse as it is already part of the U-boot source tree.
+
+b) Terminology
+
+This document defines new uImage structure by providing FDT bindings for new
+uImage internals. Bindings are defined from U-boot perspective, i.e. describe
+final form of the uImage at the moment when it reaches U-boot. User
+perspective may be simpler, as some of the properties (like timestamps and
+hashes) will need to be filled in automatically by the U-boot mkimage tool.
+
+To avoid confusion with the kernel FDT the following naming convention is
+proposed for the new uImage format related terms:
+
+FIT	- Flattened uImage Tree
+
+FIT is formally a flattened device tree (in the libfdt meaning), which
+conforms to bindings defined in this document.
+
+.its	- image tree source
+.itb	- image tree blob
+
+c) Image building procedure
+
+The following picture shows how the new uImage is prepared. Input consists of
+image source file (.its) and a set of data files. Image is created with the
+help of standard U-boot mkimage tool which in turn uses dtc (device tree
+compiler) to produce image tree blob (.itb).  Resulting .itb file is is the
+actual binary of a new uImage.
+
+
+tqm5200.its
++
+vmlinux.bin.gz     mkimage + dtc               xfer to target
+eldk-4.2-ramdisk  --------------> tqm5200.itb --------------> bootm
+tqm5200.dtb                          /|\
+...                                   |
+                                 'new uImage'
+
+	- create .its file, automatically filled-in properties are omitted
+	- call mkimage tool on a .its file
+	- mkimage calls dtc to create .itb image and assures that
+	  missing properties are added
+	- .itb (new uImage) is uploaded onto the target and used therein
+
+
+d) Unique identifiers
+
+To identify FIT sub-nodes representing images, hashes, configurations (which
+are defined in the following sections), the "unit name" of the given sub-node
+is used as it's identifier as it assures uniqueness without additional
+checking required.
+
+
+3) Root node properties
+-----------------------
+
+Root node of the uImage Tree should have the following layout:
+
+/ o image-tree
+    |- description = "image description"
+    |- timestamp = <12399321>
+    |- #address-cells = <1>
+    |
+    o images
+    | |
+    | o img@1 {...}
+    | o img@2 {...}
+    | ...
+    |
+    o configurations
+      |- default = "cfg@1"
+      |
+      o cfg@1 {...}
+      o cfg@2 {...}
+      ...
+
+
+  Optional property:
+  - description : Textual description of the uImage
+
+  Mandatory property:
+  - timestamp : Last image modification time being counted in seconds since
+    1970-01-01 00:00:00 - to be automatically calculated by mkimage tool.
+
+  Conditionally mandatory property:
+  - #address-cells : Number of 32bit cells required to represent entry and
+    load addresses supplied within sub-image nodes. May be omitted when no
+    entry or load addresses are used.
+
+  Mandatory node:
+  - images : This node contains a set of sub-nodes, each of them representing
+    single component sub-image (like kernel, ramdisk, etc.). At least one
+    sub-image is required.
+
+  Optional node:
+  - configurations : Contains a set of available configuration nodes and
+    defines a default configuration.
+
+
+4) '/images' node
+-----------------
+
+This node is a container node for component sub-image nodes. Each sub-node of
+the '/images' node should have the following layout:
+
+ o image@1
+   |- description = "component sub-image description"
+   |- data = /incbin/("path/to/data/file.bin")
+   |- type = "sub-image type name"
+   |- arch = "ARCH name"
+   |- os = "OS name"
+   |- compression = "compression name"
+   |- load = <00000000>
+   |- entry = <00000000>
+   |
+   o hash@1 {...}
+   o hash@2 {...}
+   ...
+
+  Mandatory properties:
+  - description : Textual description of the component sub-image
+  - type : Name of component sub-image type, supported types are:
+    "standalone", "kernel", "ramdisk", "firmware", "script", "filesystem",
+    "fdt".
+  - data : Path to the external file which contains this node's binary data.
+  - compression : Compression used by included data. Supported compressions
+    are "gzip" and "bzip2". If no compression is used compression property
+    should be set to "none".
+
+  Conditionally mandatory property:
+  - os : OS name, mandatory for type="kernel", valid OS names are: "openbsd",
+    "netbsd", "freebsd", "4_4bsd", "linux", "svr4", "esix", "solaris", "irix",
+    "sco", "dell", "ncr", "lynxos", "vxworks", "psos", "qnx", "u_boot",
+    "rtems", "artos", "unity".
+  - arch : Architecture name, mandatory for types: "standalone", "kernel",
+    "firmware", "ramdisk" and "fdt". Valid architecture names are: "alpha",
+    "arm", "i386", "ia64", "mips", "mips64", "ppc", "s390", "sh", "sparc",
+    "sparc64", "m68k", "nios", "microblaze", "nios2", "blackfin", "avr32",
+    "st200".
+  - entry : entry point address, address size is determined by
+    '#address-cells' property of the root node. Mandatory for for types:
+    "standalone" and "kernel".
+  - load : load address, address size is determined by '#address-cells'
+    property of the root node. Mandatory for types: "standalone" and "kernel".
+
+  Optional nodes:
+  - hash@1 : Each hash sub-node represents separate hash or checksum
+    calculated for node's data according to specified algorithm.
+
+
+5) Hash nodes
+-------------
+
+o hash@1
+  |- algo = "hash or checksum algorithm name"
+  |- value = [hash or checksum value]
+
+  Mandatory properties:
+  - algo : Algorithm name, supported are "crc32", "md5" and "sha1".
+  - value : Actual checksum or hash value, correspondingly 4, 16 or 20 bytes
+    long.
+
+
+6) '/configurations' node
+-------------------------
+
+The 'configurations' node is optional. If present, it allows to create a
+convenient, labeled boot configurations, which combine together kernel images
+with their ramdisks and fdt blobs.
+
+The 'configurations' node has has the following structure:
+
+o configurations
+  |- default = "default configuration sub-node unit name"
+  |
+  o config@1 {...}
+  o config@2 {...}
+  ...
+
+
+  Optional property:
+  - default : Selects one of the configuration sub-nodes as a default
+    configuration.
+
+  Mandatory nodes:
+  - configuration-sub-node-unit-name : At least one of the configuration
+    sub-nodes is required.
+
+
+7) Configuration nodes
+----------------------
+
+Each configuration has the following structure:
+
+o config@1
+  |- description = "configuration description"
+  |- kernel = "kernel sub-node unit name"
+  |- ramdisk = "ramdisk sub-node unit name"
+  |- fdt = "fdt sub-node unit-name"
+
+
+  Mandatory properties:
+  - description : Textual configuration description.
+  - kernel : Unit name of the corresponding kernel image (image sub-node of a
+    "kernel" type).
+
+  Optional properties:
+  - ramdisk : Unit name of the corresponding ramdisk image (component image
+    node of a "ramdisk" type).
+  - fdt : Unit name of the corresponding fdt blob (component image node of a
+    "fdt type").
+
+The FDT blob is required to properly boot FDT based kernel, so the minimal
+configuration for 2.6 FDT kernel is (kernel, fdt) pair.
+
+Older, 2.4 kernel and 2.6 non-FDT kernel do not use FDT blob, in such cases
+'struct bd_info' must be passed instead of FDT blob, thus fdt property *must
+not* be specified in a configuration node.
+
+
+8) Examples
+-----------
+
+Please see doc/uImage.FIT/*.its for actual image source files.

+ 3 - 2
examples/eepro100_eeprom.c

@@ -17,8 +17,9 @@
  * and release the resulting code under the GPL.
  * and release the resulting code under the GPL.
  */
  */
 
 
-#define _PPC_STRING_H_		/* avoid unnecessary str/mem functions */
-#define _LINUX_STRING_H_	/* avoid unnecessary str/mem functions */
+/* avoid unnecessary memcpy function */
+#define __HAVE_ARCH_MEMCPY
+#define _PPC_STRING_H_
 
 
 #include <common.h>
 #include <common.h>
 #include <exports.h>
 #include <exports.h>

+ 2 - 18
fs/cramfs/uncompress.c

@@ -29,24 +29,8 @@
 
 
 static z_stream stream;
 static z_stream stream;
 
 
-#define ZALLOC_ALIGNMENT	16
-
-static void *zalloc (void *x, unsigned items, unsigned size)
-{
-	void *p;
-
-	size *= items;
-	size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
-
-	p = malloc (size);
-
-	return (p);
-}
-
-static void zfree (void *x, void *addr, unsigned nb)
-{
-	free (addr);
-}
+void *zalloc(void *, unsigned, unsigned);
+void zfree(void *, void *, unsigned);
 
 
 /* Returns length of decompressed data. */
 /* Returns length of decompressed data. */
 int cramfs_uncompress_block (void *dst, void *src, int srclen)
 int cramfs_uncompress_block (void *dst, void *src, int srclen)

+ 0 - 1
include/asm-i386/zimage.h

@@ -70,6 +70,5 @@ void *load_zimage(char *image, unsigned long kernel_size,
 		  int auto_boot);
 		  int auto_boot);
 
 
 void boot_zimage(void *setup_base);
 void boot_zimage(void *setup_base);
-image_header_t *fake_zimage_header(image_header_t *hdr, void *ptr, int size);
 
 
 #endif
 #endif

+ 1 - 4
include/common.h

@@ -222,10 +222,7 @@ int mac_read_from_eeprom(void);
 void flash_perror (int);
 void flash_perror (int);
 
 
 /* common/cmd_autoscript.c */
 /* common/cmd_autoscript.c */
-int	autoscript (ulong addr);
-
-/* common/cmd_bootm.c */
-void	print_image_hdr (image_header_t *hdr);
+int	autoscript (ulong addr, const char *fit_uname);
 
 
 extern ulong load_addr;		/* Default Load Address */
 extern ulong load_addr;		/* Default Load Address */
 
 

+ 6 - 0
include/configs/pcs440ep.h

@@ -27,6 +27,12 @@
 #ifndef __CONFIG_H
 #ifndef __CONFIG_H
 #define __CONFIG_H
 #define __CONFIG_H
 
 
+
+/* new uImage format support */
+#define CONFIG_FIT		1
+#define CONFIG_OF_LIBFDT	1
+#define CONFIG_FIT_VERBOSE	1 /* enable fit_format_{error,warning}() */
+
 /*-----------------------------------------------------------------------
 /*-----------------------------------------------------------------------
  * High Level Configuration Options
  * High Level Configuration Options
  *----------------------------------------------------------------------*/
  *----------------------------------------------------------------------*/

+ 458 - 21
include/image.h

@@ -1,4 +1,6 @@
 /*
 /*
+ * (C) Copyright 2008 Semihalf
+ *
  * (C) Copyright 2000-2005
  * (C) Copyright 2000-2005
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  *
@@ -31,6 +33,34 @@
 #ifndef __IMAGE_H__
 #ifndef __IMAGE_H__
 #define __IMAGE_H__
 #define __IMAGE_H__
 
 
+#include <asm/byteorder.h>
+#include <command.h>
+
+#ifndef USE_HOSTCC
+#include <lmb.h>
+#include <linux/string.h>
+#include <asm/u-boot.h>
+
+#else
+
+/* new uImage format support enabled on host */
+#define CONFIG_FIT		1
+#define CONFIG_OF_LIBFDT	1
+#define CONFIG_FIT_VERBOSE	1 /* enable fit_format_{error,warning}() */
+
+#endif /* USE_HOSTCC */
+
+#if defined(CONFIG_FIT) && !defined(CONFIG_OF_LIBFDT)
+#error "CONFIG_OF_LIBFDT not enabled, required by CONFIG_FIT!"
+#endif
+
+#if defined(CONFIG_FIT)
+#include <fdt.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#define CONFIG_MD5		/* FIT images need MD5 support */
+#endif
+
 /*
 /*
  * Operating System Codes
  * Operating System Codes
  */
  */
@@ -59,25 +89,25 @@
 /*
 /*
  * CPU Architecture Codes (supported by Linux)
  * CPU Architecture Codes (supported by Linux)
  */
  */
-#define IH_CPU_INVALID		0	/* Invalid CPU	*/
-#define IH_CPU_ALPHA		1	/* Alpha	*/
-#define IH_CPU_ARM		2	/* ARM		*/
-#define IH_CPU_I386		3	/* Intel x86	*/
-#define IH_CPU_IA64		4	/* IA64		*/
-#define IH_CPU_MIPS		5	/* MIPS		*/
-#define IH_CPU_MIPS64		6	/* MIPS	 64 Bit */
-#define IH_CPU_PPC		7	/* PowerPC	*/
-#define IH_CPU_S390		8	/* IBM S390	*/
-#define IH_CPU_SH		9	/* SuperH	*/
-#define IH_CPU_SPARC		10	/* Sparc	*/
-#define IH_CPU_SPARC64		11	/* Sparc 64 Bit */
-#define IH_CPU_M68K		12	/* M68K		*/
-#define IH_CPU_NIOS		13	/* Nios-32	*/
-#define IH_CPU_MICROBLAZE	14	/* MicroBlaze   */
-#define IH_CPU_NIOS2		15	/* Nios-II	*/
-#define IH_CPU_BLACKFIN		16	/* Blackfin	*/
-#define IH_CPU_AVR32		17	/* AVR32	*/
-#define IH_CPU_ST200	        18	/* STMicroelectronics ST200  */
+#define IH_ARCH_INVALID		0	/* Invalid CPU	*/
+#define IH_ARCH_ALPHA		1	/* Alpha	*/
+#define IH_ARCH_ARM		2	/* ARM		*/
+#define IH_ARCH_I386		3	/* Intel x86	*/
+#define IH_ARCH_IA64		4	/* IA64		*/
+#define IH_ARCH_MIPS		5	/* MIPS		*/
+#define IH_ARCH_MIPS64		6	/* MIPS	 64 Bit */
+#define IH_ARCH_PPC		7	/* PowerPC	*/
+#define IH_ARCH_S390		8	/* IBM S390	*/
+#define IH_ARCH_SH		9	/* SuperH	*/
+#define IH_ARCH_SPARC		10	/* Sparc	*/
+#define IH_ARCH_SPARC64		11	/* Sparc 64 Bit */
+#define IH_ARCH_M68K		12	/* M68K		*/
+#define IH_ARCH_NIOS		13	/* Nios-32	*/
+#define IH_ARCH_MICROBLAZE	14	/* MicroBlaze   */
+#define IH_ARCH_NIOS2		15	/* Nios-II	*/
+#define IH_ARCH_BLACKFIN	16	/* Blackfin	*/
+#define IH_ARCH_AVR32		17	/* AVR32	*/
+#define IH_ARCH_ST200	        18	/* STMicroelectronics ST200  */
 
 
 /*
 /*
  * Image Types
  * Image Types
@@ -139,9 +169,9 @@
 #define IH_NMLEN		32	/* Image Name Length		*/
 #define IH_NMLEN		32	/* Image Name Length		*/
 
 
 /*
 /*
- * all data in network byte order (aka natural aka bigendian)
+ * Legacy format image header,
+ * all data in network byte order (aka natural aka bigendian).
  */
  */
-
 typedef struct image_header {
 typedef struct image_header {
 	uint32_t	ih_magic;	/* Image Header Magic Number	*/
 	uint32_t	ih_magic;	/* Image Header Magic Number	*/
 	uint32_t	ih_hcrc;	/* Image Header CRC Checksum	*/
 	uint32_t	ih_hcrc;	/* Image Header CRC Checksum	*/
@@ -157,5 +187,412 @@ typedef struct image_header {
 	uint8_t		ih_name[IH_NMLEN];	/* Image Name		*/
 	uint8_t		ih_name[IH_NMLEN];	/* Image Name		*/
 } image_header_t;
 } image_header_t;
 
 
+/*
+ * Legacy and FIT format headers used by do_bootm() and do_bootm_<os>()
+ * routines.
+ */
+typedef struct bootm_headers {
+	/*
+	 * Legacy os image header, if it is a multi component image
+	 * then boot_get_ramdisk() and get_fdt() will attempt to get
+	 * data from second and third component accordingly.
+	 */
+	image_header_t	*legacy_hdr_os;
+	ulong		legacy_hdr_valid;
+
+#if defined(CONFIG_FIT)
+	const char	*fit_uname_cfg;	/* configuration node unit name */
+
+	void		*fit_hdr_os;	/* os FIT image header */
+	const char	*fit_uname_os;	/* os subimage node unit name */
+	int		fit_noffset_os;	/* os subimage node offset */
+
+	void		*fit_hdr_rd;	/* init ramdisk FIT image header */
+	const char	*fit_uname_rd;	/* init ramdisk subimage node unit name */
+	int		fit_noffset_rd;	/* init ramdisk subimage node offset */
+
+#if defined(CONFIG_PPC)
+	void		*fit_hdr_fdt;	/* FDT blob FIT image header */
+	const char	*fit_uname_fdt;	/* FDT blob subimage node unit name */
+	int		fit_noffset_fdt;/* FDT blob subimage node offset */
+#endif
+#endif
+
+	int		verify;		/* getenv("verify")[0] != 'n' */
+	int		autostart;	/* getenv("autostart")[0] != 'n' */
+	struct lmb	*lmb;		/* for memory mgmt */
+} bootm_headers_t;
+
+/*
+ * Some systems (for example LWMON) have very short watchdog periods;
+ * we must make sure to split long operations like memmove() or
+ * crc32() into reasonable chunks.
+ */
+#define CHUNKSZ (64 * 1024)
+
+#define uimage_to_cpu(x)		ntohl(x)
+#define cpu_to_uimage(x)		htonl(x)
+
+const char *genimg_get_os_name (uint8_t os);
+const char *genimg_get_arch_name (uint8_t arch);
+const char *genimg_get_type_name (uint8_t type);
+const char *genimg_get_comp_name (uint8_t comp);
+int genimg_get_os_id (const char *name);
+int genimg_get_arch_id (const char *name);
+int genimg_get_type_id (const char *name);
+int genimg_get_comp_id (const char *name);
+
+#ifndef USE_HOSTCC
+/* Image format types, returned by _get_format() routine */
+#define IMAGE_FORMAT_INVALID	0x00
+#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_has_config (bootm_headers_t *images);
+ulong genimg_get_image (ulong img_addr);
+
+int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
+		uint8_t arch, ulong *rd_start, ulong *rd_end);
+
+#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
+int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
+		  ulong *initrd_start, ulong *initrd_end);
+
+int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
+			ulong bootmap_base);
+int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base);
+#endif /* CONFIG_PPC || CONFIG_M68K */
+#endif /* !USE_HOSTCC */
+
+/*******************************************************************/
+/* Legacy format specific code (prefixed with image_) */
+/*******************************************************************/
+static inline uint32_t image_get_header_size (void)
+{
+	return (sizeof (image_header_t));
+}
+
+#define image_get_hdr_l(f) \
+	static inline uint32_t image_get_##f(image_header_t *hdr) \
+	{ \
+		return uimage_to_cpu (hdr->ih_##f); \
+	}
+image_get_hdr_l (magic);
+image_get_hdr_l (hcrc);
+image_get_hdr_l (time);
+image_get_hdr_l (size);
+image_get_hdr_l (load);
+image_get_hdr_l (ep);
+image_get_hdr_l (dcrc);
+
+#define image_get_hdr_b(f) \
+	static inline uint8_t image_get_##f(image_header_t *hdr) \
+	{ \
+		return hdr->ih_##f; \
+	}
+image_get_hdr_b (os);
+image_get_hdr_b (arch);
+image_get_hdr_b (type);
+image_get_hdr_b (comp);
+
+static inline char *image_get_name (image_header_t *hdr)
+{
+	return (char *)hdr->ih_name;
+}
+
+static inline uint32_t image_get_data_size (image_header_t *hdr)
+{
+	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_image_end (image_header_t *hdr)
+{
+	return ((ulong)hdr + image_get_image_size (hdr));
+}
+
+#define image_set_hdr_l(f) \
+	static inline void image_set_##f(image_header_t *hdr, uint32_t val) \
+	{ \
+		hdr->ih_##f = cpu_to_uimage (val); \
+	}
+image_set_hdr_l (magic);
+image_set_hdr_l (hcrc);
+image_set_hdr_l (time);
+image_set_hdr_l (size);
+image_set_hdr_l (load);
+image_set_hdr_l (ep);
+image_set_hdr_l (dcrc);
+
+#define image_set_hdr_b(f) \
+	static inline void image_set_##f(image_header_t *hdr, uint8_t val) \
+	{ \
+		hdr->ih_##f = val; \
+	}
+image_set_hdr_b (os);
+image_set_hdr_b (arch);
+image_set_hdr_b (type);
+image_set_hdr_b (comp);
+
+static inline void image_set_name (image_header_t *hdr, const char *name)
+{
+	strncpy (image_get_name (hdr), name, IH_NMLEN);
+}
+
+int image_check_hcrc (image_header_t *hdr);
+int image_check_dcrc (image_header_t *hdr);
+#ifndef USE_HOSTCC
+int image_check_dcrc_wd (image_header_t *hdr, ulong chunksize);
+int getenv_verify (void);
+int getenv_autostart (void);
+ulong getenv_bootm_low(void);
+ulong getenv_bootm_size(void);
+void memmove_wd (void *to, void *from, size_t len, ulong chunksz);
+#endif
+
+static inline int image_check_magic (image_header_t *hdr)
+{
+	return (image_get_magic (hdr) == IH_MAGIC);
+}
+static inline int image_check_type (image_header_t *hdr, uint8_t type)
+{
+	return (image_get_type (hdr) == type);
+}
+static inline int image_check_arch (image_header_t *hdr, uint8_t arch)
+{
+	return (image_get_arch (hdr) == arch);
+}
+static inline int image_check_os (image_header_t *hdr, uint8_t os)
+{
+	return (image_get_os (hdr) == os);
+}
+
+ulong image_multi_count (image_header_t *hdr);
+void image_multi_getimg (image_header_t *hdr, ulong idx,
+			ulong *data, ulong *len);
+
+inline void image_print_contents (image_header_t *hdr);
+inline void image_print_contents_noindent (image_header_t *hdr);
+
+#ifndef USE_HOSTCC
+static inline int image_check_target_arch (image_header_t *hdr)
+{
+#if defined(__ARM__)
+	if (!image_check_arch (hdr, IH_ARCH_ARM))
+#elif defined(__avr32__)
+	if (!image_check_arch (hdr, IH_ARCH_AVR32))
+#elif defined(__bfin__)
+	if (!image_check_arch (hdr, IH_ARCH_BLACKFIN))
+#elif defined(__I386__)
+	if (!image_check_arch (hdr, IH_ARCH_I386))
+#elif defined(__M68K__)
+	if (!image_check_arch (hdr, IH_ARCH_M68K))
+#elif defined(__microblaze__)
+	if (!image_check_arch (hdr, IH_ARCH_MICROBLAZE))
+#elif defined(__mips__)
+	if (!image_check_arch (hdr, IH_ARCH_MIPS))
+#elif defined(__nios__)
+	if (!image_check_arch (hdr, IH_ARCH_NIOS))
+#elif defined(__nios2__)
+	if (!image_check_arch (hdr, IH_ARCH_NIOS2))
+#elif defined(__PPC__)
+	if (!image_check_arch (hdr, IH_ARCH_PPC))
+#elif defined(__sh__)
+	if (!image_check_arch (hdr, IH_ARCH_SH))
+#else
+# error Unknown CPU type
+#endif
+		return 0;
+
+	return 1;
+}
+#endif /* USE_HOSTCC */
+
+/*******************************************************************/
+/* New uImage format specific code (prefixed with fit_) */
+/*******************************************************************/
+#if defined(CONFIG_FIT)
+
+#define FIT_IMAGES_PATH		"/images"
+#define FIT_CONFS_PATH		"/configurations"
+
+/* hash node */
+#define FIT_HASH_NODENAME	"hash"
+#define FIT_ALGO_PROP		"algo"
+#define FIT_VALUE_PROP		"value"
+
+/* image node */
+#define FIT_DATA_PROP		"data"
+#define FIT_TIMESTAMP_PROP	"timestamp"
+#define FIT_DESC_PROP		"description"
+#define FIT_ARCH_PROP		"arch"
+#define FIT_TYPE_PROP		"type"
+#define FIT_OS_PROP		"os"
+#define FIT_COMP_PROP		"compression"
+#define FIT_ENTRY_PROP		"entry"
+#define FIT_LOAD_PROP		"load"
+
+/* configuration node */
+#define FIT_KERNEL_PROP		"kernel"
+#define FIT_RAMDISK_PROP	"ramdisk"
+#define FIT_FDT_PROP		"fdt"
+#define FIT_DEFAULT_PROP	"default"
+
+#define FIT_MAX_HASH_LEN	20	/* max(crc32_len(4), sha1_len(20)) */
+
+/* cmdline argument format parsing */
+inline int fit_parse_conf (const char *spec, ulong addr_curr,
+		ulong *addr, const char **conf_name);
+inline int fit_parse_subimage (const char *spec, ulong addr_curr,
+		ulong *addr, const char **image_name);
+
+inline void fit_print_contents (const void *fit);
+inline void fit_print_contents_noindent (const void *fit);
+void fit_image_print (const void *fit, int noffset, const char *p);
+void fit_image_print_hash (const void *fit, int noffset, const char *p);
+
+/**
+ * fit_get_end - get FIT image size
+ * @fit: pointer to the FIT format image header
+ *
+ * returns:
+ *     size of the FIT image (blob) in memory
+ */
+static inline ulong fit_get_size (const void *fit)
+{
+	return fdt_totalsize (fit);
+}
+
+/**
+ * fit_get_end - get FIT image end
+ * @fit: pointer to the FIT format image header
+ *
+ * returns:
+ *     end address of the FIT image (blob) in memory
+ */
+static inline ulong fit_get_end (const void *fit)
+{
+	return (ulong)fit + fdt_totalsize (fit);
+}
+
+/**
+ * fit_get_name - get FIT node name
+ * @fit: pointer to the FIT format image header
+ *
+ * returns:
+ *     NULL, on error
+ *     pointer to node name, on success
+ */
+static inline const char *fit_get_name (const void *fit_hdr,
+		int noffset, int *len)
+{
+	return fdt_get_name (fit_hdr, noffset, len);
+}
+
+int fit_get_desc (const void *fit, int noffset, char **desc);
+int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp);
+
+int fit_image_get_node (const void *fit, const char *image_uname);
+int fit_image_get_os (const void *fit, int noffset, uint8_t *os);
+int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch);
+int fit_image_get_type (const void *fit, int noffset, uint8_t *type);
+int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp);
+int fit_image_get_load (const void *fit, int noffset, ulong *load);
+int fit_image_get_entry (const void *fit, int noffset, ulong *entry);
+int fit_image_get_data (const void *fit, int noffset,
+				const void **data, size_t *size);
+
+int fit_image_hash_get_algo (const void *fit, int noffset, char **algo);
+int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value,
+				int *value_len);
+
+int fit_set_timestamp (void *fit, int noffset, time_t timestamp);
+int fit_set_hashes (void *fit);
+int fit_image_set_hashes (void *fit, int image_noffset);
+int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value,
+				int value_len);
+
+int fit_image_check_hashes (const void *fit, int noffset);
+int fit_image_check_os (const void *fit, int noffset, uint8_t os);
+int fit_image_check_arch (const void *fit, int noffset, uint8_t arch);
+int fit_image_check_type (const void *fit, int noffset, uint8_t type);
+int fit_image_check_comp (const void *fit, int noffset, uint8_t comp);
+int fit_check_format (const void *fit);
+
+int fit_conf_get_node (const void *fit, const char *conf_uname);
+int fit_conf_get_kernel_node (const void *fit, int noffset);
+int fit_conf_get_ramdisk_node (const void *fit, int noffset);
+int fit_conf_get_fdt_node (const void *fit, int noffset);
+
+void fit_conf_print (const void *fit, int noffset, const char *p);
+
+#ifndef USE_HOSTCC
+static inline int fit_image_check_target_arch (const void *fdt, int node)
+{
+#if defined(__ARM__)
+	if (!fit_image_check_arch (fdt, node, IH_ARCH_ARM))
+#elif defined(__avr32__)
+	if (!fit_image_check_arch (fdt, node, IH_ARCH_AVR32))
+#elif defined(__bfin__)
+	if (!fit_image_check_arch (fdt, node, IH_ARCH_BLACKFIN))
+#elif defined(__I386__)
+	if (!fit_image_check_arch (fdt, node, IH_ARCH_I386))
+#elif defined(__M68K__)
+	if (!fit_image_check_arch (fdt, node, IH_ARCH_M68K))
+#elif defined(__microblaze__)
+	if (!fit_image_check_arch (fdt, node, IH_ARCH_MICROBLAZE))
+#elif defined(__mips__)
+	if (!fit_image_check_arch (fdt, node, IH_ARCH_MIPS))
+#elif defined(__nios__)
+	if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS))
+#elif defined(__nios2__)
+	if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS2))
+#elif defined(__PPC__)
+	if (!fit_image_check_arch (fdt, node, IH_ARCH_PPC))
+#elif defined(__sh__)
+	if (!fit_image_check_arch (fdt, node, IH_ARCH_SH))
+#else
+# error Unknown CPU type
+#endif
+		return 0;
+
+	return 1;
+}
+#endif /* USE_HOSTCC */
+
+#ifdef CONFIG_FIT_VERBOSE
+#define fit_unsupported(msg)	printf ("! %s:%d " \
+				"FIT images not supported for '%s'\n", \
+				__FILE__, __LINE__, (msg))
+
+#define fit_unsupported_reset(msg)	printf ("! %s:%d " \
+				"FIT images not supported for '%s' " \
+				"- must reset board to recover!\n", \
+				__FILE__, __LINE__, (msg))
+#else
+#define fit_unsupported(msg)
+#define fit_unsupported_reset(msg)
+#endif /* CONFIG_FIT_VERBOSE */
+#endif /* CONFIG_FIT */
 
 
 #endif	/* __IMAGE_H__ */
 #endif	/* __IMAGE_H__ */

+ 4 - 0
include/libfdt_env.h

@@ -24,7 +24,11 @@
 #include <stddef.h>
 #include <stddef.h>
 #include <linux/types.h>
 #include <linux/types.h>
 #include <asm/byteorder.h>
 #include <asm/byteorder.h>
+#ifdef USE_HOSTCC
+#include <string.h>
+#else
 #include <linux/string.h>
 #include <linux/string.h>
+#endif /* USE_HOSTCC */
 
 
 extern struct fdt_header *fdt;  /* Pointer to the working fdt */
 extern struct fdt_header *fdt;  /* Pointer to the working fdt */
 
 

+ 54 - 0
include/lmb.h

@@ -0,0 +1,54 @@
+#ifndef _LINUX_LMB_H
+#define _LINUX_LMB_H
+#ifdef __KERNEL__
+
+#include <asm/types.h>
+/*
+ * Logical memory blocks.
+ *
+ * Copyright (C) 2001 Peter Bergner, IBM Corp.
+ *
+ * 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.
+ */
+
+#define MAX_LMB_REGIONS 8
+
+struct lmb_property {
+	ulong base;
+	ulong size;
+};
+
+struct lmb_region {
+	unsigned long cnt;
+	ulong size;
+	struct lmb_property region[MAX_LMB_REGIONS+1];
+};
+
+struct lmb {
+	struct lmb_region memory;
+	struct lmb_region reserved;
+};
+
+extern struct lmb lmb;
+
+extern void lmb_init(struct lmb *lmb);
+extern long lmb_add(struct lmb *lmb, ulong base, ulong size);
+extern long lmb_reserve(struct lmb *lmb, ulong base, ulong size);
+extern ulong lmb_alloc(struct lmb *lmb, ulong size, ulong align);
+extern ulong lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr);
+extern ulong __lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr);
+extern int lmb_is_reserved(struct lmb *lmb, ulong addr);
+
+extern void lmb_dump_all(struct lmb *lmb);
+
+static inline ulong
+lmb_size_bytes(struct lmb_region *type, unsigned long region_nr)
+{
+	return type->region[region_nr].size;
+}
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_LMB_H */

+ 23 - 0
include/md5.h

@@ -0,0 +1,23 @@
+/*
+ * This file was transplanted with slight modifications from Linux sources
+ * (fs/cifs/md5.h) into U-Boot by Bartlomiej Sieka <tur@semihalf.com>.
+ */
+
+#ifndef _MD5_H
+#define _MD5_H
+
+#include <linux/types.h>
+
+struct MD5Context {
+	__u32 buf[4];
+	__u32 bits[2];
+	unsigned char in[64];
+};
+
+/*
+ * Calculate and store in 'output' the MD5 digest of 'len' bytes at
+ * 'input'. 'output' must have enough space to hold 16 bytes.
+ */
+void md5 (unsigned char *input, int len, unsigned char output[16]);
+
+#endif /* _MD5_H */

+ 15 - 7
lib_arm/Makefile

@@ -25,13 +25,21 @@ include $(TOPDIR)/config.mk
 
 
 LIB	= $(obj)lib$(ARCH).a
 LIB	= $(obj)lib$(ARCH).a
 
 
-SOBJS	= _ashldi3.o _ashrdi3.o _divsi3.o _modsi3.o _udivsi3.o _umodsi3.o
-
-COBJS	= armlinux.o board.o \
-	  cache.o div0.o interrupts.o
-
-SRCS 	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+SOBJS-y	+= _ashldi3.o
+SOBJS-y	+= _ashrdi3.o
+SOBJS-y	+= _divsi3.o
+SOBJS-y	+= _modsi3.o
+SOBJS-y	+= _udivsi3.o
+SOBJS-y	+= _umodsi3.o
+
+COBJS-y	+= board.o
+COBJS-y	+= bootm.o
+COBJS-y	+= cache.o
+COBJS-y	+= div0.o
+COBJS-y	+= interrupts.o
+
+SRCS 	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
 
 
 $(LIB):	$(obj).depend $(OBJS)
 $(LIB):	$(obj).depend $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)

+ 40 - 147
lib_arm/armlinux.c → lib_arm/bootm.c

@@ -26,15 +26,9 @@
 #include <image.h>
 #include <image.h>
 #include <zlib.h>
 #include <zlib.h>
 #include <asm/byteorder.h>
 #include <asm/byteorder.h>
-#ifdef CONFIG_HAS_DATAFLASH
-#include <dataflash.h>
-#endif
 
 
 DECLARE_GLOBAL_DATA_PTR;
 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) || \
 #if defined (CONFIG_SETUP_MEMORY_TAGS) || \
     defined (CONFIG_CMDLINE_TAG) || \
     defined (CONFIG_CMDLINE_TAG) || \
     defined (CONFIG_INITRD_TAG) || \
     defined (CONFIG_INITRD_TAG) || \
@@ -62,165 +56,54 @@ static void setup_end_tag (bd_t *bd);
 static void setup_videolfb_tag (gd_t *gd);
 static void setup_videolfb_tag (gd_t *gd);
 # endif
 # endif
 
 
-
 static struct tag *params;
 static struct tag *params;
 #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
 #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
 
 
-extern image_header_t header;	/* from cmd_bootm.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[],
 void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
-		     ulong addr, ulong *len_ptr, int verify)
+		     bootm_headers_t *images)
 {
 {
-	ulong len = 0, checksum;
-	ulong initrd_start, initrd_end;
-	ulong data;
-	void (*theKernel)(int zero, int arch, uint params);
-	image_header_t *hdr = &header;
-	bd_t *bd = gd->bd;
-	int machid = bd->bi_arch_number;
-	char *s;
+	ulong	initrd_start, initrd_end;
+	ulong	ep = 0;
+	bd_t	*bd = gd->bd;
+	char	*s;
+	int	machid = bd->bi_arch_number;
+	void	(*theKernel)(int zero, int arch, uint params);
+	int	ret;
 
 
 #ifdef CONFIG_CMDLINE_TAG
 #ifdef CONFIG_CMDLINE_TAG
 	char *commandline = getenv ("bootargs");
 	char *commandline = getenv ("bootargs");
 #endif
 #endif
 
 
-	theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);
-
-	s = getenv ("machid");
-	if (s) {
-		machid = simple_strtoul (s, NULL, 16);
-		printf ("Using machid 0x%x from environment\n", machid);
-	}
-
-	/*
-	 * Check if there is an initrd image
-	 */
-	if (argc >= 3) {
-		show_boot_progress (9);
-
-		addr = simple_strtoul (argv[2], NULL, 16);
-
-		printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
-
-		/* Copy header so we can blank CRC field for re-calculation */
-#ifdef CONFIG_HAS_DATAFLASH
-		if (addr_dataflash (addr)) {
-			read_dataflash (addr, sizeof (image_header_t),
-					(char *) &header);
-		} else
-#endif
-			memcpy (&header, (char *) addr,
-				sizeof (image_header_t));
-
-		if (ntohl (hdr->ih_magic) != IH_MAGIC) {
-			printf ("Bad Magic Number\n");
-			show_boot_progress (-10);
-			do_reset (cmdtp, flag, argc, argv);
-		}
-
-		data = (ulong) & header;
-		len = sizeof (image_header_t);
-
-		checksum = ntohl (hdr->ih_hcrc);
-		hdr->ih_hcrc = 0;
-
-		if (crc32 (0, (unsigned char *) data, len) != checksum) {
-			printf ("Bad Header Checksum\n");
-			show_boot_progress (-11);
-			do_reset (cmdtp, flag, argc, argv);
-		}
-
-		show_boot_progress (10);
-
-		print_image_hdr (hdr);
-
-		data = addr + sizeof (image_header_t);
-		len = ntohl (hdr->ih_size);
-
-#ifdef CONFIG_HAS_DATAFLASH
-		if (addr_dataflash (addr)) {
-			read_dataflash (data, len, (char *) CFG_LOAD_ADDR);
-			data = CFG_LOAD_ADDR;
+	/* find kernel entry point */
+	if (images->legacy_hdr_valid) {
+		ep = image_get_ep (images->legacy_hdr_os);
+#if defined(CONFIG_FIT)
+	} else if (images->fit_uname_os) {
+		ret = fit_image_get_entry (images->fit_hdr_os,
+					images->fit_noffset_os, &ep);
+		if (ret) {
+			puts ("Can't get entry point property!\n");
+			goto error;
 		}
 		}
 #endif
 #endif
-
-		if (verify) {
-			ulong csum = 0;
-
-			printf ("   Verifying Checksum ... ");
-			csum = crc32 (0, (unsigned char *) data, len);
-			if (csum != ntohl (hdr->ih_dcrc)) {
-				printf ("Bad Data CRC\n");
-				show_boot_progress (-12);
-				do_reset (cmdtp, flag, argc, argv);
-			}
-			printf ("OK\n");
-		}
-
-		show_boot_progress (11);
-
-		if ((hdr->ih_os != IH_OS_LINUX) ||
-		    (hdr->ih_arch != IH_CPU_ARM) ||
-		    (hdr->ih_type != 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) || defined(CONFIG_M501SK)
-		/*
-		 *we need to copy the ramdisk to SRAM to let Linux boot
-		 */
-		memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len);
-		data = ntohl(hdr->ih_load);
-#endif /* CONFIG_B2 || CONFIG_EVB4510 */
-
-		/*
-		 * Now check if we have a multifile image
-		 */
-	} else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
-		ulong tail = ntohl (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 += ntohl (len_ptr[0]);
-		if (tail) {
-			data += 4 - tail;
-		}
-
-		len = ntohl (len_ptr[1]);
-
 	} else {
 	} else {
-		/*
-		 * no initrd image
-		 */
-		show_boot_progress (14);
-
-		len = data = 0;
+		puts ("Could not find kernel entry point!\n");
+		goto error;
 	}
 	}
+	theKernel = (void (*)(int, int, uint))ep;
 
 
-#ifdef	DEBUG
-	if (!data) {
-		printf ("No initrd\n");
+	s = getenv ("machid");
+	if (s) {
+		machid = simple_strtoul (s, NULL, 16);
+		printf ("Using machid 0x%x from environment\n", machid);
 	}
 	}
-#endif
 
 
-	if (data) {
-		initrd_start = data;
-		initrd_end = initrd_start + len;
-	} else {
-		initrd_start = 0;
-		initrd_end = 0;
-	}
+	ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_ARM,
+			&initrd_start, &initrd_end);
+	if (ret)
+		goto error;
 
 
 	show_boot_progress (15);
 	show_boot_progress (15);
 
 
@@ -257,6 +140,9 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
 	setup_end_tag (bd);
 	setup_end_tag (bd);
 #endif
 #endif
 
 
+	if (!images->autostart)
+		return ;
+
 	/* we assume that the kernel is in place */
 	/* we assume that the kernel is in place */
 	printf ("\nStarting kernel ...\n\n");
 	printf ("\nStarting kernel ...\n\n");
 
 
@@ -270,6 +156,13 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
 	cleanup_before_linux ();
 	cleanup_before_linux ();
 
 
 	theKernel (0, machid, bd->bi_boot_params);
 	theKernel (0, machid, bd->bi_boot_params);
+	/* does not return */
+	return;
+
+error:
+	if (images->autostart)
+		do_reset (cmdtp, flag, argc, argv);
+	return;
 }
 }
 
 
 
 

+ 6 - 4
lib_avr32/Makefile

@@ -27,12 +27,14 @@ include $(TOPDIR)/config.mk
 
 
 LIB	= $(obj)lib$(ARCH).a
 LIB	= $(obj)lib$(ARCH).a
 
 
-SOBJS	= memset.o
+SOBJS-y	+= memset.o
 
 
-COBJS	= board.o interrupts.o avr32_linux.o
+COBJS-y	+= board.o
+COBJS-y	+= bootm.o
+COBJS-y	+= interrupts.o
 
 
-SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
 
 
 $(LIB):	$(obj).depend $(OBJS)
 $(LIB):	$(obj).depend $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)

+ 37 - 105
lib_avr32/avr32_linux.c → lib_avr32/bootm.c

@@ -31,12 +31,10 @@
 
 
 DECLARE_GLOBAL_DATA_PTR;
 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. */
 /* CPU-specific hook to allow flushing of caches, etc. */
 extern void prepare_to_boot(void);
 extern void prepare_to_boot(void);
 
 
-extern image_header_t header;		/* from cmd_bootm.c */
+extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
 
 static struct tag *setup_start_tag(struct tag *params)
 static struct tag *setup_start_tag(struct tag *params)
 {
 {
@@ -176,113 +174,37 @@ static void setup_end_tag(struct tag *params)
 }
 }
 
 
 void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
 void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
-		    unsigned long addr, unsigned long *len_ptr, int verify)
+		    bootm_headers_t *images)
 {
 {
-	unsigned long data, len = 0;
-	unsigned long initrd_start, initrd_end;
-	unsigned long image_start, image_end;
-	unsigned long checksum;
-	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 + hdr->ih_size;
-
-	theKernel = (void *)ntohl(hdr->ih_ep);
-
-	/*
-	 * Check if there is an initrd image
-	 */
-	if (argc >= 3) {
-		show_boot_progress (9);
-
-		addr = simple_strtoul(argv[2], NULL, 16);
-
-		printf("## Loading RAMDISK image at %08lx ...\n", addr);
-
-		memcpy(&header, (char *)addr, sizeof(header));
-		hdr = &header;
-
-		if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-			puts("Bad Magic Number\n");
-			show_boot_progress (-10);
-			do_reset(cmdtp, flag, argc, argv);
+	ulong	initrd_start, initrd_end;
+	ulong	ep = 0;
+	void	(*theKernel)(int magic, void *tagtable);
+	struct	tag *params, *params_start;
+	char	*commandline = getenv("bootargs");
+	int	ret;
+
+	/* find kernel entry point */
+	if (images->legacy_hdr_valid) {
+		ep = image_get_ep (images->legacy_hdr_os);
+#if defined(CONFIG_FIT)
+	} else if (images->fit_uname_os) {
+		ret = fit_image_get_entry (images->fit_hdr_os,
+				images->fit_noffset_os, &ep);
+		if (ret) {
+			puts ("Can't get entry point property!\n");
+			goto error;
 		}
 		}
-
-		data = (unsigned long)hdr;
-		len = sizeof(*hdr);
-		checksum = ntohl(hdr->ih_hcrc);
-		hdr->ih_hcrc = 0;
-
-		if (crc32(0, (unsigned char *)data, len) != checksum) {
-			puts("Bad Header Checksum\n");
-			show_boot_progress (-11);
-			do_reset(cmdtp, flag, argc, argv);
-		}
-
-		show_boot_progress (10);
-
-		print_image_hdr(hdr);
-
-		data = addr + sizeof(header);
-		len = ntohl(hdr->ih_size);
-
-		if (verify) {
-			unsigned long csum = 0;
-
-			puts("   Verifying Checksum ... ");
-			csum = crc32(0, (unsigned char *)data, len);
-			if (csum != ntohl(hdr->ih_dcrc)) {
-				puts("Bad Data CRC\n");
-				show_boot_progress (-12);
-				do_reset(cmdtp, flag, argc, argv);
-			}
-			puts("OK\n");
-		}
-
-		show_boot_progress (11);
-
-		if ((hdr->ih_os != IH_OS_LINUX) ||
-		    (hdr->ih_arch != IH_CPU_AVR32) ||
-		    (hdr->ih_type != IH_TYPE_RAMDISK)) {
-			puts("Not a Linux/AVR32 RAMDISK image\n");
-			show_boot_progress (-13);
-			do_reset(cmdtp, flag, argc, argv);
-		}
-	} else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
-		ulong tail = ntohl (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 += ntohl (len_ptr[0]);
-		if (tail) {
-			data += 4 - tail;
-		}
-
-		len = ntohl (len_ptr[1]);
+#endif
 	} else {
 	} else {
-		/* no initrd image */
-		show_boot_progress (14);
-		len = data = 0;
+		puts ("Could not find kernel entry point!\n");
+		goto error;
 	}
 	}
+	theKernel = (void *)ep;
 
 
-	if (data) {
-		initrd_start = data;
-		initrd_end = initrd_start + len;
-	} else {
-		initrd_start = 0;
-		initrd_end = 0;
-	}
+	ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_AVR32,
+			&initrd_start, &initrd_end);
+	if (ret)
+		goto error;
 
 
 	show_boot_progress (15);
 	show_boot_progress (15);
 
 
@@ -299,10 +221,20 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
 	params = setup_ethernet_tags(params);
 	params = setup_ethernet_tags(params);
 	setup_end_tag(params);
 	setup_end_tag(params);
 
 
+	if (!images->autostart)
+		return ;
+
 	printf("\nStarting kernel at %p (params at %p)...\n\n",
 	printf("\nStarting kernel at %p (params at %p)...\n\n",
 	       theKernel, params_start);
 	       theKernel, params_start);
 
 
 	prepare_to_boot();
 	prepare_to_boot();
 
 
 	theKernel(ATAG_MAGIC, params_start);
 	theKernel(ATAG_MAGIC, params_start);
+	/* does not return */
+	return;
+
+error:
+	if (images->autostart)
+		do_reset (cmdtp, flag, argc, argv);
+	return;
 }
 }

+ 15 - 6
lib_blackfin/Makefile

@@ -29,12 +29,21 @@ include $(TOPDIR)/config.mk
 
 
 LIB	= $(obj)lib$(ARCH).a
 LIB	= $(obj)lib$(ARCH).a
 
 
-SOBJS	= memcpy.o memcmp.o memset.o memmove.o
-
-COBJS	= post.o tests.o board.o bf533_linux.o bf533_string.o cache.o muldi3.o
-
-SRCS 	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+SOBJS-y	+= memcmp.o
+SOBJS-y	+= memcpy.o
+SOBJS-y	+= memmove.o
+SOBJS-y	+= memset.o
+
+COBJS-y	+= bf533_string.o
+COBJS-y	+= board.o
+COBJS-y	+= bootm.o
+COBJS-y	+= cache.o
+COBJS-y	+= muldi3.o
+COBJS-y	+= post.o
+COBJS-y	+= tests.o
+
+SRCS 	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
 
 
 $(LIB):	$(obj).depend $(OBJS)
 $(LIB):	$(obj).depend $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)

+ 32 - 5
lib_blackfin/bf533_linux.c → lib_blackfin/bootm.c

@@ -42,22 +42,42 @@
 extern void swap_to(int device_id);
 extern void swap_to(int device_id);
 #endif
 #endif
 
 
-extern image_header_t header;
 extern void flush_instruction_cache(void);
 extern void flush_instruction_cache(void);
 extern void flush_data_cache(void);
 extern void flush_data_cache(void);
 static char *make_command_line(void);
 static char *make_command_line(void);
 
 
 void do_bootm_linux(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)
+		    bootm_headers_t *images)
 {
 {
-	int (*appl) (char *cmdline);
-	char *cmdline;
+	int	(*appl) (char *cmdline);
+	char	*cmdline;
+	ulong	ep = 0;
+
+	if (!images->autostart)
+		return ;
 
 
 #ifdef SHARED_RESOURCES
 #ifdef SHARED_RESOURCES
 	swap_to(FLASH);
 	swap_to(FLASH);
 #endif
 #endif
 
 
-	appl = (int (*)(char *))ntohl(header.ih_ep);
+	/* find kernel entry point */
+	if (images->legacy_hdr_valid) {
+		ep = image_get_ep (images->legacy_hdr_os);
+#if defined(CONFIG_FIT)
+	} else if (images->fit_uname_os) {
+		int ret = fit_image_get_entry (images->fit_hdr_os,
+				images->fit_noffset_os, &ep);
+		if (ret) {
+			puts ("Can't get entry point property!\n");
+			goto error;
+		}
+#endif
+	} else {
+		puts ("Could not find kernel entry point!\n");
+		goto error;
+	}
+	appl = (int (*)(char *))ep;
+
 	printf("Starting Kernel at = %x\n", appl);
 	printf("Starting Kernel at = %x\n", appl);
 	cmdline = make_command_line();
 	cmdline = make_command_line();
 	if (icache_status()) {
 	if (icache_status()) {
@@ -69,6 +89,13 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
 		dcache_disable();
 		dcache_disable();
 	}
 	}
 	(*appl) (cmdline);
 	(*appl) (cmdline);
+	/* does not return */
+	return;
+
+error:
+	if (images->autostart)
+		do_reset (cmdtp, flag, argc, argv);
+	return;
 }
 }
 
 
 char *make_command_line(void)
 char *make_command_line(void)

+ 2 - 0
lib_generic/Makefile

@@ -34,7 +34,9 @@ COBJS-y += crc32.o
 COBJS-y += ctype.o
 COBJS-y += ctype.o
 COBJS-y += display_options.o
 COBJS-y += display_options.o
 COBJS-y += div64.o
 COBJS-y += div64.o
+COBJS-y += lmb.o
 COBJS-y += ldiv.o
 COBJS-y += ldiv.o
+COBJS-$(CONFIG_MD5) += md5.o
 COBJS-y += sha1.o
 COBJS-y += sha1.o
 COBJS-y += string.o
 COBJS-y += string.o
 COBJS-y += vsprintf.o
 COBJS-y += vsprintf.o

+ 4 - 0
lib_generic/bzlib.c

@@ -1592,6 +1592,10 @@ const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
 }
 }
 #endif
 #endif
 
 
+void bz_internal_error(int errcode)
+{
+	printf ("BZIP2 internal error %d\n", errcode);
+}
 
 
 /*-------------------------------------------------------------*/
 /*-------------------------------------------------------------*/
 /*--- end                                           bzlib.c ---*/
 /*--- end                                           bzlib.c ---*/

+ 280 - 0
lib_generic/lmb.c

@@ -0,0 +1,280 @@
+/*
+ * Procedures for maintaining information about logical memory blocks.
+ *
+ * Peter Bergner, IBM Corp.	June 2001.
+ * Copyright (C) 2001 Peter Bergner.
+ *
+ *      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.
+ */
+
+#include <common.h>
+#include <lmb.h>
+
+#define LMB_ALLOC_ANYWHERE	0
+
+void lmb_dump_all(struct lmb *lmb)
+{
+#ifdef DEBUG
+	unsigned long i;
+
+	debug("lmb_dump_all:\n");
+	debug("    memory.cnt		   = 0x%lx\n", lmb->memory.cnt);
+	debug("    memory.size		   = 0x%08x\n", lmb->memory.size);
+	for (i=0; i < lmb->memory.cnt ;i++) {
+		debug("    memory.reg[0x%x].base   = 0x%08x\n", i,
+			lmb->memory.region[i].base);
+		debug("		   .size   = 0x%08x\n",
+			lmb->memory.region[i].size);
+	}
+
+	debug("\n    reserved.cnt	   = 0x%lx\n", lmb->reserved.cnt);
+	debug("    reserved.size	   = 0x%08x\n", lmb->reserved.size);
+	for (i=0; i < lmb->reserved.cnt ;i++) {
+		debug("    reserved.reg[0x%x].base = 0x%08x\n", i,
+			lmb->reserved.region[i].base);
+		debug("		     .size = 0x%08x\n",
+			lmb->reserved.region[i].size);
+	}
+#endif /* DEBUG */
+}
+
+static unsigned long lmb_addrs_overlap(ulong base1,
+		ulong size1, ulong base2, ulong size2)
+{
+	return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
+}
+
+static long lmb_addrs_adjacent(ulong base1, ulong size1,
+		ulong base2, ulong size2)
+{
+	if (base2 == base1 + size1)
+		return 1;
+	else if (base1 == base2 + size2)
+		return -1;
+
+	return 0;
+}
+
+static long lmb_regions_adjacent(struct lmb_region *rgn,
+		unsigned long r1, unsigned long r2)
+{
+	ulong base1 = rgn->region[r1].base;
+	ulong size1 = rgn->region[r1].size;
+	ulong base2 = rgn->region[r2].base;
+	ulong size2 = rgn->region[r2].size;
+
+	return lmb_addrs_adjacent(base1, size1, base2, size2);
+}
+
+static void lmb_remove_region(struct lmb_region *rgn, unsigned long r)
+{
+	unsigned long i;
+
+	for (i = r; i < rgn->cnt - 1; i++) {
+		rgn->region[i].base = rgn->region[i + 1].base;
+		rgn->region[i].size = rgn->region[i + 1].size;
+	}
+	rgn->cnt--;
+}
+
+/* Assumption: base addr of region 1 < base addr of region 2 */
+static void lmb_coalesce_regions(struct lmb_region *rgn,
+		unsigned long r1, unsigned long r2)
+{
+	rgn->region[r1].size += rgn->region[r2].size;
+	lmb_remove_region(rgn, r2);
+}
+
+void lmb_init(struct lmb *lmb)
+{
+	/* Create a dummy zero size LMB which will get coalesced away later.
+	 * This simplifies the lmb_add() code below...
+	 */
+	lmb->memory.region[0].base = 0;
+	lmb->memory.region[0].size = 0;
+	lmb->memory.cnt = 1;
+	lmb->memory.size = 0;
+
+	/* Ditto. */
+	lmb->reserved.region[0].base = 0;
+	lmb->reserved.region[0].size = 0;
+	lmb->reserved.cnt = 1;
+	lmb->reserved.size = 0;
+}
+
+/* This routine called with relocation disabled. */
+static long lmb_add_region(struct lmb_region *rgn, ulong base, ulong size)
+{
+	unsigned long coalesced = 0;
+	long adjacent, i;
+
+	if ((rgn->cnt == 1) && (rgn->region[0].size == 0)) {
+		rgn->region[0].base = base;
+		rgn->region[0].size = size;
+		return 0;
+	}
+
+	/* First try and coalesce this LMB with another. */
+	for (i=0; i < rgn->cnt; i++) {
+		ulong rgnbase = rgn->region[i].base;
+		ulong rgnsize = rgn->region[i].size;
+
+		if ((rgnbase == base) && (rgnsize == size))
+			/* Already have this region, so we're done */
+			return 0;
+
+		adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize);
+		if ( adjacent > 0 ) {
+			rgn->region[i].base -= size;
+			rgn->region[i].size += size;
+			coalesced++;
+			break;
+		}
+		else if ( adjacent < 0 ) {
+			rgn->region[i].size += size;
+			coalesced++;
+			break;
+		}
+	}
+
+	if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) {
+		lmb_coalesce_regions(rgn, i, i+1);
+		coalesced++;
+	}
+
+	if (coalesced)
+		return coalesced;
+	if (rgn->cnt >= MAX_LMB_REGIONS)
+		return -1;
+
+	/* Couldn't coalesce the LMB, so add it to the sorted table. */
+	for (i = rgn->cnt-1; i >= 0; i--) {
+		if (base < rgn->region[i].base) {
+			rgn->region[i+1].base = rgn->region[i].base;
+			rgn->region[i+1].size = rgn->region[i].size;
+		} else {
+			rgn->region[i+1].base = base;
+			rgn->region[i+1].size = size;
+			break;
+		}
+	}
+
+	if (base < rgn->region[0].base) {
+		rgn->region[0].base = base;
+		rgn->region[0].size = size;
+	}
+
+	rgn->cnt++;
+
+	return 0;
+}
+
+/* This routine may be called with relocation disabled. */
+long lmb_add(struct lmb *lmb, ulong base, ulong size)
+{
+	struct lmb_region *_rgn = &(lmb->memory);
+
+	return lmb_add_region(_rgn, base, size);
+}
+
+long lmb_reserve(struct lmb *lmb, ulong base, ulong size)
+{
+	struct lmb_region *_rgn = &(lmb->reserved);
+
+	return lmb_add_region(_rgn, base, size);
+}
+
+long lmb_overlaps_region(struct lmb_region *rgn, ulong base,
+				ulong size)
+{
+	unsigned long i;
+
+	for (i=0; i < rgn->cnt; i++) {
+		ulong rgnbase = rgn->region[i].base;
+		ulong rgnsize = rgn->region[i].size;
+		if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) {
+			break;
+		}
+	}
+
+	return (i < rgn->cnt) ? i : -1;
+}
+
+ulong lmb_alloc(struct lmb *lmb, ulong size, ulong align)
+{
+	return lmb_alloc_base(lmb, size, align, LMB_ALLOC_ANYWHERE);
+}
+
+ulong lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr)
+{
+	ulong alloc;
+
+	alloc = __lmb_alloc_base(lmb, size, align, max_addr);
+
+	if (alloc == 0)
+		printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n",
+		      size, max_addr);
+
+	return alloc;
+}
+
+static ulong lmb_align_down(ulong addr, ulong size)
+{
+	return addr & ~(size - 1);
+}
+
+static ulong lmb_align_up(ulong addr, ulong size)
+{
+	return (addr + (size - 1)) & ~(size - 1);
+}
+
+ulong __lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr)
+{
+	long i, j;
+	ulong base = 0;
+
+	for (i = lmb->memory.cnt-1; i >= 0; i--) {
+		ulong lmbbase = lmb->memory.region[i].base;
+		ulong lmbsize = lmb->memory.region[i].size;
+
+		if (max_addr == LMB_ALLOC_ANYWHERE)
+			base = lmb_align_down(lmbbase + lmbsize - size, align);
+		else if (lmbbase < max_addr) {
+			base = min(lmbbase + lmbsize, max_addr);
+			base = lmb_align_down(base - size, align);
+		} else
+			continue;
+
+		while ((lmbbase <= base) &&
+		       ((j = lmb_overlaps_region(&(lmb->reserved), base, size)) >= 0) )
+			base = lmb_align_down(lmb->reserved.region[j].base - size,
+					      align);
+
+		if ((base != 0) && (lmbbase <= base))
+			break;
+	}
+
+	if (i < 0)
+		return 0;
+
+	if (lmb_add_region(&(lmb->reserved), base, lmb_align_up(size, align)) < 0)
+		return 0;
+
+	return base;
+}
+
+int lmb_is_reserved(struct lmb *lmb, ulong addr)
+{
+	int i;
+
+	for (i = 0; i < lmb->reserved.cnt; i++) {
+		ulong upper = lmb->reserved.region[i].base +
+			lmb->reserved.region[i].size - 1;
+		if ((addr >= lmb->reserved.region[i].base) && (addr <= upper))
+			return 1;
+	}
+	return 0;
+}

+ 274 - 0
lib_generic/md5.c

@@ -0,0 +1,274 @@
+/*
+ * This file was transplanted with slight modifications from Linux sources
+ * (fs/cifs/md5.c) into U-Boot by Bartlomiej Sieka <tur@semihalf.com>.
+ */
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+/* This code slightly modified to fit into Samba by
+   abartlet@samba.org Jun 2001
+   and to fit the cifs vfs by
+   Steve French sfrench@us.ibm.com */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <md5.h>
+
+static void
+MD5Transform(__u32 buf[4], __u32 const in[16]);
+
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static void
+byteReverse(unsigned char *buf, unsigned longs)
+{
+	__u32 t;
+	do {
+		t = (__u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+		    ((unsigned) buf[1] << 8 | buf[0]);
+		*(__u32 *) buf = t;
+		buf += 4;
+	} while (--longs);
+}
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+static void
+MD5Init(struct MD5Context *ctx)
+{
+	ctx->buf[0] = 0x67452301;
+	ctx->buf[1] = 0xefcdab89;
+	ctx->buf[2] = 0x98badcfe;
+	ctx->buf[3] = 0x10325476;
+
+	ctx->bits[0] = 0;
+	ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+static void
+MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
+{
+	register __u32 t;
+
+	/* Update bitcount */
+
+	t = ctx->bits[0];
+	if ((ctx->bits[0] = t + ((__u32) len << 3)) < t)
+		ctx->bits[1]++;	/* Carry from low to high */
+	ctx->bits[1] += len >> 29;
+
+	t = (t >> 3) & 0x3f;	/* Bytes already in shsInfo->data */
+
+	/* Handle any leading odd-sized chunks */
+
+	if (t) {
+		unsigned char *p = (unsigned char *) ctx->in + t;
+
+		t = 64 - t;
+		if (len < t) {
+			memmove(p, buf, len);
+			return;
+		}
+		memmove(p, buf, t);
+		byteReverse(ctx->in, 16);
+		MD5Transform(ctx->buf, (__u32 *) ctx->in);
+		buf += t;
+		len -= t;
+	}
+	/* Process data in 64-byte chunks */
+
+	while (len >= 64) {
+		memmove(ctx->in, buf, 64);
+		byteReverse(ctx->in, 16);
+		MD5Transform(ctx->buf, (__u32 *) ctx->in);
+		buf += 64;
+		len -= 64;
+	}
+
+	/* Handle any remaining bytes of data. */
+
+	memmove(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+static void
+MD5Final(unsigned char digest[16], struct MD5Context *ctx)
+{
+	unsigned int count;
+	unsigned char *p;
+
+	/* Compute number of bytes mod 64 */
+	count = (ctx->bits[0] >> 3) & 0x3F;
+
+	/* Set the first char of padding to 0x80.  This is safe since there is
+	   always at least one byte free */
+	p = ctx->in + count;
+	*p++ = 0x80;
+
+	/* Bytes of padding needed to make 64 bytes */
+	count = 64 - 1 - count;
+
+	/* Pad out to 56 mod 64 */
+	if (count < 8) {
+		/* Two lots of padding:  Pad the first block to 64 bytes */
+		memset(p, 0, count);
+		byteReverse(ctx->in, 16);
+		MD5Transform(ctx->buf, (__u32 *) ctx->in);
+
+		/* Now fill the next block with 56 bytes */
+		memset(ctx->in, 0, 56);
+	} else {
+		/* Pad block to 56 bytes */
+		memset(p, 0, count - 8);
+	}
+	byteReverse(ctx->in, 14);
+
+	/* Append length in bits and transform */
+	((__u32 *) ctx->in)[14] = ctx->bits[0];
+	((__u32 *) ctx->in)[15] = ctx->bits[1];
+
+	MD5Transform(ctx->buf, (__u32 *) ctx->in);
+	byteReverse((unsigned char *) ctx->buf, 4);
+	memmove(digest, ctx->buf, 16);
+	memset(ctx, 0, sizeof(*ctx));	/* In case it's sensitive */
+}
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+static void
+MD5Transform(__u32 buf[4], __u32 const in[16])
+{
+	register __u32 a, b, c, d;
+
+	a = buf[0];
+	b = buf[1];
+	c = buf[2];
+	d = buf[3];
+
+	MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+	MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+	MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+	MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+	MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+	MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+	MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+	MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+	MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+	MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+	MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+	MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+	MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+	MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+	MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+	MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+	MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+	MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+	MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+	MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+	MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+	MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+	MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+	MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+	MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+	MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+	MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+	MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+	MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+	MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+	MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+	MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+	MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+	MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+	MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+	MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+	MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+	MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+	MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+	MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+	buf[0] += a;
+	buf[1] += b;
+	buf[2] += c;
+	buf[3] += d;
+}
+
+/*
+ * Calculate and store in 'output' the MD5 digest of 'len' bytes at
+ * 'input'. 'output' must have enough space to hold 16 bytes.
+ */
+void
+md5 (unsigned char *input, int len, unsigned char output[16])
+{
+	struct MD5Context context;
+
+	MD5Init(&context);
+	MD5Update(&context, input, len);
+	MD5Final(output, &context);
+}

+ 16 - 7
lib_i386/Makefile

@@ -25,13 +25,22 @@ include $(TOPDIR)/config.mk
 
 
 LIB	= $(obj)lib$(ARCH).a
 LIB	= $(obj)lib$(ARCH).a
 
 
-SOBJS	= bios.o bios_pci.o realmode_switch.o
-
-COBJS	= board.o bios_setup.o i386_linux.o zimage.o realmode.o \
-	  pci_type1.o pci.o video_bios.o video.o
-
-SRCS 	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+SOBJS-y	+= bios.o
+SOBJS-y	+= bios_pci.o
+SOBJS-y	+= realmode_switch.o
+
+COBJS-y	+= bios_setup.o
+COBJS-y	+= board.o
+COBJS-y	+= bootm.o
+COBJS-y	+= pci.o
+COBJS-y	+= pci_type1.o
+COBJS-y	+= realmode.o
+COBJS-y	+= video_bios.o
+COBJS-y	+= video.o
+COBJS-y	+= zimage.o
+
+SRCS 	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
 
 
 $(LIB):	$(obj).depend $(OBJS)
 $(LIB):	$(obj).depend $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)

+ 107 - 0
lib_i386/bootm.c

@@ -0,0 +1,107 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Copyright (C) 2001  Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ *
+ * 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
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <image.h>
+#include <zlib.h>
+#include <asm/byteorder.h>
+#include <asm/zimage.h>
+
+/*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[],
+		bootm_headers_t *images)
+{
+	void		*base_ptr;
+	ulong		os_data, os_len;
+	ulong		initrd_start, initrd_end;
+	ulong		ep;
+	image_header_t	*hdr;
+	int		ret;
+#if defined(CONFIG_FIT)
+	const void	*data;
+	size_t		len;
+#endif
+
+	ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_I386,
+			&initrd_start, &initrd_end);
+	if (ret)
+		goto error;
+
+	if (images->legacy_hdr_valid) {
+		hdr = images->legacy_hdr_os;
+		if (image_check_type (hdr, IH_TYPE_MULTI)) {
+			/* if multi-part image, we need to get first subimage */
+			image_multi_getimg (hdr, 0, &os_data, &os_len);
+		} else {
+			/* otherwise get image data */
+			os_data = image_get_data (hdr);
+			os_len = image_get_data_size (hdr);
+		}
+#if defined(CONFIG_FIT)
+	} else if (images->fit_uname_os) {
+		ret = fit_image_get_data (images->fit_hdr_os,
+					images->fit_noffset_os, &data, &len);
+		if (ret) {
+			puts ("Can't get image data/size!\n");
+			goto error;
+		}
+		os_data = (ulong)data;
+		os_len = (ulong)len;
+#endif
+	} else {
+		puts ("Could not find kernel image!\n");
+		goto error;
+	}
+
+	base_ptr = load_zimage ((void*)os_data, os_len,
+			initrd_start, initrd_end - initrd_start, 0);
+
+	if (NULL == base_ptr) {
+		printf ("## Kernel loading failed ...\n");
+		goto error;
+
+	}
+
+	if (!images->autostart)
+		return ;
+
+#ifdef DEBUG
+	printf ("## Transferring control to Linux (at address %08x) ...\n",
+		(u32)base_ptr);
+#endif
+
+	/* we assume that the kernel is in place */
+	printf("\nStarting kernel ...\n\n");
+
+	boot_zimage(base_ptr);
+	/* does not return */
+	return;
+
+error:
+	if (images->autostart)
+		do_reset (cmdtp, flag, argc, argv);
+	return;
+}

+ 0 - 179
lib_i386/i386_linux.c

@@ -1,179 +0,0 @@
-/*
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * Copyright (C) 2001  Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
- *
- * 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
- *
- */
-
-#include <common.h>
-#include <command.h>
-#include <image.h>
-#include <zlib.h>
-#include <asm/byteorder.h>
-#include <asm/zimage.h>
-
-/*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 */
-
-
-image_header_t *fake_header(image_header_t *hdr, void *ptr, int size)
-{
-	/* try each supported image type in order */
-	if (NULL != fake_zimage_header(hdr, ptr, size)) {
-		return hdr;
-	}
-
-	return NULL;
-}
-
-
-void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
-		ulong addr, ulong *len_ptr, int   verify)
-{
-	void *base_ptr;
-
-	ulong len = 0, checksum;
-	ulong initrd_start, initrd_end;
-	ulong data;
-	image_header_t *hdr = &header;
-
-	/*
-	 * Check if there is an initrd image
-	 */
-	if (argc >= 3) {
-		addr = simple_strtoul(argv[2], NULL, 16);
-
-		printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
-
-		/* Copy header so we can blank CRC field for re-calculation */
-		memcpy (&header, (char *)addr, sizeof(image_header_t));
-
-		if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-			printf ("Bad Magic Number\n");
-			do_reset (cmdtp, flag, argc, argv);
-		}
-
-		data = (ulong)&header;
-		len  = sizeof(image_header_t);
-
-		checksum = ntohl(hdr->ih_hcrc);
-		hdr->ih_hcrc = 0;
-
-		if (crc32 (0, (char *)data, len) != checksum) {
-			printf ("Bad Header Checksum\n");
-			do_reset (cmdtp, flag, argc, argv);
-		}
-
-		print_image_hdr (hdr);
-
-		data = addr + sizeof(image_header_t);
-		len  = ntohl(hdr->ih_size);
-
-		if (verify) {
-			ulong csum = 0;
-
-			printf ("   Verifying Checksum ... ");
-			csum = crc32 (0, (char *)data, len);
-			if (csum != ntohl(hdr->ih_dcrc)) {
-				printf ("Bad Data CRC\n");
-				do_reset (cmdtp, flag, argc, argv);
-			}
-			printf ("OK\n");
-		}
-
-		if ((hdr->ih_os   != IH_OS_LINUX)	||
-		    (hdr->ih_arch != IH_CPU_I386)	||
-		    (hdr->ih_type != 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 ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) {
-		ulong tail    = ntohl(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 += ntohl(len_ptr[0]);
-		if (tail) {
-			data += 4 - tail;
-		}
-
-		len   = ntohl(len_ptr[1]);
-
-	} else {
-		/*
-		 * no initrd image
-		 */
-		data = 0;
-	}
-
-#ifdef	DEBUG
-	if (!data) {
-		printf ("No initrd\n");
-	}
-#endif
-
-	if (data) {
-		initrd_start = data;
-		initrd_end   = initrd_start + len;
-		printf ("   Loading Ramdisk to %08lx, end %08lx ... ",
-			initrd_start, initrd_end);
-		memmove ((void *)initrd_start, (void *)data, len);
-		printf ("OK\n");
-	} else {
-		initrd_start = 0;
-		initrd_end = 0;
-	}
-
-	/* if multi-part image, we need to advance base ptr */
-	if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) {
-		int i;
-		for (i=0, addr+=sizeof(int); len_ptr[i++]; addr+=sizeof(int));
-	}
-
-	base_ptr = load_zimage((void*)addr + sizeof(image_header_t), ntohl(hdr->ih_size),
-			       initrd_start, initrd_end-initrd_start, 0);
-
-	if (NULL == base_ptr) {
-		printf ("## Kernel loading failed ...\n");
-		do_reset(cmdtp, flag, argc, argv);
-
-	}
-
-#ifdef DEBUG
-	printf ("## Transferring control to Linux (at address %08x) ...\n",
-		(u32)base_ptr);
-#endif
-
-	/* we assume that the kernel is in place */
-	printf("\nStarting kernel ...\n\n");
-
-	boot_zimage(base_ptr);
-
-}

+ 0 - 50
lib_i386/zimage.c

@@ -212,7 +212,6 @@ void *load_zimage(char *image, unsigned long kernel_size,
 	return setup_base;
 	return setup_base;
 }
 }
 
 
-
 void boot_zimage(void *setup_base)
 void boot_zimage(void *setup_base)
 {
 {
 	struct pt_regs regs;
 	struct pt_regs regs;
@@ -224,52 +223,3 @@ void boot_zimage(void *setup_base)
 	regs.eflags = 0;
 	regs.eflags = 0;
 	enter_realmode(((u32)setup_base+SETUP_START_OFFSET)>>4, 0, &regs, &regs);
 	enter_realmode(((u32)setup_base+SETUP_START_OFFSET)>>4, 0, &regs, &regs);
 }
 }
-
-
-image_header_t *fake_zimage_header(image_header_t *hdr, void *ptr, int size)
-{
-	/* 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
-
-	/* load a 1MB, the loaded will have to be moved to its final
-	 * position again later... */
-#define ZIMAGE_LOAD 0x100000
-
-	ulong checksum;
-
-	if (KERNEL_MAGIC != *(u16*)(ptr + BOOT_FLAG_OFF)) {
-		/* not a zImage or bzImage */
-		return NULL;
-	}
-
-	if (-1 == size) {
-		size = ZIMAGE_SIZE;
-	}
-#if 0
-	checksum = crc32 (0, ptr, size);
-#else
-	checksum = 0;
-#endif
-	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(ZIMAGE_LOAD);
-	hdr->ih_ep    = 0;
-	hdr->ih_dcrc  = htonl(checksum);
-	hdr->ih_os    = IH_OS_LINUX;
-	hdr->ih_arch  = IH_CPU_I386;
-	hdr->ih_type  = IH_TYPE_KERNEL;
-	hdr->ih_comp  = IH_COMP_NONE;
-
-	strncpy((char *)hdr->ih_name, "(none)", IH_NMLEN);
-
-	checksum = crc32(0,(const char *)hdr,sizeof(image_header_t));
-
-	hdr->ih_hcrc = htonl(checksum);
-
-	return hdr;
-}

+ 9 - 4
lib_m68k/Makefile

@@ -25,12 +25,17 @@ include $(TOPDIR)/config.mk
 
 
 LIB	= $(obj)lib$(ARCH).a
 LIB	= $(obj)lib$(ARCH).a
 
 
-SOBJS	=
+SOBJS-y	+=
 
 
-COBJS	= cache.o traps.o time.o interrupts.o board.o m68k_linux.o
+COBJS-y	+= board.o
+COBJS-y	+= bootm.o
+COBJS-y	+= cache.o
+COBJS-y	+= interrupts.o
+COBJS-y	+= time.o
+COBJS-y	+= traps.o
 
 
-SRCS 	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+SRCS 	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
 
 
 $(LIB):	$(obj).depend $(OBJS)
 $(LIB):	$(obj).depend $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)

+ 171 - 0
lib_m68k/bootm.c

@@ -0,0 +1,171 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <image.h>
+#include <zlib.h>
+#include <bzlib.h>
+#include <watchdog.h>
+#include <environment.h>
+#include <asm/byteorder.h>
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+# include <status_led.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define PHYSADDR(x) x
+
+#define LINUX_MAX_ENVS		256
+#define LINUX_MAX_ARGS		256
+
+static ulong get_sp (void);
+static void set_clocks_in_mhz (bd_t *kbd);
+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[],
+		    bootm_headers_t *images)
+{
+	ulong sp;
+
+	ulong rd_data_start, rd_data_end, rd_len;
+	ulong initrd_start, initrd_end;
+	int ret;
+
+	ulong cmd_start, cmd_end;
+	ulong bootmap_base;
+	bd_t  *kbd;
+	ulong ep = 0;
+	void  (*kernel) (bd_t *, ulong, ulong, ulong, ulong);
+	struct lmb *lmb = images->lmb;
+
+	bootmap_base = getenv_bootm_low();
+
+	/*
+	 * Booting a (Linux) kernel image
+	 *
+	 * Allocate space for command line and board info - the
+	 * address should be as high as possible within the reach of
+	 * the kernel (see CFG_BOOTMAPSZ settings), but in unused
+	 * memory, which means far enough below the current stack
+	 * pointer.
+	 */
+	sp = get_sp();
+	debug ("## Current stack ends at 0x%08lx ", sp);
+
+	/* adjust sp by 1K to be safe */
+	sp -= 1024;
+	lmb_reserve(lmb, sp, (CFG_SDRAM_BASE + gd->ram_size - sp));
+
+	/* allocate space and init command line */
+	ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base);
+	if (ret) {
+		puts("ERROR with allocation of cmdline\n");
+		goto error;
+	}
+
+	/* allocate space for kernel copy of board info */
+	ret = boot_get_kbd (lmb, &kbd, bootmap_base);
+	if (ret) {
+		puts("ERROR with allocation of kernel bd\n");
+		goto error;
+	}
+	set_clocks_in_mhz(kbd);
+
+	/* find kernel entry point */
+	if (images->legacy_hdr_valid) {
+		ep = image_get_ep (images->legacy_hdr_os);
+#if defined(CONFIG_FIT)
+	} else if (images->fit_uname_os) {
+		ret = fit_image_get_entry (images->fit_hdr_os,
+				images->fit_noffset_os, &ep);
+		if (ret) {
+			puts ("Can't get entry point property!\n");
+			goto error;
+		}
+#endif
+	} else {
+		puts ("Could not find kernel entry point!\n");
+		goto error;
+	}
+	kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep;
+
+	/* find ramdisk */
+	ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_M68K,
+			&rd_data_start, &rd_data_end);
+	if (ret)
+		goto error;
+
+	rd_len = rd_data_end - rd_data_start;
+	ret = boot_ramdisk_high (lmb, rd_data_start, rd_len,
+			&initrd_start, &initrd_end);
+	if (ret)
+		goto error;
+
+	debug("## Transferring control to Linux (at address %08lx) ...\n",
+	      (ulong) kernel);
+
+	show_boot_progress (15);
+
+	if (!images->autostart)
+		return;
+	/*
+	 * Linux Kernel Parameters (passing board info data):
+	 *   r3: ptr to board info data
+	 *   r4: initrd_start or 0 if no initrd
+	 *   r5: initrd_end - unused if r4 is 0
+	 *   r6: Start of command line string
+	 *   r7: End   of command line string
+	 */
+	(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
+	/* does not return */
+	return ;
+
+error:
+	if (images->autostart)
+		do_reset (cmdtp, flag, argc, argv);
+	return ;
+}
+
+static ulong get_sp (void)
+{
+	ulong sp;
+
+	asm("movel %%a7, %%d0\n"
+	    "movel %%d0, %0\n": "=d"(sp): :"%d0");
+
+	return sp;
+}
+
+static void set_clocks_in_mhz (bd_t *kbd)
+{
+	char *s;
+
+	if ((s = getenv("clocks_in_mhz")) != NULL) {
+		/* convert all clock information to MHz */
+		kbd->bi_intfreq /= 1000000L;
+		kbd->bi_busfreq /= 1000000L;
+	}
+}

+ 0 - 340
lib_m68k/m68k_linux.c

@@ -1,340 +0,0 @@
-/*
- * (C) Copyright 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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
- *
- */
-
-#include <common.h>
-#include <command.h>
-#include <image.h>
-#include <zlib.h>
-#include <bzlib.h>
-#include <watchdog.h>
-#include <environment.h>
-#include <asm/byteorder.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#define PHYSADDR(x) x
-
-#define LINUX_MAX_ENVS		256
-#define LINUX_MAX_ARGS		256
-
-#define CHUNKSZ			(64 * 1024)
-
-#ifdef CONFIG_SHOW_BOOT_PROGRESS
-# include <status_led.h>
-# define SHOW_BOOT_PROGRESS(arg)	show_boot_progress(arg)
-#else
-# define SHOW_BOOT_PROGRESS(arg)
-#endif
-
-extern image_header_t header;
-
-void do_bootm_linux(cmd_tbl_t * cmdtp, int flag,
-		    int argc, char *argv[],
-		    ulong addr, ulong * len_ptr, int verify)
-{
-	ulong sp;
-	ulong len, checksum;
-	ulong initrd_start, initrd_end;
-	ulong cmd_start, cmd_end;
-	ulong initrd_high;
-	ulong data;
-	int initrd_copy_to_ram = 1;
-	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,
-		 * turning the "load high" feature off. This is intentional.
-		 */
-		initrd_high = simple_strtoul(s, NULL, 16);
-		if (initrd_high == ~0)
-			initrd_copy_to_ram = 0;
-	} else {		/* not set, no restrictions to load high */
-		initrd_high = ~0;
-	}
-
-#ifdef CONFIG_LOGBUFFER
-	kbd = gd->bd;
-	/* Prevent initrd from overwriting logbuffer */
-	if (initrd_high < (kbd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD))
-		initrd_high = kbd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD;
-	debug("## Logbuffer at 0x%08lX ", kbd->bi_memsize - LOGBUFF_LEN);
-#endif
-
-	/*
-	 * Booting a (Linux) kernel image
-	 *
-	 * Allocate space for command line and board info - the
-	 * address should be as high as possible within the reach of
-	 * the kernel (see CFG_BOOTMAPSZ settings), but in unused
-	 * memory, which means far enough below the current stack
-	 * pointer.
-	 */
-	asm("movel %%a7, %%d0\n"
-	    "movel %%d0, %0\n": "=d"(sp): :"%d0");
-
-	debug("## Current stack ends at 0x%08lX ", sp);
-
-	sp -= 2048;		/* just to be sure */
-	if (sp > CFG_BOOTMAPSZ)
-		sp = CFG_BOOTMAPSZ;
-	sp &= ~0xF;
-
-	debug("=> set upper limit to 0x%08lX\n", sp);
-
-	cmdline = (char *)((sp - CFG_BARGSIZE) & ~0xF);
-	kbd = (bd_t *) (((ulong) cmdline - sizeof(bd_t)) & ~0xF);
-
-	if ((s = getenv("bootargs")) == NULL)
-		s = "";
-
-	strcpy(cmdline, s);
-
-	cmd_start = (ulong) & cmdline[0];
-	cmd_end = cmd_start + strlen(cmdline);
-
-	*kbd = *(gd->bd);
-
-#ifdef	DEBUG
-	printf("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end);
-
-	do_bdinfo(NULL, 0, 0, NULL);
-#endif
-
-	if ((s = getenv("clocks_in_mhz")) != NULL) {
-		/* convert all clock information to MHz */
-		kbd->bi_intfreq /= 1000000L;
-		kbd->bi_busfreq /= 1000000L;
-	}
-
-	kernel =
-	    (void (*)(bd_t *, ulong, ulong, ulong, ulong))ntohl(hdr->ih_ep);
-
-	/*
-	 * Check if there is an initrd image
-	 */
-
-	if (argc >= 3) {
-		debug("Not skipping initrd\n");
-		SHOW_BOOT_PROGRESS(9);
-
-		addr = simple_strtoul(argv[2], NULL, 16);
-
-		printf("## Loading RAMDisk Image at %08lx ...\n", addr);
-
-		/* Copy header so we can blank CRC field for re-calculation */
-		memmove(&header, (char *)addr, sizeof(image_header_t));
-
-		if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-			puts("Bad Magic Number\n");
-			SHOW_BOOT_PROGRESS(-10);
-			do_reset(cmdtp, flag, argc, argv);
-		}
-
-		data = (ulong) & header;
-		len = sizeof(image_header_t);
-
-		checksum = ntohl(hdr->ih_hcrc);
-		hdr->ih_hcrc = 0;
-
-		if (crc32(0, (uchar *) data, len) != checksum) {
-			puts("Bad Header Checksum\n");
-			SHOW_BOOT_PROGRESS(-11);
-			do_reset(cmdtp, flag, argc, argv);
-		}
-
-		SHOW_BOOT_PROGRESS(10);
-
-		print_image_hdr(hdr);
-
-		data = addr + sizeof(image_header_t);
-		len = ntohl(hdr->ih_size);
-
-		if (verify) {
-			ulong csum = 0;
-#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
-			ulong cdata = data, edata = cdata + len;
-#endif				/* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
-
-			puts("   Verifying Checksum ... ");
-
-#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
-
-			while (cdata < edata) {
-				ulong chunk = edata - cdata;
-
-				if (chunk > CHUNKSZ)
-					chunk = CHUNKSZ;
-				csum = crc32(csum, (uchar *) cdata, chunk);
-				cdata += chunk;
-
-				WATCHDOG_RESET();
-			}
-#else				/* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
-			csum = crc32(0, (uchar *) data, len);
-#endif				/* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
-
-			if (csum != ntohl(hdr->ih_dcrc)) {
-				puts("Bad Data CRC\n");
-				SHOW_BOOT_PROGRESS(-12);
-				do_reset(cmdtp, flag, argc, argv);
-			}
-			puts("OK\n");
-		}
-
-		SHOW_BOOT_PROGRESS(11);
-
-		if ((hdr->ih_os != IH_OS_LINUX) ||
-		    (hdr->ih_arch != IH_CPU_M68K) ||
-		    (hdr->ih_type != 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 ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
-		u_long tail = ntohl(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 += ntohl(len_ptr[0]);
-		if (tail) {
-			data += 4 - tail;
-		}
-
-		len = ntohl(len_ptr[1]);
-
-	} else {
-		/*
-		 * no initrd image
-		 */
-		SHOW_BOOT_PROGRESS(14);
-
-		len = data = 0;
-	}
-
-	if (!data) {
-		debug("No initrd\n");
-	}
-
-	if (data) {
-		if (!initrd_copy_to_ram) {	/* zero-copy ramdisk support */
-			initrd_start = data;
-			initrd_end = initrd_start + len;
-		} else {
-			initrd_start = (ulong) kbd - len;
-			initrd_start &= ~(4096 - 1);	/* align on page */
-
-			if (initrd_high) {
-				ulong nsp;
-
-				/*
-				 * the inital ramdisk does not need to be within
-				 * CFG_BOOTMAPSZ as it is not accessed until after
-				 * the mm system is initialised.
-				 *
-				 * do the stack bottom calculation again and see if
-				 * the initrd will fit just below the monitor stack
-				 * bottom without overwriting the area allocated
-				 * above for command line args and board info.
-				 */
-				asm("movel %%a7, %%d0\n"
-				    "movel %%d0, %0\n": "=d"(nsp): :"%d0");
-
-				nsp -= 2048;	/* just to be sure */
-				nsp &= ~0xF;
-
-				if (nsp > initrd_high)	/* limit as specified */
-					nsp = initrd_high;
-
-					nsp -= len;
-				nsp &= ~(4096 - 1);	/* align on page */
-
-				if (nsp >= sp)
-					initrd_start = nsp;
-			}
-
-			SHOW_BOOT_PROGRESS(12);
-
-			debug
-			    ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
-			     data, data + len - 1, len, len);
-
-			initrd_end = initrd_start + len;
-			printf("   Loading Ramdisk to %08lx, end %08lx ... ",
-			       initrd_start, initrd_end);
-#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
-			{
-				size_t l = len;
-				void *to = (void *)initrd_start;
-				void *from = (void *)data;
-
-				while (l > 0) {
-					size_t tail =
-					    (l > CHUNKSZ) ? CHUNKSZ : l;
-					WATCHDOG_RESET();
-					memmove(to, from, tail);
-					to += tail;
-					from += tail;
-					l -= tail;
-				}
-			}
-#else				/* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
-			memmove((void *)initrd_start, (void *)data, len);
-#endif				/* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
-			puts("OK\n");
-		}
-	} else {
-		initrd_start = 0;
-		initrd_end = 0;
-	}
-
-	debug("## Transferring control to Linux (at address %08lx) ...\n",
-	      (ulong) kernel);
-
-	SHOW_BOOT_PROGRESS(15);
-
-	/*
-	 * Linux Kernel Parameters (passing board info data):
-	 *   r3: ptr to board info data
-	 *   r4: initrd_start or 0 if no initrd
-	 *   r5: initrd_end - unused if r4 is 0
-	 *   r6: Start of command line string
-	 *   r7: End   of command line string
-	 */
-	(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
-	/* does not return */
-}

+ 7 - 4
lib_microblaze/Makefile

@@ -25,12 +25,15 @@ include $(TOPDIR)/config.mk
 
 
 LIB	= $(obj)lib$(ARCH).a
 LIB	= $(obj)lib$(ARCH).a
 
 
-SOBJS	=
+SOBJS-y	+=
 
 
-COBJS	= board.o microblaze_linux.o time.o cache.o
+COBJS-y	+= board.o
+COBJS-y	+= bootm.o
+COBJS-y	+= cache.o
+COBJS-y	+= time.o
 
 
-SRCS 	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+SRCS 	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
 
 
 $(LIB):	$(obj).depend $(OBJS)
 $(LIB):	$(obj).depend $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)

+ 81 - 0
lib_microblaze/bootm.c

@@ -0,0 +1,81 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ * (C) Copyright 2004 Atmark Techno, Inc.
+ *
+ * Michal  SIMEK <monstr@monstr.eu>
+ * Yasushi SHOJI <yashi@atmark-techno.com>
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <command.h>
+#include <image.h>
+#include <zlib.h>
+#include <asm/byteorder.h>
+
+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[],
+		     bootm_headers_t *images)
+{
+	/* First parameter is mapped to $r5 for kernel boot args */
+	void	(*theKernel) (char *);
+	char	*commandline = getenv ("bootargs");
+	ulong	ep = 0;
+
+	/* find kernel entry point */
+	if (images->legacy_hdr_valid) {
+		ep = image_get_ep (images->legacy_hdr_os);
+#if defined(CONFIG_FIT)
+	} else if (images->fit_uname_os) {
+		int ret = fit_image_get_entry (images->fit_hdr_os,
+				images->fit_noffset_os, &ep);
+		if (ret) {
+			puts ("Can't get entry point property!\n");
+			goto error;
+		}
+#endif
+	} else {
+		puts ("Could not find kernel entry point!\n");
+		goto error;
+	}
+	theKernel = (void (*)(char *))ep;
+
+	show_boot_progress (15);
+
+#ifdef DEBUG
+	printf ("## Transferring control to Linux (at address %08lx) ...\n",
+		(ulong) theKernel);
+#endif
+
+	if (!images->autostart)
+		return ;
+
+	theKernel (commandline);
+	/* does not return */
+	return;
+
+error:
+	if (images->autostart)
+		do_reset (cmdtp, flag, argc, argv);
+	return;
+}

+ 0 - 164
lib_microblaze/microblaze_linux.c

@@ -1,164 +0,0 @@
-/*
- * (C) Copyright 2007 Michal Simek
- * (C) Copyright 2004 Atmark Techno, Inc.
- *
- * Michal  SIMEK <monstr@monstr.eu>
- * Yasushi SHOJI <yashi@atmark-techno.com>
- *
- * 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
- */
-
-#include <common.h>
-#include <command.h>
-#include <image.h>
-#include <zlib.h>
-#include <asm/byteorder.h>
-
-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)
-{
-	ulong len = 0, checksum;
-	ulong initrd_start, initrd_end;
-	ulong data;
-	/* 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 *))ntohl (hdr->ih_ep);
-
-	/* Check if there is an initrd image */
-	if (argc >= 3) {
-		show_boot_progress (9);
-
-		addr = simple_strtoul (argv[2], NULL, 16);
-
-		printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
-
-		/* Copy header so we can blank CRC field for re-calculation */
-		memcpy (&header, (char *)addr, sizeof (image_header_t));
-
-		if (ntohl (hdr->ih_magic) != IH_MAGIC) {
-			printf ("Bad Magic Number\n");
-			show_boot_progress (-10);
-			do_reset (cmdtp, flag, argc, argv);
-		}
-
-		data = (ulong) & header;
-		len = sizeof (image_header_t);
-
-		checksum = ntohl (hdr->ih_hcrc);
-		hdr->ih_hcrc = 0;
-
-		if (crc32 (0, (char *)data, len) != checksum) {
-			printf ("Bad Header Checksum\n");
-			show_boot_progress (-11);
-			do_reset (cmdtp, flag, argc, argv);
-		}
-
-		show_boot_progress (10);
-
-		print_image_hdr (hdr);
-
-		data = addr + sizeof (image_header_t);
-		len = ntohl (hdr->ih_size);
-
-		if (verify) {
-			ulong csum = 0;
-
-			printf ("   Verifying Checksum ... ");
-			csum = crc32 (0, (char *)data, len);
-			if (csum != ntohl (hdr->ih_dcrc)) {
-				printf ("Bad Data CRC\n");
-				show_boot_progress (-12);
-				do_reset (cmdtp, flag, argc, argv);
-			}
-			printf ("OK\n");
-		}
-
-		show_boot_progress (11);
-
-		if ((hdr->ih_os != IH_OS_LINUX) ||
-		    (hdr->ih_arch != IH_CPU_MICROBLAZE) ||
-		    (hdr->ih_type != 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 ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
-		ulong tail = ntohl (len_ptr[0]) % 4;
-
-		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 += ntohl (len_ptr[0]);
-		if (tail) {
-			data += 4 - tail;
-		}
-
-		len = ntohl (len_ptr[1]);
-
-	} else {
-		/*
-		 * no initrd image
-		 */
-		show_boot_progress (14);
-
-		data = 0;
-	}
-
-#ifdef  DEBUG
-	if (!data) {
-		printf ("No initrd\n");
-	}
-#endif
-
-	if (data) {
-		initrd_start = data;
-		initrd_end = initrd_start + len;
-	} else {
-		initrd_start = 0;
-		initrd_end = 0;
-	}
-
-	show_boot_progress (15);
-
-#ifdef DEBUG
-	printf ("## Transferring control to Linux (at address %08lx) ...\n",
-		(ulong) theKernel);
-#endif
-
-	theKernel (commandline);
-}

+ 6 - 4
lib_mips/Makefile

@@ -25,12 +25,14 @@ include $(TOPDIR)/config.mk
 
 
 LIB	= $(obj)lib$(ARCH).a
 LIB	= $(obj)lib$(ARCH).a
 
 
-SOBJS	=
+SOBJS-y	+=
 
 
-COBJS	= board.o time.o mips_linux.o
+COBJS-y	+= board.o
+COBJS-y	+= bootm.o
+COBJS-y	+= time.o
 
 
-SRCS 	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+SRCS 	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
 
 
 $(LIB):	$(obj).depend $(OBJS)
 $(LIB):	$(obj).depend $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)

+ 37 - 117
lib_mips/mips_linux.c → lib_mips/bootm.c

@@ -33,10 +33,6 @@ DECLARE_GLOBAL_DATA_PTR;
 #define	LINUX_MAX_ENVS		256
 #define	LINUX_MAX_ENVS		256
 #define	LINUX_MAX_ARGS		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;
 static int	linux_argc;
 static char **	linux_argv;
 static char **	linux_argv;
 
 
@@ -47,126 +43,40 @@ static int	linux_env_idx;
 static void linux_params_init (ulong start, char * commandline);
 static void linux_params_init (ulong start, char * commandline);
 static void linux_env_set (char * env_name, char * env_val);
 static void linux_env_set (char * env_name, char * env_val);
 
 
+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[],
 void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
-		     ulong addr, ulong * len_ptr, int verify)
+		     bootm_headers_t *images)
 {
 {
-	ulong len = 0, checksum;
-	ulong initrd_start, initrd_end;
-	ulong data;
-	void (*theKernel) (int, char **, char **, int *);
-	image_header_t *hdr = &header;
-	char *commandline = getenv ("bootargs");
-	char env_buf[12];
-
-	theKernel =
-		(void (*)(int, char **, char **, int *)) ntohl (hdr->ih_ep);
-
-	/*
-	 * Check if there is an initrd image
-	 */
-	if (argc >= 3) {
-		show_boot_progress (9);
-
-		addr = simple_strtoul (argv[2], NULL, 16);
-
-		printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
-
-		/* Copy header so we can blank CRC field for re-calculation */
-		memcpy (&header, (char *) addr, sizeof (image_header_t));
-
-		if (ntohl (hdr->ih_magic) != IH_MAGIC) {
-			printf ("Bad Magic Number\n");
-			show_boot_progress (-10);
-			do_reset (cmdtp, flag, argc, argv);
-		}
-
-		data = (ulong) & header;
-		len = sizeof (image_header_t);
-
-		checksum = ntohl (hdr->ih_hcrc);
-		hdr->ih_hcrc = 0;
-
-		if (crc32 (0, (uchar *) data, len) != checksum) {
-			printf ("Bad Header Checksum\n");
-			show_boot_progress (-11);
-			do_reset (cmdtp, flag, argc, argv);
+	ulong	initrd_start, initrd_end;
+	ulong	ep = 0;
+	void	(*theKernel) (int, char **, char **, int *);
+	char	*commandline = getenv ("bootargs");
+	char	env_buf[12];
+	int	ret;
+
+	/* find kernel entry point */
+	if (images->legacy_hdr_valid) {
+		ep = image_get_ep (images->legacy_hdr_os);
+#if defined(CONFIG_FIT)
+	} else if (images->fit_uname_os) {
+		ret = fit_image_get_entry (images->fit_hdr_os,
+				images->fit_noffset_os, &ep);
+		if (ret) {
+			puts ("Can't get entry point property!\n");
+			goto error;
 		}
 		}
-
-		show_boot_progress (10);
-
-		print_image_hdr (hdr);
-
-		data = addr + sizeof (image_header_t);
-		len = ntohl (hdr->ih_size);
-
-		if (verify) {
-			ulong csum = 0;
-
-			printf ("   Verifying Checksum ... ");
-			csum = crc32 (0, (uchar *) data, len);
-			if (csum != ntohl (hdr->ih_dcrc)) {
-				printf ("Bad Data CRC\n");
-				show_boot_progress (-12);
-				do_reset (cmdtp, flag, argc, argv);
-			}
-			printf ("OK\n");
-		}
-
-		show_boot_progress (11);
-
-		if ((hdr->ih_os != IH_OS_LINUX) ||
-		    (hdr->ih_arch != IH_CPU_MIPS) ||
-		    (hdr->ih_type != 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 ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
-		ulong tail = ntohl (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 += ntohl (len_ptr[0]);
-		if (tail) {
-			data += 4 - tail;
-		}
-
-		len = ntohl (len_ptr[1]);
-
-	} else {
-		/*
-		 * no initrd image
-		 */
-		show_boot_progress (14);
-
-		data = 0;
-	}
-
-#ifdef	DEBUG
-	if (!data) {
-		printf ("No initrd\n");
-	}
 #endif
 #endif
-
-	if (data) {
-		initrd_start = data;
-		initrd_end = initrd_start + len;
 	} else {
 	} else {
-		initrd_start = 0;
-		initrd_end = 0;
+		puts ("Could not find kernel entry point!\n");
+		goto error;
 	}
 	}
+	theKernel = (void (*)(int, char **, char **, int *))ep;
+
+	ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_MIPS,
+			&initrd_start, &initrd_end);
+	if (ret)
+		goto error;
 
 
 	show_boot_progress (15);
 	show_boot_progress (15);
 
 
@@ -203,10 +113,20 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
 	sprintf (env_buf, "0x%X", (uint) (gd->bd->bi_flashsize));
 	sprintf (env_buf, "0x%X", (uint) (gd->bd->bi_flashsize));
 	linux_env_set ("flash_size", env_buf);
 	linux_env_set ("flash_size", env_buf);
 
 
+	if (!images->autostart)
+		return ;
+
 	/* we assume that the kernel is in place */
 	/* we assume that the kernel is in place */
 	printf ("\nStarting kernel ...\n\n");
 	printf ("\nStarting kernel ...\n\n");
 
 
 	theKernel (linux_argc, linux_argv, linux_env, 0);
 	theKernel (linux_argc, linux_argv, linux_env, 0);
+	/* does not return */
+	return;
+
+error:
+	if (images->autostart)
+		do_reset (cmdtp, flag, argc, argv);
+	return;
 }
 }
 
 
 static void linux_params_init (ulong start, char *line)
 static void linux_params_init (ulong start, char *line)

+ 9 - 4
lib_nios/Makefile

@@ -25,12 +25,17 @@ include $(TOPDIR)/config.mk
 
 
 LIB	= $(obj)lib$(ARCH).a
 LIB	= $(obj)lib$(ARCH).a
 
 
-SOBJS	=
+SOBJS-y	+=
 
 
-COBJS	= board.o cache.o divmod.o nios_linux.o mult.o time.o
+COBJS-y	+= board.o
+COBJS-y	+= bootm.o
+COBJS-y	+= cache.o
+COBJS-y	+= divmod.o
+COBJS-y	+= mult.o
+COBJS-y	+= time.o
 
 
-SRCS 	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+SRCS 	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
 
 
 $(LIB):	$(obj).depend $(OBJS)
 $(LIB):	$(obj).depend $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)

+ 1 - 1
lib_nios/nios_linux.c → lib_nios/bootm.c

@@ -29,6 +29,6 @@
  *
  *
  */
  */
 void do_bootm_linux(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)
+		bootm_headers_t *images)
 {
 {
 }
 }

+ 8 - 4
lib_nios2/Makefile

@@ -25,12 +25,16 @@ include $(TOPDIR)/config.mk
 
 
 LIB	= $(obj)lib$(ARCH).a
 LIB	= $(obj)lib$(ARCH).a
 
 
-SOBJS	= cache.o
+SOBJS-y	+= cache.o
 
 
-COBJS	= board.o divmod.o nios_linux.o mult.o time.o
+COBJS-y	+= board.o
+COBJS-y	+= bootm.o
+COBJS-y	+= divmod.o
+COBJS-y	+= mult.o
+COBJS-y	+= time.o
 
 
-SRCS 	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+SRCS 	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
 
 
 $(LIB):	$(obj).depend $(OBJS)
 $(LIB):	$(obj).depend $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)

+ 31 - 4
lib_nios2/nios_linux.c → lib_nios2/bootm.c

@@ -25,16 +25,43 @@
 #include <command.h>
 #include <command.h>
 #include <asm/byteorder.h>
 #include <asm/byteorder.h>
 
 
-extern image_header_t header;	/* common/cmd_bootm.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[],
 void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
-		ulong addr, ulong *len_ptr, int   verify)
+		bootm_headers_t *images)
 {
 {
-	image_header_t *hdr = &header;
-	void (*kernel)(void) = (void (*)(void))ntohl (hdr->ih_ep);
+	ulong	ep = 0;
+
+	/* find kernel entry point */
+	if (images->legacy_hdr_valid) {
+		ep = image_get_ep (images->legacy_hdr_os);
+#if defined(CONFIG_FIT)
+	} else if (images->fit_uname_os) {
+		int ret = fit_image_get_entry (images->fit_hdr_os,
+				images->fit_noffset_os, &ep);
+		if (ret) {
+			puts ("Can't get entry point property!\n");
+			goto error;
+		}
+#endif
+	} else {
+		puts ("Could not find kernel entry point!\n");
+		goto error;
+	}
+	void (*kernel)(void) = (void (*)(void))ep;
+
+	if (!images->autostart)
+		return ;
 
 
 	/* For now we assume the Microtronix linux ... which only
 	/* For now we assume the Microtronix linux ... which only
 	 * needs to be called ;-)
 	 * needs to be called ;-)
 	 */
 	 */
 	kernel ();
 	kernel ();
+	/* does not return */
+	return;
+
+error:
+	if (images->autostart)
+		do_reset (cmdtp, flag, argc, argv);
+	return;
 }
 }

+ 15 - 7
lib_ppc/Makefile

@@ -25,13 +25,21 @@ include $(TOPDIR)/config.mk
 
 
 LIB	= $(obj)lib$(ARCH).a
 LIB	= $(obj)lib$(ARCH).a
 
 
-SOBJS	= ppccache.o ppcstring.o ticks.o
-
-COBJS	= board.o \
-	  bat_rw.o cache.o extable.o kgdb.o time.o interrupts.o
-
-SRCS 	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+SOBJS-y	+= ppccache.o
+SOBJS-y	+= ppcstring.o
+SOBJS-y	+= ticks.o
+
+COBJS-y	+= bat_rw.o
+COBJS-y	+= board.o
+COBJS-y	+= bootm.o
+COBJS-y	+= cache.o
+COBJS-y	+= extable.o
+COBJS-y	+= interrupts.o
+COBJS-y	+= kgdb.o
+COBJS-y	+= time.o
+
+SRCS 	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
 
 
 $(LIB):	$(obj).depend $(OBJS)
 $(LIB):	$(obj).depend $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)

+ 774 - 0
lib_ppc/bootm.c

@@ -0,0 +1,774 @@
+/*
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ */
+
+
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <image.h>
+#include <malloc.h>
+#include <zlib.h>
+#include <bzlib.h>
+#include <environment.h>
+#include <asm/byteorder.h>
+
+#if defined(CONFIG_OF_LIBFDT)
+#include <fdt.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+
+static void fdt_error (const char *msg);
+static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
+		bootm_headers_t *images, char **of_flat_tree, ulong *of_size);
+static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
+		cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
+		char **of_flat_tree, ulong *of_size);
+#endif
+
+#ifdef CFG_INIT_RAM_LOCK
+#include <asm/cache.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern ulong get_effective_memsize(void);
+static ulong get_sp (void);
+static void set_clocks_in_mhz (bd_t *kbd);
+
+#ifndef CFG_LINUX_LOWMEM_MAX_SIZE
+#define CFG_LINUX_LOWMEM_MAX_SIZE	(768*1024*1024)
+#endif
+
+void  __attribute__((noinline))
+do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
+		bootm_headers_t *images)
+{
+	ulong	sp;
+
+	ulong	initrd_start, initrd_end;
+	ulong	rd_data_start, rd_data_end, rd_len;
+	ulong	size;
+
+	ulong	cmd_start, cmd_end, bootmap_base;
+	bd_t	*kbd;
+	ulong	ep = 0;
+	void	(*kernel)(bd_t *, ulong, ulong, ulong, ulong);
+	int	ret;
+	ulong	of_size = 0;
+	struct lmb *lmb = images->lmb;
+
+#if defined(CONFIG_OF_LIBFDT)
+	char	*of_flat_tree = NULL;
+#endif
+
+	bootmap_base = getenv_bootm_low();
+	size = getenv_bootm_size();
+
+#ifdef DEBUG
+	if (((u64)bootmap_base + size) > (CFG_SDRAM_BASE + (u64)gd->ram_size))
+		puts("WARNING: bootm_low + bootm_size exceed total memory\n");
+	if ((bootmap_base + size) > get_effective_memsize())
+		puts("WARNING: bootm_low + bootm_size exceed eff. memory\n");
+#endif
+
+	size = min(size, get_effective_memsize());
+	size = min(size, CFG_LINUX_LOWMEM_MAX_SIZE);
+
+	if (size < getenv_bootm_size()) {
+		ulong base = bootmap_base + size;
+		printf("WARNING: adjusting available memory to %x\n", size);
+		lmb_reserve(lmb, base, getenv_bootm_size() - size);
+	}
+
+	/*
+	 * Booting a (Linux) kernel image
+	 *
+	 * Allocate space for command line and board info - the
+	 * address should be as high as possible within the reach of
+	 * the kernel (see CFG_BOOTMAPSZ settings), but in unused
+	 * memory, which means far enough below the current stack
+	 * pointer.
+	 */
+	sp = get_sp();
+	debug ("## Current stack ends at 0x%08lx\n", sp);
+
+	/* adjust sp by 1K to be safe */
+	sp -= 1024;
+	lmb_reserve(lmb, sp, (CFG_SDRAM_BASE + get_effective_memsize() - sp));
+
+#if defined(CONFIG_OF_LIBFDT)
+	/* find flattened device tree */
+	ret = boot_get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size);
+
+	if (ret)
+		goto error;
+#endif
+
+	if (!of_size) {
+		/* allocate space and init command line */
+		ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base);
+		if (ret) {
+			puts("ERROR with allocation of cmdline\n");
+			goto error;
+		}
+
+		/* allocate space for kernel copy of board info */
+		ret = boot_get_kbd (lmb, &kbd, bootmap_base);
+		if (ret) {
+			puts("ERROR with allocation of kernel bd\n");
+			goto error;
+		}
+		set_clocks_in_mhz(kbd);
+	}
+
+	/* find kernel entry point */
+	if (images->legacy_hdr_valid) {
+		ep = image_get_ep (images->legacy_hdr_os);
+#if defined(CONFIG_FIT)
+	} else if (images->fit_uname_os) {
+		ret = fit_image_get_entry (images->fit_hdr_os,
+				images->fit_noffset_os, &ep);
+		if (ret) {
+			puts ("Can't get entry point property!\n");
+			goto error;
+		}
+#endif
+	} else {
+		puts ("Could not find kernel entry point!\n");
+		goto error;
+	}
+	kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep;
+
+	/* find ramdisk */
+	ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_PPC,
+			&rd_data_start, &rd_data_end);
+	if (ret)
+		goto error;
+
+	rd_len = rd_data_end - rd_data_start;
+
+#if defined(CONFIG_OF_LIBFDT)
+	ret = boot_relocate_fdt (lmb, bootmap_base,
+		cmdtp, flag, argc, argv, &of_flat_tree, &of_size);
+
+	/*
+	 * Add the chosen node if it doesn't exist, add the env and bd_t
+	 * if the user wants it (the logic is in the subroutines).
+	 */
+	if (of_size) {
+		/* pass in dummy initrd info, we'll fix up later */
+		if (fdt_chosen(of_flat_tree, rd_data_start, rd_data_end, 0) < 0) {
+			fdt_error ("/chosen node create failed");
+			goto error;
+		}
+#ifdef CONFIG_OF_HAS_UBOOT_ENV
+		if (fdt_env(of_flat_tree) < 0) {
+			fdt_error ("/u-boot-env node create failed");
+			goto error;
+		}
+#endif
+#ifdef CONFIG_OF_HAS_BD_T
+		if (fdt_bd_t(of_flat_tree) < 0) {
+			fdt_error ("/bd_t node create failed");
+			goto error;
+		}
+#endif
+#ifdef CONFIG_OF_BOARD_SETUP
+		/* Call the board-specific fixup routine */
+		ft_board_setup(of_flat_tree, gd->bd);
+#endif
+	}
+#endif	/* CONFIG_OF_LIBFDT */
+
+	ret = boot_ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end);
+	if (ret)
+		goto error;
+
+#if defined(CONFIG_OF_LIBFDT)
+	/* fixup the initrd now that we know where it should be */
+	if ((of_flat_tree) && (initrd_start && initrd_end)) {
+		uint64_t addr, size;
+		int  total = fdt_num_mem_rsv(of_flat_tree);
+		int  j;
+
+		/* Look for the dummy entry and delete it */
+		for (j = 0; j < total; j++) {
+			fdt_get_mem_rsv(of_flat_tree, j, &addr, &size);
+			if (addr == rd_data_start) {
+				fdt_del_mem_rsv(of_flat_tree, j);
+				break;
+			}
+		}
+
+		ret = fdt_add_mem_rsv(of_flat_tree, initrd_start,
+					initrd_end - initrd_start + 1);
+		if (ret < 0) {
+			printf("fdt_chosen: %s\n", fdt_strerror(ret));
+			goto error;
+		}
+
+		do_fixup_by_path_u32(of_flat_tree, "/chosen",
+					"linux,initrd-start", initrd_start, 0);
+		do_fixup_by_path_u32(of_flat_tree, "/chosen",
+					"linux,initrd-end", initrd_end, 0);
+	}
+#endif
+	debug ("## Transferring control to Linux (at address %08lx) ...\n",
+		(ulong)kernel);
+
+	show_boot_progress (15);
+
+#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500)
+	unlock_ram_in_cache();
+#endif
+	if (!images->autostart)
+		return ;
+
+#if defined(CONFIG_OF_LIBFDT)
+	if (of_flat_tree) {	/* device tree; boot new style */
+		/*
+		 * Linux Kernel Parameters (passing device tree):
+		 *   r3: pointer to the fdt, followed by the board info data
+		 *   r4: physical pointer to the kernel itself
+		 *   r5: NULL
+		 *   r6: NULL
+		 *   r7: NULL
+		 */
+		debug ("   Booting using OF flat tree...\n");
+		(*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
+		/* does not return */
+	} else
+#endif
+	{
+		/*
+		 * Linux Kernel Parameters (passing board info data):
+		 *   r3: ptr to board info data
+		 *   r4: initrd_start or 0 if no initrd
+		 *   r5: initrd_end - unused if r4 is 0
+		 *   r6: Start of command line string
+		 *   r7: End   of command line string
+		 */
+		debug ("   Booting using board info...\n");
+		(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
+		/* does not return */
+	}
+	return ;
+
+error:
+	if (images->autostart)
+		do_reset (cmdtp, flag, argc, argv);
+	return ;
+}
+
+static ulong get_sp (void)
+{
+	ulong sp;
+
+	asm( "mr %0,1": "=r"(sp) : );
+	return sp;
+}
+
+static void set_clocks_in_mhz (bd_t *kbd)
+{
+	char	*s;
+
+	if ((s = getenv ("clocks_in_mhz")) != NULL) {
+		/* convert all clock information to MHz */
+		kbd->bi_intfreq /= 1000000L;
+		kbd->bi_busfreq /= 1000000L;
+#if defined(CONFIG_MPC8220)
+		kbd->bi_inpfreq /= 1000000L;
+		kbd->bi_pcifreq /= 1000000L;
+		kbd->bi_pevfreq /= 1000000L;
+		kbd->bi_flbfreq /= 1000000L;
+		kbd->bi_vcofreq /= 1000000L;
+#endif
+#if defined(CONFIG_CPM2)
+		kbd->bi_cpmfreq /= 1000000L;
+		kbd->bi_brgfreq /= 1000000L;
+		kbd->bi_sccfreq /= 1000000L;
+		kbd->bi_vco     /= 1000000L;
+#endif
+#if defined(CONFIG_MPC5xxx)
+		kbd->bi_ipbfreq /= 1000000L;
+		kbd->bi_pcifreq /= 1000000L;
+#endif /* CONFIG_MPC5xxx */
+	}
+}
+
+#if defined(CONFIG_OF_LIBFDT)
+static void fdt_error (const char *msg)
+{
+	puts ("ERROR: ");
+	puts (msg);
+	puts (" - must RESET the board to recover.\n");
+}
+
+static image_header_t *image_get_fdt (ulong fdt_addr)
+{
+	image_header_t *fdt_hdr = (image_header_t *)fdt_addr;
+
+	image_print_contents (fdt_hdr);
+
+	puts ("   Verifying Checksum ... ");
+	if (!image_check_hcrc (fdt_hdr)) {
+		fdt_error ("fdt header checksum invalid");
+		return NULL;
+	}
+
+	if (!image_check_dcrc (fdt_hdr)) {
+		fdt_error ("fdt checksum invalid");
+		return NULL;
+	}
+	puts ("OK\n");
+
+	if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) {
+		fdt_error ("uImage is not a fdt");
+		return NULL;
+	}
+	if (image_get_comp (fdt_hdr) != IH_COMP_NONE) {
+		fdt_error ("uImage is compressed");
+		return NULL;
+	}
+	if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) {
+		fdt_error ("uImage data is not a fdt");
+		return NULL;
+	}
+	return fdt_hdr;
+}
+
+/**
+ * fit_check_fdt - verify FIT format FDT subimage
+ * @fit_hdr: pointer to the FIT  header
+ * fdt_noffset: FDT subimage node offset within FIT image
+ * @verify: data CRC verification flag
+ *
+ * fit_check_fdt() verifies integrity of the FDT subimage and from
+ * specified FIT image.
+ *
+ * returns:
+ *     1, on success
+ *     0, on failure
+ */
+#if defined(CONFIG_FIT)
+static int fit_check_fdt (const void *fit, int fdt_noffset, int verify)
+{
+	fit_image_print (fit, fdt_noffset, "   ");
+
+	if (verify) {
+		puts ("   Verifying Hash Integrity ... ");
+		if (!fit_image_check_hashes (fit, fdt_noffset)) {
+			fdt_error ("Bad Data Hash");
+			return 0;
+		}
+		puts ("OK\n");
+	}
+
+	if (!fit_image_check_type (fit, fdt_noffset, IH_TYPE_FLATDT)) {
+		fdt_error ("Not a FDT image");
+		return 0;
+	}
+
+	if (!fit_image_check_comp (fit, fdt_noffset, IH_COMP_NONE)) {
+		fdt_error ("FDT image is compressed");
+		return 0;
+	}
+
+	return 1;
+}
+#endif /* CONFIG_FIT */
+
+static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
+		bootm_headers_t *images, char **of_flat_tree, ulong *of_size)
+{
+	ulong		fdt_addr;
+	image_header_t	*fdt_hdr;
+	char		*fdt_blob = NULL;
+	ulong		image_start, image_end;
+	ulong		load_start, load_end;
+#if defined(CONFIG_FIT)
+        void            *fit_hdr;
+        const char      *fit_uname_config = NULL;
+        const char      *fit_uname_fdt = NULL;
+	ulong		default_addr;
+	int		cfg_noffset;
+	int		fdt_noffset;
+	const void	*data;
+	size_t		size;
+#endif
+
+	*of_flat_tree = NULL;
+	*of_size = 0;
+
+	if (argc > 3 || genimg_has_config (images)) {
+#if defined(CONFIG_FIT)
+		if (argc > 3) {
+			/*
+			 * If the FDT blob comes from the FIT image and the
+			 * FIT image address is omitted in the command line
+			 * argument, try to use ramdisk or os FIT image
+			 * address or default load address.
+			 */
+			if (images->fit_uname_rd)
+				default_addr = (ulong)images->fit_hdr_rd;
+			else if (images->fit_uname_os)
+				default_addr = (ulong)images->fit_hdr_os;
+			else
+				default_addr = load_addr;
+
+			if (fit_parse_conf (argv[3], default_addr,
+						&fdt_addr, &fit_uname_config)) {
+				debug ("*  fdt: config '%s' from image at 0x%08lx\n",
+						fit_uname_config, fdt_addr);
+			} else if (fit_parse_subimage (argv[3], default_addr,
+						&fdt_addr, &fit_uname_fdt)) {
+				debug ("*  fdt: subimage '%s' from image at 0x%08lx\n",
+						fit_uname_fdt, fdt_addr);
+			} else
+#endif
+			{
+				fdt_addr = simple_strtoul(argv[3], NULL, 16);
+				debug ("*  fdt: cmdline image address = 0x%08lx\n",
+						fdt_addr);
+			}
+#if defined(CONFIG_FIT)
+		} else {
+			/* use FIT configuration provided in first bootm
+			 * command argument
+			 */
+			fdt_addr = (ulong)images->fit_hdr_os;
+			fit_uname_config = images->fit_uname_cfg;
+			debug ("*  fdt: using config '%s' from image at 0x%08lx\n",
+					fit_uname_config, fdt_addr);
+
+			/*
+			 * Check whether configuration has FDT blob defined,
+			 * if not quit silently.
+			 */
+			fit_hdr = (void *)fdt_addr;
+			cfg_noffset = fit_conf_get_node (fit_hdr,
+					fit_uname_config);
+			if (cfg_noffset < 0) {
+				debug ("*  fdt: no such config\n");
+				return 0;
+			}
+
+			fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
+					cfg_noffset);
+			if (fdt_noffset < 0) {
+				debug ("*  fdt: no fdt in config\n");
+				return 0;
+			}
+		}
+#endif
+
+		debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n",
+				fdt_addr);
+
+		/* copy from dataflash if needed */
+		fdt_addr = genimg_get_image (fdt_addr);
+
+		/*
+		 * Check if there is an FDT image at the
+		 * address provided in the second bootm argument
+		 * check image type, for FIT images get a FIT node.
+		 */
+		switch (genimg_get_format ((void *)fdt_addr)) {
+		case IMAGE_FORMAT_LEGACY:
+			/* verify fdt_addr points to a valid image header */
+			printf ("## Flattened Device Tree from Legacy Image at %08lx\n",
+					fdt_addr);
+			fdt_hdr = image_get_fdt (fdt_addr);
+			if (!fdt_hdr)
+				goto error;
+
+			/*
+			 * move image data to the load address,
+			 * make sure we don't overwrite initial image
+			 */
+			image_start = (ulong)fdt_hdr;
+			image_end = image_get_image_end (fdt_hdr);
+
+			load_start = image_get_load (fdt_hdr);
+			load_end = load_start + image_get_data_size (fdt_hdr);
+
+			if ((load_start < image_end) && (load_end > image_start)) {
+				fdt_error ("fdt overwritten");
+				goto error;
+			}
+
+			debug ("   Loading FDT from 0x%08lx to 0x%08lx\n",
+					image_get_data (fdt_hdr), load_start);
+
+			memmove ((void *)load_start,
+					(void *)image_get_data (fdt_hdr),
+					image_get_data_size (fdt_hdr));
+
+			fdt_blob = (char *)load_start;
+			break;
+		case IMAGE_FORMAT_FIT:
+			/*
+			 * This case will catch both: new uImage format
+			 * (libfdt based) and raw FDT blob (also libfdt
+			 * based).
+			 */
+#if defined(CONFIG_FIT)
+			/* check FDT blob vs FIT blob */
+			if (fit_check_format ((const void *)fdt_addr)) {
+				/*
+				 * FIT image
+				 */
+				fit_hdr = (void *)fdt_addr;
+				printf ("## Flattened Device Tree from FIT Image at %08lx\n",
+						fdt_addr);
+
+				if (!fit_uname_fdt) {
+					/*
+					 * no FDT blob image node unit name,
+					 * try to get config node first. If
+					 * config unit node name is NULL
+					 * fit_conf_get_node() will try to
+					 * find default config node
+					 */
+					cfg_noffset = fit_conf_get_node (fit_hdr,
+							fit_uname_config);
+
+					if (cfg_noffset < 0) {
+						fdt_error ("Could not find configuration node\n");
+						goto error;
+					}
+
+					fit_uname_config = fdt_get_name (fit_hdr,
+							cfg_noffset, NULL);
+					printf ("   Using '%s' configuration\n",
+							fit_uname_config);
+
+					fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
+							cfg_noffset);
+					fit_uname_fdt = fit_get_name (fit_hdr,
+							fdt_noffset, NULL);
+				} else {
+					/* get FDT component image node offset */
+					fdt_noffset = fit_image_get_node (fit_hdr,
+							fit_uname_fdt);
+				}
+				if (fdt_noffset < 0) {
+					fdt_error ("Could not find subimage node\n");
+					goto error;
+				}
+
+				printf ("   Trying '%s' FDT blob subimage\n",
+						fit_uname_fdt);
+
+				if (!fit_check_fdt (fit_hdr, fdt_noffset,
+							images->verify))
+					goto error;
+
+				/* get ramdisk image data address and length */
+				if (fit_image_get_data (fit_hdr, fdt_noffset,
+							&data, &size)) {
+					fdt_error ("Could not find FDT subimage data");
+					goto error;
+				}
+
+				/* verift that image data is a proper FDT blob */
+				if (fdt_check_header ((char *)data) != 0) {
+					fdt_error ("Subimage data is not a FTD");
+					goto error;
+				}
+
+				/*
+				 * move image data to the load address,
+				 * make sure we don't overwrite initial image
+				 */
+				image_start = (ulong)fit_hdr;
+				image_end = fit_get_end (fit_hdr);
+
+				if (fit_image_get_load (fit_hdr, fdt_noffset,
+							&load_start) == 0) {
+					load_end = load_start + size;
+
+					if ((load_start < image_end) &&
+							(load_end > image_start)) {
+						fdt_error ("FDT overwritten");
+						goto error;
+					}
+
+					printf ("   Loading FDT from 0x%08lx to 0x%08lx\n",
+							(ulong)data, load_start);
+
+					memmove ((void *)load_start,
+							(void *)data, size);
+
+					fdt_blob = (char *)load_start;
+				} else {
+					fdt_blob = (char *)data;
+				}
+
+				images->fit_hdr_fdt = fit_hdr;
+				images->fit_uname_fdt = fit_uname_fdt;
+				images->fit_noffset_fdt = fdt_noffset;
+				break;
+			} else
+#endif
+			{
+				/*
+				 * FDT blob
+				 */
+				debug ("*  fdt: raw FDT blob\n");
+				printf ("## Flattened Device Tree blob at %08lx\n", fdt_blob);
+				fdt_blob = (char *)fdt_addr;
+			}
+			break;
+		default:
+			fdt_error ("Did not find a cmdline Flattened Device Tree");
+			goto error;
+		}
+
+		printf ("   Booting using the fdt blob at 0x%x\n", fdt_blob);
+
+	} else if (images->legacy_hdr_valid &&
+			image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) {
+
+		ulong fdt_data, fdt_len;
+
+		/*
+		 * Now check if we have a legacy multi-component image,
+		 * get second entry data start address and len.
+		 */
+		printf ("## Flattened Device Tree from multi "
+			"component Image at %08lX\n",
+			(ulong)images->legacy_hdr_os);
+
+		image_multi_getimg (images->legacy_hdr_os, 2, &fdt_data, &fdt_len);
+		if (fdt_len) {
+
+			fdt_blob = (char *)fdt_data;
+			printf ("   Booting using the fdt at 0x%x\n", fdt_blob);
+
+			if (fdt_check_header (fdt_blob) != 0) {
+				fdt_error ("image is not a fdt");
+				goto error;
+			}
+
+			if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) {
+				fdt_error ("fdt size != image size");
+				goto error;
+			}
+		} else {
+			fdt_error ("Did not find a Flattened Device Tree "
+				"in a legacy multi-component image");
+			goto error;
+		}
+	} else {
+		debug ("## No Flattened Device Tree\n");
+		return 0;
+	}
+
+	*of_flat_tree = fdt_blob;
+	*of_size = be32_to_cpu (fdt_totalsize (fdt_blob));
+	debug ("   of_flat_tree at 0x%08lx size 0x%08lx\n",
+			*of_flat_tree, *of_size);
+
+	return 0;
+
+error:
+	do_reset (cmdtp, flag, argc, argv);
+	return 1;
+}
+
+static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
+		cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
+		char **of_flat_tree, ulong *of_size)
+{
+	char	*fdt_blob = *of_flat_tree;
+	ulong	relocate = 0;
+	ulong	of_len = 0;
+
+	/* nothing to do */
+	if (*of_size == 0)
+		return 0;
+
+	if (fdt_check_header (fdt_blob) != 0) {
+		fdt_error ("image is not a fdt");
+		goto error;
+	}
+
+#ifndef CFG_NO_FLASH
+	/* move the blob if it is in flash (set relocate) */
+	if (addr2info ((ulong)fdt_blob) != NULL)
+		relocate = 1;
+#endif
+
+	/*
+	 * The blob must be within CFG_BOOTMAPSZ,
+	 * so we flag it to be copied if it is not.
+	 */
+	if (fdt_blob >= (char *)CFG_BOOTMAPSZ)
+		relocate = 1;
+
+	of_len = be32_to_cpu (fdt_totalsize (fdt_blob));
+
+	/* move flattend device tree if needed */
+	if (relocate) {
+		int err;
+		ulong of_start;
+
+		/* position on a 4K boundary before the alloc_current */
+		of_start = lmb_alloc_base(lmb, of_len, 0x1000,
+					 (CFG_BOOTMAPSZ + bootmap_base));
+
+		if (of_start == 0) {
+			puts("device tree - allocation error\n");
+			goto error;
+		}
+
+		debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
+			(ulong)fdt_blob, (ulong)fdt_blob + of_len - 1,
+			of_len, of_len);
+
+		printf ("   Loading Device Tree to %08lx, end %08lx ... ",
+			of_start, of_start + of_len - 1);
+
+		err = fdt_open_into (fdt_blob, (void *)of_start, of_len);
+		if (err != 0) {
+			fdt_error ("fdt move failed");
+			goto error;
+		}
+		puts ("OK\n");
+
+		*of_flat_tree = (char *)of_start;
+	} else {
+		*of_flat_tree = fdt_blob;
+		lmb_reserve(lmb, (ulong)fdt, of_len);
+	}
+
+	return 0;
+
+error:
+	return 1;
+}
+#endif

+ 6 - 4
lib_sh/Makefile

@@ -22,12 +22,14 @@ include $(TOPDIR)/config.mk
 
 
 LIB	= $(obj)lib$(ARCH).a
 LIB	= $(obj)lib$(ARCH).a
 
 
-SOBJS	=
+SOBJS-y	+=
 
 
-COBJS	= board.o sh_linux.o # time.o
+COBJS-y	+= board.o
+COBJS-y	+= bootm.o
+#COBJS-y	+= time.o
 
 
-SRCS 	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+SRCS 	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
 
 
 $(LIB):	$(obj).depend $(OBJS)
 $(LIB):	$(obj).depend $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)

+ 33 - 6
lib_sh/sh_linux.c → lib_sh/bootm.c

@@ -25,8 +25,6 @@
 #include <command.h>
 #include <command.h>
 #include <asm/byteorder.h>
 #include <asm/byteorder.h>
 
 
-extern image_header_t header;	/* common/cmd_bootm.c */
-
 /* The SH kernel reads arguments from the empty zero page at location
 /* The SH kernel reads arguments from the empty zero page at location
  * 0 at the start of SDRAM. The following are copied from
  * 0 at the start of SDRAM. The following are copied from
  * arch/sh/kernel/setup.c and may require tweaking if the kernel sources
  * arch/sh/kernel/setup.c and may require tweaking if the kernel sources
@@ -45,6 +43,8 @@ extern image_header_t header;	/* common/cmd_bootm.c */
 
 
 #define RAMDISK_IMAGE_START_MASK        0x07FF
 #define RAMDISK_IMAGE_START_MASK        0x07FF
 
 
+extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
 #ifdef CFG_DEBUG
 #ifdef CFG_DEBUG
 static void hexdump (unsigned char *buf, int len)
 static void hexdump (unsigned char *buf, int len)
 {
 {
@@ -60,15 +60,42 @@ static void hexdump (unsigned char *buf, int len)
 #endif
 #endif
 
 
 void do_bootm_linux (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)
+                     bootm_headers_t *images)
 {
 {
-	image_header_t *hdr = &header;
-	char *bootargs = getenv("bootargs");
-	void (*kernel) (void) = (void (*)(void)) ntohl (hdr->ih_ep);
+	ulong	ep = 0;
+	char	*bootargs = getenv("bootargs");
+
+	/* find kernel entry point */
+	if (images->legacy_hdr_valid) {
+		ep = image_get_ep (images->legacy_hdr_os);
+#if defined(CONFIG_FIT)
+	} else if (images->fit_uname_os) {
+		int ret = fit_image_get_entry (images->fit_hdr_os,
+				images->fit_noffset_os, &ep);
+		if (ret) {
+			puts ("Can't get entry point property!\n");
+			goto error;
+		}
+#endif
+	} else {
+		puts ("Could not find kernel entry point!\n");
+		goto error;
+	}
+	void (*kernel) (void) = (void (*)(void))ep;
+
+	if (!images->autostart)
+		return ;
 
 
 	/* Setup parameters */
 	/* Setup parameters */
 	memset(PARAM, 0, 0x1000);	/* Clear zero page */
 	memset(PARAM, 0, 0x1000);	/* Clear zero page */
 	strcpy(COMMAND_LINE, bootargs);
 	strcpy(COMMAND_LINE, bootargs);
 
 
 	kernel();
 	kernel();
+	/* does not return */
+	return;
+
+error:
+	if (images->autostart)
+		do_reset (cmdtp, flag, argc, argv);
+	return;
 }
 }

+ 4 - 0
libfdt/fdt.c

@@ -50,8 +50,12 @@
  */
  */
 #include "libfdt_env.h"
 #include "libfdt_env.h"
 
 
+#ifndef USE_HOSTCC
 #include <fdt.h>
 #include <fdt.h>
 #include <libfdt.h>
 #include <libfdt.h>
+#else
+#include "fdt_host.h"
+#endif
 
 
 #include "libfdt_internal.h"
 #include "libfdt_internal.h"
 
 

+ 4 - 0
libfdt/fdt_ro.c

@@ -50,8 +50,12 @@
  */
  */
 #include "libfdt_env.h"
 #include "libfdt_env.h"
 
 
+#ifndef USE_HOSTCC
 #include <fdt.h>
 #include <fdt.h>
 #include <libfdt.h>
 #include <libfdt.h>
+#else
+#include "fdt_host.h"
+#endif
 
 
 #include "libfdt_internal.h"
 #include "libfdt_internal.h"
 
 

+ 4 - 0
libfdt/fdt_rw.c

@@ -50,8 +50,12 @@
  */
  */
 #include "libfdt_env.h"
 #include "libfdt_env.h"
 
 
+#ifndef USE_HOSTCC
 #include <fdt.h>
 #include <fdt.h>
 #include <libfdt.h>
 #include <libfdt.h>
+#else
+#include "fdt_host.h"
+#endif
 
 
 #include "libfdt_internal.h"
 #include "libfdt_internal.h"
 
 

+ 4 - 0
libfdt/fdt_strerror.c

@@ -50,8 +50,12 @@
  */
  */
 #include "libfdt_env.h"
 #include "libfdt_env.h"
 
 
+#ifndef USE_HOSTCC
 #include <fdt.h>
 #include <fdt.h>
 #include <libfdt.h>
 #include <libfdt.h>
+#else
+#include "fdt_host.h"
+#endif
 
 
 #include "libfdt_internal.h"
 #include "libfdt_internal.h"
 
 

+ 4 - 0
libfdt/fdt_wip.c

@@ -50,8 +50,12 @@
  */
  */
 #include "libfdt_env.h"
 #include "libfdt_env.h"
 
 
+#ifndef USE_HOSTCC
 #include <fdt.h>
 #include <fdt.h>
 #include <libfdt.h>
 #include <libfdt.h>
+#else
+#include "fdt_host.h"
+#endif
 
 
 #include "libfdt_internal.h"
 #include "libfdt_internal.h"
 
 

+ 8 - 0
tools/.gitignore

@@ -4,6 +4,14 @@
 /environment.c
 /environment.c
 /gen_eth_addr
 /gen_eth_addr
 /img2srec
 /img2srec
+/md5.c
 /mkimage
 /mkimage
 /sha1.c
 /sha1.c
 /ubsha1
 /ubsha1
+/image.c
+/fdt.c
+/fdt_ro.c
+/fdt_rw.c
+/fdt_strerror.c
+/fdt_wip.c
+/libfdt_internal.h

+ 62 - 3
tools/Makefile

@@ -23,7 +23,7 @@
 
 
 BIN_FILES	= img2srec$(SFX) mkimage$(SFX) envcrc$(SFX) ubsha1$(SFX) gen_eth_addr$(SFX) bmp_logo$(SFX)
 BIN_FILES	= img2srec$(SFX) mkimage$(SFX) envcrc$(SFX) ubsha1$(SFX) gen_eth_addr$(SFX) bmp_logo$(SFX)
 
 
-OBJ_LINKS	= environment.o crc32.o sha1.o
+OBJ_LINKS	= environment.o crc32.o md5.o sha1.o image.o
 OBJ_FILES	= img2srec.o mkimage.o envcrc.o ubsha1.o gen_eth_addr.o bmp_logo.o
 OBJ_FILES	= img2srec.o mkimage.o envcrc.o ubsha1.o gen_eth_addr.o bmp_logo.o
 
 
 ifeq ($(ARCH),mips)
 ifeq ($(ARCH),mips)
@@ -37,6 +37,8 @@ endif
 #OBJ_FILES	+= mpc86x_clk.o
 #OBJ_FILES	+= mpc86x_clk.o
 #endif
 #endif
 
 
+LIBFDT_OBJ_FILES	= fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o
+
 LOGO_H	= $(OBJTREE)/include/bmp_logo.h
 LOGO_H	= $(OBJTREE)/include/bmp_logo.h
 
 
 ifeq ($(LOGO_BMP),)
 ifeq ($(LOGO_BMP),)
@@ -120,6 +122,10 @@ CPPFLAGS   = -idirafter $(SRCTREE)/include \
 		-idirafter $(OBJTREE)/include \
 		-idirafter $(OBJTREE)/include \
 		-DTEXT_BASE=$(TEXT_BASE) -DUSE_HOSTCC
 		-DTEXT_BASE=$(TEXT_BASE) -DUSE_HOSTCC
 CFLAGS     = $(HOST_CFLAGS) $(CPPFLAGS) -O
 CFLAGS     = $(HOST_CFLAGS) $(CPPFLAGS) -O
+
+# No -pedantic switch to avoid libfdt compilation warnings
+FIT_CFLAGS = -Wall $(CPPFLAGS) -O
+
 AFLAGS	   = -D__ASSEMBLY__ $(CPPFLAGS)
 AFLAGS	   = -D__ASSEMBLY__ $(CPPFLAGS)
 CC	   = $(HOSTCC)
 CC	   = $(HOSTCC)
 STRIP	   = $(HOSTSTRIP)
 STRIP	   = $(HOSTSTRIP)
@@ -137,7 +143,7 @@ $(obj)img2srec$(SFX):	$(obj)img2srec.o
 		$(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
 		$(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
 		$(STRIP) $@
 		$(STRIP) $@
 
 
-$(obj)mkimage$(SFX):	$(obj)mkimage.o $(obj)crc32.o
+$(obj)mkimage$(SFX):	$(obj)mkimage.o $(obj)crc32.o $(obj)image.o $(obj)md5.o $(obj)sha1.o $(LIBFDT_OBJ_FILES)
 		$(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
 		$(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
 		$(STRIP) $@
 		$(STRIP) $@
 
 
@@ -170,11 +176,17 @@ $(obj)ubsha1.o:	$(src)ubsha1.c
 $(obj)crc32.o:	$(obj)crc32.c
 $(obj)crc32.o:	$(obj)crc32.c
 		$(CC) -g $(CFLAGS) -c -o $@ $<
 		$(CC) -g $(CFLAGS) -c -o $@ $<
 
 
+$(obj)md5.o:	$(obj)md5.c
+		$(CC) -g $(CFLAGS) -c -o $@ $<
+
 $(obj)sha1.o:	$(obj)sha1.c
 $(obj)sha1.o:	$(obj)sha1.c
 		$(CC) -g $(CFLAGS) -c -o $@ $<
 		$(CC) -g $(CFLAGS) -c -o $@ $<
 
 
+$(obj)image.o:	$(obj)image.c
+		$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
+
 $(obj)mkimage.o:	$(src)mkimage.c
 $(obj)mkimage.o:	$(src)mkimage.c
-		$(CC) -g $(CFLAGS) -c -o $@ $<
+		$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
 
 
 $(obj)ncb.o:		$(src)ncb.c
 $(obj)ncb.o:		$(src)ncb.c
 		$(CC) -g $(CFLAGS) -c -o $@ $<
 		$(CC) -g $(CFLAGS) -c -o $@ $<
@@ -188,6 +200,21 @@ $(obj)inca-swap-bytes.o:	$(src)inca-swap-bytes.c
 $(obj)mpc86x_clk.o:	$(src)mpc86x_clk.c
 $(obj)mpc86x_clk.o:	$(src)mpc86x_clk.c
 		$(CC) -g $(CFLAGS) -c -o $@ $<
 		$(CC) -g $(CFLAGS) -c -o $@ $<
 
 
+$(obj)fdt.o:	$(obj)fdt.c
+		$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
+
+$(obj)fdt_ro.o:	$(obj)fdt_ro.c
+		$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
+
+$(obj)fdt_rw.o:	$(obj)fdt_rw.c
+		$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
+
+$(obj)fdt_strerror.o:	$(obj)fdt_strerror.c
+		$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
+
+$(obj)fdt_wip.o:	$(obj)fdt_wip.c
+		$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
+
 subdirs:
 subdirs:
 ifeq ($(TOOLSUBDIRS),)
 ifeq ($(TOOLSUBDIRS),)
 		@:
 		@:
@@ -213,10 +240,42 @@ $(obj)crc32.c:
 		@rm -f $(obj)crc32.c
 		@rm -f $(obj)crc32.c
 		ln -s $(src)../lib_generic/crc32.c $(obj)crc32.c
 		ln -s $(src)../lib_generic/crc32.c $(obj)crc32.c
 
 
+$(obj)md5.c:
+		@rm -f $(obj)md5.c
+		ln -s $(src)../lib_generic/md5.c $(obj)md5.c
+
 $(obj)sha1.c:
 $(obj)sha1.c:
 		@rm -f $(obj)sha1.c
 		@rm -f $(obj)sha1.c
 		ln -s $(src)../lib_generic/sha1.c $(obj)sha1.c
 		ln -s $(src)../lib_generic/sha1.c $(obj)sha1.c
 
 
+$(obj)image.c:
+		@rm -f $(obj)image.c
+		ln -s $(src)../common/image.c $(obj)image.c
+
+$(obj)fdt.c:	libfdt_internal.h
+		@rm -f $(obj)fdt.c
+		ln -s $(src)../libfdt/fdt.c $(obj)fdt.c
+
+$(obj)fdt_ro.c:	libfdt_internal.h
+		@rm -f $(obj)fdt_ro.c
+		ln -s $(src)../libfdt/fdt_ro.c $(obj)fdt_ro.c
+
+$(obj)fdt_rw.c:	libfdt_internal.h
+		@rm -f $(obj)fdt_rw.c
+		ln -s $(src)../libfdt/fdt_rw.c $(obj)fdt_rw.c
+
+$(obj)fdt_strerror.c:	libfdt_internal.h
+		@rm -f $(obj)fdt_strerror.c
+		ln -s $(src)../libfdt/fdt_strerror.c $(obj)fdt_strerror.c
+
+$(obj)fdt_wip.c:	libfdt_internal.h
+		@rm -f $(obj)fdt_wip.c
+		ln -s $(src)../libfdt/fdt_wip.c $(obj)fdt_wip.c
+
+$(obj)libfdt_internal.h:
+		@rm -f $(obj)libfdt_internal.h
+		ln -s $(src)../libfdt/libfdt_internal.h $(obj)libfdt_internal.h
+
 $(LOGO_H):	$(obj)bmp_logo $(LOGO_BMP)
 $(LOGO_H):	$(obj)bmp_logo $(LOGO_BMP)
 		$(obj)./bmp_logo $(LOGO_BMP) >$@
 		$(obj)./bmp_logo $(LOGO_BMP) >$@
 
 

+ 28 - 0
tools/fdt_host.h

@@ -0,0 +1,28 @@
+/*
+ * (C) Copyright 2008 Semihalf
+ *
+ * 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
+ */
+
+#ifndef __FDT_HOST_H__
+#define __FDT_HOST_H__
+
+/* Make sure to include u-boot version of libfdt include files */
+#include "../include/fdt.h"
+#include "../include/libfdt.h"
+#include "../include/fdt_support.h"
+
+#endif /* __FDT_HOST_H__ */

+ 216 - 329
tools/mkimage.c

@@ -1,4 +1,6 @@
 /*
 /*
+ * (C) Copyright 2008 Semihalf
+ *
  * (C) Copyright 2000-2004
  * (C) Copyright 2000-2004
  * DENX Software Engineering
  * DENX Software Engineering
  * Wolfgang Denk, wd@denx.de
  * Wolfgang Denk, wd@denx.de
@@ -20,44 +22,7 @@
  * MA 02111-1307 USA
  * MA 02111-1307 USA
  */
  */
 
 
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifndef __WIN32__
-#include <netinet/in.h>		/* for host / network byte order conversions	*/
-#endif
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <unistd.h>
-
-#if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__)
-#include <inttypes.h>
-#endif
-
-#ifdef __WIN32__
-typedef unsigned int __u32;
-
-#define SWAP_LONG(x) \
-	((__u32)( \
-		(((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
-		(((__u32)(x) & (__u32)0x0000ff00UL) <<  8) | \
-		(((__u32)(x) & (__u32)0x00ff0000UL) >>  8) | \
-		(((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
-typedef		unsigned char	uint8_t;
-typedef		unsigned short	uint16_t;
-typedef		unsigned int	uint32_t;
-
-#define     ntohl(a)	SWAP_LONG(a)
-#define     htonl(a)	SWAP_LONG(a)
-#endif	/* __WIN32__ */
-
-#ifndef	O_BINARY		/* should be define'd on __WIN32__ */
-#define O_BINARY	0
-#endif
-
+#include "mkimage.h"
 #include <image.h>
 #include <image.h>
 
 
 extern int errno;
 extern int errno;
@@ -66,110 +31,27 @@ extern int errno;
 #define MAP_FAILED (-1)
 #define MAP_FAILED (-1)
 #endif
 #endif
 
 
-char *cmdname;
-
-extern unsigned long crc32 (unsigned long crc, const char *buf, unsigned int len);
-
-typedef struct table_entry {
-	int	val;		/* as defined in image.h	*/
-	char	*sname;		/* short (input) name		*/
-	char	*lname;		/* long (output) name		*/
-} table_entry_t;
-
-table_entry_t arch_name[] = {
-    {	IH_CPU_INVALID,		NULL,		"Invalid CPU",	},
-    {	IH_CPU_ALPHA,		"alpha",	"Alpha",	},
-    {	IH_CPU_ARM,		"arm",		"ARM",		},
-    {	IH_CPU_I386,		"x86",		"Intel x86",	},
-    {	IH_CPU_IA64,		"ia64",		"IA64",		},
-    {	IH_CPU_M68K,		"m68k",		"MC68000",	},
-    {	IH_CPU_MICROBLAZE,	"microblaze",	"MicroBlaze",	},
-    {	IH_CPU_MIPS,		"mips",		"MIPS",		},
-    {	IH_CPU_MIPS64,		"mips64",	"MIPS 64 Bit",	},
-    {	IH_CPU_NIOS,		"nios",		"NIOS",		},
-    {	IH_CPU_NIOS2,		"nios2",	"NIOS II",	},
-    {	IH_CPU_PPC,		"ppc",		"PowerPC",	},
-    {	IH_CPU_S390,		"s390",		"IBM S390",	},
-    {	IH_CPU_SH,		"sh",		"SuperH",	},
-    {	IH_CPU_SPARC,		"sparc",	"SPARC",	},
-    {	IH_CPU_SPARC64,		"sparc64",	"SPARC 64 Bit",	},
-    {	IH_CPU_BLACKFIN,	"blackfin",	"Blackfin",	},
-    {	IH_CPU_AVR32,		"avr32",	"AVR32",	},
-    {	-1,			"",		"",		},
-};
-
-table_entry_t os_name[] = {
-    {	IH_OS_INVALID,	NULL,		"Invalid OS",		},
-    {	IH_OS_4_4BSD,	"4_4bsd",	"4_4BSD",		},
-    {	IH_OS_ARTOS,	"artos",	"ARTOS",		},
-    {	IH_OS_DELL,	"dell",		"Dell",			},
-    {	IH_OS_ESIX,	"esix",		"Esix",			},
-    {	IH_OS_FREEBSD,	"freebsd",	"FreeBSD",		},
-    {	IH_OS_IRIX,	"irix",		"Irix",			},
-    {	IH_OS_LINUX,	"linux",	"Linux",		},
-    {	IH_OS_LYNXOS,	"lynxos",	"LynxOS",		},
-    {	IH_OS_NCR,	"ncr",		"NCR",			},
-    {	IH_OS_NETBSD,	"netbsd",	"NetBSD",		},
-    {	IH_OS_OPENBSD,	"openbsd",	"OpenBSD",		},
-    {	IH_OS_PSOS,	"psos",		"pSOS",			},
-    {	IH_OS_QNX,	"qnx",		"QNX",			},
-    {	IH_OS_RTEMS,	"rtems",	"RTEMS",		},
-    {	IH_OS_SCO,	"sco",		"SCO",			},
-    {	IH_OS_SOLARIS,	"solaris",	"Solaris",		},
-    {	IH_OS_SVR4,	"svr4",		"SVR4",			},
-    {	IH_OS_U_BOOT,	"u-boot",	"U-Boot",		},
-    {	IH_OS_VXWORKS,	"vxworks",	"VxWorks",		},
-    {	-1,		"",		"",			},
-};
-
-table_entry_t type_name[] = {
-    {	IH_TYPE_INVALID,    NULL,	  "Invalid Image",	},
-    {	IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image",	},
-    {	IH_TYPE_FIRMWARE,   "firmware",	  "Firmware",		},
-    {	IH_TYPE_KERNEL,	    "kernel",	  "Kernel Image",	},
-    {	IH_TYPE_MULTI,	    "multi",	  "Multi-File Image",	},
-    {	IH_TYPE_RAMDISK,    "ramdisk",	  "RAMDisk Image",	},
-    {	IH_TYPE_SCRIPT,     "script",	  "Script",		},
-    {	IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
-    {	IH_TYPE_FLATDT,     "flat_dt",    "Flat Device Tree",	},
-    {	-1,		    "",		  "",			},
-};
-
-table_entry_t comp_name[] = {
-    {	IH_COMP_NONE,	"none",		"uncompressed",		},
-    {	IH_COMP_BZIP2,	"bzip2",	"bzip2 compressed",	},
-    {	IH_COMP_GZIP,	"gzip",		"gzip compressed",	},
-    {	-1,		"",		"",			},
-};
-
-static	void	copy_file (int, const char *, int);
-static	void	usage	(void);
-static	void	print_header (image_header_t *);
-static	void	print_type (image_header_t *);
-static	char	*put_table_entry (table_entry_t *, char *, int);
-static	char	*put_arch (int);
-static	char	*put_type (int);
-static	char	*put_os   (int);
-static	char	*put_comp (int);
-static	int	get_table_entry (table_entry_t *, char *, char *);
-static	int	get_arch(char *);
-static	int	get_comp(char *);
-static	int	get_os  (char *);
-static	int	get_type(char *);
-
+extern	unsigned long	crc32 (unsigned long crc, const char *buf, unsigned int len);
+static	void		copy_file (int, const char *, int);
+static	void		usage (void);
+static	void		image_verify_header (char *, int);
+static	void		fit_handle_file (void);
 
 
 char	*datafile;
 char	*datafile;
 char	*imagefile;
 char	*imagefile;
+char	*cmdname;
 
 
 int dflag    = 0;
 int dflag    = 0;
 int eflag    = 0;
 int eflag    = 0;
+int fflag    = 0;
 int lflag    = 0;
 int lflag    = 0;
 int vflag    = 0;
 int vflag    = 0;
 int xflag    = 0;
 int xflag    = 0;
 int opt_os   = IH_OS_LINUX;
 int opt_os   = IH_OS_LINUX;
-int opt_arch = IH_CPU_PPC;
+int opt_arch = IH_ARCH_PPC;
 int opt_type = IH_TYPE_KERNEL;
 int opt_type = IH_TYPE_KERNEL;
 int opt_comp = IH_COMP_GZIP;
 int opt_comp = IH_COMP_GZIP;
+char *opt_dtc = MKIMAGE_DEFAULT_DTC_OPTIONS;
 
 
 image_header_t header;
 image_header_t header;
 image_header_t *hdr = &header;
 image_header_t *hdr = &header;
@@ -177,7 +59,7 @@ image_header_t *hdr = &header;
 int
 int
 main (int argc, char **argv)
 main (int argc, char **argv)
 {
 {
-	int ifd;
+	int ifd = -1;
 	uint32_t checksum;
 	uint32_t checksum;
 	uint32_t addr;
 	uint32_t addr;
 	uint32_t ep;
 	uint32_t ep;
@@ -197,22 +79,28 @@ main (int argc, char **argv)
 				break;
 				break;
 			case 'A':
 			case 'A':
 				if ((--argc <= 0) ||
 				if ((--argc <= 0) ||
-				    (opt_arch = get_arch(*++argv)) < 0)
+				    (opt_arch = genimg_get_arch_id (*++argv)) < 0)
 					usage ();
 					usage ();
 				goto NXTARG;
 				goto NXTARG;
 			case 'C':
 			case 'C':
 				if ((--argc <= 0) ||
 				if ((--argc <= 0) ||
-				    (opt_comp = get_comp(*++argv)) < 0)
+				    (opt_comp = genimg_get_comp_id (*++argv)) < 0)
+					usage ();
+				goto NXTARG;
+			case 'D':
+				if (--argc <= 0)
 					usage ();
 					usage ();
+				opt_dtc = *++argv;
 				goto NXTARG;
 				goto NXTARG;
+
 			case 'O':
 			case 'O':
 				if ((--argc <= 0) ||
 				if ((--argc <= 0) ||
-				    (opt_os = get_os(*++argv)) < 0)
+				    (opt_os = genimg_get_os_id (*++argv)) < 0)
 					usage ();
 					usage ();
 				goto NXTARG;
 				goto NXTARG;
 			case 'T':
 			case 'T':
 				if ((--argc <= 0) ||
 				if ((--argc <= 0) ||
-				    (opt_type = get_type(*++argv)) < 0)
+				    (opt_type = genimg_get_type_id (*++argv)) < 0)
 					usage ();
 					usage ();
 				goto NXTARG;
 				goto NXTARG;
 
 
@@ -245,6 +133,12 @@ main (int argc, char **argv)
 				}
 				}
 				eflag = 1;
 				eflag = 1;
 				goto NXTARG;
 				goto NXTARG;
+			case 'f':
+				if (--argc <= 0)
+					usage ();
+				datafile = *++argv;
+				fflag = 1;
+				goto NXTARG;
 			case 'n':
 			case 'n':
 				if (--argc <= 0)
 				if (--argc <= 0)
 					usage ();
 					usage ();
@@ -263,14 +157,17 @@ main (int argc, char **argv)
 NXTARG:		;
 NXTARG:		;
 	}
 	}
 
 
-	if ((argc != 1) || ((lflag ^ dflag) == 0))
+	if ((argc != 1) ||
+		(dflag && (fflag || lflag)) ||
+		(fflag && (dflag || lflag)) ||
+		(lflag && (dflag || fflag)))
 		usage();
 		usage();
 
 
 	if (!eflag) {
 	if (!eflag) {
 		ep = addr;
 		ep = addr;
 		/* If XIP, entry point must be after the U-Boot header */
 		/* If XIP, entry point must be after the U-Boot header */
 		if (xflag)
 		if (xflag)
-			ep += sizeof(image_header_t);
+			ep += image_get_header_size ();
 	}
 	}
 
 
 	/*
 	/*
@@ -278,32 +175,33 @@ NXTARG:		;
 	 * the size of the U-Boot header.
 	 * the size of the U-Boot header.
 	 */
 	 */
 	if (xflag) {
 	if (xflag) {
-		if (ep != addr + sizeof(image_header_t)) {
+		if (ep != addr + image_get_header_size ()) {
 			fprintf (stderr,
 			fprintf (stderr,
 				"%s: For XIP, the entry point must be the load addr + %lu\n",
 				"%s: For XIP, the entry point must be the load addr + %lu\n",
 				cmdname,
 				cmdname,
-				(unsigned long)sizeof(image_header_t));
+				(unsigned long)image_get_header_size ());
 			exit (EXIT_FAILURE);
 			exit (EXIT_FAILURE);
 		}
 		}
 	}
 	}
 
 
 	imagefile = *argv;
 	imagefile = *argv;
 
 
-	if (lflag) {
-		ifd = open(imagefile, O_RDONLY|O_BINARY);
-	} else {
-		ifd = open(imagefile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666);
-	}
+	if (!fflag){
+		if (lflag) {
+			ifd = open (imagefile, O_RDONLY|O_BINARY);
+		} else {
+			ifd = open (imagefile,
+				O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666);
+		}
 
 
-	if (ifd < 0) {
-		fprintf (stderr, "%s: Can't open %s: %s\n",
-			cmdname, imagefile, strerror(errno));
-		exit (EXIT_FAILURE);
+		if (ifd < 0) {
+			fprintf (stderr, "%s: Can't open %s: %s\n",
+				cmdname, imagefile, strerror(errno));
+			exit (EXIT_FAILURE);
+		}
 	}
 	}
 
 
 	if (lflag) {
 	if (lflag) {
-		int len;
-		char *data;
 		/*
 		/*
 		 * list header information of existing image
 		 * list header information of existing image
 		 */
 		 */
@@ -313,7 +211,7 @@ NXTARG:		;
 			exit (EXIT_FAILURE);
 			exit (EXIT_FAILURE);
 		}
 		}
 
 
-		if ((unsigned)sbuf.st_size < sizeof(image_header_t)) {
+		if ((unsigned)sbuf.st_size < image_get_header_size ()) {
 			fprintf (stderr,
 			fprintf (stderr,
 				"%s: Bad size: \"%s\" is no valid image\n",
 				"%s: Bad size: \"%s\" is no valid image\n",
 				cmdname, imagefile);
 				cmdname, imagefile);
@@ -328,49 +226,23 @@ NXTARG:		;
 			exit (EXIT_FAILURE);
 			exit (EXIT_FAILURE);
 		}
 		}
 
 
-		/*
-		 * create copy of header so that we can blank out the
-		 * checksum field for checking - this can't be done
-		 * on the PROT_READ mapped data.
-		 */
-		memcpy (hdr, ptr, sizeof(image_header_t));
-
-		if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-			fprintf (stderr,
-				"%s: Bad Magic Number: \"%s\" is no valid image\n",
-				cmdname, imagefile);
-			exit (EXIT_FAILURE);
-		}
-
-		data = (char *)hdr;
-		len  = sizeof(image_header_t);
-
-		checksum = ntohl(hdr->ih_hcrc);
-		hdr->ih_hcrc = htonl(0);	/* clear for re-calculation */
-
-		if (crc32 (0, data, len) != checksum) {
-			fprintf (stderr,
-				"%s: ERROR: \"%s\" has bad header checksum!\n",
-				cmdname, imagefile);
-			exit (EXIT_FAILURE);
+		if (fdt_check_header (ptr)) {
+			/* old-style image */
+			image_verify_header ((char *)ptr, sbuf.st_size);
+			image_print_contents_noindent ((image_header_t *)ptr);
+		} else {
+			/* FIT image */
+			fit_print_contents_noindent (ptr);
 		}
 		}
 
 
-		data = (char *)(ptr + sizeof(image_header_t));
-		len  = sbuf.st_size - sizeof(image_header_t) ;
-
-		if (crc32 (0, data, len) != ntohl(hdr->ih_dcrc)) {
-			fprintf (stderr,
-				"%s: ERROR: \"%s\" has corrupted data!\n",
-				cmdname, imagefile);
-			exit (EXIT_FAILURE);
-		}
-
-		/* for multi-file images we need the data part, too */
-		print_header ((image_header_t *)ptr);
-
 		(void) munmap((void *)ptr, sbuf.st_size);
 		(void) munmap((void *)ptr, sbuf.st_size);
 		(void) close (ifd);
 		(void) close (ifd);
 
 
+		exit (EXIT_SUCCESS);
+	} else if (fflag) {
+		/* Flattened Image Tree (FIT) format  handling */
+		debug ("FIT format handling\n");
+		fit_handle_file ();
 		exit (EXIT_SUCCESS);
 		exit (EXIT_SUCCESS);
 	}
 	}
 
 
@@ -379,9 +251,9 @@ NXTARG:		;
 	 *
 	 *
 	 * write dummy header, to be fixed later
 	 * write dummy header, to be fixed later
 	 */
 	 */
-	memset (hdr, 0, sizeof(image_header_t));
+	memset (hdr, 0, image_get_header_size ());
 
 
-	if (write(ifd, hdr, sizeof(image_header_t)) != sizeof(image_header_t)) {
+	if (write(ifd, hdr, image_get_header_size ()) != image_get_header_size ()) {
 		fprintf (stderr, "%s: Write error on %s: %s\n",
 		fprintf (stderr, "%s: Write error on %s: %s\n",
 			cmdname, imagefile, strerror(errno));
 			cmdname, imagefile, strerror(errno));
 		exit (EXIT_FAILURE);
 		exit (EXIT_FAILURE);
@@ -404,7 +276,7 @@ NXTARG:		;
 						cmdname, file, strerror(errno));
 						cmdname, file, strerror(errno));
 					exit (EXIT_FAILURE);
 					exit (EXIT_FAILURE);
 				}
 				}
-				size = htonl(sbuf.st_size);
+				size = cpu_to_uimage (sbuf.st_size);
 			} else {
 			} else {
 				size = 0;
 				size = 0;
 			}
 			}
@@ -469,29 +341,29 @@ NXTARG:		;
 	hdr = (image_header_t *)ptr;
 	hdr = (image_header_t *)ptr;
 
 
 	checksum = crc32 (0,
 	checksum = crc32 (0,
-			  (const char *)(ptr + sizeof(image_header_t)),
-			  sbuf.st_size - sizeof(image_header_t)
+			  (const char *)(ptr + image_get_header_size ()),
+			  sbuf.st_size - image_get_header_size ()
 			 );
 			 );
 
 
 	/* Build new header */
 	/* Build new header */
-	hdr->ih_magic = htonl(IH_MAGIC);
-	hdr->ih_time  = htonl(sbuf.st_mtime);
-	hdr->ih_size  = htonl(sbuf.st_size - sizeof(image_header_t));
-	hdr->ih_load  = htonl(addr);
-	hdr->ih_ep    = htonl(ep);
-	hdr->ih_dcrc  = htonl(checksum);
-	hdr->ih_os    = opt_os;
-	hdr->ih_arch  = opt_arch;
-	hdr->ih_type  = opt_type;
-	hdr->ih_comp  = opt_comp;
+	image_set_magic (hdr, IH_MAGIC);
+	image_set_time (hdr, sbuf.st_mtime);
+	image_set_size (hdr, sbuf.st_size - image_get_header_size ());
+	image_set_load (hdr, addr);
+	image_set_ep (hdr, ep);
+	image_set_dcrc (hdr, checksum);
+	image_set_os (hdr, opt_os);
+	image_set_arch (hdr, opt_arch);
+	image_set_type (hdr, opt_type);
+	image_set_comp (hdr, opt_comp);
 
 
-	strncpy((char *)hdr->ih_name, name, IH_NMLEN);
+	image_set_name (hdr, name);
 
 
-	checksum = crc32(0,(const char *)hdr,sizeof(image_header_t));
+	checksum = crc32 (0, (const char *)hdr, image_get_header_size ());
 
 
-	hdr->ih_hcrc = htonl(checksum);
+	image_set_hcrc (hdr, checksum);
 
 
-	print_header (hdr);
+	image_print_contents_noindent (hdr);
 
 
 	(void) munmap((void *)ptr, sbuf.st_size);
 	(void) munmap((void *)ptr, sbuf.st_size);
 
 
@@ -554,14 +426,14 @@ copy_file (int ifd, const char *datafile, int pad)
 		 * reserved for it.
 		 * reserved for it.
 		 */
 		 */
 
 
-		if ((unsigned)sbuf.st_size < sizeof(image_header_t)) {
+		if ((unsigned)sbuf.st_size < image_get_header_size ()) {
 			fprintf (stderr,
 			fprintf (stderr,
 				"%s: Bad size: \"%s\" is too small for XIP\n",
 				"%s: Bad size: \"%s\" is too small for XIP\n",
 				cmdname, datafile);
 				cmdname, datafile);
 			exit (EXIT_FAILURE);
 			exit (EXIT_FAILURE);
 		}
 		}
 
 
-		for (p=ptr; p < ptr+sizeof(image_header_t); p++) {
+		for (p = ptr; p < ptr + image_get_header_size (); p++) {
 			if ( *p != 0xff ) {
 			if ( *p != 0xff ) {
 				fprintf (stderr,
 				fprintf (stderr,
 					"%s: Bad file: \"%s\" has invalid buffer for XIP\n",
 					"%s: Bad file: \"%s\" has invalid buffer for XIP\n",
@@ -570,7 +442,7 @@ copy_file (int ifd, const char *datafile, int pad)
 			}
 			}
 		}
 		}
 
 
-		offset = sizeof(image_header_t);
+		offset = image_get_header_size ();
 	}
 	}
 
 
 	size = sbuf.st_size - offset;
 	size = sbuf.st_size - offset;
@@ -597,11 +469,11 @@ void
 usage ()
 usage ()
 {
 {
 	fprintf (stderr, "Usage: %s -l image\n"
 	fprintf (stderr, "Usage: %s -l image\n"
-			 "          -l ==> list image header information\n"
-			 "       %s [-x] -A arch -O os -T type -C comp "
-			 "-a addr -e ep -n name -d data_file[:data_file...] image\n",
-		cmdname, cmdname);
-	fprintf (stderr, "          -A ==> set architecture to 'arch'\n"
+			 "          -l ==> list image header information\n",
+		cmdname);
+	fprintf (stderr, "       %s [-x] -A arch -O os -T type -C comp "
+			 "-a addr -e ep -n name -d data_file[:data_file...] image\n"
+			 "          -A ==> set architecture to 'arch'\n"
 			 "          -O ==> set operating system to 'os'\n"
 			 "          -O ==> set operating system to 'os'\n"
 			 "          -T ==> set image type to 'type'\n"
 			 "          -T ==> set image type to 'type'\n"
 			 "          -C ==> set compression type 'comp'\n"
 			 "          -C ==> set compression type 'comp'\n"
@@ -609,143 +481,158 @@ usage ()
 			 "          -e ==> set entry point to 'ep' (hex)\n"
 			 "          -e ==> set entry point to 'ep' (hex)\n"
 			 "          -n ==> set image name to 'name'\n"
 			 "          -n ==> set image name to 'name'\n"
 			 "          -d ==> use image data from 'datafile'\n"
 			 "          -d ==> use image data from 'datafile'\n"
-			 "          -x ==> set XIP (execute in place)\n"
-		);
+			 "          -x ==> set XIP (execute in place)\n",
+		cmdname);
+	fprintf (stderr, "       %s [-D dtc_options] -f fit-image.its fit-image\n",
+		cmdname);
+
 	exit (EXIT_FAILURE);
 	exit (EXIT_FAILURE);
 }
 }
 
 
 static void
 static void
-print_header (image_header_t *hdr)
+image_verify_header (char *ptr, int image_size)
 {
 {
-	time_t timestamp;
-	uint32_t size;
-
-	timestamp = (time_t)ntohl(hdr->ih_time);
-	size = ntohl(hdr->ih_size);
-
-	printf ("Image Name:   %.*s\n", IH_NMLEN, hdr->ih_name);
-	printf ("Created:      %s", ctime(&timestamp));
-	printf ("Image Type:   "); print_type(hdr);
-	printf ("Data Size:    %d Bytes = %.2f kB = %.2f MB\n",
-		size, (double)size / 1.024e3, (double)size / 1.048576e6 );
-	printf ("Load Address: 0x%08X\n", ntohl(hdr->ih_load));
-	printf ("Entry Point:  0x%08X\n", ntohl(hdr->ih_ep));
-
-	if (hdr->ih_type == IH_TYPE_MULTI || hdr->ih_type == IH_TYPE_SCRIPT) {
-		int i, ptrs;
-		uint32_t pos;
-		uint32_t *len_ptr = (uint32_t *) (
-					(unsigned long)hdr + sizeof(image_header_t)
-				);
-
-		/* determine number of images first (to calculate image offsets) */
-		for (i=0; len_ptr[i]; ++i)	/* null pointer terminates list */
-			;
-		ptrs = i;		/* null pointer terminates list */
-
-		pos = sizeof(image_header_t) + ptrs * sizeof(long);
-		printf ("Contents:\n");
-		for (i=0; len_ptr[i]; ++i) {
-			size = ntohl(len_ptr[i]);
-
-			printf ("   Image %d: %8d Bytes = %4d kB = %d MB\n",
-				i, size, size>>10, size>>20);
-			if (hdr->ih_type == IH_TYPE_SCRIPT && i > 0) {
-				/*
-				 * the user may need to know offsets
-				 * if planning to do something with
-				 * multiple files
-				 */
-				printf ("    Offset = %08X\n", pos);
-			}
-			/* copy_file() will pad the first files to even word align */
-			size += 3;
-			size &= ~3;
-			pos += size;
-		}
-	}
-}
+	int len;
+	char *data;
+	uint32_t checksum;
+	image_header_t header;
+	image_header_t *hdr = &header;
 
 
+	/*
+	 * create copy of header so that we can blank out the
+	 * checksum field for checking - this can't be done
+	 * on the PROT_READ mapped data.
+	 */
+	memcpy (hdr, ptr, sizeof(image_header_t));
 
 
-static void
-print_type (image_header_t *hdr)
-{
-	printf ("%s %s %s (%s)\n",
-		put_arch (hdr->ih_arch),
-		put_os   (hdr->ih_os  ),
-		put_type (hdr->ih_type),
-		put_comp (hdr->ih_comp)
-	);
-}
+	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
+		fprintf (stderr,
+			"%s: Bad Magic Number: \"%s\" is no valid image\n",
+			cmdname, imagefile);
+		exit (EXIT_FAILURE);
+	}
 
 
-static char *put_arch (int arch)
-{
-	return (put_table_entry(arch_name, "Unknown Architecture", arch));
-}
+	data = (char *)hdr;
+	len  = sizeof(image_header_t);
 
 
-static char *put_os (int os)
-{
-	return (put_table_entry(os_name, "Unknown OS", os));
-}
+	checksum = ntohl(hdr->ih_hcrc);
+	hdr->ih_hcrc = htonl(0);	/* clear for re-calculation */
 
 
-static char *put_type (int type)
-{
-	return (put_table_entry(type_name, "Unknown Image", type));
-}
+	if (crc32 (0, data, len) != checksum) {
+		fprintf (stderr,
+			"%s: ERROR: \"%s\" has bad header checksum!\n",
+			cmdname, imagefile);
+		exit (EXIT_FAILURE);
+	}
 
 
-static char *put_comp (int comp)
-{
-	return (put_table_entry(comp_name, "Unknown Compression", comp));
-}
+	data = ptr + sizeof(image_header_t);
+	len  = image_size - sizeof(image_header_t) ;
 
 
-static char *put_table_entry (table_entry_t *table, char *msg, int type)
-{
-	for (; table->val>=0; ++table) {
-		if (table->val == type)
-			return (table->lname);
+	if (crc32 (0, data, len) != ntohl(hdr->ih_dcrc)) {
+		fprintf (stderr,
+			"%s: ERROR: \"%s\" has corrupted data!\n",
+			cmdname, imagefile);
+		exit (EXIT_FAILURE);
 	}
 	}
-	return (msg);
 }
 }
 
 
-static int get_arch(char *name)
+/**
+ * fit_handle_file - main FIT file processing function
+ *
+ * fit_handle_file() runs dtc to convert .its to .itb, includes
+ * binary data, updates timestamp property and calculates hashes.
+ *
+ * datafile  - .its file
+ * imagefile - .itb file
+ *
+ * returns:
+ *     only on success, otherwise calls exit (EXIT_FAILURE);
+ */
+static void fit_handle_file (void)
 {
 {
-	return (get_table_entry(arch_name, "CPU", name));
-}
+	char tmpfile[MKIMAGE_MAX_TMPFILE_LEN];
+	char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN];
+	int tfd;
+	struct stat sbuf;
+	unsigned char *ptr;
 
 
+	/* call dtc to include binary properties into the tmp file */
+	if (strlen (imagefile) + strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 >
+		sizeof (tmpfile)) {
+		fprintf (stderr, "%s: Image file name (%s) too long, "
+				"can't create tmpfile",
+				imagefile, cmdname);
+		exit (EXIT_FAILURE);
+	}
+	sprintf (tmpfile, "%s%s", imagefile, MKIMAGE_TMPFILE_SUFFIX);
+
+	/* dtc -I dts -O -p 200 datafile > tmpfile */
+	sprintf (cmd, "%s %s %s > %s",
+			MKIMAGE_DTC, opt_dtc, datafile, tmpfile);
+	debug ("Trying to execute \"%s\"\n", cmd);
+	if (system (cmd) == -1) {
+		fprintf (stderr, "%s: system(%s) failed: %s\n",
+				cmdname, cmd, strerror(errno));
+		unlink (tmpfile);
+		exit (EXIT_FAILURE);
+	}
 
 
-static int get_comp(char *name)
-{
-	return (get_table_entry(comp_name, "Compression", name));
-}
+	/* load FIT blob into memory */
+	tfd = open (tmpfile, O_RDWR|O_BINARY);
 
 
+	if (tfd < 0) {
+		fprintf (stderr, "%s: Can't open %s: %s\n",
+				cmdname, tmpfile, strerror(errno));
+		unlink (tmpfile);
+		exit (EXIT_FAILURE);
+	}
 
 
-static int get_os (char *name)
-{
-	return (get_table_entry(os_name, "OS", name));
-}
+	if (fstat (tfd, &sbuf) < 0) {
+		fprintf (stderr, "%s: Can't stat %s: %s\n",
+				cmdname, tmpfile, strerror(errno));
+		unlink (tmpfile);
+		exit (EXIT_FAILURE);
+	}
 
 
+	ptr = (unsigned char *)mmap (0, sbuf.st_size,
+			PROT_READ|PROT_WRITE, MAP_SHARED, tfd, 0);
+	if ((caddr_t)ptr == (caddr_t)-1) {
+		fprintf (stderr, "%s: Can't read %s: %s\n",
+				cmdname, tmpfile, strerror(errno));
+		unlink (tmpfile);
+		exit (EXIT_FAILURE);
+	}
 
 
-static int get_type(char *name)
-{
-	return (get_table_entry(type_name, "Image", name));
-}
+	/* check if ptr has a valid blob */
+	if (fdt_check_header (ptr)) {
+		fprintf (stderr, "%s: Invalid FIT blob\n", cmdname);
+		unlink (tmpfile);
+		exit (EXIT_FAILURE);
+	}
 
 
-static int get_table_entry (table_entry_t *table, char *msg, char *name)
-{
-	table_entry_t *t;
-	int first = 1;
+	/* set hashes for images in the blob */
+	if (fit_set_hashes (ptr)) {
+		fprintf (stderr, "%s Can't add hashes to FIT blob", cmdname);
+		unlink (tmpfile);
+		exit (EXIT_FAILURE);
+	}
 
 
-	for (t=table; t->val>=0; ++t) {
-		if (t->sname && strcasecmp(t->sname, name)==0)
-			return (t->val);
+	/* add a timestamp at offset 0 i.e., root  */
+	if (fit_set_timestamp (ptr, 0, sbuf.st_mtime)) {
+		fprintf (stderr, "%s: Can't add image timestamp\n", cmdname);
+		unlink (tmpfile);
+		exit (EXIT_FAILURE);
 	}
 	}
-	fprintf (stderr, "\nInvalid %s Type - valid names are", msg);
-	for (t=table; t->val>=0; ++t) {
-		if (t->sname == NULL)
-			continue;
-		fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname);
-		first = 0;
+	debug ("Added timestamp successfully\n");
+
+	munmap ((void *)ptr, sbuf.st_size);
+	close (tfd);
+
+	if (rename (tmpfile, imagefile) == -1) {
+		fprintf (stderr, "%s: Can't rename %s to %s: %s\n",
+				cmdname, tmpfile, imagefile, strerror (errno));
+		unlink (tmpfile);
+		unlink (imagefile);
+		exit (EXIT_FAILURE);
 	}
 	}
-	fprintf (stderr, "\n");
-	return (-1);
 }
 }

+ 75 - 0
tools/mkimage.h

@@ -0,0 +1,75 @@
+/*
+ * (C) Copyright 2000-2004
+ * DENX Software Engineering
+ * Wolfgang Denk, wd@denx.de
+ * All rights reserved.
+ *
+ * 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
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef __WIN32__
+#include <netinet/in.h>		/* for host / network byte order conversions	*/
+#endif
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+#include <sha1.h>
+#include "fdt_host.h"
+
+#define MKIMAGE_DEBUG
+
+#ifdef MKIMAGE_DEBUG
+#define debug(fmt,args...)	printf (fmt ,##args)
+#else
+#define debug(fmt,args...)
+#endif /* MKIMAGE_DEBUG */
+
+#define MKIMAGE_TMPFILE_SUFFIX		".tmp"
+#define MKIMAGE_MAX_TMPFILE_LEN		256
+#define MKIMAGE_DEFAULT_DTC_OPTIONS	"-I dts -O dtb -p 500"
+#define MKIMAGE_MAX_DTC_CMDLINE_LEN	512
+#define MKIMAGE_DTC			"dtc"   /* assume dtc is in $PATH */
+
+#if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__)
+#include <inttypes.h>
+#endif
+
+#ifdef __WIN32__
+typedef unsigned int __u32;
+
+#define SWAP_LONG(x) \
+	((__u32)( \
+		(((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
+		(((__u32)(x) & (__u32)0x0000ff00UL) <<  8) | \
+		(((__u32)(x) & (__u32)0x00ff0000UL) >>  8) | \
+		(((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
+typedef		unsigned char	uint8_t;
+typedef		unsigned short	uint16_t;
+typedef		unsigned int	uint32_t;
+
+#define     ntohl(a)	SWAP_LONG(a)
+#define     htonl(a)	SWAP_LONG(a)
+#endif	/* __WIN32__ */
+
+#ifndef	O_BINARY		/* should be define'd on __WIN32__ */
+#define O_BINARY	0
+#endif

Some files were not shown because too many files changed in this diff