Example #1
0
/* Show all image types supported by mkimage */
static void show_image_types(void)
{
	struct image_type_params *tparams;
	int order[IH_TYPE_COUNT];
	int count;
	int type;
	int i;

	/* Sort the names in order of short name for easier reading */
	memset(order, '\0', sizeof(order));
	for (count = 0, type = 0; type < IH_TYPE_COUNT; type++) {
		tparams = imagetool_get_type(type);
		if (tparams)
			order[count++] = type;
	}
	qsort(order, count, sizeof(int), h_compare_image_name);

	fprintf(stderr, "\nInvalid image type. Supported image types:\n");
	for (i = 0; i < count; i++) {
		type = order[i];
		tparams = imagetool_get_type(type);
		if (tparams) {
			fprintf(stderr, "\t%-15s  %s\n",
				genimg_get_type_short_name(type),
				genimg_get_type_name(type));
		}
	}
	fprintf(stderr, "\n");
}
Example #2
0
/**
 * print_decomp_msg() - Print a suitable decompression/loading message
 *
 * @type:	OS type (IH_OS_...)
 * @comp_type:	Compression type being used (IH_COMP_...)
 * @is_xip:	true if the load address matches the image start
 */
static void print_decomp_msg(int comp_type, int type, bool is_xip)
{
	const char *name = genimg_get_type_name(type);

	if (comp_type == IH_COMP_NONE)
		printf("   %s %s ... ", is_xip ? "XIP" : "Loading", name);
	else
		printf("   Uncompressing %s ... ", name);
}
Example #3
0
static void image_print_type(const image_header_t *hdr)
{
	const char *os, *arch, *type, *comp;

	os = genimg_get_os_name(image_get_os(hdr));
	arch = genimg_get_arch_name(image_get_arch(hdr));
	type = genimg_get_type_name(image_get_type(hdr));
	comp = genimg_get_comp_name(image_get_comp(hdr));

	printf("%s %s %s (%s)\n", arch, os, type, comp);
}
Example #4
0
static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
{
	uint8_t comp = os.comp;
	ulong load = os.load;
	ulong blob_start = os.start;
	ulong blob_end = os.end;
	ulong image_start = os.image_start;
	ulong image_len = os.image_len;
	__maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN;
	int no_overlap = 0;
#if defined(CONFIG_LZMA) || defined(CONFIG_LZO)
	int ret;
#endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */

	const char *type_name = genimg_get_type_name(os.type);

	switch (comp) {
	case IH_COMP_NONE:
		if (load == blob_start || load == image_start) {
			printf("   XIP %s ... ", type_name);
			no_overlap = 1;
		} else {
			printf("   Loading %s ... ", type_name);
			memmove_wd((void *)load, (void *)image_start,
					image_len, CHUNKSZ);
		}
		*load_end = load + image_len;
		puts("OK\n");
		break;
#ifdef CONFIG_GZIP
	case IH_COMP_GZIP:
		printf("   Uncompressing %s ... ", type_name);
		if (gunzip((void *)load, unc_len,
				(uchar *)image_start, &image_len) != 0) {
			puts("GUNZIP: uncompress, out-of-mem or overwrite "
				"error - must RESET board to recover\n");
			if (boot_progress)
				bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + image_len;
		break;
#endif /* CONFIG_GZIP */
#ifdef CONFIG_BZIP2
	case IH_COMP_BZIP2:
		printf("   Uncompressing %s ... ", type_name);
		/*
		 * If we've got less than 4 MB of malloc() space,
		 * use slower decompression algorithm which requires
		 * at most 2300 KB of memory.
		 */
		int i = BZ2_bzBuffToBuffDecompress((char *)load,
					&unc_len, (char *)image_start, image_len,
					CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
		if (i != BZ_OK) {
			printf("BUNZIP2: uncompress or overwrite error %d "
				"- must RESET board to recover\n", i);
			if (boot_progress)
				bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + unc_len;
		break;
#endif /* CONFIG_BZIP2 */
#ifdef CONFIG_LZMA
	case IH_COMP_LZMA: {
		SizeT lzma_len = unc_len;
		printf("   Uncompressing %s ... ", type_name);

		ret = lzmaBuffToBuffDecompress(
			(unsigned char *)load, &lzma_len,
			(unsigned char *)image_start, image_len);
		unc_len = lzma_len;
		if (ret != SZ_OK) {
			printf("LZMA: uncompress or overwrite error %d "
				"- must RESET board to recover\n", ret);
			bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}
		*load_end = load + unc_len;
		break;
	}
#endif /* CONFIG_LZMA */
#ifdef CONFIG_LZO
	case IH_COMP_LZO:
		printf("   Uncompressing %s ... ", type_name);

		ret = lzop_decompress((const unsigned char *)image_start,
					  image_len, (unsigned char *)load,
					  &unc_len);
		if (ret != LZO_E_OK) {
			printf("LZO: uncompress or overwrite error %d "
			      "- must RESET board to recover\n", ret);
			if (boot_progress)
				bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + unc_len;
		break;
#endif /* CONFIG_LZO */
	default:
		printf("Unimplemented compression type %d\n", comp);
		return BOOTM_ERR_UNIMPLEMENTED;
	}

	flush_cache(load, (*load_end - load) * sizeof(ulong));

	puts("OK\n");
	debug("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
	bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);

	if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) {
		debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
			blob_start, blob_end);
		debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
			*load_end);

		return BOOTM_ERR_OVERLAP;
	}

	return 0;
}
Example #5
0
int main(int argc, char **argv)
{
	int ifd = -1;
	struct stat sbuf;
	char *ptr;
	int retval = 0;
	struct image_type_params *tparams = NULL;
	int pad_len = 0;
	int dfd;

	params.cmdname = *argv;
	params.addr = 0;
	params.ep = 0;

	process_args(argc, argv);

	/* set tparams as per input type_id */
	tparams = imagetool_get_type(params.type);
	if (tparams == NULL) {
		fprintf (stderr, "%s: unsupported type %s\n",
			params.cmdname, genimg_get_type_name(params.type));
		exit (EXIT_FAILURE);
	}

	/*
	 * check the passed arguments parameters meets the requirements
	 * as per image type to be generated/listed
	 */
	if (tparams->check_params)
		if (tparams->check_params (&params))
			usage("Bad parameters for image type");

	if (!params.eflag) {
		params.ep = params.addr;
		/* If XIP, entry point must be after the U-Boot header */
		if (params.xflag)
			params.ep += tparams->header_size;
	}

	if (params.fflag){
		if (tparams->fflag_handle)
			/*
			 * in some cases, some additional processing needs
			 * to be done if fflag is defined
			 *
			 * For ex. fit_handle_file for Fit file support
			 */
			retval = tparams->fflag_handle(&params);

		if (retval != EXIT_SUCCESS)
			exit (retval);
	}

	if (params.lflag || params.fflag) {
		ifd = open (params.imagefile, O_RDONLY|O_BINARY);
	} else {
		ifd = open (params.imagefile,
			O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666);
	}

	if (ifd < 0) {
		fprintf (stderr, "%s: Can't open %s: %s\n",
			params.cmdname, params.imagefile,
			strerror(errno));
		exit (EXIT_FAILURE);
	}

	if (params.lflag || params.fflag) {
		/*
		 * list header information of existing image
		 */
		if (fstat(ifd, &sbuf) < 0) {
			fprintf (stderr, "%s: Can't stat %s: %s\n",
				params.cmdname, params.imagefile,
				strerror(errno));
			exit (EXIT_FAILURE);
		}

		if ((unsigned)sbuf.st_size < tparams->header_size) {
			fprintf (stderr,
				"%s: Bad size: \"%s\" is not valid image\n",
				params.cmdname, params.imagefile);
			exit (EXIT_FAILURE);
		}

		ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0);
		if (ptr == MAP_FAILED) {
			fprintf (stderr, "%s: Can't read %s: %s\n",
				params.cmdname, params.imagefile,
				strerror(errno));
			exit (EXIT_FAILURE);
		}

		/*
		 * scan through mkimage registry for all supported image types
		 * and verify the input image file header for match
		 * Print the image information for matched image type
		 * Returns the error code if not matched
		 */
		retval = imagetool_verify_print_header(ptr, &sbuf,
				tparams, &params);

		(void) munmap((void *)ptr, sbuf.st_size);
		(void) close (ifd);

		exit (retval);
	}

	if ((params.type != IH_TYPE_MULTI) && (params.type != IH_TYPE_SCRIPT)) {
		dfd = open(params.datafile, O_RDONLY | O_BINARY);
		if (dfd < 0) {
			fprintf(stderr, "%s: Can't open %s: %s\n",
				params.cmdname, params.datafile,
				strerror(errno));
			exit(EXIT_FAILURE);
		}

		if (fstat(dfd, &sbuf) < 0) {
			fprintf(stderr, "%s: Can't stat %s: %s\n",
				params.cmdname, params.datafile,
				strerror(errno));
			exit(EXIT_FAILURE);
		}

		params.file_size = sbuf.st_size + tparams->header_size;
		close(dfd);
	}

	/*
	 * In case there an header with a variable
	 * length will be added, the corresponding
	 * function is called. This is responsible to
	 * allocate memory for the header itself.
	 */
	if (tparams->vrec_header)
		pad_len = tparams->vrec_header(&params, tparams);
	else
		memset(tparams->hdr, 0, tparams->header_size);

	if (write(ifd, tparams->hdr, tparams->header_size)
					!= tparams->header_size) {
		fprintf (stderr, "%s: Write error on %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	if (!params.skipcpy) {
		if (params.type == IH_TYPE_MULTI ||
		    params.type == IH_TYPE_SCRIPT) {
			char *file = params.datafile;
			uint32_t size;

			for (;;) {
				char *sep = NULL;

				if (file) {
					if ((sep = strchr(file, ':')) != NULL) {
						*sep = '\0';
					}

					if (stat (file, &sbuf) < 0) {
						fprintf (stderr, "%s: Can't stat %s: %s\n",
							 params.cmdname, file, strerror(errno));
						exit (EXIT_FAILURE);
					}
					size = cpu_to_uimage (sbuf.st_size);
				} else {
					size = 0;
				}

				if (write(ifd, (char *)&size, sizeof(size)) != sizeof(size)) {
					fprintf (stderr, "%s: Write error on %s: %s\n",
						 params.cmdname, params.imagefile,
						 strerror(errno));
					exit (EXIT_FAILURE);
				}

				if (!file) {
					break;
				}

				if (sep) {
					*sep = ':';
					file = sep + 1;
				} else {
					file = NULL;
				}
			}

			file = params.datafile;

			for (;;) {
				char *sep = strchr(file, ':');
				if (sep) {
					*sep = '\0';
					copy_file (ifd, file, 1);
					*sep++ = ':';
					file = sep;
				} else {
					copy_file (ifd, file, 0);
					break;
				}
			}
		} else if (params.type == IH_TYPE_PBLIMAGE) {
			/* PBL has special Image format, implements its' own */
			pbl_load_uboot(ifd, &params);
		} else {
			copy_file(ifd, params.datafile, pad_len);
		}
	}

	/* We're a bit of paranoid */
#if defined(_POSIX_SYNCHRONIZED_IO) && \
   !defined(__sun__) && \
   !defined(__FreeBSD__) && \
   !defined(__OpenBSD__) && \
   !defined(__APPLE__)
	(void) fdatasync (ifd);
#else
	(void) fsync (ifd);
#endif

	if (fstat(ifd, &sbuf) < 0) {
		fprintf (stderr, "%s: Can't stat %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}
	params.file_size = sbuf.st_size;

	ptr = mmap(0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0);
	if (ptr == MAP_FAILED) {
		fprintf (stderr, "%s: Can't map %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	/* Setup the image header as per input image type*/
	if (tparams->set_header)
		tparams->set_header (ptr, &sbuf, ifd, &params);
	else {
		fprintf (stderr, "%s: Can't set header for %s: %s\n",
			params.cmdname, tparams->name, strerror(errno));
		exit (EXIT_FAILURE);
	}

	/* Print the image information by processing image header */
	if (tparams->print_header)
		tparams->print_header (ptr);
	else {
		fprintf (stderr, "%s: Can't print header for %s: %s\n",
			params.cmdname, tparams->name, strerror(errno));
		exit (EXIT_FAILURE);
	}

	(void) munmap((void *)ptr, sbuf.st_size);

	/* We're a bit of paranoid */
#if defined(_POSIX_SYNCHRONIZED_IO) && \
   !defined(__sun__) && \
   !defined(__FreeBSD__) && \
   !defined(__OpenBSD__) && \
   !defined(__APPLE__)
	(void) fdatasync (ifd);
#else
	(void) fsync (ifd);
#endif

	if (close(ifd)) {
		fprintf (stderr, "%s: Write error on %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	exit (EXIT_SUCCESS);
}
Example #6
0
static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
		int boot_progress)
{
	image_info_t os = images->os;
	uint8_t comp = os.comp;
	ulong load = os.load;
	ulong blob_start = os.start;
	ulong blob_end = os.end;
	ulong image_start = os.image_start;
	ulong image_len = os.image_len;
	__maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN;
	int no_overlap = 0;
	void *load_buf, *image_buf;
#if defined(CONFIG_LZMA) || defined(CONFIG_LZO)
	int ret;
#endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */

	const char *type_name = genimg_get_type_name(os.type);

	load_buf = map_sysmem(load, unc_len);
	image_buf = map_sysmem(image_start, image_len);
	switch (comp) {
	case IH_COMP_NONE:
		if (load == image_start) {
			printf("   XIP %s ... ", type_name);
			no_overlap = 1;
		} else {
			printf("   Loading %s ... ", type_name);
			memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
		}
		*load_end = load + image_len;
		break;
#ifdef CONFIG_GZIP
	case IH_COMP_GZIP:
		printf("   Uncompressing %s ... ", type_name);
		if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) {
			puts("GUNZIP: uncompress, out-of-mem or overwrite "
				"error - must RESET board to recover\n");
			if (boot_progress)
				bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + image_len;
		break;
#endif /* CONFIG_GZIP */
#ifdef CONFIG_BZIP2
	case IH_COMP_BZIP2:
		printf("   Uncompressing %s ... ", type_name);
		/*
		 * If we've got less than 4 MB of malloc() space,
		 * use slower decompression algorithm which requires
		 * at most 2300 KB of memory.
		 */
		int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len,
			image_buf, image_len,
			CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
		if (i != BZ_OK) {
			printf("BUNZIP2: uncompress or overwrite error %d "
				"- must RESET board to recover\n", i);
			if (boot_progress)
				bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + unc_len;
		break;
#endif /* CONFIG_BZIP2 */
#ifdef CONFIG_LZMA
	case IH_COMP_LZMA: {
		SizeT lzma_len = unc_len;
		printf("   Uncompressing %s ... ", type_name);

		ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
					       image_buf, image_len);
		unc_len = lzma_len;
		if (ret != SZ_OK) {
			printf("LZMA: uncompress or overwrite error %d "
				"- must RESET board to recover\n", ret);
			bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}
		*load_end = load + unc_len;
		break;
	}
#endif /* CONFIG_LZMA */
#ifdef CONFIG_LZO
	case IH_COMP_LZO: {
		size_t size = unc_len;

		printf("   Uncompressing %s ... ", type_name);

		ret = lzop_decompress(image_buf, image_len, load_buf, &size);
		if (ret != LZO_E_OK) {
			printf("LZO: uncompress or overwrite error %d "
			      "- must RESET board to recover\n", ret);
			if (boot_progress)
				bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + size;
		break;
	}
#endif /* CONFIG_LZO */
	default:
		printf("Unimplemented compression type %d\n", comp);
		return BOOTM_ERR_UNIMPLEMENTED;
	}

	flush_cache(load, (*load_end - load) * sizeof(ulong));

	puts("OK\n");
	debug("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
	bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);

	if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) {
		debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
			blob_start, blob_end);
		debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
			*load_end);

		/* Check what type of image this is. */
		if (images->legacy_hdr_valid) {
			if (image_get_type(&images->legacy_hdr_os_copy)
					== IH_TYPE_MULTI)
				puts("WARNING: legacy format multi component image overwritten\n");
			return BOOTM_ERR_OVERLAP;
		} else {
			puts("ERROR: new format image overwritten - must RESET the board to recover\n");
			bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
			return BOOTM_ERR_RESET;
		}
	}

	return 0;
}
Example #7
0
/**
 * decomp_image() - decompress the operating system
 *
 * @comp:	Compression algorithm that is used (IH_COMP_...)
 * @load:	Destination load address in U-Boot memory
 * @image_start Image start address (where we are decompressing from)
 * @type:	OS type (IH_OS_...)
 * @load_bug:	Place to decompress to
 * @image_buf:	Address to decompress from
 * @return 0 if OK, -ve on error (BOOTM_ERR_...)
 */
static int decomp_image(int comp, ulong load, ulong image_start, int type,
			void *load_buf, void *image_buf, ulong image_len,
			ulong *load_end)
{
	const char *type_name = genimg_get_type_name(type);
	__attribute__((unused)) uint unc_len = CONFIG_SYS_BOOTM_LEN;

	*load_end = load;
	switch (comp) {
	case IH_COMP_NONE:
		if (load == image_start) {
			printf("   XIP %s ... ", type_name);
		} else {
			printf("   Loading %s ... ", type_name);
			memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
		}
		*load_end = load + image_len;
		break;
#ifdef CONFIG_GZIP
	case IH_COMP_GZIP:
		printf("   Uncompressing %s ... ", type_name);
		if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) {
			puts("GUNZIP: uncompress, out-of-mem or overwrite error - must RESET board to recover\n");
			return BOOTM_ERR_RESET;
		}

		*load_end = load + image_len;
		break;
#endif /* CONFIG_GZIP */
#ifdef CONFIG_BZIP2
	case IH_COMP_BZIP2:
		printf("   Uncompressing %s ... ", type_name);
		/*
		 * If we've got less than 4 MB of malloc() space,
		 * use slower decompression algorithm which requires
		 * at most 2300 KB of memory.
		 */
		int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len,
			image_buf, image_len,
			CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
		if (i != BZ_OK) {
			printf("BUNZIP2: uncompress or overwrite error %d - must RESET board to recover\n",
			       i);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + unc_len;
		break;
#endif /* CONFIG_BZIP2 */
#ifdef CONFIG_LZMA
	case IH_COMP_LZMA: {
		SizeT lzma_len = unc_len;
		int ret;

		printf("   Uncompressing %s ... ", type_name);

		ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
					       image_buf, image_len);
		unc_len = lzma_len;
		if (ret != SZ_OK) {
			printf("LZMA: uncompress or overwrite error %d - must RESET board to recover\n",
			       ret);
			bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}
		*load_end = load + unc_len;
		break;
	}
#endif /* CONFIG_LZMA */
#ifdef CONFIG_LZO
	case IH_COMP_LZO: {
		size_t size = unc_len;
		int ret;

		printf("   Uncompressing %s ... ", type_name);

		ret = lzop_decompress(image_buf, image_len, load_buf, &size);
		if (ret != LZO_E_OK) {
			printf("LZO: uncompress or overwrite error %d - must RESET board to recover\n",
			       ret);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + size;
		break;
	}
#endif /* CONFIG_LZO */
	default:
		printf("Unimplemented compression type %d\n", comp);
		return BOOTM_ERR_UNIMPLEMENTED;
	}

	puts("OK\n");

	return 0;
}
Example #8
0
int bootm_image(const image_header_t *header)
{
    const char * failure = NULL;
    const char * type_name = NULL;
    uint32_t load, image_start, image_len;

    /* Display to standard output the image contents. */

    image_print_contents(header);

    /* Validate the image header and image data CRCs */

    puts("   Verifying Checksum ... ");

    {
        if (!image_check_hcrc(header)) {
            failure = "Header Invalid\n";
            goto fail;
        }

        if (!image_check_dcrc(header)) {
            failure = "Data Invalid\n";
            goto fail;
        }
    }

    puts("OK\n");

    /* We ONLY support uncompressed ARM U-Boot firmware images. Check
     * to make sure that's what we are going to boot.
     */

    if (!image_check_type(header, IH_TYPE_FIRMWARE)) {
        failure = "Image is not a firmware image\n";
        goto fail;
    }

    if (!image_check_os(header, IH_OS_U_BOOT)) {
        failure = "Image is not u-boot firmware\n";
        goto fail;
    }

    if (image_get_comp(header) != IH_COMP_NONE) {
        failure = "Image is compressed\n";
        goto fail;
    }

    if (!image_check_target_arch(header)) {
        failure = "Image is not built for this processor\n";
        goto fail;
    }

    type_name = genimg_get_type_name(image_get_type(header));

    printf("   Loading %s ... ", type_name);

    {
        load = image_get_load(header);
        image_start = image_get_data(header);
        image_len = image_get_data_size(header);

        memmove_wd((void *)load, (void *)image_start, image_len, CHUNKSZ);
    }

    puts("OK\n");

    /* This should never return. */

    exec(load, type_name);

    /* However, if it does, return failed status. */

fail:
    puts(failure);

    return (BOOTM_STATUS_FAILURE);
}
Example #9
0
int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr,
		   const char **fit_unamep, const char **fit_uname_configp,
		   int arch, int image_type, int bootstage_id,
		   enum fit_load_op load_op, ulong *datap, ulong *lenp)
{
	int cfg_noffset, noffset;
	const char *fit_uname;
	const char *fit_uname_config;
	const void *fit;
	const void *buf;
	size_t size;
	int type_ok, os_ok;
	ulong load, data, len;
	int ret;

	fit = map_sysmem(addr, 0);
	fit_uname = fit_unamep ? *fit_unamep : NULL;
	fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
	printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
	if (!fit_check_format(fit)) {
		printf("Bad FIT %s image format!\n", prop_name);
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
		return -ENOEXEC;
	}
	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
	if (fit_uname) {
		/* get ramdisk component image node offset */
		bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
		noffset = fit_image_get_node(fit, fit_uname);
	} else {
		/*
		 * no image node unit name, try to get config
		 * node first. If config unit node name is NULL
		 * fit_conf_get_node() will try to find default config node
		 */
		bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
		if (IMAGE_ENABLE_BEST_MATCH && !fit_uname_config) {
			cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
		} else {
			cfg_noffset = fit_conf_get_node(fit,
							fit_uname_config);
		}
		if (cfg_noffset < 0) {
			puts("Could not find configuration node\n");
			bootstage_error(bootstage_id +
					BOOTSTAGE_SUB_NO_UNIT_NAME);
			return -ENOENT;
		}
		fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
		printf("   Using '%s' configuration\n", fit_uname_config);
		if (image_type == IH_TYPE_KERNEL) {
			/* Remember (and possibly verify) this config */
			images->fit_uname_cfg = fit_uname_config;
			if (IMAGE_ENABLE_VERIFY && images->verify) {
				puts("   Verifying Hash Integrity ... ");
				if (!fit_config_verify(fit, cfg_noffset)) {
					puts("Bad Data Hash\n");
					bootstage_error(bootstage_id +
						BOOTSTAGE_SUB_HASH);
					return -EACCES;
				}
				puts("OK\n");
			}
			bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
		}

		noffset = fit_conf_get_prop_node(fit, cfg_noffset,
						 prop_name);
		fit_uname = fit_get_name(fit, noffset, NULL);
	}
	if (noffset < 0) {
		puts("Could not find subimage node\n");
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
		return -ENOENT;
	}

	printf("   Trying '%s' %s subimage\n", fit_uname, prop_name);

	ret = fit_image_select(fit, noffset, images->verify);
	if (ret) {
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
		return ret;
	}

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
	if (!fit_image_check_target_arch(fit, noffset)) {
		puts("Unsupported Architecture\n");
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
		return -ENOEXEC;
	}

	if (image_type == IH_TYPE_FLATDT &&
	    !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) {
		puts("FDT image is compressed");
		return -EPROTONOSUPPORT;
	}

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
	type_ok = fit_image_check_type(fit, noffset, image_type) ||
		(image_type == IH_TYPE_KERNEL &&
			fit_image_check_type(fit, noffset,
					     IH_TYPE_KERNEL_NOLOAD));
	os_ok = image_type == IH_TYPE_FLATDT ||
		fit_image_check_os(fit, noffset, IH_OS_LINUX);
	if (!type_ok || !os_ok) {
		printf("No Linux %s %s Image\n", genimg_get_arch_name(arch),
		       genimg_get_type_name(image_type));
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
		return -EIO;
	}

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);

	/* get image data address and length */
	if (fit_image_get_data(fit, noffset, &buf, &size)) {
		printf("Could not find %s subimage data!\n", prop_name);
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
		return -ENOENT;
	}
	len = (ulong)size;

	/* verify that image data is a proper FDT blob */
	if (image_type == IH_TYPE_FLATDT && fdt_check_header((char *)buf)) {
		puts("Subimage data is not a FDT");
		return -ENOEXEC;
	}

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);

	/*
	 * Work-around for eldk-4.2 which gives this warning if we try to
	 * case in the unmap_sysmem() call:
	 * warning: initialization discards qualifiers from pointer target type
	 */
	{
		void *vbuf = (void *)buf;

		data = map_to_sysmem(vbuf);
	}

	if (load_op == FIT_LOAD_IGNORED) {
		/* Don't load */
	} else if (fit_image_get_load(fit, noffset, &load)) {
		if (load_op == FIT_LOAD_REQUIRED) {
			printf("Can't get %s subimage load address!\n",
			       prop_name);
			bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
			return -EBADF;
		}
	} else {
		ulong image_start, image_end;
		ulong load_end;
		void *dst;

		/*
		 * move image data to the load address,
		 * make sure we don't overwrite initial image
		 */
		image_start = addr;
		image_end = addr + fit_get_size(fit);

		load_end = load + len;
		if (image_type != IH_TYPE_KERNEL &&
		    load < image_end && load_end > image_start) {
			printf("Error: %s overwritten\n", prop_name);
			return -EXDEV;
		}

		printf("   Loading %s from 0x%08lx to 0x%08lx\n",
		       prop_name, data, load);

		dst = map_sysmem(load, len);
		memmove(dst, buf, len);
		data = load;
	}
	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);

	*datap = data;
	*lenp = len;
	if (fit_unamep)
		*fit_unamep = (char *)fit_uname;
	if (fit_uname_configp)
		*fit_uname_configp = (char *)fit_uname_config;

	return noffset;
}
int
main (int argc, char **argv)
{
	int ifd = -1;
	struct stat sbuf;
	unsigned char *ptr;
	int retval = 0;
	struct image_type_params *tparams = NULL;

	/* Init Kirkwood Boot image generation/list support */
	init_kwb_image_type ();
	/* Init Freescale imx Boot image generation/list support */
	init_imx_image_type ();
	/* Init FIT image generation/list support */
	init_fit_image_type ();
	/* Init Default image generation/list support */
	init_default_image_type ();

	params.cmdname = *argv;
	params.addr = params.ep = 0;

	while (--argc > 0 && **++argv == '-') {
		while (*++*argv) {
			switch (**argv) {
			case 'l':
				params.lflag = 1;
				break;
			case 'A':
				if ((--argc <= 0) ||
					(params.arch =
					genimg_get_arch_id (*++argv)) < 0)
					usage ();
				goto NXTARG;
			case 'C':
				if ((--argc <= 0) ||
					(params.comp =
					genimg_get_comp_id (*++argv)) < 0)
					usage ();
				goto NXTARG;
			case 'D':
				if (--argc <= 0)
					usage ();
				params.dtc = *++argv;
				goto NXTARG;

			case 'O':
				if ((--argc <= 0) ||
					(params.os =
					genimg_get_os_id (*++argv)) < 0)
					usage ();
				goto NXTARG;
			case 'T':
				if ((--argc <= 0) ||
					(params.type =
					genimg_get_type_id (*++argv)) < 0)
					usage ();
				goto NXTARG;

			case 'a':
				if (--argc <= 0)
					usage ();
				params.addr = strtoul (*++argv,
					(char **)&ptr, 16);
				if (*ptr) {
					fprintf (stderr,
						"%s: invalid load address %s\n",
						params.cmdname, *argv);
					exit (EXIT_FAILURE);
				}
				goto NXTARG;
			case 'd':
				if (--argc <= 0)
					usage ();
				params.datafile = *++argv;
				params.dflag = 1;
				goto NXTARG;
			case 'e':
				if (--argc <= 0)
					usage ();
				params.ep = strtoul (*++argv,
						(char **)&ptr, 16);
				if (*ptr) {
					fprintf (stderr,
						"%s: invalid entry point %s\n",
						params.cmdname, *argv);
					exit (EXIT_FAILURE);
				}
				params.eflag = 1;
				goto NXTARG;
			case 'f':
				if (--argc <= 0)
					usage ();
				/*
				 * The flattened image tree (FIT) format
				 * requires a flattened device tree image type
				 */
				params.type = IH_TYPE_FLATDT;
				params.datafile = *++argv;
				params.fflag = 1;
				goto NXTARG;
			case 'n':
				if (--argc <= 0)
					usage ();
				params.imagename = *++argv;
				goto NXTARG;
			case 'v':
				params.vflag++;
				break;
			case 'x':
				params.xflag++;
				break;
			default:
				usage ();
			}
		}
NXTARG:		;
	}

	if (argc != 1)
		usage ();

	/* set tparams as per input type_id */
	tparams = mkimage_get_type(params.type);
	if (tparams == NULL) {
		fprintf (stderr, "%s: unsupported type %s\n",
			params.cmdname, genimg_get_type_name(params.type));
		exit (EXIT_FAILURE);
	}

	/*
	 * check the passed arguments parameters meets the requirements
	 * as per image type to be generated/listed
	 */
	if (tparams->check_params)
		if (tparams->check_params (&params))
			usage ();

	if (!params.eflag) {
		params.ep = params.addr;
		/* If XIP, entry point must be after the U-Boot header */
		if (params.xflag)
			params.ep += tparams->header_size;
	}

	params.imagefile = *argv;

	if (params.fflag){
		if (tparams->fflag_handle)
			/*
			 * in some cases, some additional processing needs
			 * to be done if fflag is defined
			 *
			 * For ex. fit_handle_file for Fit file support
			 */
			retval = tparams->fflag_handle(&params);

		if (retval != EXIT_SUCCESS)
			exit (retval);
	}

	if (params.lflag || params.fflag) {
		ifd = open (params.imagefile, O_RDONLY|O_BINARY);
	} else {
		ifd = open (params.imagefile,
			O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666);
	}

	if (ifd < 0) {
		fprintf (stderr, "%s: Can't open %s: %s\n",
			params.cmdname, params.imagefile,
			strerror(errno));
		exit (EXIT_FAILURE);
	}

	if (params.lflag || params.fflag) {
		/*
		 * list header information of existing image
		 */
		if (fstat(ifd, &sbuf) < 0) {
			fprintf (stderr, "%s: Can't stat %s: %s\n",
				params.cmdname, params.imagefile,
				strerror(errno));
			exit (EXIT_FAILURE);
		}

		if ((unsigned)sbuf.st_size < tparams->header_size) {
			fprintf (stderr,
				"%s: Bad size: \"%s\" is not valid image\n",
				params.cmdname, params.imagefile);
			exit (EXIT_FAILURE);
		}

		ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0);
		if (ptr == MAP_FAILED) {
			fprintf (stderr, "%s: Can't read %s: %s\n",
				params.cmdname, params.imagefile,
				strerror(errno));
			exit (EXIT_FAILURE);
		}

		/*
		 * scan through mkimage registry for all supported image types
		 * and verify the input image file header for match
		 * Print the image information for matched image type
		 * Returns the error code if not matched
		 */
		retval = mkimage_verify_print_header (ptr, &sbuf);

		(void) munmap((void *)ptr, sbuf.st_size);
		(void) close (ifd);

		exit (retval);
	}

	/*
	 * Must be -w then:
	 *
	 * write dummy header, to be fixed later
	 */
	memset (tparams->hdr, 0, tparams->header_size);

	if (write(ifd, tparams->hdr, tparams->header_size)
					!= tparams->header_size) {
		fprintf (stderr, "%s: Write error on %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	if (params.type == IH_TYPE_MULTI || params.type == IH_TYPE_SCRIPT) {
		char *file = params.datafile;
		uint32_t size;

		for (;;) {
			char *sep = NULL;

			if (file) {
				if ((sep = strchr(file, ':')) != NULL) {
					*sep = '\0';
				}

				if (stat (file, &sbuf) < 0) {
					fprintf (stderr, "%s: Can't stat %s: %s\n",
						params.cmdname, file, strerror(errno));
					exit (EXIT_FAILURE);
				}
				size = cpu_to_uimage (sbuf.st_size);
			} else {
				size = 0;
			}

			if (write(ifd, (char *)&size, sizeof(size)) != sizeof(size)) {
				fprintf (stderr, "%s: Write error on %s: %s\n",
					params.cmdname, params.imagefile,
					strerror(errno));
				exit (EXIT_FAILURE);
			}

			if (!file) {
				break;
			}

			if (sep) {
				*sep = ':';
				file = sep + 1;
			} else {
				file = NULL;
			}
		}

		file = params.datafile;

		for (;;) {
			char *sep = strchr(file, ':');
			if (sep) {
				*sep = '\0';
				copy_file (ifd, file, 1);
				*sep++ = ':';
				file = sep;
			} else {
				copy_file (ifd, file, 0);
				break;
			}
		}
	} else {
		copy_file (ifd, params.datafile, 0);
	}

	/* We're a bit of paranoid */
#if defined(_POSIX_SYNCHRONIZED_IO) && \
   !defined(__sun__) && \
   !defined(__FreeBSD__) && \
   !defined(__APPLE__)
	(void) fdatasync (ifd);
#else
	(void) fsync (ifd);
#endif

	if (fstat(ifd, &sbuf) < 0) {
		fprintf (stderr, "%s: Can't stat %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	ptr = mmap(0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0);
	if (ptr == MAP_FAILED) {
		fprintf (stderr, "%s: Can't map %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	/* Setup the image header as per input image type*/
	if (tparams->set_header)
		tparams->set_header (ptr, &sbuf, ifd, &params);
	else {
		fprintf (stderr, "%s: Can't set header for %s: %s\n",
			params.cmdname, tparams->name, strerror(errno));
		exit (EXIT_FAILURE);
	}

	/* Print the image information by processing image header */
	if (tparams->print_header)
		tparams->print_header (ptr);
	else {
		fprintf (stderr, "%s: Can't print header for %s: %s\n",
			params.cmdname, tparams->name, strerror(errno));
		exit (EXIT_FAILURE);
	}

	(void) munmap((void *)ptr, sbuf.st_size);

	/* We're a bit of paranoid */
#if defined(_POSIX_SYNCHRONIZED_IO) && \
   !defined(__sun__) && \
   !defined(__FreeBSD__) && \
   !defined(__APPLE__)
	(void) fdatasync (ifd);
#else
	(void) fsync (ifd);
#endif

	if (close(ifd)) {
		fprintf (stderr, "%s: Write error on %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	exit (EXIT_SUCCESS);
}
Example #11
0
/**
 * spl_load_fit_image(): load the image described in a certain FIT node
 * @info:	points to information about the device to load data from
 * @sector:	the start sector of the FIT image on the device
 * @fit:	points to the flattened device tree blob describing the FIT
 *		image
 * @base_offset: the beginning of the data area containing the actual
 *		image data, relative to the beginning of the FIT
 * @node:	offset of the DT node describing the image to load (relative
 *		to @fit)
 * @image_info:	will be filled with information about the loaded image
 *		If the FIT node does not contain a "load" (address) property,
 *		the image gets loaded to the address pointed to by the
 *		load_addr member in this struct.
 *
 * Return:	0 on success or a negative error number.
 */
static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
			      void *fit, ulong base_offset, int node,
			      struct spl_image_info *image_info)
{
	int offset;
	size_t length;
	int len;
	ulong size;
	ulong load_addr, load_ptr;
	void *src;
	ulong overhead;
	int nr_sectors;
	int align_len = ARCH_DMA_MINALIGN - 1;
	uint8_t image_comp = -1, type = -1;
	const void *data;

	if (IS_ENABLED(CONFIG_SPL_OS_BOOT) && IS_ENABLED(CONFIG_SPL_GZIP)) {
		if (fit_image_get_comp(fit, node, &image_comp))
			puts("Cannot get image compression format.\n");
		else
			debug("%s ", genimg_get_comp_name(image_comp));

		if (fit_image_get_type(fit, node, &type))
			puts("Cannot get image type.\n");
		else
			debug("%s ", genimg_get_type_name(type));
	}

	if (fit_image_get_load(fit, node, &load_addr))
		load_addr = image_info->load_addr;

	if (!fit_image_get_data_offset(fit, node, &offset)) {
		/* External data */
		offset += base_offset;
		if (fit_image_get_data_size(fit, node, &len))
			return -ENOENT;

		load_ptr = (load_addr + align_len) & ~align_len;
		length = len;

		overhead = get_aligned_image_overhead(info, offset);
		nr_sectors = get_aligned_image_size(info, length, offset);

		if (info->read(info,
			       sector + get_aligned_image_offset(info, offset),
			       nr_sectors, (void *)load_ptr) != nr_sectors)
			return -EIO;

		debug("External data: dst=%lx, offset=%x, size=%lx\n",
		      load_ptr, offset, (unsigned long)length);
		src = (void *)load_ptr + overhead;
	} else {
		/* Embedded data */
		if (fit_image_get_data(fit, node, &data, &length)) {
			puts("Cannot get image data/size\n");
			return -ENOENT;
		}
		debug("Embedded data: dst=%lx, size=%lx\n", load_addr,
		      (unsigned long)length);
		src = (void *)data;
	}

#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
	board_fit_image_post_process(&src, &length);
#endif

	if (IS_ENABLED(CONFIG_SPL_OS_BOOT)	&&
	    IS_ENABLED(CONFIG_SPL_GZIP)		&&
	    image_comp == IH_COMP_GZIP		&&
	    type == IH_TYPE_KERNEL) {
		size = length;
		if (gunzip((void *)load_addr, CONFIG_SYS_BOOTM_LEN,
			   src, &size)) {
			puts("Uncompressing error\n");
			return -EIO;
		}
		length = size;
	} else {
		memcpy((void *)load_addr, src, length);
	}

	if (image_info) {
		image_info->load_addr = load_addr;
		image_info->size = length;
		image_info->entry_point = fdt_getprop_u32(fit, node, "entry");
	}

	return 0;
}
Example #12
0
int
main (int argc, char **argv)
{
	long imagelen; /* CWWeng 2014/4/30 */
	int aes_blockno; /* CWWeng 2014/4/30 */
	aes_context ctx; /* CWWeng 2014/5/12 add */
	int ifd = -1;
	struct stat sbuf;
	char *ptr;
	int retval = 0;
	struct image_type_params *tparams = NULL;

	/* Init Freescale PBL Boot image generation/list support */
	init_pbl_image_type();
	/* Init Kirkwood Boot image generation/list support */
	init_kwb_image_type ();
	/* Init Freescale imx Boot image generation/list support */
	init_imx_image_type ();
	/* Init FIT image generation/list support */
	init_fit_image_type ();
	/* Init TI OMAP Boot image generation/list support */
	init_omap_image_type();
	/* Init Default image generation/list support */
	init_default_image_type ();
	/* Init Davinci UBL support */
	init_ubl_image_type();
	/* Init Davinci AIS support */
	init_ais_image_type();

	params.cmdname = *argv;
	params.addr = params.ep = 0;

	while (--argc > 0 && **++argv == '-') {
		while (*++*argv) {
			switch (**argv) {
			case 'l':
				params.lflag = 1;
				break;
			case 'A':
				if ((--argc <= 0) ||
					(params.arch =
					genimg_get_arch_id (*++argv)) < 0)
					usage ();
				goto NXTARG;
			case 'C':
				if ((--argc <= 0) ||
					(params.comp =
					genimg_get_comp_id (*++argv)) < 0)
					usage ();
				goto NXTARG;
			case 'D':
				if (--argc <= 0)
					usage ();
				params.dtc = *++argv;
				goto NXTARG;

			case 'E': /* CWWeng 2014/4/29 add */
				if ((--argc <= 0) ||  
					(params.encrypt = 
					genimg_get_encrypt_id (*++argv)) < 0)
					usage ();
				goto NXTARG;

			case 'K': /* CWWeng 2015/2/6 add */
				if (--argc <= 0)
					usage ();
				params.keyfile = *++argv;
				params.kflag = 1;
				goto NXTARG;

			case 'O':
				if ((--argc <= 0) ||
					(params.os =
					genimg_get_os_id (*++argv)) < 0)
					usage ();
				goto NXTARG;

			case 'S': /* CWWeng 2015/3/5 add */
				if ((--argc <= 0) ||
					(params.checksum =
					genimg_get_checksum_id (*++argv)) < 0)
					usage ();
				goto NXTARG;

			case 'T':
				if ((--argc <= 0) ||
					(params.type =
					genimg_get_type_id (*++argv)) < 0)
					usage ();
				goto NXTARG;

			case 'a':
				if (--argc <= 0)
					usage ();
				params.addr = strtoul (*++argv, &ptr, 16);
				if (*ptr) {
					fprintf (stderr,
						"%s: invalid load address %s\n",
						params.cmdname, *argv);
					exit (EXIT_FAILURE);
				}
				goto NXTARG;
			case 'd':
				if (--argc <= 0)
					usage ();
				params.datafile = *++argv;
				params.dflag = 1;
				goto NXTARG;
			case 'e':
				if (--argc <= 0)
					usage ();
				params.ep = strtoul (*++argv, &ptr, 16);
				if (*ptr) {
					fprintf (stderr,
						"%s: invalid entry point %s\n",
						params.cmdname, *argv);
					exit (EXIT_FAILURE);
				}
				params.eflag = 1;
				goto NXTARG;
			case 'f':
				if (--argc <= 0)
					usage ();
				/*
				 * The flattened image tree (FIT) format
				 * requires a flattened device tree image type
				 */
				params.type = IH_TYPE_FLATDT;
				params.datafile = *++argv;
				params.fflag = 1;
				goto NXTARG;
			case 'n':
				if (--argc <= 0)
					usage ();
				params.imagename = *++argv;
				goto NXTARG;
			case 'R':
				if (--argc <= 0)
					usage();
				/*
				 * This entry is for the second configuration
				 * file, if only one is not enough.
				 */
				params.imagename2 = *++argv;
				goto NXTARG;
			case 's':
				params.skipcpy = 1;
				break;
			case 'v':
				params.vflag++;
				break;
			case 'V':
				printf("mkimage version %s\n", PLAIN_VERSION);
				exit(EXIT_SUCCESS);
			case 'x':
				params.xflag++;
				break;
			default:
				usage ();
			}
		}
NXTARG:		;
	}

	if (argc != 1)
		usage ();

	/* set tparams as per input type_id */
	tparams = mkimage_get_type(params.type);
	if (tparams == NULL) {
		fprintf (stderr, "%s: unsupported type %s\n",
			params.cmdname, genimg_get_type_name(params.type));
		exit (EXIT_FAILURE);
	}

	/*
	 * check the passed arguments parameters meets the requirements
	 * as per image type to be generated/listed
	 */
	if (tparams->check_params)
		if (tparams->check_params (&params))
			usage ();

	if (!params.eflag) {
		params.ep = params.addr;
		/* If XIP, entry point must be after the U-Boot header */
		if (params.xflag)
			params.ep += tparams->header_size;
	}

	params.imagefile = *argv;

	if (params.fflag){
		if (tparams->fflag_handle)
			/*
			 * in some cases, some additional processing needs
			 * to be done if fflag is defined
			 *
			 * For ex. fit_handle_file for Fit file support
			 */
			retval = tparams->fflag_handle(&params);

		if (retval != EXIT_SUCCESS)
			exit (retval);
	}

	/* CWWeng 2015/2/6 add to read key file */
	if (params.kflag) 
		_read_key(params.cmdname, params.keyfile);
	

	if (params.lflag || params.fflag) {
		ifd = open (params.imagefile, O_RDONLY|O_BINARY);
	} else {
		ifd = open (params.imagefile,
			O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666);
	}

	if (ifd < 0) {
		fprintf (stderr, "%s: Can't open %s: %s\n",
			params.cmdname, params.imagefile,
			strerror(errno));
		exit (EXIT_FAILURE);
	}

	if (params.lflag || params.fflag) {
		/*
		 * list header information of existing image
		 */
		if (fstat(ifd, &sbuf) < 0) {
			fprintf (stderr, "%s: Can't stat %s: %s\n",
				params.cmdname, params.imagefile,
				strerror(errno));
			exit (EXIT_FAILURE);
		}

		if ((unsigned)sbuf.st_size < tparams->header_size) {
			fprintf (stderr,
				"%s: Bad size: \"%s\" is not valid image\n",
				params.cmdname, params.imagefile);
			exit (EXIT_FAILURE);
		}

		/* CWWeng 2014/5/28 : append 0 to the end of image 
		 * aes_encrypt() encrypt one 128 bit block
		 * if the image is not multiple of 16 byte (128 bit),
		 * patch 0 to the end of the image
		 */
		if (params.encrypt == IH_ENCRPT_AES) {
			char ch[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
			lseek(ifd,0,SEEK_END);
			if (sbuf.st_size % 16)
				write(ifd,ch, 16 - (sbuf.st_size % 16));
		}

		ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0);
		if (ptr == MAP_FAILED) {
			fprintf (stderr, "%s: Can't read %s: %s\n",
				params.cmdname, params.imagefile,
				strerror(errno));
			exit (EXIT_FAILURE);
		}

		/*
		 * scan through mkimage registry for all supported image types
		 * and verify the input image file header for match
		 * Print the image information for matched image type
		 * Returns the error code if not matched
		 */
		retval = mkimage_verify_print_header (ptr, &sbuf);

		/*
		 * CWWeng 2014/4/30 : encrypt the image
		 * aes_encrypt() encrypt one 128 bit block
		 * if the image is not multiple of 16 byte (128 bit),
		 * patch 0 to the end of the image
		 */
		if (params.encrypt == IH_ENCRPT_AES) {
			int i;
			u8 temp_key;
			for (i=0; i<32; i+=4)
			{
				temp_key = otp_key[i];
				otp_key[i] = otp_key[i+3];
				otp_key[i+3] = temp_key;
				
				temp_key = otp_key[i+1];
				otp_key[i+1] = otp_key[i+2];
				otp_key[i+2] = temp_key;
			}

			for (i=0; i<32; i+=4)
				printf("Key%d = 0x%02x%02x%02x%02x\n",i/4,otp_key[i],otp_key[i+1],otp_key[i+2],otp_key[i+3]);

			aes_set_key(&ctx, (u8 *)otp_key, 256);
			imagelen = sbuf.st_size + 64;
			aes_blockno = 0;
			do
			{
				aes_encrypt(&ctx, (u8 *)(ptr+(16*aes_blockno)), (u8 *)(ptr+(16*aes_blockno)));
				imagelen -= 16;
				aes_blockno++;
			} while (imagelen > 0);
		}

		(void) munmap((void *)ptr, sbuf.st_size);
		(void) close (ifd);

		exit (retval);
	}

	/*
	 * In case there an header with a variable
	 * length will be added, the corresponding
	 * function is called. This is responsible to
	 * allocate memory for the header itself.
	 */
	if (tparams->vrec_header)
		tparams->vrec_header(&params, tparams);
	else
		memset(tparams->hdr, 0, tparams->header_size);

	if (write(ifd, tparams->hdr, tparams->header_size)
					!= tparams->header_size) {
		fprintf (stderr, "%s: Write error on %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	if (!params.skipcpy) {
		if (params.type == IH_TYPE_MULTI ||
		    params.type == IH_TYPE_SCRIPT) {
			char *file = params.datafile;
			uint32_t size;

			for (;;) {
				char *sep = NULL;

				if (file) {
					if ((sep = strchr(file, ':')) != NULL) {
						*sep = '\0';
					}

					if (stat (file, &sbuf) < 0) {
						fprintf (stderr, "%s: Can't stat %s: %s\n",
							 params.cmdname, file, strerror(errno));
						exit (EXIT_FAILURE);
					}
					size = cpu_to_uimage (sbuf.st_size);
				} else {
					size = 0;
				}

				if (write(ifd, (char *)&size, sizeof(size)) != sizeof(size)) {
					fprintf (stderr, "%s: Write error on %s: %s\n",
						 params.cmdname, params.imagefile,
						 strerror(errno));
					exit (EXIT_FAILURE);
				}

				if (!file) {
					break;
				}

				if (sep) {
					*sep = ':';
					file = sep + 1;
				} else {
					file = NULL;
				}
			}

			file = params.datafile;

			for (;;) {
				char *sep = strchr(file, ':');
				if (sep) {
					*sep = '\0';
					copy_file (ifd, file, 1);
					*sep++ = ':';
					file = sep;
				} else {
					copy_file (ifd, file, 0);
					break;
				}
			}
		} else if (params.type == IH_TYPE_PBLIMAGE) {
			/* PBL has special Image format, implements its' own */
			pbl_load_uboot(ifd, &params);
		} else {
			copy_file (ifd, params.datafile, 0);
		}
	}

	/* We're a bit of paranoid */
#if defined(_POSIX_SYNCHRONIZED_IO) && \
   !defined(__sun__) && \
   !defined(__FreeBSD__) && \
   !defined(__APPLE__)
	(void) fdatasync (ifd);
#else
	(void) fsync (ifd);
#endif

	if (fstat(ifd, &sbuf) < 0) {
		fprintf (stderr, "%s: Can't stat %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	/* CWWeng 2014/5/28 : append 0 to the end of image
	 * aes_encrypt() encrypt one 128 bit block
	 * if the image is not multiple of 16 byte (128 bit),
	 * patch 0 to the end of the image
	 */
	if (params.encrypt == IH_ENCRPT_AES) {
		char ch[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
		lseek(ifd,0,SEEK_END);
		if (sbuf.st_size % 16)
			write(ifd,ch, 16 - (sbuf.st_size % 16));
	}

	ptr = mmap(0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0);
	if (ptr == MAP_FAILED) {
		fprintf (stderr, "%s: Can't map %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	/* Setup the image header as per input image type*/
	if (tparams->set_header)
		tparams->set_header (ptr, &sbuf, ifd, &params);
	else {
		fprintf (stderr, "%s: Can't set header for %s: %s\n",
			params.cmdname, tparams->name, strerror(errno));
		exit (EXIT_FAILURE);
	}

	/* Print the image information by processing image header */
	if (tparams->print_header)
		tparams->print_header (ptr);
	else {
		fprintf (stderr, "%s: Can't print header for %s: %s\n",
			params.cmdname, tparams->name, strerror(errno));
		exit (EXIT_FAILURE);
	}

	/*
	 * CWWeng 2014/4/30 : encrypt the image
	 * aes_encrypt() encrypt one 128 bit block
	 * if the image is not multiple of 16 byte (128 bit),
	 * patch 0 to the end of the image
	 */
	if (params.encrypt == IH_ENCRPT_AES) {
		int i;
		u8 temp_key;
		for (i=0; i<32; i+=4)
		{
			temp_key = otp_key[i];
			otp_key[i] = otp_key[i+3];
			otp_key[i+3] = temp_key;
				
			temp_key = otp_key[i+1];
			otp_key[i+1] = otp_key[i+2];
			otp_key[i+2] = temp_key;
		}

		for (i=0; i<32; i+=4)
			printf("Key%d = 0x%02x%02x%02x%02x\n",i/4,otp_key[i],otp_key[i+1],otp_key[i+2],otp_key[i+3]);

		aes_set_key(&ctx, (u8 *)otp_key, 256);
		imagelen = sbuf.st_size + 64;
		aes_blockno = 0;
		do
		{
			aes_encrypt(&ctx, (u8 *)(ptr+(16*aes_blockno)), (u8 *)(ptr+(16*aes_blockno)));
			imagelen -= 16;
			aes_blockno++;
		} while (imagelen > 0);
	}

	(void) munmap((void *)ptr, sbuf.st_size);

	/* We're a bit of paranoid */
#if defined(_POSIX_SYNCHRONIZED_IO) && \
   !defined(__sun__) && \
   !defined(__FreeBSD__) && \
   !defined(__APPLE__)
	(void) fdatasync (ifd);
#else
	(void) fsync (ifd);
#endif

	if (close(ifd)) {
		fprintf (stderr, "%s: Write error on %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	exit (EXIT_SUCCESS);
}
Example #13
0
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	image_header_t	*hdr;
	ulong		addr;
	ulong		iflag;
	const char	*type_name;
	uint		unc_len = CONFIG_SYS_BOOTM_LEN;
	uint8_t		comp, type, os;

	void		*os_hdr;
	ulong		os_data, os_len;
	ulong		image_start, image_end;
	ulong		load_start, load_end;
	ulong		mem_start;
	phys_size_t	mem_size;

	struct lmb lmb;

#if defined(CONFIG_SECURE_BOOT)
	int rv;
#endif

#if defined(CONFIG_SECURE_BOOT)
	rv = Check_Signature( (SecureBoot_CTX *)SECURE_BOOT_CONTEXT_ADDR,
                                (unsigned char*)CONFIG_SECURE_KERNEL_BASE,
                                CONFIG_SECURE_KERNEL_SIZE-128,
                                (unsigned char*)(CONFIG_SECURE_KERNEL_BASE+CONFIG_SECURE_KERNEL_SIZE-128),
                                128 );
        if(rv != SB_OK) {
                printf("Kernel Integrity check fail\nSystem Halt....");
                while(1);
        }
        printf("Kernel Integirty check success.\n");

	rv = Check_Signature( (SecureBoot_CTX *)SECURE_BOOT_CONTEXT_ADDR,
                                (unsigned char*)CONFIG_SECURE_ROOTFS_BASE,
                                CONFIG_SECURE_ROOTFS_SIZE-128,
                                (unsigned char*)(CONFIG_SECURE_ROOTFS_BASE+CONFIG_SECURE_ROOTFS_SIZE-128),
                                128 );
	if(rv != SB_OK) {
                printf("rootfs Integrity check fail\nSystem Halt....");
                while(1);
        }

        printf("rootfs Integirty check success.\n");

#endif
	
	memset ((void *)&images, 0, sizeof (images));
	images.verify = getenv_yesno ("verify");
//	images.lmb = &lmb;
	memcpy (&images.lmb, &lmb, sizeof(struct lmb));

	lmb_init(&lmb);

	mem_start = getenv_bootm_low();
	mem_size = getenv_bootm_size();

	lmb_add(&lmb, (phys_addr_t)mem_start, mem_size);

	board_lmb_reserve(&lmb);

#ifdef CONFIG_ZIMAGE_BOOT
#define LINUX_ZIMAGE_MAGIC	0x016f2818
	/* find out kernel image address */
	if (argc < 2) {
		addr = load_addr;
		debug ("*  kernel: default image load address = 0x%08lx\n",
				load_addr);
	} else {
		addr = simple_strtoul(argv[1], NULL, 16);
		//debug ("*  kernel: cmdline image address = 0x%08lx\n", img_addr);
	}


	if (*(ulong *)(addr + 9*4) == LINUX_ZIMAGE_MAGIC) {
		printf("Boot with zImage\n");
		addr = virt_to_phys(addr);
		hdr = (image_header_t *)addr;
		hdr->ih_os = IH_OS_LINUX;
		hdr->ih_ep = ntohl(addr);

		memmove (&images.legacy_hdr_os_copy, hdr, sizeof(image_header_t));

		/* save pointer to image header */
		images.legacy_hdr_os = hdr;

		images.legacy_hdr_valid = 1;

		goto after_header_check;
	}
#endif

	/* get kernel image header, start address and length */
	os_hdr = boot_get_kernel (cmdtp, flag, argc, argv,
			&images, &os_data, &os_len);
	if (os_len == 0) {
		puts ("ERROR: can't get kernel image!\n");
		return 1;
	}

	/* get image parameters */
	switch (genimg_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:
		if (fit_image_get_type (images.fit_hdr_os,
					images.fit_noffset_os, &type)) {
			puts ("Can't get image type!\n");
			show_boot_progress (-109);
			return 1;
		}

		if (fit_image_get_comp (images.fit_hdr_os,
					images.fit_noffset_os, &comp)) {
			puts ("Can't get image compression!\n");
			show_boot_progress (-110);
			return 1;
		}

		if (fit_image_get_os (images.fit_hdr_os,
					images.fit_noffset_os, &os)) {
			puts ("Can't get image OS!\n");
			show_boot_progress (-111);
			return 1;
		}

		image_end = fit_get_end (images.fit_hdr_os);

		if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os,
					&load_start)) {
			puts ("Can't get image load address!\n");
			show_boot_progress (-112);
			return 1;
		}
		break;
#endif
	default:
		puts ("ERROR: unknown image format type!\n");
		return 1;
	}

	image_start = (ulong)os_hdr;
	load_end = 0;
	type_name = genimg_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
	 * recover from any failures any more...
	 */
	iflag = disable_interrupts();

#if defined(CONFIG_CMD_USB)
	/*
	 * turn off USB to prevent the host controller from writing to the
	 * SDRAM while Linux is booting. This could happen (at least for OHCI
	 * controller), because the HCCA (Host Controller Communication Area)
	 * lies within the SDRAM and the host controller writes continously to
	 * this area (as busmaster!). The HccaFrameNumber is for example
	 * updated every 1 ms within the HCCA structure in SDRAM! For more
	 * details see the OpenHCI specification.
	 */
	usb_stop();
#endif


#ifdef CONFIG_AMIGAONEG3SE
	/*
	 * We've possible left the caches enabled during
	 * bios emulation, so turn them off again
	 */
	icache_disable();
	invalidate_l1_instruction_cache();
	flush_data_cache();
	dcache_disable();
#endif

	switch (comp) {
	case IH_COMP_NONE:
		if (load_start == (ulong)os_hdr) {
			printf ("   XIP %s ... ", type_name);
		} else {
			printf ("   Loading %s ... ", type_name);

			memmove_wd ((void *)load_start,
				   (void *)os_data, os_len, CHUNKSZ);
		}
		load_end = load_start + os_len;
		puts("OK\n");
		break;
	case IH_COMP_GZIP:
		printf ("   Uncompressing %s ... ", type_name);
		if (gunzip ((void *)load_start, unc_len,
					(uchar *)os_data, &os_len) != 0) {
			puts ("GUNZIP: uncompress or overwrite error "
				"- must RESET board to recover\n");
			show_boot_progress (-6);
			do_reset (cmdtp, flag, argc, argv);
		}

		load_end = load_start + os_len;
		break;
#ifdef CONFIG_BZIP2
	case IH_COMP_BZIP2:
		printf ("   Uncompressing %s ... ", type_name);
		/*
		 * If we've got less than 4 MB of malloc() space,
		 * use slower decompression algorithm which requires
		 * at most 2300 KB of memory.
		 */
		int i = BZ2_bzBuffToBuffDecompress ((char*)load_start,
					&unc_len, (char *)os_data, os_len,
					CFG_MALLOC_LEN < (4096 * 1024), 0);
		if (i != BZ_OK) {
			printf ("BUNZIP2: uncompress or overwrite error %d "
				"- must RESET board to recover\n", i);
			show_boot_progress (-6);
			do_reset (cmdtp, flag, argc, argv);
		}

		load_end = load_start + unc_len;
		break;
#endif /* CONFIG_BZIP2 */
	default:
		if (iflag)
			enable_interrupts();
		printf ("Unimplemented compression type %d\n", comp);
		show_boot_progress (-7);
		return 1;
	}
	puts ("OK\n");
	debug ("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load_start, load_end);
	show_boot_progress (7);

	if ((load_start < image_end) && (load_end > image_start)) {
		debug ("image_start = 0x%lX, image_end = 0x%lx\n", image_start, image_end);
		debug ("load_start = 0x%lx, load_end = 0x%lx\n", load_start, load_end);

		if (images.legacy_hdr_valid) {
			if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI)
				puts ("WARNING: legacy format multi component "
					"image overwritten\n");
		} else {
			puts ("ERROR: new format image overwritten - "
				"must RESET the board to recover\n");
			show_boot_progress (-113);
			do_reset (cmdtp, flag, argc, argv);
		}
	}

	show_boot_progress (8);

	lmb_reserve(&lmb, load_start, (load_end - load_start));

#if defined(CONFIG_ZIMAGE_BOOT)
after_header_check:
	os = hdr->ih_os;
#endif

	switch (os) {
	default:			/* handled by (original) Linux case */
	case IH_OS_LINUX:
#ifdef CONFIG_SILENT_CONSOLE
	    fixup_silent_linux();
#endif
	    do_bootm_linux (flag, argc, argv, &images);
	    break;
#ifdef CONFIG_BOOTM_NETBSD
	case IH_OS_NETBSD:
	    do_bootm_netbsd (flag, argc, argv, &images);
	    break;
#endif
#ifdef CONFIG_LYNXKDI
	case IH_OS_LYNXOS:
	    do_bootm_lynxkdi (flag, argc, argv, &images);
	    break;
#endif
#ifdef CONFIG_BOOTM_RTEMS
	case IH_OS_RTEMS:
	    do_bootm_rtems (flag, argc, argv, &images);
	    break;
#endif
/*
#if defined(CONFIG_CMD_ELF)
	case IH_OS_VXWORKS:
	    do_bootm_vxworks (cmdtp, flag, argc, argv, &images);
	    break;

	case IH_OS_QNX:
	    do_bootm_qnxelf (cmdtp, flag, argc, argv, &images);
	    break;
#endif
*/
#ifdef CONFIG_ARTOS
	case IH_OS_ARTOS:
	    do_bootm_artos (cmdtp, flag, argc, argv, &images);
	    break;
#endif
	}

	show_boot_progress (-9);
#ifdef DEBUG
	puts ("\n## Control returned to monitor - resetting...\n");
	do_reset (cmdtp, flag, argc, argv);
#endif
	if (iflag)
		enable_interrupts();

	return 1;
}
Example #14
0
static int ait_menu_install_images(void)
{
	int ret = 0;
	int count = 0;
	char s[100];
	char *t;

	/*
	 * possible image types:
	 * FIT_SUBTYPE_UNKNOWN
	 * FIT_SUBTYPE_UBL_HEADER
	 * FIT_SUBTYPE_SPL_IMAGE
	 * FIT_SUBTYPE_UBOOT_IMAGE
	 * FIT_SUBTYPE_DF_ENV_IMAGE
	 * FIT_SUBTYPE_RAMDISK_IMAGE
	 *
	 * use Envvariables:
	 * img_addr_r: image start addr
	 * header_addr: addr where to write to UBL header
	 * img_writeheader: write ubl header to nand
	 * img_writespl: write spl to nand
	 * img_writeuboot: write uboot to nand
	 * img_writedfenv: write default environment to ubi volume
	 * img_volume: which ubi volume should be updated with img_writeramdisk
	 * filesize: size of data for updating ubi volume
	 * img_writeramdisk: write ramdisk to ubi volume
	 */

	while (imgs[count].type != IH_TYPE_INVALID) {
		printf("Installing %s\n",
			genimg_get_type_name(imgs[count].type));
		sprintf(s, "%p", imgs[count].data);
		setenv("img_addr_r", s);
		sprintf(s, "%lx", (unsigned long)imgs[count].size);
		setenv("filesize", s);
		switch (imgs[count].subtype) {
		case FIT_SUBTYPE_DF_ENV_IMAGE:
			ret = run_command("run img_writedfenv", 0);
			break;
		case FIT_SUBTYPE_RAMDISK_IMAGE:
			t = getenv("img_volume");
			if (!t) {
				ret = setenv("img_volume", "rootfs1");
			} else {
				/* switch to other volume */
				if (strncmp(t, "rootfs1", 7) == 0)
					ret = setenv("img_volume", "rootfs2");
				else
					ret = setenv("img_volume", "rootfs1");
			}
			if (ret != 0)
				break;

			ret = run_command("run img_writeramdisk", 0);
			break;
		case FIT_SUBTYPE_SPL_IMAGE:
			ret = run_command("run img_writespl", 0);
			break;
		case FIT_SUBTYPE_UBL_HEADER:
			ret = ait_writeublheader();
			break;
		case FIT_SUBTYPE_UBOOT_IMAGE:
			ret = run_command("run img_writeuboot", 0);
			break;
		default:
			/* not supported type */
			break;
		}
		count++;
	}
	/* now save dvn_* and img_volume env vars to new values */
	if (ret == 0) {
		t = getenv("x_dvn_boot_vers");
		if (t)
			setenv("dvn_boot_vers", t);

		t = getenv("x_dvn_app_vers");
		if (t)
			setenv("dvn_boot_vers", t);

		setenv("x_dvn_boot_vers", NULL);
		setenv("x_dvn_app_vers", NULL);
		ret = run_command("run savenewvers", 0);
	}

	return ret;
}
Example #15
0
int main(int argc, char **argv)
{
	int ifd = -1;
	struct stat sbuf;
	char *ptr;
	int retval = 0;
	struct image_type_params *tparams = NULL;
	int pad_len = 0;
	int dfd;

	params.cmdname = *argv;
	params.addr = params.ep = 0;

	while (--argc > 0 && **++argv == '-') {
		while (*++*argv) {
			switch (**argv) {
			case 'l':
				params.lflag = 1;
				break;
			case 'A':
				if ((--argc <= 0) ||
					(params.arch =
					genimg_get_arch_id (*++argv)) < 0)
					usage ();
				goto NXTARG;
			case 'c':
				if (--argc <= 0)
					usage();
				params.comment = *++argv;
				goto NXTARG;
			case 'C':
				if ((--argc <= 0) ||
					(params.comp =
					genimg_get_comp_id (*++argv)) < 0)
					usage ();
				goto NXTARG;
			case 'D':
				if (--argc <= 0)
					usage ();
				params.dtc = *++argv;
				goto NXTARG;

			case 'O':
				if ((--argc <= 0) ||
					(params.os =
					genimg_get_os_id (*++argv)) < 0)
					usage ();
				goto NXTARG;
			case 'T':
				params.type = -1;
				if (--argc >= 0 && argv[1]) {
					params.type =
						genimg_get_type_id(*++argv);
				}
				if (params.type < 0) {
					show_image_types();
					usage();
				}
				goto NXTARG;
			case 'a':
				if (--argc <= 0)
					usage ();
				params.addr = strtoull(*++argv, &ptr, 16);
				if (*ptr) {
					fprintf (stderr,
						"%s: invalid load address %s\n",
						params.cmdname, *argv);
					exit (EXIT_FAILURE);
				}
				goto NXTARG;
			case 'd':
				if (--argc <= 0)
					usage ();
				params.datafile = *++argv;
				params.dflag = 1;
				goto NXTARG;
			case 'e':
				if (--argc <= 0)
					usage ();
				params.ep = strtoull(*++argv, &ptr, 16);
				if (*ptr) {
					fprintf (stderr,
						"%s: invalid entry point %s\n",
						params.cmdname, *argv);
					exit (EXIT_FAILURE);
				}
				params.eflag = 1;
				goto NXTARG;
			case 'f':
				if (--argc <= 0)
					usage ();
				params.datafile = *++argv;
				/* no break */
			case 'F':
				/*
				 * The flattened image tree (FIT) format
				 * requires a flattened device tree image type
				 */
				params.type = IH_TYPE_FLATDT;
				params.fflag = 1;
				goto NXTARG;
			case 'k':
				if (--argc <= 0)
					usage();
				params.keydir = *++argv;
				goto NXTARG;
			case 'K':
				if (--argc <= 0)
					usage();
				params.keydest = *++argv;
				goto NXTARG;
			case 'n':
				if (--argc <= 0)
					usage ();
				params.imagename = *++argv;
				goto NXTARG;
			case 'r':
				params.require_keys = 1;
				break;
			case 'R':
				if (--argc <= 0)
					usage();
				/*
				 * This entry is for the second configuration
				 * file, if only one is not enough.
				 */
				params.imagename2 = *++argv;
				goto NXTARG;
			case 's':
				params.skipcpy = 1;
				break;
			case 'v':
				params.vflag++;
				break;
			case 'V':
				printf("mkimage version %s\n", PLAIN_VERSION);
				exit(EXIT_SUCCESS);
			case 'x':
				params.xflag++;
				break;
			default:
				usage ();
			}
		}
NXTARG:		;
	}

	if (argc != 1)
		usage ();

	/* set tparams as per input type_id */
	tparams = imagetool_get_type(params.type);
	if (tparams == NULL) {
		fprintf (stderr, "%s: unsupported type %s\n",
			params.cmdname, genimg_get_type_name(params.type));
		exit (EXIT_FAILURE);
	}

	/*
	 * check the passed arguments parameters meets the requirements
	 * as per image type to be generated/listed
	 */
	if (tparams->check_params)
		if (tparams->check_params (&params))
			usage ();

	if (!params.eflag) {
		params.ep = params.addr;
		/* If XIP, entry point must be after the U-Boot header */
		if (params.xflag)
			params.ep += tparams->header_size;
	}

	params.imagefile = *argv;

	if (params.fflag){
		if (tparams->fflag_handle)
			/*
			 * in some cases, some additional processing needs
			 * to be done if fflag is defined
			 *
			 * For ex. fit_handle_file for Fit file support
			 */
			retval = tparams->fflag_handle(&params);

		if (retval != EXIT_SUCCESS)
			exit (retval);
	}

	if (params.lflag || params.fflag) {
		ifd = open (params.imagefile, O_RDONLY|O_BINARY);
	} else {
		ifd = open (params.imagefile,
			O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666);
	}

	if (ifd < 0) {
		fprintf (stderr, "%s: Can't open %s: %s\n",
			params.cmdname, params.imagefile,
			strerror(errno));
		exit (EXIT_FAILURE);
	}

	if (params.lflag || params.fflag) {
		/*
		 * list header information of existing image
		 */
		if (fstat(ifd, &sbuf) < 0) {
			fprintf (stderr, "%s: Can't stat %s: %s\n",
				params.cmdname, params.imagefile,
				strerror(errno));
			exit (EXIT_FAILURE);
		}

		if ((unsigned)sbuf.st_size < tparams->header_size) {
			fprintf (stderr,
				"%s: Bad size: \"%s\" is not valid image\n",
				params.cmdname, params.imagefile);
			exit (EXIT_FAILURE);
		}

		ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0);
		if (ptr == MAP_FAILED) {
			fprintf (stderr, "%s: Can't read %s: %s\n",
				params.cmdname, params.imagefile,
				strerror(errno));
			exit (EXIT_FAILURE);
		}

		/*
		 * scan through mkimage registry for all supported image types
		 * and verify the input image file header for match
		 * Print the image information for matched image type
		 * Returns the error code if not matched
		 */
		retval = imagetool_verify_print_header(ptr, &sbuf,
				tparams, &params);

		(void) munmap((void *)ptr, sbuf.st_size);
		(void) close (ifd);

		exit (retval);
	}

	if ((params.type != IH_TYPE_MULTI) && (params.type != IH_TYPE_SCRIPT)) {
		dfd = open(params.datafile, O_RDONLY | O_BINARY);
		if (dfd < 0) {
			fprintf(stderr, "%s: Can't open %s: %s\n",
				params.cmdname, params.datafile,
				strerror(errno));
			exit(EXIT_FAILURE);
		}

		if (fstat(dfd, &sbuf) < 0) {
			fprintf(stderr, "%s: Can't stat %s: %s\n",
				params.cmdname, params.datafile,
				strerror(errno));
			exit(EXIT_FAILURE);
		}

		params.file_size = sbuf.st_size + tparams->header_size;
		close(dfd);
	}

	/*
	 * In case there an header with a variable
	 * length will be added, the corresponding
	 * function is called. This is responsible to
	 * allocate memory for the header itself.
	 */
	if (tparams->vrec_header)
		pad_len = tparams->vrec_header(&params, tparams);
	else
		memset(tparams->hdr, 0, tparams->header_size);

	if (write(ifd, tparams->hdr, tparams->header_size)
					!= tparams->header_size) {
		fprintf (stderr, "%s: Write error on %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	if (!params.skipcpy) {
		if (params.type == IH_TYPE_MULTI ||
		    params.type == IH_TYPE_SCRIPT) {
			char *file = params.datafile;
			uint32_t size;

			for (;;) {
				char *sep = NULL;

				if (file) {
					if ((sep = strchr(file, ':')) != NULL) {
						*sep = '\0';
					}

					if (stat (file, &sbuf) < 0) {
						fprintf (stderr, "%s: Can't stat %s: %s\n",
							 params.cmdname, file, strerror(errno));
						exit (EXIT_FAILURE);
					}
					size = cpu_to_uimage (sbuf.st_size);
				} else {
					size = 0;
				}

				if (write(ifd, (char *)&size, sizeof(size)) != sizeof(size)) {
					fprintf (stderr, "%s: Write error on %s: %s\n",
						 params.cmdname, params.imagefile,
						 strerror(errno));
					exit (EXIT_FAILURE);
				}

				if (!file) {
					break;
				}

				if (sep) {
					*sep = ':';
					file = sep + 1;
				} else {
					file = NULL;
				}
			}

			file = params.datafile;

			for (;;) {
				char *sep = strchr(file, ':');
				if (sep) {
					*sep = '\0';
					copy_file (ifd, file, 1);
					*sep++ = ':';
					file = sep;
				} else {
					copy_file (ifd, file, 0);
					break;
				}
			}
		} else if (params.type == IH_TYPE_PBLIMAGE) {
			/* PBL has special Image format, implements its' own */
			pbl_load_uboot(ifd, &params);
		} else {
			copy_file(ifd, params.datafile, pad_len);
		}
	}

	/* We're a bit of paranoid */
#if defined(_POSIX_SYNCHRONIZED_IO) && \
   !defined(__sun__) && \
   !defined(__FreeBSD__) && \
   !defined(__OpenBSD__) && \
   !defined(__APPLE__)
	(void) fdatasync (ifd);
#else
	(void) fsync (ifd);
#endif

	if (fstat(ifd, &sbuf) < 0) {
		fprintf (stderr, "%s: Can't stat %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}
	params.file_size = sbuf.st_size;

	ptr = mmap(0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0);
	if (ptr == MAP_FAILED) {
		fprintf (stderr, "%s: Can't map %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	/* Setup the image header as per input image type*/
	if (tparams->set_header)
		tparams->set_header (ptr, &sbuf, ifd, &params);
	else {
		fprintf (stderr, "%s: Can't set header for %s: %s\n",
			params.cmdname, tparams->name, strerror(errno));
		exit (EXIT_FAILURE);
	}

	/* Print the image information by processing image header */
	if (tparams->print_header)
		tparams->print_header (ptr);
	else {
		fprintf (stderr, "%s: Can't print header for %s: %s\n",
			params.cmdname, tparams->name, strerror(errno));
		exit (EXIT_FAILURE);
	}

	(void) munmap((void *)ptr, sbuf.st_size);

	/* We're a bit of paranoid */
#if defined(_POSIX_SYNCHRONIZED_IO) && \
   !defined(__sun__) && \
   !defined(__FreeBSD__) && \
   !defined(__OpenBSD__) && \
   !defined(__APPLE__)
	(void) fdatasync (ifd);
#else
	(void) fsync (ifd);
#endif

	if (close(ifd)) {
		fprintf (stderr, "%s: Write error on %s: %s\n",
			params.cmdname, params.imagefile, strerror(errno));
		exit (EXIT_FAILURE);
	}

	exit (EXIT_SUCCESS);
}
Example #16
0
static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
{
	uint8_t comp = os.comp;
	ulong load = os.load;
	ulong blob_start = os.start;
	ulong blob_end = os.end;
	ulong image_start = os.image_start;
	ulong image_len = os.image_len;
	uint unc_len = CONFIG_SYS_BOOTM_LEN;

	const char *type_name = genimg_get_type_name (os.type);

	switch (comp) {
	case IH_COMP_NONE:
		if (load == blob_start) {
			printf ("   XIP %s ... ", type_name);
		} else {
			printf ("   Loading %s ... ", type_name);

			if (load != image_start) {
				memmove_wd ((void *)load,
						(void *)image_start, image_len, CHUNKSZ);
			}
		}
		*load_end = load + image_len;
		puts("OK\n");
		break;
	case IH_COMP_GZIP:
		printf ("   Uncompressing %s ... ", type_name);
		if (gunzip ((void *)load, unc_len,
					(uchar *)image_start, &image_len) != 0) {
			puts ("GUNZIP: uncompress, out-of-mem or overwrite error "
				"- must RESET board to recover\n");
			if (boot_progress)
				show_boot_progress (-6);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + image_len;
		break;
#ifdef CONFIG_BZIP2
	case IH_COMP_BZIP2:
		printf ("   Uncompressing %s ... ", type_name);
		/*
		 * If we've got less than 4 MB of malloc() space,
		 * use slower decompression algorithm which requires
		 * at most 2300 KB of memory.
		 */
		int i = BZ2_bzBuffToBuffDecompress ((char*)load,
					&unc_len, (char *)image_start, image_len,
					CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
		if (i != BZ_OK) {
			printf ("BUNZIP2: uncompress or overwrite error %d "
				"- must RESET board to recover\n", i);
			if (boot_progress)
				show_boot_progress (-6);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + unc_len;
		break;
#endif /* CONFIG_BZIP2 */
#ifdef CONFIG_LZMA
	case IH_COMP_LZMA:
		printf ("   Uncompressing %s ... ", type_name);

		int ret = lzmaBuffToBuffDecompress(
			(unsigned char *)load, &unc_len,
			(unsigned char *)image_start, image_len);
		if (ret != SZ_OK) {
			printf ("LZMA: uncompress or overwrite error %d "
				"- must RESET board to recover\n", ret);
			show_boot_progress (-6);
			return BOOTM_ERR_RESET;
		}
		*load_end = load + unc_len;
		break;
#endif /* CONFIG_LZMA */
	default:
		printf ("Unimplemented compression type %d\n", comp);
		return BOOTM_ERR_UNIMPLEMENTED;
	}
	puts ("OK\n");
	debug ("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
	if (boot_progress)
		show_boot_progress (7);

	if ((load < blob_end) && (*load_end > blob_start)) {
		debug ("images.os.start = 0x%lX, images.os.end = 0x%lx\n", blob_start, blob_end);
		debug ("images.os.load = 0x%lx, load_end = 0x%lx\n", load, *load_end);

		return BOOTM_ERR_OVERLAP;
	}

	return 0;
}
Example #17
0
static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
{
	uint8_t comp = os.comp;
	ulong load = os.load;
	ulong blob_start = os.start;
	ulong blob_end = os.end;
	ulong image_start = os.image_start;
	ulong image_len = os.image_len;
#if defined(CONFIG_GZIP) || defined(CONFIG_BZIP2) \
	|| defined(CONFIG_LZMA) || defined(CONFIG_LZO)
	uint unc_len = CONFIG_SYS_BOOTM_LEN;
#endif
	ulong image_end;

	const char *type_name = genimg_get_type_name (os.type);
	int boot_sp;

	__asm__ __volatile__(
		"mov    %0, sp\n"
		:"=r"(boot_sp)
		:
		:"cc"
		);

	/* Check whether kernel zImage overwrite uboot,
	 * which will lead to kernel boot fail. */
	image_end = load + image_len;
	/* leave at most 32KByte for move image stack */
	boot_sp -= BOOTM_STACK_GUARD;
	if( !((load > _bss_end) || (image_end < boot_sp)) ) {
		printf("\nkernel image will overwrite uboot! kernel boot fail!\n");
		return BOOTM_ERR_RESET;
	}

	switch (comp) {
	case IH_COMP_NONE:
		if (load == blob_start || load == image_start) {
			printf ("   XIP %s ... ", type_name);
		} else {
			printf ("   Loading %s ... ", type_name);
			memmove_wd ((void *)load, (void *)image_start,
					image_len, CHUNKSZ);
		}
		*load_end = load + image_len;
		puts("OK\n");
		break;
#ifdef CONFIG_GZIP
	case IH_COMP_GZIP:
		printf ("   Uncompressing %s ... ", type_name);
		if (gunzip ((void *)load, unc_len,
					(uchar *)image_start, &image_len) != 0) {
			puts ("GUNZIP: uncompress, out-of-mem or overwrite error "
				"- must RESET board to recover\n");
			if (boot_progress)
				show_boot_progress (-6);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + image_len;
		break;
#endif /* CONFIG_GZIP */
#ifdef CONFIG_BZIP2
	case IH_COMP_BZIP2:
		printf ("   Uncompressing %s ... ", type_name);
		/*
		 * If we've got less than 4 MB of malloc() space,
		 * use slower decompression algorithm which requires
		 * at most 2300 KB of memory.
		 */
		int i = BZ2_bzBuffToBuffDecompress ((char*)load,
					&unc_len, (char *)image_start, image_len,
					CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
		if (i != BZ_OK) {
			printf ("BUNZIP2: uncompress or overwrite error %d "
				"- must RESET board to recover\n", i);
			if (boot_progress)
				show_boot_progress (-6);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + unc_len;
		break;
#endif /* CONFIG_BZIP2 */
#ifdef CONFIG_LZMA
	case IH_COMP_LZMA:
		printf ("   Uncompressing %s ... ", type_name);

		int ret = lzmaBuffToBuffDecompress(
			(unsigned char *)load, &unc_len,
			(unsigned char *)image_start, image_len);
		if (ret != SZ_OK) {
			printf ("LZMA: uncompress or overwrite error %d "
				"- must RESET board to recover\n", ret);
			show_boot_progress (-6);
			return BOOTM_ERR_RESET;
		}
		*load_end = load + unc_len;
		break;
#endif /* CONFIG_LZMA */
#ifdef CONFIG_LZO
	case IH_COMP_LZO:
		printf ("   Uncompressing %s ... ", type_name);

		int ret = lzop_decompress((const unsigned char *)image_start,
					  image_len, (unsigned char *)load,
					  &unc_len);
		if (ret != LZO_E_OK) {
			printf ("LZO: uncompress or overwrite error %d "
			      "- must RESET board to recover\n", ret);
			if (boot_progress)
				show_boot_progress (-6);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + unc_len;
		break;
#endif /* CONFIG_LZO */
	default:
		printf ("Unimplemented compression type %d\n", comp);
		return BOOTM_ERR_UNIMPLEMENTED;
	}
	puts ("OK\n");
	debug ("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
	if (boot_progress)
		show_boot_progress (7);

	if ((load < blob_end) && (*load_end > blob_start)) {
		debug ("images.os.start = 0x%lX, images.os.end = 0x%lx\n", blob_start, blob_end);
		debug ("images.os.load = 0x%lx, load_end = 0x%lx\n", load, *load_end);

		return BOOTM_ERR_OVERLAP;
	}

	return 0;
}
Example #18
0
/**
 * fit_image_print - prints out the FIT component image details
 * @fit: pointer to the FIT format image header
 * @image_noffset: offset of the component image node
 * @p: pointer to prefix string
 *
 * fit_image_print() lists all mandatory properies for the processed component
 * image. If present, hash nodes are printed out as well. Load
 * address for images of type firmware is also printed out. Since the load
 * address is not mandatory for firmware images, it will be output as
 * "unavailable" when not present.
 *
 * returns:
 *     no returned results
 */
void fit_image_print(const void *fit, int image_noffset, const char *p)
{
	char *desc;
	uint8_t type, arch, os, comp;
	size_t size;
	ulong load, entry;
	const void *data;
	int noffset;
	int ndepth;
	int ret;

	/* Mandatory properties */
	ret = fit_get_desc(fit, image_noffset, &desc);
	printf("%s  Description:  ", p);
	if (ret)
		printf("unavailable\n");
	else
		printf("%s\n", desc);

	fit_image_get_type(fit, image_noffset, &type);
	printf("%s  Type:         %s\n", p, genimg_get_type_name(type));

	fit_image_get_comp(fit, image_noffset, &comp);
	printf("%s  Compression:  %s\n", p, genimg_get_comp_name(comp));

	ret = fit_image_get_data(fit, image_noffset, &data, &size);

#ifndef USE_HOSTCC
	printf("%s  Data Start:   ", p);
	if (ret) {
		printf("unavailable\n");
	} else {
		void *vdata = (void *)data;

		printf("0x%08lx\n", (ulong)map_to_sysmem(vdata));
	}
#endif

	printf("%s  Data Size:    ", p);
	if (ret)
		printf("unavailable\n");
	else
		genimg_print_size(size);

	/* Remaining, type dependent properties */
	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
	    (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
	    (type == IH_TYPE_FLATDT)) {
		fit_image_get_arch(fit, image_noffset, &arch);
		printf("%s  Architecture: %s\n", p, genimg_get_arch_name(arch));
	}

	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK)) {
		fit_image_get_os(fit, image_noffset, &os);
		printf("%s  OS:           %s\n", p, genimg_get_os_name(os));
	}

	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
	    (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK)) {
		ret = fit_image_get_load(fit, image_noffset, &load);
		printf("%s  Load Address: ", p);
		if (ret)
			printf("unavailable\n");
		else
			printf("0x%08lx\n", load);
	}

	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
	    (type == IH_TYPE_RAMDISK)) {
		fit_image_get_entry(fit, image_noffset, &entry);
		printf("%s  Entry Point:  ", p);
		if (ret)
			printf("unavailable\n");
		else
			printf("0x%08lx\n", entry);
	}

	/* Process all hash subnodes of the component image node */
	for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth);
	     (noffset >= 0) && (ndepth > 0);
	     noffset = fdt_next_node(fit, noffset, &ndepth)) {
		if (ndepth == 1) {
			/* Direct child node of the component image node */
			fit_image_print_verification_data(fit, noffset, p);
		}
	}
}
Example #19
0
static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
{
	uint8_t comp = os.comp;
	ulong load = os.load;
	ulong blob_start = os.start;
	ulong blob_end = os.end;
	ulong image_start = os.image_start;
	ulong image_len = os.image_len;
	__maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN;
	int no_overlap = 0;
	void *load_buf, *image_buf;

	const char *type_name = genimg_get_type_name(os.type);

	load_buf = map_sysmem(load, image_len);
	image_buf = map_sysmem(image_start, image_len);
	switch (comp) {
	case IH_COMP_NONE:
		if (load == blob_start || load == image_start) {
			printf("   XIP %s ... ", type_name);
			no_overlap = 1;
		} else {
			printf("   Loading %s ... ", type_name);
			memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
		}
		*load_end = load + image_len;
		puts("OK\n");
		break;
#ifdef CONFIG_GZIP
	case IH_COMP_GZIP:
		printf("   Uncompressing %s ... ", type_name);
		if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) {
			puts("GUNZIP: uncompress, out-of-mem or overwrite "
				"error - must RESET board to recover\n");
			if (boot_progress)
				bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + image_len;
		break;
#endif /* CONFIG_GZIP */
	default:
		printf("Unimplemented compression type %d\n", comp);
		return BOOTM_ERR_UNIMPLEMENTED;
	}

	flush_cache(load, (*load_end - load) * sizeof(ulong));

	puts("OK\n");
	debug("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
	bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);

	if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) {
		debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
			blob_start, blob_end);
		debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
			*load_end);

		return BOOTM_ERR_OVERLAP;
	}

	return 0;
}