static int fit_check_kernel(const void *fit, int os_noffset, int verify) { fit_image_print(fit, os_noffset, " "); if (verify) { puts(" Verifying Hash Integrity ... "); if (!fit_image_verify(fit, os_noffset)) { puts("Bad Data Hash\n"); bootstage_error(BOOTSTAGE_ID_FIT_CHECK_HASH); return 0; } puts("OK\n"); } bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_ARCH); if (!fit_image_check_target_arch(fit, os_noffset)) { puts("Unsupported Architecture\n"); bootstage_error(BOOTSTAGE_ID_FIT_CHECK_ARCH); return 0; } bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_KERNEL); if (!fit_image_check_type(fit, os_noffset, IH_TYPE_KERNEL) && !fit_image_check_type(fit, os_noffset, IH_TYPE_KERNEL_NOLOAD)) { puts("Not a kernel image\n"); bootstage_error(BOOTSTAGE_ID_FIT_CHECK_KERNEL); return 0; } bootstage_mark(BOOTSTAGE_ID_FIT_CHECKED); return 1; }
/** * MC firmware FIT image parser checks if the image is in FIT * format, verifies integrity of the image and calculates * raw image address and size values. * Returns 0 on success and a negative errno on error. * task fail. **/ int parse_mc_firmware_fit_image(const void **raw_image_addr, size_t *raw_image_size) { int format; void *fit_hdr; int node_offset; const void *data; size_t size; const char *uname = "firmware"; /* Check if the image is in NOR flash */ #ifdef CONFIG_SYS_LS_MC_FW_IN_NOR fit_hdr = (void *)CONFIG_SYS_LS_MC_FW_ADDR; #else #error "No CONFIG_SYS_LS_MC_FW_IN_xxx defined" #endif /* Check if Image is in FIT format */ format = genimg_get_format(fit_hdr); if (format != IMAGE_FORMAT_FIT) { printf("fsl-mc: ERROR: Bad firmware image (not a FIT image)\n"); return -EINVAL; } if (!fit_check_format(fit_hdr)) { printf("fsl-mc: ERROR: Bad firmware image (bad FIT header)\n"); return -EINVAL; } node_offset = fit_image_get_node(fit_hdr, uname); if (node_offset < 0) { printf("fsl-mc: ERROR: Bad firmware image (missing subimage)\n"); return -ENOENT; } /* Verify MC firmware image */ if (!(fit_image_verify(fit_hdr, node_offset))) { printf("fsl-mc: ERROR: Bad firmware image (bad CRC)\n"); return -EINVAL; } /* Get address and size of raw image */ fit_image_get_data(fit_hdr, node_offset, &data, &size); *raw_image_addr = data; *raw_image_size = size; return 0; }
int fit_image_select(const void *fit, int rd_noffset, int verify) { fit_image_print(fit, rd_noffset, " "); if (verify) { puts(" Verifying Hash Integrity ... "); if (!fit_image_verify(fit, rd_noffset)) { puts("Bad Data Hash\n"); return -EACCES; } puts("OK\n"); } return 0; }
/** * MC firmware FIT image parser checks if the image is in FIT * format, verifies integrity of the image and calculates * raw image address and size values. * Returns 0 on success and a negative errno on error. * task fail. **/ int parse_mc_firmware_fit_image(u64 mc_fw_addr, const void **raw_image_addr, size_t *raw_image_size) { int format; void *fit_hdr; int node_offset; const void *data; size_t size; const char *uname = "firmware"; fit_hdr = (void *)mc_fw_addr; /* Check if Image is in FIT format */ format = genimg_get_format(fit_hdr); if (format != IMAGE_FORMAT_FIT) { printf("fsl-mc: ERR: Bad firmware image (not a FIT image)\n"); return -EINVAL; } if (!fit_check_format(fit_hdr)) { printf("fsl-mc: ERR: Bad firmware image (bad FIT header)\n"); return -EINVAL; } node_offset = fit_image_get_node(fit_hdr, uname); if (node_offset < 0) { printf("fsl-mc: ERR: Bad firmware image (missing subimage)\n"); return -ENOENT; } /* Verify MC firmware image */ if (!(fit_image_verify(fit_hdr, node_offset))) { printf("fsl-mc: ERR: Bad firmware image (bad CRC)\n"); return -EINVAL; } /* Get address and size of raw image */ fit_image_get_data(fit_hdr, node_offset, &data, &size); *raw_image_addr = data; *raw_image_size = size; return 0; }
static int sec_firmware_get_data(const void *sec_firmware_img, const void **data, size_t *size) { int conf_node_off, fw_node_off; char *conf_node_name = NULL; char *desc; int ret; conf_node_name = SEC_FIRMEWARE_FIT_CNF_NAME; conf_node_off = fit_conf_get_node(sec_firmware_img, conf_node_name); if (conf_node_off < 0) { printf("SEC Firmware: %s: no such config\n", conf_node_name); return -ENOENT; } fw_node_off = fit_conf_get_prop_node(sec_firmware_img, conf_node_off, SEC_FIRMWARE_FIT_IMAGE); if (fw_node_off < 0) { printf("SEC Firmware: No '%s' in config\n", SEC_FIRMWARE_FIT_IMAGE); return -ENOLINK; } /* Verify secure firmware image */ if (!(fit_image_verify(sec_firmware_img, fw_node_off))) { printf("SEC Firmware: Bad firmware image (bad CRC)\n"); return -EINVAL; } if (fit_image_get_data(sec_firmware_img, fw_node_off, data, size)) { printf("SEC Firmware: Can't get %s subimage data/size", SEC_FIRMWARE_FIT_IMAGE); return -ENOENT; } ret = fit_get_desc(sec_firmware_img, fw_node_off, &desc); if (ret) printf("SEC Firmware: Can't get description\n"); else printf("%s\n", desc); return ret; }
/* * Get PFE firmware from FIT image * * @param data pointer to PFE firmware * @param size pointer to size of the firmware * @param fw_name pfe firmware name, either class or tmu * * @return 0 on success, a negative value on error */ static int pfe_get_fw(const void **data, size_t *size, char *fw_name) { int conf_node_off, fw_node_off; char *conf_node_name = NULL; char *desc; int ret = 0; conf_node_name = PFE_FIRMEWARE_FIT_CNF_NAME; conf_node_off = fit_conf_get_node(pfe_fit_addr, conf_node_name); if (conf_node_off < 0) { printf("PFE Firmware: %s: no such config\n", conf_node_name); return -ENOENT; } fw_node_off = fit_conf_get_prop_node(pfe_fit_addr, conf_node_off, fw_name); if (fw_node_off < 0) { printf("PFE Firmware: No '%s' in config\n", fw_name); return -ENOLINK; } if (!(fit_image_verify(pfe_fit_addr, fw_node_off))) { printf("PFE Firmware: Bad firmware image (bad CRC)\n"); return -EINVAL; } if (fit_image_get_data(pfe_fit_addr, fw_node_off, data, size)) { printf("PFE Firmware: Can't get %s subimage data/size", fw_name); return -ENOENT; } ret = fit_get_desc(pfe_fit_addr, fw_node_off, &desc); if (ret) printf("PFE Firmware: Can't get description\n"); else printf("%s\n", desc); return ret; }
/** * fit_all_image_verify - verify data intergity for all images * @fit: pointer to the FIT format image header * * fit_all_image_verify() goes over all images in the FIT and * for every images checks if all it's hashes are valid. * * returns: * 1, if all hashes of all images are valid * 0, otherwise (or on error) */ int fit_all_image_verify(const void *fit) { int images_noffset; int noffset; int ndepth; int count; /* Find images parent node offset */ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); if (images_noffset < 0) { printf("Can't find images parent node '%s' (%s)\n", FIT_IMAGES_PATH, fdt_strerror(images_noffset)); return 0; } /* Process all image subnodes, check hashes for each */ printf("## Checking hash(es) for FIT Image at %08lx ...\n", (ulong)fit); for (ndepth = 0, count = 0, noffset = fdt_next_node(fit, images_noffset, &ndepth); (noffset >= 0) && (ndepth > 0); noffset = fdt_next_node(fit, noffset, &ndepth)) { if (ndepth == 1) { /* * Direct child node of the images parent node, * i.e. component image node. */ printf(" Hash(es) for Image %u (%s): ", count, fit_get_name(fit, noffset, NULL)); count++; if (!fit_image_verify(fit, noffset)) return 0; printf("\n"); } } return 1; }
static int fit_image_select(const void *fit, int rd_noffset, int verify) { #if !defined(USE_HOSTCC) && defined(CONFIG_FIT_IMAGE_POST_PROCESS) const void *data; size_t size; int ret; #endif fit_image_print(fit, rd_noffset, " "); if (verify) { puts(" Verifying Hash Integrity ... "); if (!fit_image_verify(fit, rd_noffset)) { puts("Bad Data Hash\n"); return -EACCES; } puts("OK\n"); } #if !defined(USE_HOSTCC) && defined(CONFIG_FIT_IMAGE_POST_PROCESS) ret = fit_image_get_data(fit, rd_noffset, &data, &size); if (ret) return ret; /* perform any post-processing on the image data */ board_fit_image_post_process((void **)&data, &size); /* * update U-Boot's understanding of the "data" property start address * and size according to the performed post-processing */ ret = fdt_setprop((void *)fit, rd_noffset, FIT_DATA_PROP, data, size); if (ret) return ret; #endif return 0; }
/* command form: * fpga <op> <device number> <data addr> <datasize> * where op is 'load', 'dump', or 'info' * If there is no device number field, the fpga environment variable is used. * If there is no data addr field, the fpgadata environment variable is used. * The info command requires no data address field. */ int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { int op, dev = FPGA_INVALID_DEVICE; size_t data_size = 0; void *fpga_data = NULL; char *devstr = getenv("fpga"); char *datastr = getenv("fpgadata"); int rc = FPGA_FAIL; int wrong_parms = 0; #if defined(CONFIG_FIT) const char *fit_uname = NULL; ulong fit_addr; #endif #if defined(CONFIG_CMD_FPGA_LOADFS) fpga_fs_info fpga_fsinfo; fpga_fsinfo.fstype = FS_TYPE_ANY; #endif if (devstr) dev = (int) simple_strtoul(devstr, NULL, 16); if (datastr) fpga_data = (void *)simple_strtoul(datastr, NULL, 16); switch (argc) { #if defined(CONFIG_CMD_FPGA_LOADFS) case 9: fpga_fsinfo.blocksize = (unsigned int) simple_strtoul(argv[5], NULL, 16); fpga_fsinfo.interface = argv[6]; fpga_fsinfo.dev_part = argv[7]; fpga_fsinfo.filename = argv[8]; #endif case 5: /* fpga <op> <dev> <data> <datasize> */ data_size = simple_strtoul(argv[4], NULL, 16); case 4: /* fpga <op> <dev> <data> */ #if defined(CONFIG_FIT) if (fit_parse_subimage(argv[3], (ulong)fpga_data, &fit_addr, &fit_uname)) { fpga_data = (void *)fit_addr; debug("* fpga: subimage '%s' from FIT image ", fit_uname); debug("at 0x%08lx\n", fit_addr); } else #endif { fpga_data = (void *)simple_strtoul(argv[3], NULL, 16); debug("* fpga: cmdline image address = 0x%08lx\n", (ulong)fpga_data); } debug("%s: fpga_data = 0x%lx\n", __func__, (ulong)fpga_data); case 3: /* fpga <op> <dev | data addr> */ dev = (int)simple_strtoul(argv[2], NULL, 16); debug("%s: device = %d\n", __func__, dev); /* FIXME - this is a really weak test */ if ((argc == 3) && (dev > fpga_count())) { /* must be buffer ptr */ debug("%s: Assuming buffer pointer in arg 3\n", __func__); #if defined(CONFIG_FIT) if (fit_parse_subimage(argv[2], (ulong)fpga_data, &fit_addr, &fit_uname)) { fpga_data = (void *)fit_addr; debug("* fpga: subimage '%s' from FIT image ", fit_uname); debug("at 0x%08lx\n", fit_addr); } else #endif { fpga_data = (void *)(uintptr_t)dev; debug("* fpga: cmdline image addr = 0x%08lx\n", (ulong)fpga_data); } debug("%s: fpga_data = 0x%lx\n", __func__, (ulong)fpga_data); dev = FPGA_INVALID_DEVICE; /* reset device num */ } case 2: /* fpga <op> */ op = (int)fpga_get_op(argv[1]); break; default: debug("%s: Too many or too few args (%d)\n", __func__, argc); op = FPGA_NONE; /* force usage display */ break; } if (dev == FPGA_INVALID_DEVICE) { puts("FPGA device not specified\n"); op = FPGA_NONE; } switch (op) { case FPGA_NONE: case FPGA_INFO: break; #if defined(CONFIG_CMD_FPGA_LOADFS) case FPGA_LOADFS: /* Blocksize can be zero */ if (!fpga_fsinfo.interface || !fpga_fsinfo.dev_part || !fpga_fsinfo.filename) wrong_parms = 1; #endif case FPGA_LOAD: case FPGA_LOADP: case FPGA_LOADB: case FPGA_LOADBP: case FPGA_DUMP: if (!fpga_data || !data_size) wrong_parms = 1; break; #if defined(CONFIG_CMD_FPGA_LOADMK) case FPGA_LOADMK: if (!fpga_data) wrong_parms = 1; break; #endif } if (wrong_parms) { puts("Wrong parameters for FPGA request\n"); op = FPGA_NONE; } switch (op) { case FPGA_NONE: return CMD_RET_USAGE; case FPGA_INFO: rc = fpga_info(dev); break; case FPGA_LOAD: rc = fpga_load(dev, fpga_data, data_size, BIT_FULL); break; #if defined(CONFIG_CMD_FPGA_LOADP) case FPGA_LOADP: rc = fpga_load(dev, fpga_data, data_size, BIT_PARTIAL); break; #endif case FPGA_LOADB: rc = fpga_loadbitstream(dev, fpga_data, data_size, BIT_FULL); break; #if defined(CONFIG_CMD_FPGA_LOADBP) case FPGA_LOADBP: rc = fpga_loadbitstream(dev, fpga_data, data_size, BIT_PARTIAL); break; #endif #if defined(CONFIG_CMD_FPGA_LOADFS) case FPGA_LOADFS: rc = fpga_fsload(dev, fpga_data, data_size, &fpga_fsinfo); break; #endif #if defined(CONFIG_CMD_FPGA_LOADMK) case FPGA_LOADMK: switch (genimg_get_format(fpga_data)) { #if defined(CONFIG_IMAGE_FORMAT_LEGACY) case IMAGE_FORMAT_LEGACY: { image_header_t *hdr = (image_header_t *)fpga_data; ulong data; uint8_t comp; comp = image_get_comp(hdr); if (comp == IH_COMP_GZIP) { #if defined(CONFIG_GZIP) ulong image_buf = image_get_data(hdr); data = image_get_load(hdr); ulong image_size = ~0UL; if (gunzip((void *)data, ~0UL, (void *)image_buf, &image_size) != 0) { puts("GUNZIP: error\n"); return 1; } data_size = image_size; #else puts("Gunzip image is not supported\n"); return 1; #endif } else { data = (ulong)image_get_data(hdr); data_size = image_get_data_size(hdr); } rc = fpga_load(dev, (void *)data, data_size, BIT_FULL); } break; #endif #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: { const void *fit_hdr = (const void *)fpga_data; int noffset; const void *fit_data; if (fit_uname == NULL) { puts("No FIT subimage unit name\n"); return 1; } if (!fit_check_format(fit_hdr)) { puts("Bad FIT image format\n"); return 1; } /* get fpga component image node offset */ noffset = fit_image_get_node(fit_hdr, fit_uname); if (noffset < 0) { printf("Can't find '%s' FIT subimage\n", fit_uname); return 1; } /* verify integrity */ if (!fit_image_verify(fit_hdr, noffset)) { puts ("Bad Data Hash\n"); return 1; } /* get fpga subimage data address and length */ if (fit_image_get_data(fit_hdr, noffset, &fit_data, &data_size)) { puts("Fpga subimage data not found\n"); return 1; } rc = fpga_load(dev, fit_data, data_size, BIT_FULL); } break; #endif default: puts("** Unknown image type\n"); rc = FPGA_FAIL; break; } break; #endif case FPGA_DUMP: rc = fpga_dump(dev, fpga_data, data_size); break; default: printf("Unknown operation\n"); return CMD_RET_USAGE; } return rc; }
int source (ulong addr, const char *fit_uname) { ulong len; #if defined(CONFIG_IMAGE_FORMAT_LEGACY) const image_header_t *hdr; #endif ulong *data; int verify; void *buf; #if defined(CONFIG_FIT) const void* fit_hdr; int noffset; const void *fit_data; size_t fit_len; #endif verify = getenv_yesno ("verify"); buf = map_sysmem(addr, 0); switch (genimg_get_format(buf)) { #if defined(CONFIG_IMAGE_FORMAT_LEGACY) case IMAGE_FORMAT_LEGACY: hdr = buf; if (!image_check_magic (hdr)) { puts ("Bad magic number\n"); return 1; } if (!image_check_hcrc (hdr)) { puts ("Bad header crc\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); if ((len = uimage_to_cpu (*data)) == 0) { puts ("Empty Script\n"); return 1; } /* * scripts are just multi-image files with one component, seek * past the zero-terminated sequence of image lengths to get * to the actual image data */ while (*data++); break; #endif #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: if (fit_uname == NULL) { puts ("No FIT subimage unit name\n"); return 1; } fit_hdr = buf; if (!fit_check_format (fit_hdr)) { puts ("Bad FIT image format\n"); return 1; } /* get script component image node offset */ noffset = fit_image_get_node (fit_hdr, fit_uname); if (noffset < 0) { printf ("Can't find '%s' FIT subimage\n", fit_uname); return 1; } if (!fit_image_check_type (fit_hdr, noffset, IH_TYPE_SCRIPT)) { puts ("Not a image image\n"); return 1; } /* verify integrity */ if (verify) { if (!fit_image_verify(fit_hdr, noffset)) { puts ("Bad Data Hash\n"); return 1; } } /* get script subimage data address and length */ if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) { puts ("Could not find script subimage data\n"); return 1; } data = (ulong *)fit_data; len = (ulong)fit_len; break; #endif default: puts ("Wrong image format for \"source\" command\n"); return 1; } debug ("** Script length: %ld\n", len); return run_command_list((char *)data, len, 0); }
int update_tftp(ulong addr, char *interface, char *devstring) { char *filename, *env_addr, *fit_image_name; ulong update_addr, update_fladdr, update_size; int images_noffset, ndepth, noffset; bool update_tftp_dfu; int ret = 0; void *fit; if (interface == NULL && devstring == NULL) { update_tftp_dfu = false; } else if (interface && devstring) { update_tftp_dfu = true; } else { error("Interface: %s and devstring: %s not supported!\n", interface, devstring); return -EINVAL; } /* use already present image */ if (addr) goto got_update_file; printf("Auto-update from TFTP: "); /* get the file name of the update file */ filename = getenv(UPDATE_FILE_ENV); if (filename == NULL) { printf("failed, env. variable '%s' not found\n", UPDATE_FILE_ENV); return 1; } printf("trying update file '%s'\n", filename); /* get load address of downloaded update file */ if ((env_addr = getenv("loadaddr")) != NULL) addr = simple_strtoul(env_addr, NULL, 16); else addr = CONFIG_UPDATE_LOAD_ADDR; if (update_load(filename, CONFIG_UPDATE_TFTP_MSEC_MAX, CONFIG_UPDATE_TFTP_CNT_MAX, addr)) { printf("Can't load update file, aborting auto-update\n"); return 1; } got_update_file: fit = (void *)addr; if (!fit_check_format((void *)fit)) { printf("Bad FIT format of the update file, aborting " "auto-update\n"); return 1; } /* process updates */ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); ndepth = 0; noffset = fdt_next_node(fit, images_noffset, &ndepth); while (noffset >= 0 && ndepth > 0) { if (ndepth != 1) goto next_node; fit_image_name = (char *)fit_get_name(fit, noffset, NULL); printf("Processing update '%s' :", fit_image_name); if (!fit_image_verify(fit, noffset)) { printf("Error: invalid update hash, aborting\n"); ret = 1; goto next_node; } printf("\n"); if (update_fit_getparams(fit, noffset, &update_addr, &update_fladdr, &update_size)) { printf("Error: can't get update parameteres, " "aborting\n"); ret = 1; goto next_node; } if (!update_tftp_dfu) { if (update_flash(update_addr, update_fladdr, update_size)) { printf("Error: can't flash update, aborting\n"); ret = 1; goto next_node; } } else if (fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE)) { ret = dfu_tftp_write(fit_image_name, update_addr, update_size, interface, devstring); if (ret) return ret; } next_node: noffset = fdt_next_node(fit, noffset, &ndepth); } return ret; }
/* command form: * fpga <op> <device number> <data addr> <datasize> * where op is 'load', 'dump', or 'info' * If there is no device number field, the fpga environment variable is used. * If there is no data addr field, the fpgadata environment variable is used. * The info command requires no data address field. */ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { int op, dev = FPGA_INVALID_DEVICE; size_t data_size = 0; void *fpga_data = NULL; char *devstr = getenv ("fpga"); char *datastr = getenv ("fpgadata"); int rc = FPGA_FAIL; int wrong_parms = 0; #if defined (CONFIG_FIT) const char *fit_uname = NULL; ulong fit_addr; #endif if (devstr) dev = (int) simple_strtoul (devstr, NULL, 16); if (datastr) fpga_data = (void *) simple_strtoul (datastr, NULL, 16); switch (argc) { case 5: /* fpga <op> <dev> <data> <datasize> */ data_size = simple_strtoul (argv[4], NULL, 16); case 4: /* fpga <op> <dev> <data> */ #if defined(CONFIG_FIT) if (fit_parse_subimage (argv[3], (ulong)fpga_data, &fit_addr, &fit_uname)) { fpga_data = (void *)fit_addr; debug("* fpga: subimage '%s' from FIT image " "at 0x%08lx\n", fit_uname, fit_addr); } else #endif { fpga_data = (void *) simple_strtoul (argv[3], NULL, 16); debug("* fpga: cmdline image address = 0x%08lx\n", (ulong)fpga_data); } debug("%s: fpga_data = 0x%x\n", __func__, (uint) fpga_data); case 3: /* fpga <op> <dev | data addr> */ dev = (int) simple_strtoul (argv[2], NULL, 16); debug("%s: device = %d\n", __func__, dev); /* FIXME - this is a really weak test */ if ((argc == 3) && (dev > fpga_count ())) { /* must be buffer ptr */ debug("%s: Assuming buffer pointer in arg 3\n", __func__); #if defined(CONFIG_FIT) if (fit_parse_subimage (argv[2], (ulong)fpga_data, &fit_addr, &fit_uname)) { fpga_data = (void *)fit_addr; debug("* fpga: subimage '%s' from FIT image " "at 0x%08lx\n", fit_uname, fit_addr); } else #endif { fpga_data = (void *) dev; debug("* fpga: cmdline image address = " "0x%08lx\n", (ulong)fpga_data); } debug("%s: fpga_data = 0x%x\n", __func__, (uint) fpga_data); dev = FPGA_INVALID_DEVICE; /* reset device num */ } case 2: /* fpga <op> */ op = (int) fpga_get_op (argv[1]); break; default: debug("%s: Too many or too few args (%d)\n", __func__, argc); op = FPGA_NONE; /* force usage display */ break; } if (dev == FPGA_INVALID_DEVICE) { puts("FPGA device not specified\n"); op = FPGA_NONE; } switch (op) { case FPGA_NONE: case FPGA_INFO: break; case FPGA_LOAD: case FPGA_LOADB: case FPGA_DUMP: if (!fpga_data || !data_size) wrong_parms = 1; break; case FPGA_LOADMK: if (!fpga_data) wrong_parms = 1; break; } if (wrong_parms) { puts("Wrong parameters for FPGA request\n"); op = FPGA_NONE; } switch (op) { case FPGA_NONE: return CMD_RET_USAGE; case FPGA_INFO: rc = fpga_info (dev); break; case FPGA_LOAD: rc = fpga_load (dev, fpga_data, data_size); break; case FPGA_LOADB: rc = fpga_loadbitstream(dev, fpga_data, data_size); break; case FPGA_LOADMK: switch (genimg_get_format (fpga_data)) { case IMAGE_FORMAT_LEGACY: { image_header_t *hdr = (image_header_t *)fpga_data; ulong data; data = (ulong)image_get_data (hdr); data_size = image_get_data_size (hdr); rc = fpga_load (dev, (void *)data, data_size); } break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: { const void *fit_hdr = (const void *)fpga_data; int noffset; const void *fit_data; if (fit_uname == NULL) { puts ("No FIT subimage unit name\n"); return 1; } if (!fit_check_format (fit_hdr)) { puts ("Bad FIT image format\n"); return 1; } /* get fpga component image node offset */ noffset = fit_image_get_node (fit_hdr, fit_uname); if (noffset < 0) { printf ("Can't find '%s' FIT subimage\n", fit_uname); return 1; } /* verify integrity */ if (!fit_image_verify(fit_hdr, noffset)) { puts ("Bad Data Hash\n"); return 1; } /* get fpga subimage data address and length */ if (fit_image_get_data (fit_hdr, noffset, &fit_data, &data_size)) { puts ("Could not find fpga subimage data\n"); return 1; } rc = fpga_load (dev, fit_data, data_size); } break; #endif default: puts ("** Unknown image type\n"); rc = FPGA_FAIL; break; } break; case FPGA_DUMP: rc = fpga_dump (dev, fpga_data, data_size); break; default: printf ("Unknown operation\n"); return CMD_RET_USAGE; } return (rc); }
static int do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { ulong addr = load_addr; ulong dest = 0; ulong data, len; int verify; int part = 0; #if defined(CONFIG_IMAGE_FORMAT_LEGACY) ulong count; image_header_t *hdr = NULL; #endif #if defined(CONFIG_FIT) const char *uname = NULL; const void* fit_hdr; int noffset; const void *fit_data; size_t fit_len; #endif #ifdef CONFIG_GZIP uint unc_len = CONFIG_SYS_XIMG_LEN; #endif uint8_t comp; verify = env_get_yesno("verify"); if (argc > 1) { addr = simple_strtoul(argv[1], NULL, 16); } if (argc > 2) { part = simple_strtoul(argv[2], NULL, 16); #if defined(CONFIG_FIT) uname = argv[2]; #endif } if (argc > 3) { dest = simple_strtoul(argv[3], NULL, 16); } switch (genimg_get_format((void *)addr)) { #if defined(CONFIG_IMAGE_FORMAT_LEGACY) case IMAGE_FORMAT_LEGACY: printf("## Copying part %d from legacy image " "at %08lx ...\n", part, addr); hdr = (image_header_t *)addr; 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 if (!image_check_type(hdr, IH_TYPE_MULTI) && !image_check_type(hdr, IH_TYPE_SCRIPT)) { printf("Wrong Image Type for %s command\n", cmdtp->name); return 1; } comp = image_get_comp(hdr); if ((comp != IH_COMP_NONE) && (argc < 4)) { printf("Must specify load address for %s command " "with compressed image\n", cmdtp->name); return 1; } if (verify) { printf(" Verifying Checksum ... "); if (!image_check_dcrc(hdr)) { printf("Bad Data CRC\n"); return 1; } printf("OK\n"); } count = image_multi_count(hdr); if (part >= count) { printf("Bad Image Part\n"); return 1; } image_multi_getimg(hdr, part, &data, &len); break; #endif #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: if (uname == NULL) { puts("No FIT subimage unit name\n"); return 1; } printf("## Copying '%s' subimage from FIT image " "at %08lx ...\n", uname, addr); fit_hdr = (const void *)addr; if (!fit_check_format(fit_hdr)) { puts("Bad FIT image format\n"); return 1; } /* get subimage node offset */ noffset = fit_image_get_node(fit_hdr, uname); if (noffset < 0) { printf("Can't find '%s' FIT subimage\n", uname); return 1; } if (!fit_image_check_comp(fit_hdr, noffset, IH_COMP_NONE) && (argc < 4)) { printf("Must specify load address for %s command " "with compressed image\n", cmdtp->name); return 1; } /* verify integrity */ if (verify) { if (!fit_image_verify(fit_hdr, noffset)) { puts("Bad Data Hash\n"); return 1; } } /* get subimage/external data address and length */ if (fit_image_get_data_and_size(fit_hdr, noffset, &fit_data, &fit_len)) { puts("Could not find script subimage data\n"); return 1; } if (fit_image_get_comp(fit_hdr, noffset, &comp)) { puts("Could not find script subimage " "compression type\n"); return 1; } data = (ulong)fit_data; len = (ulong)fit_len; break; #endif default: puts("Invalid image type for imxtract\n"); return 1; } if (argc > 3) { switch (comp) { case IH_COMP_NONE: #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) { size_t l = len; size_t tail; void *to = (void *) dest; void *from = (void *)data; printf(" Loading part %d ... ", part); while (l > 0) { tail = (l > CHUNKSZ) ? CHUNKSZ : l; WATCHDOG_RESET(); memmove(to, from, tail); to += tail; from += tail; l -= tail; } } #else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ printf(" Loading part %d ... ", part); memmove((char *) dest, (char *)data, len); #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ break; #ifdef CONFIG_GZIP case IH_COMP_GZIP: printf(" Uncompressing part %d ... ", part); if (gunzip((void *) dest, unc_len, (uchar *) data, &len) != 0) { puts("GUNZIP ERROR - image not loaded\n"); return 1; } break; #endif #if defined(CONFIG_BZIP2) && defined(CONFIG_IMAGE_FORMAT_LEGACY) case IH_COMP_BZIP2: { int i; printf(" Uncompressing part %d ... ", part); /* * If we've got less than 4 MB of malloc() * space, use slower decompression algorithm * which requires at most 2300 KB of memory. */ i = BZ2_bzBuffToBuffDecompress( map_sysmem(ntohl(hdr->ih_load), 0), &unc_len, (char *)data, len, CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); if (i != BZ_OK) { printf("BUNZIP2 ERROR %d - " "image not loaded\n", i); return 1; } } break; #endif /* CONFIG_BZIP2 */ default: printf("Unimplemented compression type %d\n", comp); return 1; } puts("OK\n"); } flush_cache(dest, ALIGN(len, ARCH_DMA_MINALIGN)); env_set_hex("fileaddr", data); env_set_hex("filesize", len); return 0; }
int update_tftp(ulong addr) { char *filename, *env_addr; int images_noffset, ndepth, noffset; ulong update_addr, update_fladdr, update_size; void *fit; int ret = 0; /* use already present image */ if (addr) goto got_update_file; printf("Auto-update from TFTP: "); /* get the file name of the update file */ filename = getenv(UPDATE_FILE_ENV); if (filename == NULL) { printf("failed, env. variable '%s' not found\n", UPDATE_FILE_ENV); return 1; } printf("trying update file '%s'\n", filename); /* get load address of downloaded update file */ if ((env_addr = getenv("loadaddr")) != NULL) addr = simple_strtoul(env_addr, NULL, 16); else addr = CONFIG_UPDATE_LOAD_ADDR; if (update_load(filename, CONFIG_UPDATE_TFTP_MSEC_MAX, CONFIG_UPDATE_TFTP_CNT_MAX, addr)) { printf("Can't load update file, aborting auto-update\n"); return 1; } got_update_file: fit = (void *)addr; if (!fit_check_format((void *)fit)) { printf("Bad FIT format of the update file, aborting " "auto-update\n"); return 1; } /* process updates */ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); ndepth = 0; noffset = fdt_next_node(fit, images_noffset, &ndepth); while (noffset >= 0 && ndepth > 0) { if (ndepth != 1) goto next_node; printf("Processing update '%s' :", fit_get_name(fit, noffset, NULL)); if (!fit_image_verify(fit, noffset)) { printf("Error: invalid update hash, aborting\n"); ret = 1; goto next_node; } printf("\n"); if (update_fit_getparams(fit, noffset, &update_addr, &update_fladdr, &update_size)) { printf("Error: can't get update parameteres, " "aborting\n"); ret = 1; goto next_node; } if (update_flash(update_addr, update_fladdr, update_size)) { printf("Error: can't flash update, aborting\n"); ret = 1; goto next_node; } next_node: noffset = fdt_next_node(fit, noffset, &ndepth); } return ret; }