X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fimage.c;h=d8d14e871c6473b68c11938c5357ab7edfefe157;hb=a595a0e910960ccd4611719d5fb5c279859efaee;hp=75b84d50091d1fa435c9cca1b18bce58fb620da8;hpb=7d994067424776b6184872b82fcaf4c0b95528f9;p=oweals%2Fu-boot.git diff --git a/common/image.c b/common/image.c index 75b84d5009..d8d14e871c 100644 --- a/common/image.c +++ b/common/image.c @@ -8,6 +8,10 @@ #ifndef USE_HOSTCC #include +#include +#include +#include +#include #include #ifdef CONFIG_SHOW_BOOT_PROGRESS @@ -16,8 +20,9 @@ #include -#include +#include #include +#include #include #if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT @@ -32,13 +37,19 @@ #include #include +#include +#include +#include +#include +#include + #ifdef CONFIG_CMD_BDI extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); #endif DECLARE_GLOBAL_DATA_PTR; -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, int verify); #endif @@ -54,6 +65,7 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, #endif /* !USE_HOSTCC*/ #include +#include #ifndef CONFIG_SYS_BARGSIZE #define CONFIG_SYS_BARGSIZE 512 @@ -125,6 +137,8 @@ static const table_entry_t uimage_os[] = { #if defined(CONFIG_BOOTM_OPENRTOS) || defined(USE_HOSTCC) { IH_OS_OPENRTOS, "openrtos", "OpenRTOS", }, #endif + { IH_OS_OPENSBI, "opensbi", "RISC-V OpenSBI", }, + { IH_OS_EFI, "efi", "EFI Firmware" }, { -1, "", "", }, }; @@ -168,6 +182,7 @@ static const table_entry_t uimage_type[] = { { IH_TYPE_PMMC, "pmmc", "TI Power Management Micro-Controller Firmware",}, { IH_TYPE_STM32IMAGE, "stm32image", "STMicroelectronics STM32 Image" }, { IH_TYPE_MTKIMAGE, "mtk_image", "MediaTek BootROM loadable Image" }, + { IH_TYPE_COPRO, "copro", "Coprocessor Image"}, { -1, "", "", }, }; @@ -187,6 +202,14 @@ struct table_info { const table_entry_t *table; }; +static const struct comp_magic_map image_comp[] = { + { IH_COMP_BZIP2, "bzip2", {0x42, 0x5a},}, + { IH_COMP_GZIP, "gzip", {0x1f, 0x8b},}, + { IH_COMP_LZMA, "lzma", {0x5d, 0x00},}, + { IH_COMP_LZO, "lzo", {0x89, 0x4c},}, + { IH_COMP_NONE, "none", {}, }, +}; + static const struct table_info table_info[IH_COUNT] = { { "architecture", IH_ARCH_COUNT, uimage_arch }, { "compression", IH_COMP_COUNT, uimage_comp }, @@ -369,15 +392,130 @@ void image_print_contents(const void *ptr) } } else if (image_check_type(hdr, IH_TYPE_FIRMWARE_IVT)) { printf("HAB Blocks: 0x%08x 0x0000 0x%08x\n", - image_get_load(hdr) - image_get_header_size(), - image_get_size(hdr) + image_get_header_size() - - 0x1FE0); + image_get_load(hdr) - image_get_header_size(), + (int)(image_get_size(hdr) + image_get_header_size() + + sizeof(flash_header_v2_t) - 0x2060)); + } +} + +/** + * 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\n", is_xip ? "XIP" : "Loading", name); + else + printf(" Uncompressing %s\n", name); +} + +int image_decomp_type(const unsigned char *buf, ulong len) +{ + const struct comp_magic_map *cmagic = image_comp; + + if (len < 2) + return -EINVAL; + + for (; cmagic->comp_id > 0; cmagic++) { + if (!memcmp(buf, cmagic->magic, 2)) + break; + } + + return cmagic->comp_id; +} + +int image_decomp(int comp, ulong load, ulong image_start, int type, + void *load_buf, void *image_buf, ulong image_len, + uint unc_len, ulong *load_end) +{ + int ret = 0; + + *load_end = load; + print_decomp_msg(comp, type, load == image_start); + + /* + * Load the image to the right place, decompressing if needed. After + * this, image_len will be set to the number of uncompressed bytes + * loaded, ret will be non-zero on error. + */ + switch (comp) { + case IH_COMP_NONE: + if (load == image_start) + break; + if (image_len <= unc_len) + memmove_wd(load_buf, image_buf, image_len, CHUNKSZ); + else + ret = -ENOSPC; + break; +#ifdef CONFIG_GZIP + case IH_COMP_GZIP: { + ret = gunzip(load_buf, unc_len, image_buf, &image_len); + break; + } +#endif /* CONFIG_GZIP */ +#ifdef CONFIG_BZIP2 + case IH_COMP_BZIP2: { + uint size = unc_len; + + /* + * If we've got less than 4 MB of malloc() space, + * use slower decompression algorithm which requires + * at most 2300 KB of memory. + */ + ret = BZ2_bzBuffToBuffDecompress(load_buf, &size, + image_buf, image_len, + CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); + image_len = size; + break; + } +#endif /* CONFIG_BZIP2 */ +#ifdef CONFIG_LZMA + case IH_COMP_LZMA: { + SizeT lzma_len = unc_len; + + ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len, + image_buf, image_len); + image_len = lzma_len; + break; + } +#endif /* CONFIG_LZMA */ +#ifdef CONFIG_LZO + case IH_COMP_LZO: { + size_t size = unc_len; + + ret = lzop_decompress(image_buf, image_len, load_buf, &size); + image_len = size; + break; + } +#endif /* CONFIG_LZO */ +#ifdef CONFIG_LZ4 + case IH_COMP_LZ4: { + size_t size = unc_len; + + ret = ulz4fn(image_buf, image_len, load_buf, &size); + image_len = size; + break; + } +#endif /* CONFIG_LZ4 */ + default: + printf("Unimplemented compression type %d\n", comp); + return -ENOSYS; } + + *load_end = load + image_len; + + return ret; } #ifndef USE_HOSTCC -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) /** * image_get_ramdisk - get and verify ramdisk image * @rd_addr: ramdisk image start address @@ -443,9 +581,9 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, /* Shared dual-format routines */ /*****************************************************************************/ #ifndef USE_HOSTCC -ulong load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */ -ulong save_addr; /* Default Save Address */ -ulong save_size; /* Default Save Size (in bytes) */ +ulong image_load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */ +ulong image_save_addr; /* Default Save Address */ +ulong image_save_size; /* Default Save Size (in bytes) */ static int on_loadaddr(const char *name, const char *value, enum env_op op, int flags) @@ -453,7 +591,7 @@ static int on_loadaddr(const char *name, const char *value, enum env_op op, switch (op) { case env_op_create: case env_op_overwrite: - load_addr = simple_strtoul(value, NULL, 16); + image_load_addr = simple_strtoul(value, NULL, 16); break; default: break; @@ -473,7 +611,7 @@ ulong env_get_bootm_low(void) #if defined(CONFIG_SYS_SDRAM_BASE) return CONFIG_SYS_SDRAM_BASE; -#elif defined(CONFIG_ARM) +#elif defined(CONFIG_ARM) || defined(CONFIG_MICROBLAZE) return gd->bd->bi_dram[0].start; #else return 0; @@ -490,7 +628,8 @@ phys_size_t env_get_bootm_size(void) return tmp; } -#if defined(CONFIG_ARM) && defined(CONFIG_NR_DRAM_BANKS) +#if (defined(CONFIG_ARM) || defined(CONFIG_MICROBLAZE)) && \ + defined(CONFIG_NR_DRAM_BANKS) start = gd->bd->bi_dram[0].start; size = gd->bd->bi_dram[0].size; #else @@ -551,6 +690,11 @@ void memmove_wd(void *to, void *from, size_t len, ulong chunksz) memmove(to, from, len); #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ } +#else /* USE_HOSTCC */ +void memmove_wd(void *to, void *from, size_t len, ulong chunksz) +{ + memmove(to, from, len); +} #endif /* !USE_HOSTCC */ void genimg_print_size(uint32_t size) @@ -816,15 +960,15 @@ ulong genimg_get_kernel_addr_fit(char * const img_addr, /* find out kernel image address */ if (!img_addr) { - kernel_addr = load_addr; + kernel_addr = image_load_addr; debug("* kernel: default image load address = 0x%08lx\n", - load_addr); + image_load_addr); #if CONFIG_IS_ENABLED(FIT) - } else if (fit_parse_conf(img_addr, load_addr, &kernel_addr, + } else if (fit_parse_conf(img_addr, image_load_addr, &kernel_addr, fit_uname_config)) { debug("* kernel: config '%s' from image at 0x%08lx\n", *fit_uname_config, kernel_addr); - } else if (fit_parse_subimage(img_addr, load_addr, &kernel_addr, + } else if (fit_parse_subimage(img_addr, image_load_addr, &kernel_addr, fit_uname_kernel)) { debug("* kernel: subimage '%s' from image at 0x%08lx\n", *fit_uname_kernel, kernel_addr); @@ -867,7 +1011,7 @@ ulong genimg_get_kernel_addr(char * const img_addr) */ int genimg_get_format(const void *img_addr) { -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) const image_header_t *hdr; hdr = (const image_header_t *)img_addr; @@ -933,7 +1077,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, { ulong rd_addr, rd_load; ulong rd_data, rd_len; -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) const image_header_t *rd_hdr; #endif void *buf; @@ -982,7 +1126,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, if (images->fit_uname_os) default_addr = (ulong)images->fit_hdr_os; else - default_addr = load_addr; + default_addr = image_load_addr; if (fit_parse_conf(select, default_addr, &rd_addr, &fit_uname_config)) { @@ -1025,7 +1169,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, */ buf = map_sysmem(rd_addr, 0); switch (genimg_get_format(buf)) { -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: printf("## Loading init Ramdisk from Legacy " "Image at %08lx ...\n", rd_addr);