]> git.sur5r.net Git - u-boot/blobdiff - common/cmd_bootm.c
[new uImage] Rename and move print_image_hdr() routine
[u-boot] / common / cmd_bootm.c
index 2d17bdd4f9514f103ba7cd1b07b762270dedfb5b..bb60a840ecf83f75bc44a37f6b73f9fc48e33a64 100644 (file)
 #include <environment.h>
 #include <asm/byteorder.h>
 
-#if defined(CONFIG_OF_LIBFDT)
-#include <fdt.h>
-#include <libfdt.h>
-#include <fdt_support.h>
-#elif defined(CONFIG_OF_FLAT_TREE)
-#include <ft_build.h>
-#endif
-
-#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE)
-#include <rtc.h>
-#endif
-
 #ifdef CFG_HUSH_PARSER
 #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);
@@ -81,7 +65,9 @@ static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 static void fixup_silent_linux (void);
 #endif
 
-static void print_type (image_header_t *hdr);
+static image_header_t *get_kernel (cmd_tbl_t *cmdtp, int flag,
+               int argc, char *argv[], int verify,
+               ulong *os_data, ulong *os_len);
 extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
 /*
@@ -124,96 +110,22 @@ ulong load_addr = CFG_LOAD_ADDR;  /* Default Load Address */
 int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
        ulong           iflag;
-       char            *name, *s;
-       int             (*appl)(int, char *[]);
+       const char      *type_name;
        uint            unc_len = CFG_BOOTM_LEN;
        int             verify = getenv_verify();
 
        image_header_t  *hdr;
-       ulong           img_addr;
        ulong           os_data, os_len;
 
-       if (argc < 2) {
-               img_addr = load_addr;
-       } else {
-               img_addr = simple_strtoul(argv[1], NULL, 16);
-       }
-
-       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
-       hdr = (image_header_t *)img_addr;
-
-       if (!image_check_magic(hdr)) {
-               puts ("Bad Magic Number\n");
-               show_boot_progress (-1);
-               return 1;
-       }
-       show_boot_progress (2);
-
-       if (!image_check_hcrc (hdr)) {
-               puts ("Bad Header Checksum\n");
-               show_boot_progress (-2);
-               return 1;
-       }
-       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 */
-       print_image_hdr (hdr);
-
-       if (verify) {
-               puts ("   Verifying Checksum ... ");
-               if (!image_check_dcrc (hdr)) {
-                       printf ("Bad Data CRC\n");
-                       show_boot_progress (-3);
-                       return 1;
-               }
-               puts ("OK\n");
-       }
-       show_boot_progress (4);
+       ulong           image_start, image_end;
+       ulong           load_start, load_end;
 
-       if (!image_check_target_arch (hdr)) {
-               printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr));
-               show_boot_progress (-4);
+       /* get kernel image header, start address and length */
+       hdr = get_kernel (cmdtp, flag, argc, argv, verify,
+                       &os_data, &os_len);
+       if (hdr == NULL)
                return 1;
-       }
-       show_boot_progress (5);
 
