Esempio n. 1
0
/**
 * 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;
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}
Esempio n. 6
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);
}
Esempio n. 7
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(&copystr[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(&copystr[i], CONFIG_ISO_STRING, sizeof(CONFIG_ISO_STRING)-1) != 0) {
		printf("Wrong Firmware Image: %s\n", &copystr[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;
}