static int bootm_load_os(bootm_headers_t *images, int boot_progress) { image_info_t os = images->os; ulong load = os.load; ulong load_end; ulong blob_start = os.start; ulong blob_end = os.end; ulong image_start = os.image_start; ulong image_len = os.image_len; ulong flush_start = ALIGN_DOWN(load, ARCH_DMA_MINALIGN); ulong flush_len; bool no_overlap; void *load_buf, *image_buf; int err; load_buf = map_sysmem(load, 0); image_buf = map_sysmem(os.image_start, image_len); err = bootm_decomp_image(os.comp, load, os.image_start, os.type, load_buf, image_buf, image_len, CONFIG_SYS_BOOTM_LEN, &load_end); if (err) { bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); return err; } flush_len = load_end - load; if (flush_start < load) flush_len += load - flush_start; flush_cache(flush_start, ALIGN(flush_len, ARCH_DMA_MINALIGN)); debug(" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, load_end); bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED); no_overlap = (os.comp == IH_COMP_NONE && load == image_start); 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; } } lmb_reserve(&images->lmb, images->os.load, (load_end - images->os.load)); return 0; }
/** * run_bootm_test() - Run tests on the bootm decopmression function * * @comp_type: Compression type to test * @compress: Our function to compress data * @return 0 if OK, non-zero on failure */ static int run_bootm_test(int comp_type, mutate_func compress) { ulong compress_size = 1024; void *compress_buff; int unc_len; int err = 0; const ulong image_start = 0; const ulong load_addr = 0x1000; ulong load_end; printf("Testing: %s\n", genimg_get_comp_name(comp_type)); compress_buff = map_sysmem(image_start, 0); unc_len = strlen(plain); compress((void *)plain, unc_len, compress_buff, compress_size, &compress_size); err = bootm_decomp_image(comp_type, load_addr, image_start, IH_TYPE_KERNEL, map_sysmem(load_addr, 0), compress_buff, compress_size, unc_len, &load_end); if (err) return err; err = bootm_decomp_image(comp_type, load_addr, image_start, IH_TYPE_KERNEL, map_sysmem(load_addr, 0), compress_buff, compress_size, unc_len - 1, &load_end); if (!err) return -EINVAL; /* We can't detect corruption when not decompressing */ if (comp_type == IH_COMP_NONE) return 0; memset(compress_buff + compress_size / 2, '\x49', compress_size / 2); err = bootm_decomp_image(comp_type, load_addr, image_start, IH_TYPE_KERNEL, map_sysmem(load_addr, 0), compress_buff, compress_size, 0x10000, &load_end); if (!err) return -EINVAL; return 0; }
static int bootm_host_load_image(const void *fit, int req_image_type) { const char *fit_uname_config = NULL; ulong data, len; bootm_headers_t images; int noffset; ulong load_end; uint8_t image_type; uint8_t imape_comp; void *load_buf; int ret; memset(&images, '\0', sizeof(images)); images.verify = 1; noffset = fit_image_load(&images, (ulong)fit, NULL, &fit_uname_config, IH_ARCH_DEFAULT, req_image_type, -1, FIT_LOAD_IGNORED, &data, &len); if (noffset < 0) return noffset; if (fit_image_get_type(fit, noffset, &image_type)) { puts("Can't get image type!\n"); return -EINVAL; } if (fit_image_get_comp(fit, noffset, &imape_comp)) { puts("Can't get image compression!\n"); return -EINVAL; } /* Allow the image to expand by a factor of 4, should be safe */ load_buf = malloc((1 << 20) + len * 4); ret = bootm_decomp_image(imape_comp, 0, data, image_type, load_buf, (void *)data, len, CONFIG_SYS_BOOTM_LEN, &load_end); free(load_buf); if (ret && ret != BOOTM_ERR_UNIMPLEMENTED) return ret; return 0; }