From: Bartlomiej Sieka Date: Wed, 26 Mar 2008 08:38:06 +0000 (+0100) Subject: Merge branch 'new-image' of git://www.denx.de/git/u-boot-testing X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=27f33e9f45ef7f9685cbdc65066a1828e85dde4f;p=u-boot.git Merge branch 'new-image' of git://www.denx.de/git/u-boot-testing Conflicts: common/cmd_bootm.c cpu/mpc8xx/cpu.c Signed-off-by: Bartlomiej Sieka --- 27f33e9f45ef7f9685cbdc65066a1828e85dde4f diff --cc common/Makefile index 56176ca2af,fc842225d5..1c81fcfe4f --- a/common/Makefile +++ b/common/Makefile @@@ -36,8 -36,9 +36,10 @@@ COBJS-y += cmd_autoscript. COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o COBJS-$(CONFIG_CMD_BEDBUG) += cmd_bedbug.o COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o + COBJS-y += image.o + COBJS-y += gunzip.o COBJS-y += cmd_boot.o +COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o COBJS-y += cmd_bootm.o COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o diff --cc common/cmd_bootm.c index 5a8572602c,789ee03387..9e5ce4b38f --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@@ -460,620 -347,525 +347,536 @@@ int do_bootm (cmd_tbl_t *cmdtp, int fla return 1; } - 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) - "\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" - "\tuse a '-' for the second argument. If you do not pass a third\n" - "\ta bd_info struct will be passed instead\n" - #endif - ); - - #ifdef CONFIG_SILENT_CONSOLE - static void - fixup_silent_linux () + /** + * image_get_kernel - verify legacy format kernel image + * @img_addr: in RAM address of the legacy format image to be verified + * @verify: data CRC verification flag + * + * image_get_kernel() verifies legacy image integrity and returns pointer to + * legacy image header if image verification was completed successfully. + * + * returns: + * pointer to a legacy image header if valid image was found + * otherwise return NULL + */ + static image_header_t *image_get_kernel (ulong img_addr, int verify) { - char buf[256], *start, *end; - char *cmdline = getenv ("bootargs"); + image_header_t *hdr = (image_header_t *)img_addr; - /* Only fix cmdline when requested */ - if (!(gd->flags & GD_FLG_SILENT)) - return; + if (!image_check_magic(hdr)) { + puts ("Bad Magic Number\n"); + show_boot_progress (-1); + return NULL; + } + show_boot_progress (2); - 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="); + 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; } - } else { - strcpy (buf, "console="); + puts ("OK\n"); } + show_boot_progress (4); - setenv ("bootargs", buf); - debug ("after silent fix-up: %s\n", buf); + if (!image_check_target_arch (hdr)) { + printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr)); + show_boot_progress (-4); + return NULL; + } + return hdr; } - #endif /* CONFIG_SILENT_CONSOLE */ - #ifdef CONFIG_PPC - static void __attribute__((noinline)) - do_bootm_linux (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong addr, - ulong *len_ptr, - int verify) + /** + * fit_check_kernel - verify FIT format kernel subimage + * @fit_hdr: pointer to the FIT image header + * os_noffset: kernel subimage node offset within FIT image + * @verify: data CRC verification flag + * + * fit_check_kernel() verifies integrity of the kernel subimage and from + * specified FIT image. + * + * returns: + * 1, on success + * 0, on failure + */ + #if defined (CONFIG_FIT) + static int fit_check_kernel (const void *fit, int os_noffset, 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 defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - char *of_flat_tree = NULL; - ulong of_data = 0; - #endif + fit_image_print (fit, os_noffset, " "); - 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; + if (verify) { + puts (" Verifying Hash Integrity ... "); + if (!fit_image_check_hashes (fit, os_noffset)) { + puts ("Bad Data Hash\n"); + show_boot_progress (-104); + return 0; + } + puts ("OK\n"); } + show_boot_progress (105); +#ifdef CONFIG_LOGBUFFER +#ifndef CONFIG_ALT_LB_ADDR + 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); +#else + debug ("## Logbuffer at 0x%08lX ", CONFIG_ALT_LB_ADDR); +#endif +#endif + if (!fit_image_check_target_arch (fit, os_noffset)) { + puts ("Unsupported Architecture\n"); + show_boot_progress (-105); + return 0; + } - /* - * 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. - */ + show_boot_progress (106); + if (!fit_image_check_type (fit, os_noffset, IH_TYPE_KERNEL)) { + puts ("Not a kernel image\n"); + show_boot_progress (-106); + return 0; + } - asm( "mr %0,1": "=r"(sp) : ); + show_boot_progress (107); + return 1; + } + #endif /* CONFIG_FIT */ - debug ("## Current stack ends at 0x%08lX ", sp); + /** + * boot_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 + * + * boot_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 void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images, ulong *os_data, ulong *os_len) + { + image_header_t *hdr; + ulong img_addr; + #if defined(CONFIG_FIT) + void *fit_hdr; + const char *fit_uname_config = NULL; + const char *fit_uname_kernel = NULL; + const void *data; + size_t len; + int cfg_noffset; + int os_noffset; + #endif - sp -= 2048; /* just to be sure */ - if (sp > CFG_BOOTMAPSZ) - sp = CFG_BOOTMAPSZ; - sp &= ~0xF; + /* find out kernel image address */ + if (argc < 2) { + img_addr = load_addr; + debug ("* kernel: default image load address = 0x%08lx\n", + load_addr); + #if defined(CONFIG_FIT) + } else if (fit_parse_conf (argv[1], load_addr, &img_addr, + &fit_uname_config)) { + debug ("* kernel: config '%s' from image at 0x%08lx\n", + fit_uname_config, img_addr); + } else if (fit_parse_subimage (argv[1], load_addr, &img_addr, + &fit_uname_kernel)) { + debug ("* kernel: subimage '%s' from image at 0x%08lx\n", + fit_uname_kernel, img_addr); + #endif + } else { + img_addr = simple_strtoul(argv[1], NULL, 16); + debug ("* kernel: cmdline image address = 0x%08lx\n", img_addr); + } - debug ("=> set upper limit to 0x%08lX\n", sp); + show_boot_progress (1); - cmdline = (char *)((sp - CFG_BARGSIZE) & ~0xF); - kbd = (bd_t *)(((ulong)cmdline - sizeof(bd_t)) & ~0xF); + /* copy from dataflash if needed */ + img_addr = genimg_get_image (img_addr); + + /* check image type, for FIT images get FIT kernel node */ + *os_data = *os_len = 0; + switch (genimg_get_format ((void *)img_addr)) { + case IMAGE_FORMAT_LEGACY: + printf ("## Booting kernel from Legacy Image at %08lx ...\n", + img_addr); + hdr = image_get_kernel (img_addr, images->verify); + if (!hdr) + return NULL; + show_boot_progress (5); + + /* get os_data and os_len */ + 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; + } + images->legacy_hdr_os = hdr; + images->legacy_hdr_valid = 1; - if ((s = getenv("bootargs")) == NULL) - s = ""; + show_boot_progress (6); + break; + #if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (void *)img_addr; + printf ("## Booting kernel from FIT Image at %08lx ...\n", + img_addr); + + if (!fit_check_format (fit_hdr)) { + puts ("Bad FIT kernel image format!\n"); + show_boot_progress (-100); + return NULL; + } + show_boot_progress (100); - strcpy (cmdline, s); + if (!fit_uname_kernel) { + /* + * no kernel 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 (101); + cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); + if (cfg_noffset < 0) { + show_boot_progress (-101); + return NULL; + } + /* save configuration uname provided in the first + * bootm argument + */ + images->fit_uname_cfg = fdt_get_name (fit_hdr, cfg_noffset, NULL); + printf (" Using '%s' configuration\n", images->fit_uname_cfg); + show_boot_progress (103); - cmd_start = (ulong)&cmdline[0]; - cmd_end = cmd_start + strlen(cmdline); + os_noffset = fit_conf_get_kernel_node (fit_hdr, cfg_noffset); + fit_uname_kernel = fit_get_name (fit_hdr, os_noffset, NULL); + } else { + /* get kernel component image node offset */ + show_boot_progress (102); + os_noffset = fit_image_get_node (fit_hdr, fit_uname_kernel); + } + if (os_noffset < 0) { + show_boot_progress (-103); + return NULL; + } - *kbd = *(gd->bd); + printf (" Trying '%s' kernel subimage\n", fit_uname_kernel); - #ifdef DEBUG - printf ("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end); + show_boot_progress (104); + if (!fit_check_kernel (fit_hdr, os_noffset, images->verify)) + return NULL; - do_bdinfo (NULL, 0, 0, NULL); - #endif + /* get kernel image data address and length */ + if (fit_image_get_data (fit_hdr, os_noffset, &data, &len)) { + puts ("Could not find kernel subimage data!\n"); + show_boot_progress (-107); + return NULL; + } + show_boot_progress (108); - 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; + *os_len = len; + *os_data = (ulong)data; + images->fit_hdr_os = fit_hdr; + images->fit_uname_os = fit_uname_kernel; + images->fit_noffset_os = os_noffset; + break; #endif - #if defined(CONFIG_MPC5xxx) - kbd->bi_ipbfreq /= 1000000L; - kbd->bi_pcifreq /= 1000000L; - #endif /* CONFIG_MPC5xxx */ + default: + printf ("Wrong Image Format for %s command\n", cmdtp->name); + show_boot_progress (-108); + return NULL; } - kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong)) ntohl(hdr->ih_ep); + debug (" kernel data at 0x%08lx, len = 0x%08lx (%d)\n", + *os_data, *os_len, *os_len); - /* - * Check if there is an initrd image - */ + return (void *)img_addr; + } - #if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - /* Look for a '-' which indicates to ignore the ramdisk argument */ - if (argc >= 3 && strcmp(argv[2], "-") == 0) { - debug ("Skipping initrd\n"); - len = data = 0; - } - else + 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_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" + "\tuse a '-' for the second argument. If you do not pass a third\n" + "\ta bd_info struct will be passed instead\n" #endif - if (argc >= 3) { - debug ("Not skipping initrd\n"); - show_boot_progress (9); + #if defined(CONFIG_FIT) + "\t\nFor the new multi component uImage format (FIT) addresses\n" + "\tmust be extened to include component or configuration unit name:\n" + "\taddr: - direct component image specification\n" + "\taddr# - configuration specification\n" + "\tUse iminfo command to get the list of existing component\n" + "\timages and configurations.\n" + #endif + ); - addr = simple_strtoul(argv[2], NULL, 16); + /*******************************************************************/ + /* bootd - boot default image */ + /*******************************************************************/ + #if defined(CONFIG_CMD_BOOTD) + int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) + { + int rcode = 0; - printf ("## Loading RAMDisk Image at %08lx ...\n", addr); + #ifndef CFG_HUSH_PARSER + if (run_command (getenv ("bootcmd"), flag) < 0) + rcode = 1; + #else + if (parse_string_outer (getenv ("bootcmd"), + FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0) + rcode = 1; + #endif + return rcode; + } - /* Copy header so we can blank CRC field for re-calculation */ - memmove (&header, (char *)addr, sizeof(image_header_t)); + U_BOOT_CMD( + boot, 1, 1, do_bootd, + "boot - boot default, i.e., run 'bootcmd'\n", + NULL + ); - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - puts ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } + /* keep old command name "bootd" for backward compatibility */ + U_BOOT_CMD( + bootd, 1, 1, do_bootd, + "bootd - boot default, i.e., run 'bootcmd'\n", + NULL + ); - data = (ulong)&header; - len = sizeof(image_header_t); + #endif - 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); - } + /*******************************************************************/ + /* iminfo - print header info for a requested image */ + /*******************************************************************/ + #if defined(CONFIG_CMD_IMI) + int do_iminfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) + { + int arg; + ulong addr; + int rcode = 0; - show_boot_progress (10); + if (argc < 2) { + return image_info (load_addr); + } - print_image_hdr (hdr); + for (arg = 1; arg < argc; ++arg) { + addr = simple_strtoul (argv[arg], NULL, 16); + if (image_info (addr) != 0) + rcode = 1; + } + return rcode; + } - data = addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); + static int image_info (ulong addr) + { + void *hdr = (void *)addr; - 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 */ + printf ("\n## Checking Image at %08lx ...\n", addr); - puts (" Verifying Checksum ... "); + switch (genimg_get_format (hdr)) { + case IMAGE_FORMAT_LEGACY: + puts (" Legacy image found\n"); + if (!image_check_magic (hdr)) { + puts (" Bad Magic Number\n"); + return 1; + } - #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"); + if (!image_check_hcrc (hdr)) { + puts (" Bad Header Checksum\n"); + return 1; } - show_boot_progress (11); + image_print_contents (hdr); - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_PPC) || - (hdr->ih_type != IH_TYPE_RAMDISK) ) { - puts ("No Linux PPC Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); + puts (" Verifying Checksum ... "); + if (!image_check_dcrc (hdr)) { + puts (" Bad Data CRC\n"); + return 1; } + puts ("OK\n"); + return 0; + #if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + puts (" FIT image found\n"); - /* - * 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; + if (!fit_check_format (hdr)) { + puts ("Bad FIT image format!\n"); + return 1; } - len = ntohl(len_ptr[1]); - - } else { - /* - * no initrd image - */ - show_boot_progress (14); - - len = data = 0; + fit_print_contents (hdr); + return 0; + #endif + default: + puts ("Unknown image format!\n"); + break; } - #if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - if(argc > 3) { - of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); - hdr = (image_header_t *)of_flat_tree; - #if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) { - #else - if (fdt_check_header(of_flat_tree + sizeof(image_header_t)) != 0) { - #endif - #ifndef CFG_NO_FLASH - if (addr2info((ulong)of_flat_tree) != NULL) - of_data = (ulong)of_flat_tree; + return 1; + } + + U_BOOT_CMD( + iminfo, CFG_MAXARGS, 1, do_iminfo, + "iminfo - print header information for application image\n", + "addr [addr ...]\n" + " - print header information for application image starting at\n" + " address 'addr' in memory; this includes verification of the\n" + " image contents (magic number, header and payload checksums)\n" + ); #endif - } else if (ntohl(hdr->ih_magic) == IH_MAGIC) { - printf("## Flat Device Tree at %08lX\n", hdr); - print_image_hdr(hdr); - - if ((ntohl(hdr->ih_load) < ((unsigned long)hdr + ntohl(hdr->ih_size) + sizeof(hdr))) && - ((ntohl(hdr->ih_load) + ntohl(hdr->ih_size)) > (unsigned long)hdr)) { - puts ("ERROR: fdt overwritten - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - puts (" Verifying Checksum ... "); - memmove (&header, (char *)hdr, sizeof(image_header_t)); - checksum = ntohl(header.ih_hcrc); - header.ih_hcrc = 0; - if(checksum != crc32(0, (uchar *)&header, sizeof(image_header_t))) { - puts ("ERROR: fdt header checksum invalid - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } + /*******************************************************************/ + /* imls - list all images found in flash */ + /*******************************************************************/ + #if defined(CONFIG_CMD_IMLS) + int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) + { + flash_info_t *info; + int i, j; + void *hdr; - checksum = ntohl(hdr->ih_dcrc); - addr = (ulong)((uchar *)(hdr) + sizeof(image_header_t)); + for (i = 0, info = &flash_info[0]; + i < CFG_MAX_FLASH_BANKS; ++i, ++info) { - if(checksum != crc32(0, (uchar *)addr, ntohl(hdr->ih_size))) { - puts ("ERROR: fdt checksum invalid - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); + if (info->flash_id == FLASH_UNKNOWN) + goto next_bank; + for (j = 0; j < info->sector_count; ++j) { - if (ntohl(hdr->ih_type) != IH_TYPE_FLATDT) { - puts ("ERROR: uImage is not a fdt - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - if (ntohl(hdr->ih_comp) != IH_COMP_NONE) { - puts ("ERROR: uImage is compressed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - #if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) { - #else - if (fdt_check_header(of_flat_tree + sizeof(image_header_t)) != 0) { + hdr = (void *)info->start[j]; + if (!hdr) + goto next_sector; + + switch (genimg_get_format (hdr)) { + case IMAGE_FORMAT_LEGACY: + if (!image_check_hcrc (hdr)) + goto next_sector; + + printf ("Legacy Image at %08lX:\n", (ulong)hdr); + image_print_contents (hdr); + + puts (" Verifying Checksum ... "); + if (!image_check_dcrc (hdr)) { + puts ("Bad Data CRC\n"); + } else { + puts ("OK\n"); + } + break; + #if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + if (!fit_check_format (hdr)) + goto next_sector; + + printf ("FIT Image at %08lX:\n", (ulong)hdr); + fit_print_contents (hdr); + break; #endif - puts ("ERROR: uImage data is not a fdt - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); + default: + goto next_sector; } - memmove((void *)ntohl(hdr->ih_load), - (void *)(of_flat_tree + sizeof(image_header_t)), - ntohl(hdr->ih_size)); - of_flat_tree = (char *)ntohl(hdr->ih_load); - } else { - puts ("Did not find a flat Flat Device Tree.\n" - "Must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - printf (" Booting using the fdt at 0x%x\n", - of_flat_tree); - } else if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1]) && (len_ptr[2])) { - u_long tail = ntohl(len_ptr[0]) % 4; - int i; - - /* skip kernel length, initrd length, and terminator */ - of_flat_tree = (char *)(&len_ptr[3]); - /* skip any additional image length fields */ - for (i=2; len_ptr[i]; ++i) - of_flat_tree += 4; - /* add kernel length, and align */ - of_flat_tree += ntohl(len_ptr[0]); - if (tail) { - of_flat_tree += 4 - tail; - } - - /* add initrd length, and align */ - tail = ntohl(len_ptr[1]) % 4; - of_flat_tree += ntohl(len_ptr[1]); - if (tail) { - of_flat_tree += 4 - tail; + next_sector: ; } + next_bank: ; + } - #ifndef CFG_NO_FLASH - /* move the blob if it is in flash (set of_data to !null) */ - if (addr2info ((ulong)of_flat_tree) != NULL) - of_data = (ulong)of_flat_tree; - #endif - - - #if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) { - #else - if (fdt_check_header (of_flat_tree) != 0) { - #endif - puts ("ERROR: image is not a fdt - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } + return (0); + } - #if defined(CONFIG_OF_FLAT_TREE) - if (((struct boot_param_header *)of_flat_tree)->totalsize != - ntohl (len_ptr[2])) { - #else - if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != - ntohl(len_ptr[2])) { - #endif - puts ("ERROR: fdt size != image size - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - } + 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 - 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; + /*******************************************************************/ + /* helper routines */ + /*******************************************************************/ + #ifdef CONFIG_SILENT_CONSOLE + static void fixup_silent_linux () + { + char buf[256], *start, *end; + char *cmdline = getenv ("bootargs"); - /* - * 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( "mr %0,1": "=r"(nsp) : ); - 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; - } + /* Only fix cmdline when requested */ + if (!(gd->flags & GD_FLG_SILENT)) + return; - 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; - } + 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 /* !(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; - } - - #if defined(CONFIG_OF_LIBFDT) - - #ifdef CFG_BOOTMAPSZ - /* - * The blob must be within CFG_BOOTMAPSZ, - * so we flag it to be copied if it is not. - */ - if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) - of_data = (ulong)of_flat_tree; - #endif - - /* move of_flat_tree if needed */ - if (of_data) { - int err; - ulong of_start, of_len; - - of_len = be32_to_cpu(fdt_totalsize(of_data)); - - /* position on a 4K boundary before the kbd */ - of_start = (ulong)kbd - of_len; - of_start &= ~(4096 - 1); /* align on page */ - debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - of_data, of_data + of_len - 1, of_len, of_len); - - of_flat_tree = (char *)of_start; - printf (" Loading Device Tree to %08lx, end %08lx ... ", - of_start, of_start + of_len - 1); - err = fdt_open_into((void *)of_data, (void *)of_start, of_len); - if (err != 0) { - puts ("ERROR: fdt move failed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); - } - /* - * 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_flat_tree) { - if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { - puts ("ERROR: /chosen node create failed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - #ifdef CONFIG_OF_BOARD_SETUP - /* Call the board-specific fixup routine */ - ft_board_setup(of_flat_tree, gd->bd); - #endif + strcpy (buf, "console="); } - #endif /* CONFIG_OF_LIBFDT */ - #if defined(CONFIG_OF_FLAT_TREE) - #ifdef CFG_BOOTMAPSZ - /* - * The blob must be within CFG_BOOTMAPSZ, - * so we flag it to be copied if it is not. - */ - if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) - of_data = (ulong)of_flat_tree; - #endif - /* move of_flat_tree if needed */ - if (of_data) { - ulong of_start, of_len; - of_len = ((struct boot_param_header *)of_data)->totalsize; - - /* provide extra 8k pad */ - of_start = (ulong)kbd - of_len - 8192; - of_start &= ~(4096 - 1); /* align on page */ - debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - of_data, of_data + of_len - 1, of_len, of_len); - - of_flat_tree = (char *)of_start; - printf (" Loading Device Tree to %08lx, end %08lx ... ", - of_start, of_start + of_len - 1); - memmove ((void *)of_start, (void *)of_data, of_len); - puts ("OK\n"); - } - /* - * Create the /chosen node and modify the blob with board specific - * values as needed. - */ - ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); - /* ft_dump_blob(of_flat_tree); */ - #endif - debug ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong)kernel); + setenv ("bootargs", buf); + debug ("after silent fix-up: %s\n", buf); + } + #endif /* CONFIG_SILENT_CONSOLE */ - show_boot_progress (15); - #if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500) - unlock_ram_in_cache(); - #endif + /*******************************************************************/ + /* OS booting routines */ + /*******************************************************************/ - #if defined(CONFIG_OF_FLAT_TREE) || 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 - */ - (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); - /* does not return */ + static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + bootm_headers_t *images) + { + void (*loader)(bd_t *, image_header_t *, char *, char *); + image_header_t *os_hdr, *hdr; + ulong kernel_data, kernel_len; + char *consdev; + char *cmdline; + + #if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("NetBSD"); + do_reset (cmdtp, flag, argc, argv); } #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 - */ - (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); - /* does not return */ - } - #endif /* CONFIG_PPC */ - - static void - do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong addr, - ulong *len_ptr, - int verify) - { - image_header_t *hdr = &header; - - void (*loader)(bd_t *, image_header_t *, char *, char *); - image_header_t *img_addr; - char *consdev; - char *cmdline; - + hdr = images->legacy_hdr_os; /* * Booting a (NetBSD) kernel image