From d5934ad7756f038a393a9cfab76a4fe306d9d930 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Mon, 4 Feb 2008 08:28:09 +0100 Subject: [PATCH] [new uImage] Add dual format uImage support framework This patch adds framework for dual format images. Format detection is added and the bootm controll flow is updated to include cases for new FIT format uImages. When the legacy (image_header based) format is detected appropriate legacy specific handling is invoked. For the new (FIT based) format uImages dual boot framework has a minial support, that will only print out a corresponding debug messages. Implementation of the FIT specific handling will be added in following patches. Signed-off-by: Marian Balakowicz --- board/cray/L1/L1.c | 7 + board/esd/common/auto_update.c | 19 ++ board/mcc200/auto_update.c | 19 ++ board/mpl/common/common_util.c | 7 + board/siemens/common/fpga.c | 14 ++ board/trab/auto_update.c | 26 +++ common/cmd_autoscript.c | 56 +++-- common/cmd_bootm.c | 361 +++++++++++++++++++++++---------- common/cmd_doc.c | 28 ++- common/cmd_fdc.c | 44 ++-- common/cmd_fpga.c | 36 ++-- common/cmd_ide.c | 41 ++-- common/cmd_nand.c | 59 ++++-- common/cmd_scsi.c | 31 ++- common/cmd_usb.c | 33 ++- common/cmd_ximg.c | 103 ++++++---- common/image.c | 117 ++++++++--- include/image.h | 53 ++++- lib_arm/bootm.c | 32 ++- lib_avr32/bootm.c | 32 ++- lib_blackfin/bootm.c | 22 +- lib_i386/bootm.c | 35 +++- lib_m68k/bootm.c | 26 ++- lib_microblaze/bootm.c | 23 ++- lib_mips/bootm.c | 32 ++- lib_nios/bootm.c | 2 +- lib_nios2/bootm.c | 20 +- lib_ppc/bootm.c | 178 +++++++++++----- lib_sh/bootm.c | 22 +- 29 files changed, 1074 insertions(+), 404 deletions(-) diff --git a/board/cray/L1/L1.c b/board/cray/L1/L1.c index 8e6d74eef5..c00acc87ae 100644 --- a/board/cray/L1/L1.c +++ b/board/cray/L1/L1.c @@ -140,6 +140,13 @@ int misc_init_r (void) char bootcmd[32]; hdr = (image_header_t *) (CFG_MONITOR_BASE - image_get_header_size ()); +#if defined(CONFIG_FIT) + if (gen_image_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); 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); diff --git a/board/esd/common/auto_update.c b/board/esd/common/auto_update.c index cb8087bee8..976707dfe6 100644 --- a/board/esd/common/auto_update.c +++ b/board/esd/common/auto_update.c @@ -91,6 +91,12 @@ int au_check_cksum_valid(int i, long nbytes) image_header_t *hdr; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_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 != image_get_data_size (hdr))) { @@ -118,6 +124,13 @@ int au_check_header_valid(int i, long nbytes) unsigned long checksum; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + /* check the easy ones first */ #undef CHECK_VALID_DEBUG #ifdef CHECK_VALID_DEBUG @@ -183,6 +196,12 @@ int au_do_update(int i, long sz) #endif hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif switch (au_image[i].type) { case AU_SCRIPT: diff --git a/board/mcc200/auto_update.c b/board/mcc200/auto_update.c index 8b520c8599..fcae35aaf8 100644 --- a/board/mcc200/auto_update.c +++ b/board/mcc200/auto_update.c @@ -143,6 +143,12 @@ int au_check_cksum_valid(int idx, long nbytes) image_header_t *hdr; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif if (nbytes != image_get_image_size (hdr)) { printf ("Image %s bad total SIZE\n", aufile[idx]); @@ -162,6 +168,13 @@ int au_check_header_valid(int idx, long nbytes) unsigned long checksum, fsize; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + /* check the easy ones first */ #undef CHECK_VALID_DEBUG #ifdef CHECK_VALID_DEBUG @@ -233,6 +246,12 @@ int au_do_update(int idx, long sz) uint nbytes; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif /* execute a script */ if (image_check_type (hdr, IH_TYPE_SCRIPT)) { diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c index b171ca5173..fffd25c2be 100644 --- a/board/mpl/common/common_util.c +++ b/board/mpl/common/common_util.c @@ -181,6 +181,13 @@ mpl_prg_image(uchar *ld_addr) image_header_t *hdr = (image_header_t *)ld_addr; int rc; +#if defined(CONFIG_FIT) + if (gen_image_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"); return 1; diff --git a/board/siemens/common/fpga.c b/board/siemens/common/fpga.c index 9d719460dc..a9a6dfed69 100644 --- a/board/siemens/common/fpga.c +++ b/board/siemens/common/fpga.c @@ -137,6 +137,13 @@ static int fpga_load (fpga_t* fpga, ulong addr, int checkall) char msg[32]; int verify, i; +#if defined(CONFIG_FIT) + if (gen_image_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 */ @@ -333,6 +340,13 @@ int fpga_init (void) } hdr = (image_header_t *)addr; +#if defined(CONFIG_FIT) + if (gen_image_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; diff --git a/board/trab/auto_update.c b/board/trab/auto_update.c index bd9ee0c011..8f6753592b 100644 --- a/board/trab/auto_update.c +++ b/board/trab/auto_update.c @@ -211,6 +211,12 @@ au_check_cksum_valid(int idx, long nbytes) image_header_t *hdr; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif if (nbytes != image_get_image_size (hdr)) { @@ -234,6 +240,13 @@ au_check_header_valid(int idx, long nbytes) unsigned char buf[4]; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + /* check the easy ones first */ #undef CHECK_VALID_DEBUG #ifdef CHECK_VALID_DEBUG @@ -327,6 +340,12 @@ au_do_update(int idx, long sz) uint nbytes; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif /* disable the power switch */ *CPLD_VFD_BK |= POWER_OFF; @@ -417,6 +436,13 @@ au_update_eeprom(int idx) } hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + /* write the time field into EEPROM */ off = auee_off[idx].time; val = image_get_time (hdr); diff --git a/common/cmd_autoscript.c b/common/cmd_autoscript.c index 53f8e8311a..f9ab1d9a13 100644 --- a/common/cmd_autoscript.c +++ b/common/cmd_autoscript.c @@ -53,7 +53,7 @@ int autoscript (ulong addr) { ulong len; - image_header_t *hdr = (image_header_t *)addr; + image_header_t *hdr; ulong *data; char *cmd; int rcode = 0; @@ -61,33 +61,47 @@ autoscript (ulong addr) verify = getenv_verify (); - if (!image_check_magic (hdr)) { - puts ("Bad magic number\n"); - return 1; - } + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (!image_check_hcrc (hdr)) { - puts ("Bad header crc\n"); - return 1; - } + if (!image_check_magic (hdr)) { + puts ("Bad magic number\n"); + return 1; + } - if (verify) { - if (!image_check_dcrc (hdr)) { - puts ("Bad data crc\n"); + if (!image_check_hcrc (hdr)) { + puts ("Bad header crc\n"); return 1; } - } - if (!image_check_type (hdr, IH_TYPE_SCRIPT)) { - puts ("Bad image type\n"); - return 1; - } + if (verify) { + if (!image_check_dcrc (hdr)) { + puts ("Bad data crc\n"); + return 1; + } + } + + 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); + /* get length of script */ + data = (ulong *)image_get_data (hdr); - if ((len = image_to_cpu (*data)) == 0) { - puts ("Empty Script\n"); + if ((len = image_to_cpu (*data)) == 0) { + puts ("Empty Script\n"); + return 1; + } + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("autoscript"); + return 1; +#endif + default: + puts ("Wrong image format for autoscript\n"); return 1; } diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index bb60a840ec..3f099888f2 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -65,8 +65,9 @@ static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); static void fixup_silent_linux (void); #endif -static image_header_t *get_kernel (cmd_tbl_t *cmdtp, int flag, +static void *get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], int verify, + bootm_headers_t *images, ulong *os_data, ulong *os_len); extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); @@ -80,7 +81,7 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); */ typedef void boot_os_fn (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, /* of image to boot */ + bootm_headers_t *images,/* pointers to os/initrd/fdt */ int verify); /* getenv("verify")[0] != 'n' */ extern boot_os_fn do_bootm_linux; @@ -102,6 +103,7 @@ static boot_os_fn do_bootm_artos; #endif ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */ +static bootm_headers_t images; /* pointers to os/initrd/fdt images */ /*******************************************************************/ @@ -113,21 +115,47 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) const char *type_name; uint unc_len = CFG_BOOTM_LEN; int verify = getenv_verify(); + uint8_t comp, type, os; - image_header_t *hdr; + void *os_hdr; ulong os_data, os_len; - ulong image_start, image_end; ulong load_start, load_end; + memset ((void *)&images, 0, sizeof (images)); + /* get kernel image header, start address and length */ - hdr = get_kernel (cmdtp, flag, argc, argv, verify, - &os_data, &os_len); - if (hdr == NULL) + os_hdr = get_kernel (cmdtp, flag, argc, argv, verify, + &images, &os_data, &os_len); + if (os_len == 0) return 1; show_boot_progress (6); + /* get image parameters */ + switch (gen_image_get_format (os_hdr)) { + case IMAGE_FORMAT_LEGACY: + type = image_get_type (os_hdr); + comp = image_get_comp (os_hdr); + os = image_get_os (os_hdr); + + image_end = image_get_image_end (os_hdr); + load_start = image_get_load (os_hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("bootm"); + return 1; +#endif + default: + puts ("ERROR: unknown image format type!\n"); + return 1; + } + + image_start = (ulong)os_hdr; + load_end = 0; + type_name = image_get_type_name (type); + /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily @@ -146,21 +174,14 @@ 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)) { + switch (comp) { case IH_COMP_NONE: - if (image_get_load (hdr) == (ulong)hdr) { + if (load_start == (ulong)os_hdr) { printf (" XIP %s ... ", type_name); } else { printf (" Loading %s ... ", type_name); - memmove_wd ((void *)image_get_load (hdr), + memmove_wd ((void *)load_start, (void *)os_data, os_len, CHUNKSZ); load_end = load_start + os_len; @@ -169,7 +190,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; case IH_COMP_GZIP: printf (" Uncompressing %s ... ", type_name); - if (gunzip ((void *)image_get_load (hdr), unc_len, + if (gunzip ((void *)load_start, unc_len, (uchar *)os_data, &os_len) != 0) { puts ("GUNZIP ERROR - must RESET board to recover\n"); show_boot_progress (-6); @@ -186,7 +207,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * use slower decompression algorithm which requires * at most 2300 KB of memory. */ - int i = BZ2_bzBuffToBuffDecompress ((char*)image_get_load (hdr), + int i = BZ2_bzBuffToBuffDecompress ((char*)load_start, &unc_len, (char *)os_data, os_len, CFG_MALLOC_LEN < (4096 * 1024), 0); if (i != BZ_OK) { @@ -201,7 +222,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) default: if (iflag) enable_interrupts(); - printf ("Unimplemented compression type %d\n", image_get_comp (hdr)); + printf ("Unimplemented compression type %d\n", comp); show_boot_progress (-7); return 1; } @@ -219,42 +240,42 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress (8); - switch (image_get_os (hdr)) { + switch (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, hdr, verify); + do_bootm_linux (cmdtp, flag, argc, argv, &images, verify); break; case IH_OS_NETBSD: - do_bootm_netbsd (cmdtp, flag, argc, argv, hdr, verify); + do_bootm_netbsd (cmdtp, flag, argc, argv, &images, verify); break; #ifdef CONFIG_LYNXKDI case IH_OS_LYNXOS: - do_bootm_lynxkdi (cmdtp, flag, argc, argv, hdr, verify); + do_bootm_lynxkdi (cmdtp, flag, argc, argv, &images, verify); break; #endif case IH_OS_RTEMS: - do_bootm_rtems (cmdtp, flag, argc, argv, hdr, verify); + do_bootm_rtems (cmdtp, flag, argc, argv, &images, verify); break; #if defined(CONFIG_CMD_ELF) case IH_OS_VXWORKS: - do_bootm_vxworks (cmdtp, flag, argc, argv, hdr, verify); + do_bootm_vxworks (cmdtp, flag, argc, argv, &images, verify); break; case IH_OS_QNX: - do_bootm_qnxelf (cmdtp, flag, argc, argv, hdr, verify); + do_bootm_qnxelf (cmdtp, flag, argc, argv, &images, verify); break; #endif #ifdef CONFIG_ARTOS case IH_OS_ARTOS: - do_bootm_artos (cmdtp, flag, argc, argv, hdr, verify); + do_bootm_artos (cmdtp, flag, argc, argv, &images, verify); break; #endif } @@ -279,77 +300,119 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * 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, +static void *get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], int verify, + 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; +#endif + /* 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); } show_boot_progress (1); - printf ("## Booting image at %08lx ...\n", img_addr); + printf ("## Booting kernel 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); + /* check image type, for FIT images get FIT kernel node */ + switch (gen_image_get_format ((void *)img_addr)) { + case IMAGE_FORMAT_LEGACY: - if (!image_check_hcrc (hdr)) { - puts ("Bad Header Checksum\n"); - show_boot_progress (-2); - return NULL; - } + debug ("* kernel: legacy format image\n"); + hdr = (image_header_t *)img_addr; - show_boot_progress (3); - image_print_contents (hdr); + if (!image_check_magic(hdr)) { + puts ("Bad Magic Number\n"); + show_boot_progress (-1); + return NULL; + } + show_boot_progress (2); - if (verify) { - puts (" Verifying Checksum ... "); - if (!image_check_dcrc (hdr)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-3); + if (!image_check_hcrc (hdr)) { + puts ("Bad Header Checksum\n"); + show_boot_progress (-2); 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); + 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; + } + images->legacy_hdr_os = hdr; + images->legacy_hdr_valid = 1; - 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; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (void *)img_addr; + debug ("* kernel: FIT format image\n"); + fit_unsupported ("kernel"); + return NULL; +#endif default: - printf ("Wrong Image Type for %s command\n", cmdtp->name); - show_boot_progress (-5); + printf ("Wrong Image Format for %s command\n", cmdtp->name); return NULL; } + debug (" kernel data at 0x%08lx, end = 0x%08lx\n", *os_data, *os_data + *os_len); - return hdr; + return (void *)img_addr; } U_BOOT_CMD( @@ -426,29 +489,44 @@ int do_iminfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) static int image_info (ulong addr) { - image_header_t *hdr = (image_header_t *)addr; + void *hdr = (void *)addr; printf ("\n## Checking Image at %08lx ...\n", addr); - if (!image_check_magic (hdr)) { - puts (" Bad Magic Number\n"); - return 1; - } + switch (gen_image_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 (!image_check_hcrc (hdr)) { - puts (" Bad Header Checksum\n"); - return 1; - } + if (!image_check_hcrc (hdr)) { + puts (" Bad Header Checksum\n"); + return 1; + } - image_print_contents (hdr); + image_print_contents (hdr); - puts (" Verifying Checksum ... "); - if (!image_check_dcrc (hdr)) { - puts (" Bad Data CRC\n"); - return 1; + 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"); + fit_unsupported ("iminfo"); + return 0; +#endif + default: + puts ("Unknown image format!\n"); + break; } - puts ("OK\n"); - return 0; + + return 1; } U_BOOT_CMD( @@ -470,7 +548,7 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { flash_info_t *info; int i, j; - image_header_t *hdr; + void *hdr; for (i = 0, info = &flash_info[0]; i < CFG_MAX_FLASH_BANKS; ++i, ++info) { @@ -479,23 +557,38 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) goto next_bank; for (j = 0; j < info->sector_count; ++j) { - hdr = (image_header_t *)info->start[j]; - - if (!hdr || !image_check_magic (hdr)) + hdr = (void *)info->start[j]; + if (!hdr) goto next_sector; - if (!image_check_hcrc (hdr)) + switch (gen_image_get_format (hdr)) { + case IMAGE_FORMAT_LEGACY: + if (!image_check_magic (hdr)) + goto next_sector; + + 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: + printf ("FIT Image at %08lX:\n", (ulong)hdr); + fit_unsupported ("imls"); + break; +#endif + default: goto next_sector; - - printf ("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"); } + next_sector: ; } next_bank: ; @@ -555,14 +648,22 @@ static void fixup_silent_linux () static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { void (*loader)(bd_t *, image_header_t *, char *, char *); - image_header_t *img_addr; + 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 + hdr = images->legacy_hdr_os; + /* * Booting a (NetBSD) kernel image * @@ -574,12 +675,11 @@ static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, * line, the name of the console device, and (optionally) the * address of the original image header. */ - - img_addr = 0; + os_hdr = NULL; if (image_check_type (hdr, IH_TYPE_MULTI)) { image_multi_getimg (hdr, 1, &kernel_data, &kernel_len); if (kernel_len) - img_addr = hdr; + os_hdr = hdr; } consdev = ""; @@ -625,24 +725,41 @@ static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, * r5: console device * r6: boot args string */ - (*loader) (gd->bd, img_addr, consdev, cmdline); + (*loader) (gd->bd, os_hdr, consdev, cmdline); } #ifdef CONFIG_LYNXKDI static void do_bootm_lynxkdi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - lynxkdi_boot (hdr); + image_header_t *hdr = images->legacy_hdr_os; + +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("Lynx"); + do_reset (cmdtp, flag, argc, argv); + } +#endif + + lynxkdi_boot ((image_header_t *)hdr); } #endif /* CONFIG_LYNXKDI */ static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { + image_header_t *hdr = images->legacy_hdr_os; void (*entry_point)(bd_t *); +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("RTEMS"); + do_reset (cmdtp, flag, argc, argv); + } +#endif + entry_point = (void (*)(bd_t *))image_get_ep (hdr); printf ("## Transferring control to RTEMS (at address %08lx) ...\n", @@ -660,9 +777,17 @@ static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_CMD_ELF) static void do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { char str[80]; + image_header_t *hdr = images->legacy_hdr_os; + +#if defined(CONFIG_FIT) + if (hdr == NULL) { + fit_unsupported_reset ("VxWorks"); + do_reset (cmdtp, flag, argc, argv); + } +#endif sprintf(str, "%x", image_get_ep (hdr)); /* write entry-point into string */ setenv("loadaddr", str); @@ -671,10 +796,18 @@ static void do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, static void do_bootm_qnxelf(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { char *local_args[2]; char str[16]; + image_header_t *hdr = images->legacy_hdr_os; + +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("QNX"); + do_reset (cmdtp, flag, argc, argv); + } +#endif sprintf(str, "%x", image_get_ep (hdr)); /* write entry-point into string */ local_args[0] = argv[0]; @@ -686,7 +819,7 @@ static void do_bootm_qnxelf(cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_ARTOS) && defined(CONFIG_PPC) static void do_bootm_artos (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { ulong top; char *s, *cmdline; @@ -694,6 +827,14 @@ static void do_bootm_artos (cmd_tbl_t *cmdtp, int flag, int i, j, nxt, len, envno, envsz; bd_t *kbd; void (*entry)(bd_t *bd, char *cmdline, char **fwenv, ulong top); + image_header_t *hdr = images->legacy_hdr_os; + +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("ARTOS"); + do_reset (cmdtp, flag, argc, argv); + } +#endif /* * Booting an ARTOS kernel image + application diff --git a/common/cmd_doc.c b/common/cmd_doc.c index 70bbd31dde..3358b04622 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -261,17 +261,29 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (38); - hdr = (image_header_t *)addr; + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (image_check_magic (hdr)) { + if (image_check_magic (hdr)) { - image_print_contents (hdr); + image_print_contents (hdr); - cnt = image_get_image_size (hdr); - cnt -= SECTORSIZE; - } else { - puts ("\n** Bad Magic Number **\n"); - show_boot_progress (-39); + cnt = image_get_image_size (hdr); + cnt -= SECTORSIZE; + } else { + puts ("\n** Bad Magic Number **\n"); + show_boot_progress (-39); + return 1; + } + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("docboot"); + return 1; +#endif + default: + puts ("** Unknown image type\n"); return 1; } show_boot_progress (39); diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index 9ddc59b7a0..b6e023a5da 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -835,14 +835,28 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf("result%d: 0x%02X\n",i,pCMD->result[i]); return 1; } - hdr = (image_header_t *)addr; - if (!image_check_magic (hdr)) { - printf ("Bad Magic Number\n"); + + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; + if (!image_check_magic (hdr)) { + printf ("Bad Magic Number\n"); + return 1; + } + image_print_contents (hdr); + + imsize = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("fdcboot"); + return 1; +#endif + default: + puts ("** Unknown image type\n"); return 1; } - image_print_contents (hdr); - imsize= image_get_image_size (hdr); nrofblk=imsize/512; if((imsize%512)>0) nrofblk++; @@ -861,20 +875,18 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* Loading ok, update default load address */ load_addr = addr; - if(image_check_type (hdr, 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 *[]); + /* 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; + local_args[0] = argv[0]; + local_args[1] = NULL; - printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); + printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); - do_bootm (cmdtp, 0, 1, local_args); - rcode ++; - } + do_bootm (cmdtp, 0, 1, local_args); + rcode ++; } return rcode; } diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c index 4030d04f8d..10199f59d4 100644 --- a/common/cmd_fpga.c +++ b/common/cmd_fpga.c @@ -216,19 +216,31 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) break; case FPGA_LOADMK: - { - image_header_t header; - image_header_t *hdr = &header; - ulong data; - - memmove (&header, (char *)fpga_data, image_get_header_size ()); - if (!image_check_magic (hdr)) { - puts ("Bad Magic Number\n"); - return 1; + switch (gen_image_get_format (fpga_data)) { + case IMAGE_FORMAT_LEGACY: + { + image_header_t *hdr = (image_header_t *)fpga_data; + ulong data; + + if (!image_check_magic (hdr)) { + puts ("Bad Magic Number\n"); + return 1; + } + data = (ulong)image_get_data (hdr); + data_size = image_get_data_size (hdr); + rc = fpga_load (dev, (void *)data, data_size); } - data = ((ulong)fpga_data + image_get_header_size ()); - data_size = image_get_data_size (hdr); - rc = fpga_load (dev, (void *)data, data_size); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("fpga"); + rc = FPGA_FAIL; + break; +#endif + default: + puts ("** Unknown image type\n"); + rc = FPGA_FAIL; + break; } break; diff --git a/common/cmd_ide.c b/common/cmd_ide.c index a3966435d6..bef04db4f6 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -446,25 +446,38 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (48); - hdr = (image_header_t *)addr; + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (!image_check_magic (hdr)) { - printf("\n** Bad Magic Number **\n"); - show_boot_progress (-49); - return 1; - } - show_boot_progress (49); + if (!image_check_magic (hdr)) { + printf("\n** Bad Magic Number **\n"); + show_boot_progress (-49); + return 1; + } + show_boot_progress (49); + + if (!image_check_hcrc (hdr)) { + puts ("\n** Bad Header Checksum **\n"); + show_boot_progress (-50); + return 1; + } + show_boot_progress (50); - if (!image_check_hcrc (hdr)) { - puts ("\n** Bad Header Checksum **\n"); - show_boot_progress (-50); + image_print_contents (hdr); + + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("diskboot"); + return 1; +#endif + default: + puts ("** Unknown image type\n"); return 1; } - show_boot_progress (50); - - image_print_contents (hdr); - cnt = image_get_image_size (hdr); cnt += info.blksz - 1; cnt /= info.blksz; cnt -= 1; diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 7fd6667a7e..b099afeca0 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -512,18 +512,32 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, } show_boot_progress (56); - hdr = (image_header_t *) addr; + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; + + if (!image_check_magic (hdr)) { + printf("\n** Bad Magic Number 0x%x **\n", + image_get_magic (hdr)); + show_boot_progress (-57); + return 1; + } + show_boot_progress (57); + + image_print_contents (hdr); - if (!image_check_magic (hdr)) { - printf("\n** Bad Magic Number 0x%x **\n", image_get_magic (hdr)); - show_boot_progress (-57); + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("nand_load_image"); + return 1; +#endif + default: + puts ("** Unknown image type\n"); return 1; } - show_boot_progress (57); - - image_print_contents (hdr); - cnt = image_get_image_size (hdr); if (jffs2) { nand_read_options_t opts; memset(&opts, 0, sizeof(opts)); @@ -980,17 +994,30 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (56); - hdr = (image_header_t *)addr; + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (image_check_magic (hdr)) { + if (image_check_magic (hdr)) { - image_print_contents (hdr); + image_print_contents (hdr); - cnt = image_get_image_size (hdr); - cnt -= SECTORSIZE; - } else { - printf ("\n** Bad Magic Number 0x%x **\n", image_get_magic (hdr)); - show_boot_progress (-57); + cnt = image_get_image_size (hdr); + cnt -= SECTORSIZE; + } else { + printf ("\n** Bad Magic Number 0x%x **\n", + image_get_magic (hdr)); + show_boot_progress (-57); + return 1; + } + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("nboot"); + return 1; +#endif + default: + puts ("** Unknown image type\n"); return 1; } show_boot_progress (57); diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index 5aae7ece5e..42b3072984 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -273,20 +273,33 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - hdr = (image_header_t *)addr; + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (!image_check_magic (hdr)) { - printf("\n** Bad Magic Number **\n"); - return 1; - } + if (!image_check_magic (hdr)) { + printf("\n** Bad Magic Number **\n"); + return 1; + } - if (!image_check_hcrc (hdr)) { - puts ("\n** Bad Header Checksum **\n"); + if (!image_check_hcrc (hdr)) { + puts ("\n** Bad Header Checksum **\n"); + return 1; + } + + image_print_contents (hdr); + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("scsi"); + return 1; +#endif + default: + puts ("** Unknown image type\n"); return 1; } - image_print_contents (hdr); - cnt = image_get_image_size (hdr); cnt += info.blksz - 1; cnt /= info.blksz; cnt -= 1; diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 3f1aa7d9fe..ad3873c2cb 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -386,21 +386,34 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - hdr = (image_header_t *)addr; + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (!image_check_magic (hdr)) { - printf("\n** Bad Magic Number **\n"); - return 1; - } + if (!image_check_magic (hdr)) { + printf("\n** Bad Magic Number **\n"); + return 1; + } + + if (!image_check_hcrc (hdr)) { + puts ("\n** Bad Header Checksum **\n"); + return 1; + } - if (!image_check_hcrc (hdr)) { - puts ("\n** Bad Header Checksum **\n"); + image_print_contents (hdr); + + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("usbboot"); + return 1; +#endif + default: + puts ("** Unknown image type\n"); return 1; } - image_print_contents (hdr); - - cnt = image_get_image_size (hdr); cnt += info.blksz - 1; cnt /= info.blksz; cnt -= 1; diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c index 7d83dc35bc..4dadc3709d 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -56,63 +56,76 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) dest = simple_strtoul(argv[3], NULL, 16); } - printf("## Copying from image at %08lx ...\n", addr); - hdr = (image_header_t *)addr; + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: - if (!image_check_magic (hdr)) { - printf("Bad Magic Number\n"); - return 1; - } - - if (!image_check_hcrc (hdr)) { - printf("Bad Header Checksum\n"); - return 1; - } -#ifdef DEBUG - image_print_contents (hdr); -#endif + printf("## Copying from legacy image at %08lx ...\n", addr); + hdr = (image_header_t *)addr; + if (!image_check_magic (hdr)) { + printf("Bad Magic Number\n"); + return 1; + } - if (!image_check_type (hdr, IH_TYPE_MULTI)) { - printf("Wrong Image Type for %s command\n", cmdtp->name); - return 1; - } + if (!image_check_hcrc (hdr)) { + printf("Bad Header Checksum\n"); + return 1; + } + #ifdef DEBUG + image_print_contents (hdr); + #endif - if (image_get_comp (hdr) != IH_COMP_NONE) { - printf("Wrong Compression Type for %s command\n", cmdtp->name); - return 1; - } + if (!image_check_type (hdr, IH_TYPE_MULTI)) { + printf("Wrong Image Type for %s command\n", + cmdtp->name); + return 1; + } - if (verify) { - printf(" Verifying Checksum ... "); - if (!image_check_dcrc (hdr)) { - printf("Bad Data CRC\n"); + if (image_get_comp (hdr) != IH_COMP_NONE) { + printf("Wrong Compression Type for %s command\n", + cmdtp->name); return 1; } - printf("OK\n"); - } - data = image_get_data (hdr); - 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 = image_to_cpu (len_ptr[i]); - tail = len % 4; - data += len; - if (tail) { - data += 4 - tail; + if (verify) { + printf(" Verifying Checksum ... "); + if (!image_check_dcrc (hdr)) { + printf("Bad Data CRC\n"); + return 1; } + printf("OK\n"); } - } - if (argc > 2 && part >= i) { - printf("Bad Image Part\n"); + + data = image_get_data (hdr); + 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 = image_to_cpu (len_ptr[i]); + tail = len % 4; + data += len; + if (tail) { + data += 4 - tail; + } + } + } + if (argc > 2 && part >= i) { + printf("Bad Image Part\n"); + return 1; + } + len = image_to_cpu (len_ptr[part]); +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("imxtract"); + return 1; +#endif + default: + puts ("Invalid image type for imxtract\n"); return 1; } - len = image_to_cpu (len_ptr[part]); if (argc > 3) { memcpy((char *) dest, (char *) data, len); diff --git a/common/image.c b/common/image.c index 690e0af6cb..ea27b0ba5b 100644 --- a/common/image.c +++ b/common/image.c @@ -490,9 +490,6 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, image_header_t *rd_hdr; show_boot_progress (9); - - /* 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)) { @@ -540,7 +537,7 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, * @flag: command flag * @argc: command argument count * @argv: command argument list - * @hdr: pointer to the posiibly multi componet kernel image + * @images: pointer to the bootm images strcture * @verify: checksum verification flag * @arch: expected ramdisk architecture * @rd_start: pointer to a ulong variable, will hold ramdisk start address @@ -558,56 +555,111 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, * board is reset if ramdisk image is found but corrupted */ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify, uint8_t arch, + bootm_headers_t *images, int verify, uint8_t arch, ulong *rd_start, ulong *rd_end) { - ulong rd_addr; + 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; +#endif - if (argc >= 3) { + /* + * 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) { +#if defined(CONFIG_FIT) /* - * Look for a '-' which indicates to ignore the - * ramdisk argument + * 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 (strcmp(argv[2], "-") == 0) { - debug ("## Skipping init Ramdisk\n"); - rd_len = rd_data = 0; - } else { - /* - * Check if there is an initrd image at the - * address provided in the second bootm argument - */ - rd_addr = simple_strtoul (argv[2], NULL, 16); - printf ("## Loading init Ramdisk Image at %08lx ...\n", + 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); + } + + /* copy from dataflash if needed */ + printf ("## Loading init Ramdisk Image at %08lx ...\n", + rd_addr); + rd_addr = gen_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 (gen_image_get_format ((void *)rd_addr)) { + case IMAGE_FORMAT_LEGACY: + + debug ("* ramdisk: legacy format image\n"); rd_hdr = image_get_ramdisk (cmdtp, flag, argc, argv, rd_addr, arch, verify); 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; + debug ("* ramdisk: FIT format image\n"); + fit_unsupported_reset ("ramdisk"); + do_reset (cmdtp, flag, argc, argv); +#endif + default: + printf ("Wrong Image Format for %s command\n", + cmdtp->name); + rd_data = rd_len = 0; + } #if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO) - /* - *we need to copy the ramdisk to SRAM to let Linux boot - */ - memmove ((void *)image_get_load (rd_hdr), - (uchar *)rd_data, rd_len); - - rd_data = image_get_load (rd_hdr); -#endif /* CONFIG_B2 || CONFIG_EVB4510 || 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 (image_check_type (hdr, IH_TYPE_MULTI)) { + } else if (images->legacy_hdr_valid && + image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) { /* - * Now check if we have a multifile image - * Get second entry data start address and len + * 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 " - "Image at %08lx ...\n", (ulong)hdr); - image_multi_getimg (hdr, 1, &rd_data, &rd_len); + "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 @@ -904,6 +956,7 @@ inline int fit_parse_subimage (const char *spec, ulong addr_curr, { return fit_parse_spec (spec, ':', addr_curr, addr, image_name); } + #endif /* CONFIG_FIT */ #endif /* USE_HOSTCC */ diff --git a/include/image.h b/include/image.h index 502d35a3ef..2f4b67d445 100644 --- a/include/image.h +++ b/include/image.h @@ -44,6 +44,9 @@ #define CONFIG_FIT 1 #define CONFIG_OF_LIBFDT 1 +/* enable fit_format_error(), fit_format_warning() */ +#define CONFIG_FIT_VERBOSE 1 + #if defined(CONFIG_FIT) && !defined(CONFIG_OF_LIBFDT) #error "CONFIG_OF_LIBFDT not enabled, required by CONFIG_FIT!" #endif @@ -175,6 +178,33 @@ typedef struct image_header { uint8_t ih_name[IH_NMLEN]; /* Image Name */ } image_header_t; +/* + * Legacy and FIT format headers used by do_bootm() and do_bootm_() + * routines. + */ +typedef struct bootm_headers { + /* + * Legacy os image header, if it is a multi component image + * then 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) + void *fit_hdr_os; /* os FIT image header */ + char *fit_uname_os; /* os subimage node unit name */ + + void *fit_hdr_rd; /* init ramdisk FIT image header */ + char *fit_uname_rd; /* init ramdisk node unit name */ + +#if defined(CONFIG_PPC) + void *fit_hdr_fdt; /* FDT blob FIT image header */ + char *fit_uname_fdt; /* FDT blob node unit name */ +#endif +#endif +} bootm_headers_t; + /* * Some systems (for example LWMON) have very short watchdog periods; * we must make sure to split long operations like memmove() or @@ -355,7 +385,7 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, ulong rd_addr, uint8_t arch, int verify); void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify, uint8_t arch, + bootm_headers_t *images, int verify, uint8_t arch, ulong *rd_start, ulong *rd_end); #if defined(CONFIG_PPC) || defined(CONFIG_M68K) @@ -368,14 +398,29 @@ ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end); ulong get_boot_kbd (ulong alloc_current, bd_t **kbd); #endif /* CONFIG_PPC || CONFIG_M68K */ +/*******************************************************************/ +/* New uImage format */ +/*******************************************************************/ #if defined(CONFIG_FIT) -/* - * New uImage format - */ 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); + +#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 /* USE_HOSTCC */ diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c index 31c2d67225..4849c8ab0b 100644 --- a/lib_arm/bootm.c +++ b/lib_arm/bootm.c @@ -56,24 +56,38 @@ static void setup_end_tag (bd_t *bd); static void setup_videolfb_tag (gd_t *gd); # endif - static struct tag *params; #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ +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[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - ulong initrd_start, initrd_end; - void (*theKernel)(int zero, int arch, uint params); - 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); #ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); #endif - theKernel = (void (*)(int, int, uint))image_get_ep (hdr); + /* 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) { + fit_unsupported_reset ("ARM linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + theKernel = (void (*)(int, int, uint))ep; s = getenv ("machid"); if (s) { @@ -81,7 +95,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], printf ("Using machid 0x%x from environment\n", machid); } - get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, verify, IH_ARCH_ARM, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c index a934cae9d9..c449394e6b 100644 --- a/lib_avr32/bootm.c +++ b/lib_avr32/bootm.c @@ -34,6 +34,8 @@ DECLARE_GLOBAL_DATA_PTR; /* CPU-specific hook to allow flushing of caches, etc. */ extern void prepare_to_boot(void); +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + static struct tag *setup_start_tag(struct tag *params) { params->hdr.tag = ATAG_CORE; @@ -172,17 +174,29 @@ static void setup_end_tag(struct tag *params) } void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - ulong initrd_start, initrd_end; - - void (*theKernel)(int magic, void *tagtable); - struct tag *params, *params_start; - char *commandline = getenv("bootargs"); - - theKernel = (void *)image_get_ep (hdr); + ulong initrd_start, initrd_end; + ulong ep = 0; + void (*theKernel)(int magic, void *tagtable); + struct tag *params, *params_start; + char *commandline = 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) { + fit_unsupported_reset ("AVR32 linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + theKernel = (void *)ep; - get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, verify, IH_ARCH_AVR32, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_blackfin/bootm.c b/lib_blackfin/bootm.c index 6299415b11..8010e5d64f 100644 --- a/lib_blackfin/bootm.c +++ b/lib_blackfin/bootm.c @@ -47,16 +47,30 @@ extern void flush_data_cache(void); static char *make_command_line(void); void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - int (*appl) (char *cmdline); - char *cmdline; + int (*appl) (char *cmdline); + char *cmdline; + ulong ep = 0; #ifdef SHARED_RESOURCES swap_to(FLASH); #endif - appl = (int (*)(char *))image_get_ep (hdr); + /* 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) { + fit_unsupported_reset ("AVR32 linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + appl = (int (*)(char *))ep; + printf("Starting Kernel at = %x\n", appl); cmdline = make_command_line(); if (icache_status()) { diff --git a/lib_i386/bootm.c b/lib_i386/bootm.c index ab6c2a9676..3a6497c77a 100644 --- a/lib_i386/bootm.c +++ b/lib_i386/bootm.c @@ -32,22 +32,35 @@ 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[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - void *base_ptr; + void *base_ptr; + ulong os_data, os_len; + ulong initrd_start, initrd_end; + ulong ep; + image_header_t *hdr; - ulong os_data, os_len; - ulong initrd_start, initrd_end; - - get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, verify, IH_ARCH_I386, &initrd_start, &initrd_end); - /* if multi-part image, we need to advance base ptr */ - if (image_check_type (hdr, IH_TYPE_MULTI)) { - image_multi_getimg (hdr, 0, &os_data, &os_len); + 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) { + fit_unsupported_reset ("I386 linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif } else { - os_data = image_get_data (hdr); - os_len = image_get_data_size (hdr); + puts ("Could not find kernel image!\n"); + do_reset (cmdtp, flag, argc, argv); } base_ptr = load_zimage ((void*)os_data, os_len, diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index ac04da08a5..ce8be05e4c 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -42,10 +42,11 @@ DECLARE_GLOBAL_DATA_PTR; 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[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { ulong sp, sp_limit, alloc_current; @@ -53,8 +54,9 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, ulong initrd_start, initrd_end; ulong cmd_start, cmd_end; - bd_t *kbd; - void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); + bd_t *kbd; + ulong ep = 0; + void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); /* * Booting a (Linux) kernel image @@ -78,12 +80,22 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, alloc_current = get_boot_kbd (alloc_current, &kbd); set_clocks_in_mhz(kbd); - /* find kernel */ - kernel = - (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); + /* 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) { + fit_unsupported_reset ("M68K linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, verify, IH_ARCH_M68K, &rd_data_start, &rd_data_end); rd_len = rd_data_end - rd_data_start; diff --git a/lib_microblaze/bootm.c b/lib_microblaze/bootm.c index bccfbe1457..1455211864 100644 --- a/lib_microblaze/bootm.c +++ b/lib_microblaze/bootm.c @@ -32,14 +32,29 @@ 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[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { /* First parameter is mapped to $r5 for kernel boot args */ - void (*theKernel) (char *); - char *commandline = getenv ("bootargs"); + void (*theKernel) (char *); + char *commandline = getenv ("bootargs"); + ulong ep = 0; - theKernel = (void (*)(char *))image_get_ep (hdr); + /* 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) { + fit_unsupported_reset ("MICROBLAZE linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + theKernel = (void (*)(char *))ep; show_boot_progress (15); diff --git a/lib_mips/bootm.c b/lib_mips/bootm.c index fb91c76d94..5c2f28e622 100644 --- a/lib_mips/bootm.c +++ b/lib_mips/bootm.c @@ -43,20 +43,32 @@ static int linux_env_idx; static void linux_params_init (ulong start, char * commandline); 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[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - ulong initrd_start, initrd_end; - - void (*theKernel) (int, char **, char **, int *); - char *commandline = getenv ("bootargs"); - char env_buf[12]; - - theKernel = - (void (*)(int, char **, char **, int *))image_get_ep (hdr); + ulong initrd_start, initrd_end; + ulong ep = 0; + void (*theKernel) (int, char **, char **, int *); + char *commandline = getenv ("bootargs"); + char env_buf[12]; + + /* 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) { + fit_unsupported_reset ("MIPS linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + theKernel = (void (*)(int, char **, char **, int *))ep; - get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, verify, IH_ARCH_MIPS, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_nios/bootm.c b/lib_nios/bootm.c index 55f7e3adc1..92a58f2b7f 100644 --- a/lib_nios/bootm.c +++ b/lib_nios/bootm.c @@ -29,6 +29,6 @@ * */ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image__header_t *hdr, int verify) + bootm_headers_t *images, int verify) { } diff --git a/lib_nios2/bootm.c b/lib_nios2/bootm.c index cb843246b8..56d1d19dd4 100644 --- a/lib_nios2/bootm.c +++ b/lib_nios2/bootm.c @@ -25,10 +25,26 @@ #include #include +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[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - void (*kernel)(void) = (void (*)(void))image_get_ep (hdr); + 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) { + fit_unsupported_reset ("NIOS2 linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + void (*kernel)(void) = (void (*)(void))ep; /* For now we assume the Microtronix linux ... which only * needs to be called ;-) diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index d2ee3dc5cc..a1bbfc6314 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -43,7 +43,7 @@ static void fdt_error (const char *msg); static ulong get_fdt (ulong alloc_current, cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, char **of_flat_tree); + bootm_headers_t *images, char **of_flat_tree); #endif #ifdef CFG_INIT_RAM_LOCK @@ -59,7 +59,7 @@ static void set_clocks_in_mhz (bd_t *kbd); void __attribute__((noinline)) do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, + bootm_headers_t *images, int verify) { ulong sp, sp_limit, alloc_current; @@ -69,6 +69,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, ulong cmd_start, cmd_end; bd_t *kbd; + ulong ep = 0; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); #if defined(CONFIG_OF_LIBFDT) @@ -97,11 +98,22 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, alloc_current = get_boot_kbd (alloc_current, &kbd); set_clocks_in_mhz(kbd); - /* find kernel */ - kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); + /* 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) { + fit_unsupported_reset ("PPC linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, verify, IH_ARCH_PPC, &rd_data_start, &rd_data_end); rd_len = rd_data_end - rd_data_start; @@ -113,7 +125,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ alloc_current = get_fdt (alloc_current, - cmdtp, flag, argc, argv, hdr, &of_flat_tree); + cmdtp, flag, argc, argv, images, &of_flat_tree); /* * Add the chosen node if it doesn't exist, add the env and bd_t @@ -225,33 +237,69 @@ static void fdt_error (const char *msg) static ulong get_fdt (ulong alloc_current, cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, char **of_flat_tree) + bootm_headers_t *images, char **of_flat_tree) { + ulong fdt_addr; image_header_t *fdt_hdr; + char *fdt_blob = NULL; ulong fdt_relocate = 0; - char *fdt = NULL; ulong new_alloc_current; + 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; +#endif - if(argc > 3) { - fdt = (char *)simple_strtoul (argv[3], NULL, 16); + if (argc > 3) { +#if defined(CONFIG_FIT) + /* + * 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); + } - debug ("## Checking for 'FDT'/'FDT image' at %08lx\n", fdt); + debug ("## Checking for 'FDT'/'FDT image' at %08lx\n", + fdt_addr); /* copy from dataflash if needed */ - fdt = (char *)gen_get_image ((ulong)fdt); - fdt_hdr = (image_header_t *)fdt; + fdt_addr = gen_get_image (fdt_addr); - if (fdt_check_header (fdt) == 0) { - printf ("## Flattened Device Tree blob at %08lx\n", fdt); -#ifndef CFG_NO_FLASH - if (addr2info ((ulong)fdt) != NULL) - fdt_relocate = 1; -#endif - } else if (image_check_magic (fdt_hdr)) { - ulong image_start, image_end; - ulong load_start, load_end; + /* + * 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 (gen_image_get_format ((void *)fdt_addr)) { + case IMAGE_FORMAT_LEGACY: + debug ("* fdt: legacy format image\n"); - printf ("## Flattened Device Tree Image at %08lx\n", + fdt_hdr = (image_header_t *)fdt_addr; + printf ("## Flattened Device Tree Legacy Image at %08lx\n", fdt_hdr); image_print_contents (fdt_hdr); @@ -296,51 +344,87 @@ static ulong get_fdt (ulong alloc_current, (void *)image_get_data (fdt_hdr), image_get_data_size (fdt_hdr)); - fdt = (char *)image_get_load (fdt_hdr); - } else { - fdt_error ("Did not find a Flattened Device Tree"); + fdt_blob = (char *)image_get_load (fdt_hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + + /* check FDT blob vs FIT hdr */ + if (fit_uname_config || fit_uname_fdt) { + /* + * FIT image + */ + fit_hdr = (void *)fdt_addr; + debug ("* fdt: FIT format image\n"); + fit_unsupported_reset ("PPC fdt"); + do_reset (cmdtp, flag, argc, argv); + } else { + /* + * FDT blob + */ + printf ("## Flattened Device Tree blob at %08lx\n", fdt_blob); + fdt_blob = (char *)fdt_addr; + } + break; +#endif + default: + fdt_error ("Did not find a cmdline Flattened Device Tree"); do_reset (cmdtp, flag, argc, argv); } - printf (" Booting using the fdt at 0x%x\n", - fdt); - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + + 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)hdr); + "component Image at %08lX\n", + (ulong)images->legacy_hdr_os); - image_multi_getimg (hdr, 2, &fdt_data, &fdt_len); + image_multi_getimg (images->legacy_hdr_os, 2, &fdt_data, &fdt_len); if (fdt_len) { - fdt = (char *)fdt_data; - printf (" Booting using the fdt at 0x%x\n", fdt); + fdt_blob = (char *)fdt_data; + printf (" Booting using the fdt at 0x%x\n", fdt_blob); -#ifndef CFG_NO_FLASH - /* move the blob if it is in flash (set of_relocte) */ - if (addr2info ((ulong)fdt) != NULL) - fdt_relocate = 1; -#endif - - if (fdt_check_header (fdt) != 0) { + if (fdt_check_header (fdt_blob) != 0) { fdt_error ("image is not a fdt"); do_reset (cmdtp, flag, argc, argv); } - if (be32_to_cpu (fdt_totalsize (fdt)) != fdt_len) { + if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) { fdt_error ("fdt size != image size"); do_reset (cmdtp, flag, argc, argv); } } else { - debug (" Did not find a Flattened Device Tree"); + fdt_error ("Did not find a Flattened Device Tree " + "in a legacy multi-component image"); + do_reset (cmdtp, flag, argc, argv); } + } else { + debug ("## No Flattened Device Tree\n"); + *of_flat_tree = NULL; + return alloc_current; } +#ifndef CFG_NO_FLASH + /* move the blob if it is in flash (set fdt_relocate) */ + if (addr2info ((ulong)fdt_blob) != NULL) + fdt_relocate = 1; +#endif + #ifdef CFG_BOOTMAPSZ /* * The blob must be within CFG_BOOTMAPSZ, * so we flag it to be copied if it is not. */ - if (fdt >= (char *)CFG_BOOTMAPSZ) + if (fdt_blob >= (char *)CFG_BOOTMAPSZ) fdt_relocate = 1; #endif @@ -349,20 +433,20 @@ static ulong get_fdt (ulong alloc_current, int err; ulong of_start, of_len; - of_len = be32_to_cpu (fdt_totalsize (fdt)); + of_len = be32_to_cpu (fdt_totalsize (fdt_blob)); /* position on a 4K boundary before the alloc_current */ of_start = alloc_current - of_len; of_start &= ~(4096 - 1); /* align on page */ debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - (ulong)fdt, (ulong)fdt + of_len - 1, + (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, (void *)of_start, of_len); + err = fdt_open_into (fdt_blob, (void *)of_start, of_len); if (err != 0) { fdt_error ("fdt move failed"); do_reset (cmdtp, flag, argc, argv); @@ -372,7 +456,7 @@ static ulong get_fdt (ulong alloc_current, *of_flat_tree = (char *)of_start; new_alloc_current = of_start; } else { - *of_flat_tree = fdt; + *of_flat_tree = fdt_blob; new_alloc_current = alloc_current; } diff --git a/lib_sh/bootm.c b/lib_sh/bootm.c index 4e5fe775de..55e64f5182 100644 --- a/lib_sh/bootm.c +++ b/lib_sh/bootm.c @@ -43,6 +43,8 @@ #define RAMDISK_IMAGE_START_MASK 0x07FF +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + #ifdef CFG_DEBUG static void hexdump (unsigned char *buf, int len) { @@ -58,10 +60,24 @@ static void hexdump (unsigned char *buf, int len) #endif void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - char *bootargs = getenv("bootargs"); - void (*kernel) (void) = (void (*)(void))image_get_ep (hdr); + 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) { + fit_unsupported_reset ("SH linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + void (*kernel) (void) = (void (*)(void))ep; /* Setup parameters */ memset(PARAM, 0, 0x1000); /* Clear zero page */ -- 2.25.1