X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=common%2Fcmd_bootm.c;h=ab6ccbb07cb257e2dbd366ccb8ad1686752dc823;hb=87cb6862b94e342d6c99467e0dbb0d4f625cc7ef;hp=489fa6146132f7bc4470781fa406e09e55ee1d7b;hpb=8564acf936726c5568d71e4fa93a0ae9814e0d07;p=u-boot diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 489fa61461..ab6ccbb07c 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -72,7 +73,7 @@ # define CHUNKSZ (64 * 1024) #endif -int gunzip (void *, int, unsigned char *, int *); +int gunzip (void *, int, unsigned char *, unsigned long *); static void *zalloc(void *, unsigned, unsigned); static void zfree(void *, void *, unsigned); @@ -80,6 +81,13 @@ static void zfree(void *, void *, unsigned); #if (CONFIG_COMMANDS & CFG_CMD_IMI) static int image_info (unsigned long addr); #endif + +#if (CONFIG_COMMANDS & CFG_CMD_IMLS) +#include +extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ +static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +#endif + static void print_type (image_header_t *hdr); #ifdef __I386__ @@ -109,6 +117,9 @@ static boot_os_Fcn do_bootm_linux; #else extern boot_os_Fcn do_bootm_linux; #endif +#ifdef CONFIG_SILENT_CONSOLE +static void fixup_silent_linux (void); +#endif static boot_os_Fcn do_bootm_netbsd; static boot_os_Fcn do_bootm_rtems; #if (CONFIG_COMMANDS & CFG_CMD_ELF) @@ -120,6 +131,10 @@ int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] ); #if defined(CONFIG_ARTOS) && defined(CONFIG_PPC) static boot_os_Fcn do_bootm_artos; #endif +#ifdef CONFIG_LYNXKDI +static boot_os_Fcn do_bootm_lynxkdi; +extern void lynxkdi_boot( image_header_t * ); +#endif image_header_t header; @@ -131,9 +146,10 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong addr; ulong data, len, checksum; ulong *len_ptr; + uint unc_len = 0x400000; int i, verify; char *name, *s; - int (*appl)(cmd_tbl_t *, int, int, char *[]); + int (*appl)(int, char *[]); image_header_t *hdr = &header; s = getenv ("verify"); @@ -168,7 +184,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } else #endif /* __I386__ */ { - printf ("Bad Magic Number\n"); + puts ("Bad Magic Number\n"); SHOW_BOOT_PROGRESS (-1); return 1; } @@ -182,33 +198,35 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) hdr->ih_hcrc = 0; if (crc32 (0, (char *)data, len) != checksum) { - printf ("Bad Header Checksum\n"); + puts ("Bad Header Checksum\n"); SHOW_BOOT_PROGRESS (-2); return 1; } SHOW_BOOT_PROGRESS (3); - /* for multi-file images we need the data part, too */ - 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; + len = ntohl(hdr->ih_size) + sizeof(image_header_t); + read_dataflash(addr, len, (char *)CFG_LOAD_ADDR); + addr = CFG_LOAD_ADDR; } #endif + + /* for multi-file images we need the data part, too */ + print_image_hdr ((image_header_t *)addr); + + data = addr + sizeof(image_header_t); + len = ntohl(hdr->ih_size); + if (verify) { - printf (" Verifying Checksum ... "); + puts (" Verifying Checksum ... "); if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) { printf ("Bad Data CRC\n"); SHOW_BOOT_PROGRESS (-3); return 1; } - printf ("OK\n"); + puts ("OK\n"); } SHOW_BOOT_PROGRESS (4); @@ -222,6 +240,14 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (hdr->ih_arch != IH_CPU_I386) #elif defined(__mips__) if (hdr->ih_arch != IH_CPU_MIPS) +#elif defined(__nios__) + if (hdr->ih_arch != IH_CPU_NIOS) +#elif defined(__M68K__) + if (hdr->ih_arch != IH_CPU_M68K) +#elif defined(__microblaze__) + if (hdr->ih_arch != IH_CPU_MICROBLAZE) +#elif defined(__nios2__) + if (hdr->ih_arch != IH_CPU_NIOS2) #else # error Unknown CPU type #endif @@ -233,17 +259,24 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) SHOW_BOOT_PROGRESS (5); switch (hdr->ih_type) { - case IH_TYPE_STANDALONE: name = "Standalone Application"; - break; - case IH_TYPE_KERNEL: name = "Kernel Image"; - break; - case IH_TYPE_MULTI: name = "Multi-File Image"; - len = ntohl(len_ptr[0]); - /* OS kernel is always the first image */ - data += 8; /* kernel_len + terminator */ - for (i=1; len_ptr[i]; ++i) - data += 4; - break; + case IH_TYPE_STANDALONE: + name = "Standalone Application"; + /* A second argument overwrites the load address */ + if (argc > 2) { + hdr->ih_load = htonl(simple_strtoul(argv[2], NULL, 16)); + } + break; + case IH_TYPE_KERNEL: + name = "Kernel Image"; + break; + case IH_TYPE_MULTI: + name = "Multi-File Image"; + len = ntohl(len_ptr[0]); + /* OS kernel is always the first image */ + data += 8; /* kernel_len + terminator */ + for (i=1; len_ptr[i]; ++i) + data += 4; + break; default: printf ("Wrong Image Type for %s command\n", cmdtp->name); SHOW_BOOT_PROGRESS (-5); return 1; @@ -296,13 +329,32 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; case IH_COMP_GZIP: printf (" Uncompressing %s ... ", name); - if (gunzip ((void *)ntohl(hdr->ih_load), 0x400000, - (uchar *)data, (int *)&len) != 0) { - printf ("GUNZIP ERROR - must RESET board to recover\n"); + if (gunzip ((void *)ntohl(hdr->ih_load), unc_len, + (uchar *)data, &len) != 0) { + puts ("GUNZIP ERROR - must RESET board to recover\n"); + SHOW_BOOT_PROGRESS (-6); + do_reset (cmdtp, flag, argc, argv); + } + break; +#ifdef CONFIG_BZIP2 + case IH_COMP_BZIP2: + printf (" Uncompressing %s ... ", name); + /* + * If we've got less than 4 MB of malloc() space, + * use slower decompression algorithm which requires + * at most 2300 KB of memory. + */ + i = BZ2_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load), + &unc_len, (char *)data, len, + CFG_MALLOC_LEN < (4096 * 1024), 0); + if (i != BZ_OK) { + printf ("BUNZIP2 ERROR %d - must RESET board to recover\n", i); SHOW_BOOT_PROGRESS (-6); + udelay(100000); do_reset (cmdtp, flag, argc, argv); } break; +#endif /* CONFIG_BZIP2 */ default: if (iflag) enable_interrupts(); @@ -310,7 +362,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) SHOW_BOOT_PROGRESS (-7); return 1; } - printf ("OK\n"); + puts ("OK\n"); SHOW_BOOT_PROGRESS (7); switch (hdr->ih_type) { @@ -321,10 +373,14 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* load (and uncompress), but don't start if "autostart" * is set to "no" */ - if (((s = getenv("autostart")) != NULL) && (strcmp(s,"no") == 0)) + if (((s = getenv("autostart")) != NULL) && (strcmp(s,"no") == 0)) { + char buf[32]; + sprintf(buf, "%lX", len); + setenv("filesize", buf); return 0; - appl = (int (*)(cmd_tbl_t *, int, int, char *[]))ntohl(hdr->ih_ep); - (*appl)(cmdtp, flag, argc-1, &argv[1]); + } + appl = (int (*)(int, char *[]))ntohl(hdr->ih_ep); + (*appl)(argc-1, &argv[1]); return 0; case IH_TYPE_KERNEL: case IH_TYPE_MULTI: @@ -342,6 +398,9 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) switch (hdr->ih_os) { default: /* handled by (original) Linux case */ case IH_OS_LINUX: +#ifdef CONFIG_SILENT_CONSOLE + fixup_silent_linux(); +#endif do_bootm_linux (cmdtp, flag, argc, argv, addr, len_ptr, verify); break; @@ -350,6 +409,13 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) addr, len_ptr, verify); break; +#ifdef CONFIG_LYNXKDI + case IH_OS_LYNXOS: + do_bootm_lynxkdi (cmdtp, flag, argc, argv, + addr, len_ptr, verify); + break; +#endif + case IH_OS_RTEMS: do_bootm_rtems (cmdtp, flag, argc, argv, addr, len_ptr, verify); @@ -375,7 +441,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) SHOW_BOOT_PROGRESS (-9); #ifdef DEBUG - printf ("\n## Control returned to monitor - resetting...\n"); + puts ("\n## Control returned to monitor - resetting...\n"); do_reset (cmdtp, flag, argc, argv); #endif return 1; @@ -385,10 +451,44 @@ 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" - " passing arguments 'arg ...'; when booting a Linux kernel,\n" - " 'arg' can be the address of an initrd image\n" + "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n" + "\t'arg' can be the address of an initrd image\n" ); +#ifdef CONFIG_SILENT_CONSOLE +static void +fixup_silent_linux () +{ + DECLARE_GLOBAL_DATA_PTR; + char buf[256], *start, *end; + char *cmdline = getenv ("bootargs"); + + /* Only fix cmdline when requested */ + if (!(gd->flags & GD_FLG_SILENT)) + return; + + debug ("before silent fix-up: %s\n", cmdline); + if (cmdline) { + if ((start = strstr (cmdline, "console=")) != NULL) { + end = strchr (start, ' '); + strncpy (buf, cmdline, (start - cmdline + 8)); + if (end) + strcpy (buf + (start - cmdline + 8), end); + else + buf[start - cmdline + 8] = '\0'; + } else { + strcpy (buf, cmdline); + strcat (buf, " console="); + } + } else { + strcpy (buf, "console="); + } + + setenv ("bootargs", buf); + debug ("after silent fix-up: %s\n", buf); +} +#endif /* CONFIG_SILENT_CONSOLE */ + #ifdef CONFIG_PPC static void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, @@ -475,12 +575,23 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, /* convert all clock information to MHz */ kbd->bi_intfreq /= 1000000L; kbd->bi_busfreq /= 1000000L; -#if defined(CONFIG_8260) +#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 /* CONFIG_8260 */ +#endif +#if defined(CONFIG_MPC5xxx) + kbd->bi_ipbfreq /= 1000000L; + kbd->bi_pcifreq /= 1000000L; +#endif /* CONFIG_MPC5xxx */ } kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))hdr->ih_ep; @@ -499,7 +610,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, memmove (&header, (char *)addr, sizeof(image_header_t)); if (hdr->ih_magic != IH_MAGIC) { - printf ("Bad Magic Number\n"); + puts ("Bad Magic Number\n"); SHOW_BOOT_PROGRESS (-10); do_reset (cmdtp, flag, argc, argv); } @@ -511,7 +622,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, hdr->ih_hcrc = 0; if (crc32 (0, (char *)data, len) != checksum) { - printf ("Bad Header Checksum\n"); + puts ("Bad Header Checksum\n"); SHOW_BOOT_PROGRESS (-11); do_reset (cmdtp, flag, argc, argv); } @@ -529,7 +640,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, ulong cdata = data, edata = cdata + len; #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ - printf (" Verifying Checksum ... "); + puts (" Verifying Checksum ... "); #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) @@ -548,11 +659,11 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ if (csum != hdr->ih_dcrc) { - printf ("Bad Data CRC\n"); + puts ("Bad Data CRC\n"); SHOW_BOOT_PROGRESS (-12); do_reset (cmdtp, flag, argc, argv); } - printf ("OK\n"); + puts ("OK\n"); } SHOW_BOOT_PROGRESS (11); @@ -560,7 +671,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, if ((hdr->ih_os != IH_OS_LINUX) || (hdr->ih_arch != IH_CPU_PPC) || (hdr->ih_type != IH_TYPE_RAMDISK) ) { - printf ("No Linux PPC Ramdisk Image\n"); + puts ("No Linux PPC Ramdisk Image\n"); SHOW_BOOT_PROGRESS (-13); do_reset (cmdtp, flag, argc, argv); } @@ -658,7 +769,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, #else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ memmove ((void *)initrd_start, (void *)data, len); #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ - printf ("OK\n"); + puts ("OK\n"); } } else { initrd_start = 0; @@ -671,7 +782,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, SHOW_BOOT_PROGRESS (15); -#ifdef CFG_INIT_RAM_LOCK +#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500) unlock_ram_in_cache(); #endif /* @@ -916,7 +1027,7 @@ static int image_info (ulong addr) memmove (&header, (char *)addr, sizeof(image_header_t)); if (ntohl(hdr->ih_magic) != IH_MAGIC) { - printf (" Bad Magic Number\n"); + puts (" Bad Magic Number\n"); return 1; } @@ -927,7 +1038,7 @@ static int image_info (ulong addr) hdr->ih_hcrc = 0; if (crc32 (0, (char *)data, len) != checksum) { - printf (" Bad Header Checksum\n"); + puts (" Bad Header Checksum\n"); return 1; } @@ -937,12 +1048,12 @@ static int image_info (ulong addr) data = addr + sizeof(image_header_t); len = ntohl(hdr->ih_size); - printf (" Verifying Checksum ... "); + puts (" Verifying Checksum ... "); if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) { - printf (" Bad Data CRC\n"); + puts (" Bad Data CRC\n"); return 1; } - printf ("OK\n"); + puts ("OK\n"); return 0; } @@ -957,6 +1068,64 @@ U_BOOT_CMD( #endif /* CFG_CMD_IMI */ +#if (CONFIG_COMMANDS & CFG_CMD_IMLS) +/*----------------------------------------------------------------------- + * List all images found in flash. + */ +int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + flash_info_t *info; + int i, j; + image_header_t *hdr; + ulong data, len, checksum; + + for (i=0, info=&flash_info[0]; iflash_id == FLASH_UNKNOWN) + goto next_bank; + for (j=0; jstart[j]) || + (ntohl(hdr->ih_magic) != IH_MAGIC)) + goto next_sector; + + /* Copy header so we can blank CRC field for re-calculation */ + memmove (&header, (char *)hdr, sizeof(image_header_t)); + + checksum = ntohl(header.ih_hcrc); + header.ih_hcrc = 0; + + if (crc32 (0, (char *)&header, sizeof(image_header_t)) + != checksum) + goto next_sector; + + printf ("Image at %08lX:\n", (ulong)hdr); + print_image_hdr( hdr ); + + data = (ulong)hdr + sizeof(image_header_t); + len = ntohl(hdr->ih_size); + + puts (" Verifying Checksum ... "); + if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) { + puts (" Bad Data CRC\n"); + } + puts ("OK\n"); +next_sector: ; + } +next_bank: ; + } + + return (0); +} + +U_BOOT_CMD( + imls, 1, 1, do_imls, + "imls - list all images found in flash\n", + "\n" + " - Prints information about all images found at sector\n" + " boundaries in flash.\n" +); +#endif /* CFG_CMD_IMLS */ + void print_image_hdr (image_header_t *hdr) { @@ -972,18 +1141,19 @@ print_image_hdr (image_header_t *hdr) tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); #endif /* CFG_CMD_DATE, CONFIG_TIMESTAMP */ - printf (" Image Type: "); print_type(hdr); printf ("\n"); - printf (" Data Size: %d Bytes = ", ntohl(hdr->ih_size)); + puts (" Image Type: "); print_type(hdr); + printf ("\n Data Size: %d Bytes = ", ntohl(hdr->ih_size)); print_size (ntohl(hdr->ih_size), "\n"); - printf (" Load Address: %08x\n", ntohl(hdr->ih_load)); - printf (" Entry Point: %08x\n", ntohl(hdr->ih_ep)); + printf (" Load Address: %08x\n" + " Entry Point: %08x\n", + ntohl(hdr->ih_load), ntohl(hdr->ih_ep)); if (hdr->ih_type == IH_TYPE_MULTI) { int i; ulong len; ulong *len_ptr = (ulong *)((ulong)hdr + sizeof(image_header_t)); - printf (" Contents:\n"); + puts (" Contents:\n"); for (i=0; (len = ntohl(*len_ptr)); ++i, ++len_ptr) { printf (" Image %d: %8ld Bytes = ", i, len); print_size (len, "\n"); @@ -1007,6 +1177,9 @@ print_type (image_header_t *hdr) 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; } @@ -1025,6 +1198,9 @@ print_type (image_header_t *hdr) case IH_CPU_SPARC: arch = "SPARC"; break; case IH_CPU_SPARC64: arch = "SPARC 64 Bit"; break; case IH_CPU_M68K: arch = "M68K"; break; + case IH_CPU_MICROBLAZE: arch = "Microblaze"; break; + case IH_CPU_NIOS: arch = "Nios"; break; + case IH_CPU_NIOS2: arch = "Nios-II"; break; default: arch = "Unknown Architecture"; break; } @@ -1076,7 +1252,7 @@ static void zfree(void *x, void *addr, unsigned nb) #define DEFLATED 8 -int gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) +int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp) { z_stream s; int r, i, flags; @@ -1085,7 +1261,7 @@ int gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) i = 10; flags = src[3]; if (src[2] != DEFLATED || (flags & RESERVED) != 0) { - printf ("Error: Bad gzipped data\n"); + puts ("Error: Bad gzipped data\n"); return (-1); } if ((flags & EXTRA_FIELD) != 0) @@ -1099,7 +1275,7 @@ int gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) if ((flags & HEAD_CRC) != 0) i += 2; if (i >= *lenp) { - printf ("Error: gunzip out of data in header\n"); + puts ("Error: gunzip out of data in header\n"); return (-1); } @@ -1131,6 +1307,13 @@ int gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) return (0); } +#ifdef CONFIG_BZIP2 +void bz_internal_error(int errcode) +{ + printf ("BZIP2 internal error %d\n", errcode); +} +#endif /* CONFIG_BZIP2 */ + static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong addr, ulong *len_ptr, int verify) @@ -1181,3 +1364,16 @@ do_bootm_qnxelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], do_bootelf(cmdtp, 0, 2, local_args); } #endif /* CFG_CMD_ELF */ + +#ifdef CONFIG_LYNXKDI +static void +do_bootm_lynxkdi (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + ulong addr, + ulong *len_ptr, + int verify) +{ + lynxkdi_boot( &header ); +} + +#endif /* CONFIG_LYNXKDI */