-       switch (image_get_type (hdr)) {
-       case IH_TYPE_STANDALONE:
-               name = "Standalone Application";
-               /* A second argument overwrites the load address */
-               if (argc > 2) {
-                       image_set_load (hdr, simple_strtoul (argv[2], NULL, 16));
-               }
-               break;
-       case IH_TYPE_KERNEL:
-               name = "Kernel Image";
-               os_data = image_get_data (hdr);
-               os_len = image_get_data_size (hdr);
-               break;
-       case IH_TYPE_MULTI:
-               name = "Multi-File Image";
-               image_multi_getimg (hdr, 0, &os_data, &os_len);
-               break;
-       default:
-               printf ("Wrong Image Type for %s command\n", cmdtp->name);
-               show_boot_progress (-5);
-               return 1;
-       }
        show_boot_progress (6);
 
        /*
@@ -234,31 +146,41 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        dcache_disable();
 #endif
 
+       type_name = image_get_type_name (image_get_type (hdr));
+
+       image_start = (ulong)hdr;
+       image_end = image_get_image_end (hdr);
+       load_start = image_get_load (hdr);
+       load_end = 0;
+
        switch (image_get_comp (hdr)) {
        case IH_COMP_NONE:
-               if (image_get_load (hdr) == img_addr) {
-                       printf ("   XIP %s ... ", name);
+               if (image_get_load (hdr) == (ulong)hdr) {
+                       printf ("   XIP %s ... ", type_name);
                } else {
-                       printf ("   Loading %s ... ", name);
+                       printf ("   Loading %s ... ", type_name);
 
                        memmove_wd ((void *)image_get_load (hdr),
                                   (void *)os_data, os_len, CHUNKSZ);
 
+                       load_end = load_start + os_len;
                        puts("OK\n");
                }
                break;
        case IH_COMP_GZIP:
-               printf ("   Uncompressing %s ... ", name);
+               printf ("   Uncompressing %s ... ", type_name);
                if (gunzip ((void *)image_get_load (hdr), unc_len,
                                        (uchar *)os_data, &os_len) != 0) {
                        puts ("GUNZIP ERROR - must RESET board to recover\n");
                        show_boot_progress (-6);
                        do_reset (cmdtp, flag, argc, argv);
                }
+
+               load_end = load_start + os_len;
                break;
 #ifdef CONFIG_BZIP2
        case IH_COMP_BZIP2:
-               printf ("   Uncompressing %s ... ", name);
+               printf ("   Uncompressing %s ... ", type_name);
                /*
                 * If we've got less than 4 MB of malloc() space,
                 * use slower decompression algorithm which requires
@@ -272,6 +194,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                        show_boot_progress (-6);
                        do_reset (cmdtp, flag, argc, argv);
                }
+
+               load_end = load_start + unc_len;
                break;
 #endif /* CONFIG_BZIP2 */
        default:
@@ -282,36 +206,17 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                return 1;
        }
        puts ("OK\n");
