/** * image_multi_getimg - get component data address and size * @hdr: pointer to the header of the multi component image * @idx: index of the requested component * @data: pointer to a ulong variable, will hold component data address * @len: pointer to a ulong variable, will hold component size * * image_multi_getimg() returns size and data address for the requested * component in a multi component image. * * Note: no checking of the image type is done, caller must pass * a valid multi component image. * * returns: * data address and size of the component, if idx is valid * 0 in data and len, if idx is out of range */ void image_multi_getimg(const image_header_t *hdr, ulong idx, ulong *data, ulong *len) { int i; uint32_t *size; ulong offset, count, img_data; /* get number of component */ count = image_multi_count(hdr); /* get start of the image payload, which in case of multi * component images that points to a table of component sizes */ size = (uint32_t *)image_get_data(hdr); /* get address of the proper component data start, which means * skipping sizes table (add 1 for last, null entry) */ img_data = image_get_data(hdr) + (count + 1) * sizeof (uint32_t); if (idx < count) { *len = uimage_to_cpu(size[idx]); offset = 0; /* go over all indices preceding requested component idx */ for (i = 0; i < idx; i++) { /* add up i-th component size, rounding up to 4 bytes */ offset += (uimage_to_cpu(size[i]) + 3) & ~3 ; } /* calculate idx-th component data address */ *data = img_data + offset; } else { *len = 0; *data = 0; } }
static int fit_image_get_address(const void *fit, int noffset, char *name, ulong *load) { int len, cell_len; const fdt32_t *cell; uint64_t load64 = 0; cell = fdt_getprop(fit, noffset, name, &len); if (cell == NULL) { fit_get_debug(fit, noffset, name, len); return -1; } if (len > sizeof(ulong)) { printf("Unsupported %s address size\n", name); return -1; } cell_len = len >> 2; /* Use load64 to avoid compiling warning for 32-bit target */ while (cell_len--) { load64 = (load64 << 32) | uimage_to_cpu(*cell); cell++; } *load = (ulong)load64; return 0; }
/** * fit_image_get_entry() - get entry point address property * @fit: pointer to the FIT format image header * @noffset: component image node offset * @entry: pointer to the uint32_t, will hold entry point address * * This gets the entry point address property for a given component image * node. * * fit_image_get_entry() finds entry point address property in a given * component image node. If the property is found, its value is returned * to the caller. * * returns: * 0, on success * -1, on failure */ int fit_image_get_entry(const void *fit, int noffset, ulong *entry) { int len; const uint32_t *data; data = fdt_getprop(fit, noffset, FIT_ENTRY_PROP, &len); if (data == NULL) { fit_get_debug(fit, noffset, FIT_ENTRY_PROP, len); return -1; } *entry = uimage_to_cpu(*data); return 0; }
/** * fit_image_get_load() - get load addr property for given component image node * @fit: pointer to the FIT format image header * @noffset: component image node offset * @load: pointer to the uint32_t, will hold load address * * fit_image_get_load() finds load address property in a given component * image node. If the property is found, its value is returned to the caller. * * returns: * 0, on success * -1, on failure */ int fit_image_get_load(const void *fit, int noffset, ulong *load) { int len; const uint32_t *data; data = fdt_getprop(fit, noffset, FIT_LOAD_PROP, &len); if (data == NULL) { fit_get_debug(fit, noffset, FIT_LOAD_PROP, len); return -1; } *load = uimage_to_cpu(*data); return 0; }
/** * fit_get_timestamp - get node timestamp property * @fit: pointer to the FIT format image header * @noffset: node offset * @timestamp: pointer to the time_t, will hold read timestamp * * fit_get_timestamp() reads timestamp poperty from given node, if timestamp * is found and has a correct size its value is retured in third call * argument. * * returns: * 0, on success * -1, on property read failure * -2, on wrong timestamp size */ int fit_get_timestamp(const void *fit, int noffset, time_t *timestamp) { int len; const void *data; data = fdt_getprop(fit, noffset, FIT_TIMESTAMP_PROP, &len); if (data == NULL) { fit_get_debug(fit, noffset, FIT_TIMESTAMP_PROP, len); return -1; } if (len != sizeof(uint32_t)) { debug("FIT timestamp with incorrect size of (%u)\n", len); return -2; } *timestamp = uimage_to_cpu(*((uint32_t *)data)); return 0; }
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); }
/* * open a uimage. This will check the header contents and * return a handle to the uImage */ struct uimage_handle *uimage_open(const char *filename) { int fd; uint32_t checksum; struct uimage_handle *handle; struct image_header *header; int i; int ret; struct stat s; again: fd = open(filename, O_RDONLY); if (fd < 0) { printf("could not open: %s\n", errno_str()); return NULL; } /* * Hack around tftp fs. We need lseek for uImage support, but * this cannot be implemented in tftp fs, so we detect this * by doing a test lseek and copy the file to ram if it fails */ if (IS_BUILTIN(CONFIG_FS_TFTP) && lseek(fd, 0, SEEK_SET)) { close(fd); ret = copy_file(filename, uimage_tmp, 0); if (ret) return NULL; filename = uimage_tmp; goto again; } handle = xzalloc(sizeof(struct uimage_handle)); header = &handle->header; if (read(fd, header, sizeof(*header)) < 0) { printf("could not read: %s\n", errno_str()); goto err_out; } if (uimage_to_cpu(header->ih_magic) != IH_MAGIC) { printf("Bad Magic Number\n"); goto err_out; } checksum = uimage_to_cpu(header->ih_hcrc); header->ih_hcrc = 0; if (crc32(0, header, sizeof(*header)) != checksum) { printf("Bad Header Checksum\n"); goto err_out; } /* convert header to cpu native endianess */ header->ih_magic = uimage_to_cpu(header->ih_magic); header->ih_hcrc = uimage_to_cpu(header->ih_hcrc); header->ih_time = uimage_to_cpu(header->ih_time); header->ih_size = uimage_to_cpu(header->ih_size); header->ih_load = uimage_to_cpu(header->ih_load); header->ih_ep = uimage_to_cpu(header->ih_ep); header->ih_dcrc = uimage_to_cpu(header->ih_dcrc); if (header->ih_name[0]) { handle->name = xzalloc(IH_NMLEN + 1); strncpy(handle->name, header->ih_name, IH_NMLEN); } else { handle->name = xstrdup(filename); } if (uimage_is_multi_image(handle)) { size_t offset; for (i = 0; i < MAX_MULTI_IMAGE_COUNT; i++) { u32 size; ret = read(fd, &size, sizeof(size)); if (ret < 0) goto err_out; if (!size) break; handle->ihd[i].len = uimage_to_cpu(size); } handle->nb_data_entries = i; /* offset of the first image in a multifile image */ offset = 0; for (i = 0; i < handle->nb_data_entries; i++) { handle->ihd[i].offset = offset; offset += (handle->ihd[i].len + 3) & ~3; } handle->data_offset = sizeof(struct image_header) + sizeof(u32) * (handle->nb_data_entries + 1); } else { handle->ihd[0].offset = 0; handle->ihd[0].len = header->ih_size; handle->nb_data_entries = 1; handle->data_offset = sizeof(struct image_header); } /* * fd is now at the first data word */ handle->fd = fd; return handle; err_out: close(fd); free(handle); if (IS_BUILTIN(CONFIG_FS_TFTP) && !stat(uimage_tmp, &s)) unlink(uimage_tmp); return NULL; }
int autoscript (ulong addr, const char *fit_uname) { ulong len; image_header_t *hdr; ulong *data; char *cmd; int rcode = 0; int verify; #if defined(CONFIG_FIT) const void* fit_hdr; int noffset; const void *fit_data; size_t fit_len; #endif verify = getenv_yesno ("verify"); switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; 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; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: if (fit_uname == NULL) { puts ("No FIT subimage unit name\n"); return 1; } fit_hdr = (const void *)addr; 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_check_hashes (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 autoscript\n"); return 1; } debug ("** Script length: %ld\n", len); if ((cmd = malloc (len + 1)) == NULL) { return 1; } /* make sure cmd is null terminated */ memmove (cmd, (char *)data, len); *(cmd + len) = 0; #ifdef CONFIG_SYS_HUSH_PARSER /*?? */ rcode = parse_string_outer (cmd, FLAG_PARSE_SEMICOLON); #else { char *line = cmd; char *next = cmd; /* * break into individual lines, * and execute each line; * terminate on error. */ while (*next) { if (*next == '\n') { *next = '\0'; /* run only non-empty commands */ if (*line) { debug ("** exec: \"%s\"\n", line); if (run_command (line, 0) < 0) { rcode = 1; break; } } line = next + 1; } ++next; } if (rcode == 0 && *line) rcode = (run_command(line, 0) >= 0); } #endif free (cmd); return rcode; }
static int mpl_prg(uchar *src, ulong size) { ulong start; flash_info_t *info; int i, rc; #if defined(CONFIG_PATI) int start_sect; #endif #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI) char *copystr = (char *)src; ulong *magic = (ulong *)src; #endif info = &flash_info[0]; #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI) if (uimage_to_cpu (magic[0]) != IH_MAGIC) { puts("Bad Magic number\n"); return -1; } /* some more checks before we delete the Flash... */ /* Checking the ISO_STRING prevents to program a * wrong Firmware Image into the flash. */ i = 4; /* skip Magic number */ while (1) { if (strncmp(©str[i], "MEV-", 4) == 0) break; if (i++ >= 0x100) { puts("Firmware Image for unknown Target\n"); return -1; } } /* we have the ISO STRING, check */ if (strncmp(©str[i], CONFIG_ISO_STRING, sizeof(CONFIG_ISO_STRING)-1) != 0) { printf("Wrong Firmware Image: %s\n", ©str[i]); return -1; } #if !defined(CONFIG_PATI) start = 0 - size; for (i = info->sector_count-1; i > 0; i--) { info->protect[i] = 0; /* unprotect this sector */ if (start >= info->start[i]) break; } /* set-up flash location */ /* now erase flash */ printf("Erasing at %lx (sector %d) (start %lx)\n", start,i,info->start[i]); if ((rc = flash_erase (info, i, info->sector_count-1)) != 0) { puts("ERROR "); flash_perror(rc); return (1); } #else /* #if !defined(CONFIG_PATI */ start = FIRM_START; start_sect = -1; for (i = 0; i < info->sector_count; i++) { if (start < info->start[i]) { start_sect = i - 1; break; } } info->protect[i - 1] = 0; /* unprotect this sector */ for (; i < info->sector_count; i++) { if ((start + size) < info->start[i]) break; info->protect[i] = 0; /* unprotect this sector */ } i--; /* set-up flash location */ /* now erase flash */ printf ("Erasing at %lx to %lx (sector %d to %d) (%lx to %lx)\n", start, start + size, start_sect, i, info->start[start_sect], info->start[i]); if ((rc = flash_erase (info, start_sect, i)) != 0) { puts ("ERROR "); flash_perror (rc); return (1); } #endif /* defined(CONFIG_PATI) */ #elif defined(CONFIG_VCMA9) start = 0; for (i = 0; i <info->sector_count; i++) { info->protect[i] = 0; /* unprotect this sector */ if (size < info->start[i]) break; } /* set-up flash location */ /* now erase flash */ printf("Erasing at %lx (sector %d) (start %lx)\n", start,0,info->start[0]); if ((rc = flash_erase (info, 0, i)) != 0) { puts("ERROR "); flash_perror(rc); return (1); } #endif printf("flash erased, programming from 0x%lx 0x%lx Bytes\n", (ulong)src, size); if ((rc = flash_write ((char *)src, start, size)) != 0) { puts("ERROR "); flash_perror(rc); return (1); } puts("OK programming done\n"); return 0; }