/* 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"); }
/** * 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); }
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); }
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; }
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 (¶ms)) 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(¶ms); 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, ¶ms); (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(¶ms, 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, ¶ms); } 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, ¶ms); 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); }
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; }
/** * 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; }
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); }
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 (¶ms)) 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(¶ms); 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, ¶ms); 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); }
/** * 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; }
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 (¶ms)) 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(¶ms); 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(¶ms, 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, ¶ms); } 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, ¶ms); 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); }
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; }
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; }
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 (¶ms)) 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(¶ms); 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, ¶ms); (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(¶ms, 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, ¶ms); } 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, ¶ms); 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); }
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; }
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; }
/** * 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); } } }
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; }