+       debug ("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load_start, load_end);
        show_boot_progress (7);
 
-       switch (image_get_type (hdr)) {
-       case IH_TYPE_STANDALONE:
-               if (iflag)
-                       enable_interrupts();
+       if ((load_start < image_end) && (load_end > image_start)) {
+               debug ("image_start = 0x%lX, image_end = 0x%lx\n", image_start, image_end);
+               debug ("load_start = 0x%lx, load_end = 0x%lx\n", load_start, load_end);
 
-               /* load (and uncompress), but don't start if "autostart"
-                * is set to "no"
-                */
-               if (((s = getenv("autostart")) != NULL) && (strcmp(s,"no") == 0)) {
-                       char buf[32];
-                       sprintf(buf, "%lX", image_get_data_size(hdr));
-                       setenv("filesize", buf);
-                       return 0;
-               }
-               appl = (int (*)(int, char *[]))image_get_ep (hdr);
-               (*appl)(argc-1, &argv[1]);
-               return 0;
-       case IH_TYPE_KERNEL:
-       case IH_TYPE_MULTI:
-               /* handled below */
-               break;
-       default:
-               if (iflag)
-                       enable_interrupts();
-               printf ("Can't boot image type %d\n", image_get_type (hdr));
-               show_boot_progress (-8);
-               return 1;
+               puts ("ERROR: image overwritten - must RESET the board to recover.\n");
+               do_reset (cmdtp, flag, argc, argv);
        }
+
        show_boot_progress (8);
 
        switch (image_get_os (hdr)) {
@@ -362,13 +267,98 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        return 1;
 }
 
+/**
+ * get_kernel - find kernel image
+ * @os_data: pointer to a ulong variable, will hold os data start address
+ * @os_len: pointer to a ulong variable, will hold os data length
+ *
+ * get_kernel() tries to find a kernel image, verifies its integrity
+ * and locates kernel data.
+ *
+ * returns:
+ *     pointer to image header if valid image was found, plus kernel start
+ *     address and length, otherwise NULL
+ */
+static image_header_t *get_kernel (cmd_tbl_t *cmdtp, int flag,
+               int argc, char *argv[], int verify,
+               ulong *os_data, ulong *os_len)
+{
+       image_header_t  *hdr;
+       ulong           img_addr;
+
+       if (argc < 2) {
+               img_addr = load_addr;
+       } else {
+               img_addr = simple_strtoul(argv[1], NULL, 16);
+       }
+
+       show_boot_progress (1);
+       printf ("## Booting image at %08lx ...\n", img_addr);
+
+       /* copy from dataflash if needed */
+       img_addr = gen_get_image (img_addr);
+       hdr = (image_header_t *)img_addr;
+
+       if (!image_check_magic(hdr)) {
+               puts ("Bad Magic Number\n");
+               show_boot_progress (-1);
+               return NULL;
+       }
+       show_boot_progress (2);
+
+       if (!image_check_hcrc (hdr)) {
+               puts ("Bad Header Checksum\n");
+               show_boot_progress (-2);
+               return NULL;
+       }
+
+       show_boot_progress (3);
+       image_print_contents (hdr);
+
+       if (verify) {
+               puts ("   Verifying Checksum ... ");
+               if (!image_check_dcrc (hdr)) {
+                       printf ("Bad Data CRC\n");
+                       show_boot_progress (-3);
+                       return NULL;
+               }
+               puts ("OK\n");
+       }
+       show_boot_progress (4);
+
+       if (!image_check_target_arch (hdr)) {
+               printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr));
+               show_boot_progress (-4);
+               return NULL;
+       }
+       show_boot_progress (5);
+
+       switch (image_get_type (hdr)) {
+       case IH_TYPE_KERNEL:
+               *os_data = image_get_data (hdr);
+               *os_len = image_get_data_size (hdr);
+               break;
+       case IH_TYPE_MULTI:
+               image_multi_getimg (hdr, 0, os_data, os_len);
+               break;
+       default:
+               printf ("Wrong Image Type for %s command\n", cmdtp->name);
+               show_boot_progress (-5);
+               return NULL;
+       }
+       debug ("   kernel data at 0x%08lx, end = 0x%08lx\n",
+                       *os_data, *os_data + *os_len);
+
+       return hdr;
+}
+
 U_BOOT_CMD(
        bootm,  CFG_MAXARGS,    1,      do_bootm,
        "bootm   - boot application image from memory\n",
        "[addr [arg ...]]\n    - boot application image stored in memory\n"
        "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
        "\t'arg' can be the address of an initrd image\n"
-#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
+#if defined(CONFIG_OF_LIBFDT)
        "\tWhen booting a Linux kernel which requires a flat device-tree\n"
        "\ta third argument is required which is the address of the\n"
        "\tdevice-tree blob. To boot that kernel without an initrd image,\n"
@@ -450,7 +440,7 @@ static int image_info (ulong addr)
                return 1;
        }
 
