[new uImage] Add gen_get_image() routine
authorMarian Balakowicz <m8@semihalf.com>
Thu, 21 Feb 2008 16:20:19 +0000 (17:20 +0100)
committerMarian Balakowicz <m8@semihalf.com>
Thu, 21 Feb 2008 16:20:19 +0000 (17:20 +0100)
This routine assures that image (whether legacy or FIT) is not
in a special dataflash storage.

If image address is a dataflash address image is moved to system RAM.

Signed-off-by: Marian Balakowicz <m8@semihalf.com>
common/cmd_bootm.c
common/image.c
include/image.h
lib_ppc/bootm.c

index 2ddb191033c4a16198d5b27a737c958bee988f74..ebb6b69f4d11c84e8af56959eeacd80a55addb78 100644 (file)
 #include <hush.h>
 #endif
 
-#ifdef CONFIG_HAS_DATAFLASH
-#include <dataflash.h>
-#endif
-
 DECLARE_GLOBAL_DATA_PTR;
 
 extern int gunzip (void *dst, int dstlen, unsigned char *src, unsigned long *lenp);
@@ -304,12 +300,8 @@ static image_header_t *get_kernel (cmd_tbl_t *cmdtp, int flag,
        show_boot_progress (1);
        printf ("## Booting image at %08lx ...\n", img_addr);
 
-#ifdef CONFIG_HAS_DATAFLASH
-       if (addr_dataflash (img_addr)){
-               hdr = (image_header_t *)CFG_LOAD_ADDR;
-               read_dataflash (img_addr, image_get_header_size (), (char *)hdr);
-       } else
-#endif
+       /* copy from dataflash if needed */
+       img_addr = gen_get_image (img_addr);
        hdr = (image_header_t *)img_addr;
 
        if (!image_check_magic(hdr)) {
@@ -324,16 +316,8 @@ static image_header_t *get_kernel (cmd_tbl_t *cmdtp, int flag,
                show_boot_progress (-2);
                return NULL;
        }
-       show_boot_progress (3);
 
-#ifdef CONFIG_HAS_DATAFLASH
-       if (addr_dataflash (img_addr))
-               read_dataflash (img_addr + image_get_header_size (),
-                               image_get_data_size (hdr),
-                               (char *)image_get_data (hdr));
-#endif
-
-       /* uImage is in a system RAM, pointed to by hdr */
+       show_boot_progress (3);
        print_image_hdr (hdr);
 
        if (verify) {
index 39e5f23c51b858214cff025b90b699dda4de4aa9..ab6b8e65a9eaf875a11007b14dc6ead8fa9c5b47 100644 (file)
 #include <logbuff.h>
 #endif
 
+#if defined(CONFIG_FIT)
+#include <fdt.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#endif
+
 extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
 #ifdef CONFIG_CMD_BDI
@@ -304,6 +310,103 @@ const char* image_get_comp_name (uint8_t comp)
        return name;
 }
 
+/**
+ * gen_image_get_format - get image format type
+ * @img_addr: image start address
+ *
+ * gen_image_get_format() checks whether provided address points to a valid
+ * legacy or FIT image.
+ *
+ * returns:
+ *     image format type or IMAGE_FORMAT_INVALID if no image is present
+ */
+int gen_image_get_format (void *img_addr)
+{
+       ulong           format = IMAGE_FORMAT_INVALID;
+       image_header_t  *hdr;
+#if defined(CONFIG_FIT)
+       char            *fit_hdr;
+#endif
+
+       hdr = (image_header_t *)img_addr;
+       if (image_check_magic(hdr))
+               format = IMAGE_FORMAT_LEGACY;
+#if defined(CONFIG_FIT)
+       else {
+               fit_hdr = (char *)img_addr;
+               if (fdt_check_header (fit_hdr) == 0)
+                       format = IMAGE_FORMAT_FIT;
+       }
+#endif
+
+       return format;
+}
+
+/**
+ * gen_get_image - get image from special storage (if necessary)
+ * @img_addr: image start address
+ *
+ * gen_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 gen_get_image (ulong img_addr)
+{
+       ulong ram_addr, h_size, d_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
+
+#ifdef CONFIG_HAS_DATAFLASH
+       if (addr_dataflash (img_addr)){
+               ram_addr = CFG_LOAD_ADDR;
+               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);
+       } else
+#endif
+               return img_addr;
+
+       ram_addr = img_addr;
+
+       switch (gen_image_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 = fdt_totalsize((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;
+       }
+
+#ifdef CONFIG_HAS_DATAFLASH
+       if (addr_dataflash (img_addr)) {
+               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
+
+       return ram_addr;
+}
+
 /**
  * image_get_ramdisk - get and verify ramdisk image
  * @cmdtp: command table pointer
@@ -334,15 +437,8 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag,
 
        show_boot_progress (9);
 
-#ifdef CONFIG_HAS_DATAFLASH
-       if (addr_dataflash (rd_addr)) {
-               rd_hdr = (image_header_t *)CFG_LOAD_ADDR;
-               debug ("   Reading Ramdisk image header from dataflash address "
-                       "%08lx to %08lx\n", rd_addr, (ulong)rd_hdr);
-               read_dataflash (rd_addr, image_get_header_size (),
-                               (char *)rd_hdr);
-       } else
-#endif
+       /* copy from dataflash if needed */
+       rd_addr = gen_get_image (rd_addr);
        rd_hdr = (image_header_t *)rd_addr;
 
        if (!image_check_magic (rd_hdr)) {
@@ -360,18 +456,6 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag,
        show_boot_progress (10);
        print_image_hdr (rd_hdr);
 
-#ifdef CONFIG_HAS_DATAFLASH
-       if (addr_dataflash (rd_addr)) {
-               debug ("   Reading Ramdisk image data from dataflash address "
-                       "%08lx to %08lx\n", rd_addr + image_get_header_size,
-                       (ulong)image_get_data (rd_hdr));
-
-               read_dataflash (rd_addr + image_get_header_size (),
-                               image_get_data_size (rd_hdr),
-                               (char *)image_get_data (rd_hdr));
-       }
-#endif
-
        if (verify) {
                puts("   Verifying Checksum ... ");
                if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) {
index ecfce7215d21f9d6c39305ef33acff58a2683650..b4de49d6ba006828025ab934db26c0ada3f2b722 100644 (file)
@@ -343,6 +343,12 @@ const char* image_get_arch_name (uint8_t arch);
 const char* image_get_type_name (uint8_t type);
 const char* image_get_comp_name (uint8_t comp);
 
+#define IMAGE_FORMAT_INVALID   0x00
+#define IMAGE_FORMAT_LEGACY    0x01
+#define IMAGE_FORMAT_FIT       0x02
+int gen_image_get_format (void *img_addr);
+ulong gen_get_image (ulong img_addr);
+
 image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag,
                int argc, char *argv[],
                ulong rd_addr, uint8_t arch, int verify);
index 69ec459105cf1d12218cac60c3101713b781c53d..04a9665a9ac053f34cc697baf6239cc81493901a 100644 (file)
@@ -234,6 +234,11 @@ static ulong get_fdt (ulong alloc_current,
 
        if(argc > 3) {
                fdt = (char *)simple_strtoul (argv[3], NULL, 16);
+
+               debug ("## Checking for 'FDT'/'FDT image' at %08lx\n", fdt);
+
+               /* copy from dataflash if needed */
+               fdt = (char *)gen_get_image ((ulong)fdt);
                fdt_hdr = (image_header_t *)fdt;
 
                if (fdt_check_header (fdt) == 0) {