-       print_image_hdr (hdr);
+       image_print_contents (hdr);
 
        puts ("   Verifying Checksum ... ");
        if (!image_check_dcrc (hdr)) {
@@ -498,7 +488,7 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                                goto next_sector;
 
                        printf ("Image at %08lX:\n", (ulong)hdr);
-                       print_image_hdr (hdr);
+                       image_print_contents (hdr);
 
                        puts ("   Verifying Checksum ... ");
                        if (!image_check_dcrc (hdr)) {
@@ -524,111 +514,8 @@ U_BOOT_CMD(
 #endif
 
 /*******************************************************************/
-/* */
+/* helper routines */
 /*******************************************************************/
-void print_image_hdr (image_header_t *hdr)
-{
-#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE)
-       time_t timestamp = (time_t)image_get_time (hdr);
-       struct rtc_time tm;
-#endif
-
-       printf ("   Image Name:   %.*s\n", IH_NMLEN, image_get_name (hdr));
-
-#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE)
-       to_tm (timestamp, &tm);
-       printf ("   Created:      %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);
-#endif
-       puts ("   Image Type:   ");
-       print_type (hdr);
-
-       printf ("\n   Data Size:    %d Bytes = ", image_get_data_size (hdr));
-       print_size (image_get_data_size (hdr), "\n");
-       printf ("   Load Address: %08x\n"
-               "   Entry Point:  %08x\n",
-                image_get_load (hdr), image_get_ep (hdr));
-
-       if (image_check_type (hdr, IH_TYPE_MULTI)) {
-               int i;
-               ulong data, len;
-               ulong count = image_multi_count (hdr);
-
-               puts ("   Contents:\n");
-               for (i = 0; i < count; i++) {
-                       image_multi_getimg (hdr, i, &data, &len);
-                       printf ("   Image %d: %8ld Bytes = ", i, len);
-                       print_size (len, "\n");
-               }
-       }
-}
-
-static void print_type (image_header_t *hdr)
-{
-       char *os, *arch, *type, *comp;
-
-       switch (image_get_os (hdr)) {
-       case IH_OS_INVALID:     os = "Invalid OS";              break;
-       case IH_OS_NETBSD:      os = "NetBSD";                  break;
-       case IH_OS_LINUX:       os = "Linux";                   break;
-       case IH_OS_VXWORKS:     os = "VxWorks";                 break;
-       case IH_OS_QNX:         os = "QNX";                     break;
-       case IH_OS_U_BOOT:      os = "U-Boot";                  break;
-       case IH_OS_RTEMS:       os = "RTEMS";                   break;
-#ifdef CONFIG_ARTOS
-       case IH_OS_ARTOS:       os = "ARTOS";                   break;
-#endif
-#ifdef CONFIG_LYNXKDI
-       case IH_OS_LYNXOS:      os = "LynxOS";                  break;
-#endif
-       default:                os = "Unknown OS";              break;
-       }
-
-       switch (image_get_arch (hdr)) {
-       case IH_ARCH_INVALID:   arch = "Invalid CPU";           break;
-       case IH_ARCH_ALPHA:     arch = "Alpha";                 break;
-       case IH_ARCH_ARM:       arch = "ARM";                   break;
-       case IH_ARCH_AVR32:     arch = "AVR32";                 break;
-       case IH_ARCH_BLACKFIN:  arch = "Blackfin";              break;
-       case IH_ARCH_I386:      arch = "Intel x86";             break;
-       case IH_ARCH_IA64:      arch = "IA64";                  break;
-       case IH_ARCH_M68K:      arch = "M68K";                  break;
-       case IH_ARCH_MICROBLAZE:arch = "Microblaze";            break;
-       case IH_ARCH_MIPS64:    arch = "MIPS 64 Bit";           break;
-       case IH_ARCH_MIPS:      arch = "MIPS";                  break;
-       case IH_ARCH_NIOS2:     arch = "Nios-II";               break;
-       case IH_ARCH_NIOS:      arch = "Nios";                  break;
-       case IH_ARCH_PPC:       arch = "PowerPC";               break;
-       case IH_ARCH_S390:      arch = "IBM S390";              break;
-       case IH_ARCH_SH:        arch = "SuperH";                break;
-       case IH_ARCH_SPARC64:   arch = "SPARC 64 Bit";          break;
-       case IH_ARCH_SPARC:     arch = "SPARC";                 break;
-       default:                arch = "Unknown Architecture";  break;
-       }
-
-       switch (image_get_type (hdr)) {
-       case IH_TYPE_INVALID:   type = "Invalid Image";         break;
-       case IH_TYPE_STANDALONE:type = "Standalone Program";    break;
-       case IH_TYPE_KERNEL:    type = "Kernel Image";          break;
-       case IH_TYPE_RAMDISK:   type = "RAMDisk Image";         break;
-       case IH_TYPE_MULTI:     type = "Multi-File Image";      break;
-       case IH_TYPE_FIRMWARE:  type = "Firmware";              break;
-       case IH_TYPE_SCRIPT:    type = "Script";                break;
-       case IH_TYPE_FLATDT:    type = "Flat Device Tree";      break;
-       default:                type = "Unknown Image";         break;
-       }
-
-       switch (image_get_comp (hdr)) {
-       case IH_COMP_NONE:      comp = "uncompressed";          break;
-       case IH_COMP_GZIP:      comp = "gzip compressed";       break;
-       case IH_COMP_BZIP2:     comp = "bzip2 compressed";      break;
-       default:                comp = "unknown compression";   break;
-       }
-
-       printf ("%s %s %s (%s)", arch, os, type, comp);
-}
-
 #ifdef CONFIG_SILENT_CONSOLE
 static void fixup_silent_linux ()
 {