X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fbootm.c;h=3bbe490ab9ae5bdd778bfdc37a716bc5775acd55;hb=1eb69ae498567bb0b62ee554647204e8245cdacc;hp=9ed6428281b35c4c9e60d107e5188db1d982d706;hpb=45031f1a1e575bf2e5ceb3e6e9f5b8b09f4945a1;p=oweals%2Fu-boot.git diff --git a/common/bootm.c b/common/bootm.c index 9ed6428281..3bbe490ab9 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -1,24 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2000-2009 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ */ #ifndef USE_HOSTCC #include #include -#include +#include +#include #include #include #include #include #include #include -#include -#include -#include -#include #if defined(CONFIG_CMD_USB) #include #endif @@ -41,25 +37,27 @@ DECLARE_GLOBAL_DATA_PTR; +bootm_headers_t images; /* pointers to os/initrd/fdt images */ + static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], bootm_headers_t *images, ulong *os_data, ulong *os_len); +__weak void board_quiesce_devices(void) +{ +} + #ifdef CONFIG_LMB static void boot_start_lmb(bootm_headers_t *images) { ulong mem_start; phys_size_t mem_size; - lmb_init(&images->lmb); + mem_start = env_get_bootm_low(); + mem_size = env_get_bootm_size(); - mem_start = getenv_bootm_low(); - mem_size = getenv_bootm_size(); - - lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size); - - arch_lmb_reserve(&images->lmb); - board_lmb_reserve(&images->lmb); + lmb_init_and_reserve_range(&images->lmb, (phys_addr_t)mem_start, + mem_size, NULL); } #else #define lmb_reserve(lmb, base, size) @@ -70,7 +68,7 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { memset((void *)&images, 0, sizeof(images)); - images.verify = getenv_yesno("verify"); + images.verify = env_get_yesno("verify"); boot_start_lmb(&images); @@ -97,7 +95,7 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc, /* get image parameters */ switch (genimg_get_format(os_hdr)) { -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: images.os.type = image_get_type(os_hdr); images.os.comp = image_get_comp(os_hdr); @@ -153,7 +151,7 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc, #ifdef CONFIG_ANDROID_BOOT_IMAGE case IMAGE_FORMAT_ANDROID: images.os.type = IH_TYPE_KERNEL; - images.os.comp = IH_COMP_NONE; + images.os.comp = android_image_get_kcomp(os_hdr); images.os.os = IH_OS_LINUX; images.os.end = android_image_get_end(os_hdr); @@ -197,8 +195,23 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc, } if (images.os.type == IH_TYPE_KERNEL_NOLOAD) { - images.os.load = images.os.image_start; - images.ep += images.os.load; + if (CONFIG_IS_ENABLED(CMD_BOOTI) && + images.os.arch == IH_ARCH_ARM64) { + ulong image_addr; + ulong image_size; + + ret = booti_setup(images.os.image_start, &image_addr, + &image_size, true); + if (ret != 0) + return 1; + + images.os.type = IH_TYPE_KERNEL; + images.os.load = image_addr; + images.ep = image_addr; + } else { + images.os.load = images.os.image_start; + images.ep += images.os.image_start; + } } images.os.start = map_to_sysmem(os_hdr); @@ -242,11 +255,12 @@ int bootm_find_images(int flag, int argc, char * const argv[]) puts("Could not find a valid device tree\n"); return 1; } - set_working_fdt_addr((ulong)images.ft_addr); + if (CONFIG_IS_ENABLED(CMD_FDT)) + set_working_fdt_addr(map_to_sysmem(images.ft_addr)); #endif #if IMAGE_ENABLE_FIT -#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_XILINX) +#if defined(CONFIG_FPGA) /* find bitstreams */ ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT, NULL, NULL); @@ -282,23 +296,7 @@ static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc, } #endif /* USE_HOSTC */ -/** - * 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); -} - +#if !defined(USE_HOSTCC) || defined(CONFIG_FIT_SIGNATURE) /** * handle_decomp_error() - display a decompression error * @@ -308,16 +306,18 @@ static void print_decomp_msg(int comp_type, int type, bool is_xip) * * @comp_type: Compression type being used (IH_COMP_...) * @uncomp_size: Number of bytes uncompressed - * @unc_len: Amount of space available for decompression - * @ret: Error code to report - * @return BOOTM_ERR_RESET, indicating that the board must be reset + * @ret: errno error code received from compression library + * @return Appropriate BOOTM_ERR_ error code */ -static int handle_decomp_error(int comp_type, size_t uncomp_size, - size_t unc_len, int ret) +static int handle_decomp_error(int comp_type, size_t uncomp_size, int ret) { const char *name = genimg_get_comp_name(comp_type); - if (uncomp_size >= unc_len) + /* ENOSYS means unimplemented compression type, don't reset. */ + if (ret == -ENOSYS) + return BOOTM_ERR_UNIMPLEMENTED; + + if (uncomp_size >= CONFIG_SYS_BOOTM_LEN) printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n"); else printf("%s: uncompress error %d\n", name, ret); @@ -334,129 +334,46 @@ static int handle_decomp_error(int comp_type, size_t uncomp_size, return BOOTM_ERR_RESET; } - -int bootm_decomp_image(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 = 1; - 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 BOOTM_ERR_UNIMPLEMENTED; - } - - if (ret) - return handle_decomp_error(comp, image_len, unc_len, ret); - *load_end = load + image_len; - - puts("OK\n"); - - return 0; -} +#endif #ifndef USE_HOSTCC -static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end, - int boot_progress) +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); 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); + err = image_decomp(os.comp, load, os.image_start, os.type, + load_buf, image_buf, image_len, + CONFIG_SYS_BOOTM_LEN, &load_end); if (err) { + err = handle_decomp_error(os.comp, load_end - load, err); bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); return err; } - flush_cache(load, ALIGN(*load_end - load, ARCH_DMA_MINALIGN)); - debug(" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end); + flush_cache(flush_start, ALIGN(load_end, ARCH_DMA_MINALIGN) - flush_start); + + 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)) { + 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); + load_end); /* Check what type of image this is. */ if (images->legacy_hdr_valid) { @@ -471,6 +388,8 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end, } } + lmb_reserve(&images->lmb, images->os.load, (load_end - + images->os.load)); return 0; } @@ -522,7 +441,7 @@ static void fixup_silent_linux(void) { char *buf; const char *env_val; - char *cmdline = getenv("bootargs"); + char *cmdline = env_get("bootargs"); int want_silent; /* @@ -532,7 +451,7 @@ static void fixup_silent_linux(void) * yes - we always fixup * unset - we rely on the console silent flag */ - want_silent = getenv_yesno("silent_linux"); + want_silent = env_get_yesno("silent_linux"); if (want_silent == 0) return; else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT)) @@ -567,7 +486,7 @@ static void fixup_silent_linux(void) env_val = CONSOLE_ARG; } - setenv("bootargs", env_val); + env_set("bootargs", env_val); debug("after silent fix-up: %s\n", env_val); free(buf); } @@ -617,21 +536,14 @@ int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], if (!ret && (states & BOOTM_STATE_FINDOS)) ret = bootm_find_os(cmdtp, flag, argc, argv); - if (!ret && (states & BOOTM_STATE_FINDOTHER)) { + if (!ret && (states & BOOTM_STATE_FINDOTHER)) ret = bootm_find_other(cmdtp, flag, argc, argv); - argc = 0; /* consume the args */ - } /* Load the OS */ if (!ret && (states & BOOTM_STATE_LOADOS)) { - ulong load_end; - iflag = bootm_disable_interrupts(); - ret = bootm_load_os(images, &load_end, 0); - if (ret == 0) - lmb_reserve(&images->lmb, images->os.load, - (load_end - images->os.load)); - else if (ret && ret != BOOTM_ERR_OVERLAP) + ret = bootm_load_os(images, 0); + if (ret && ret != BOOTM_ERR_OVERLAP) goto err; else if (ret == BOOTM_ERR_OVERLAP) ret = 0; @@ -645,8 +557,8 @@ int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], ret = boot_ramdisk_high(&images->lmb, images->rd_start, rd_len, &images->initrd_start, &images->initrd_end); if (!ret) { - setenv_hex("initrd_start", images->initrd_start); - setenv_hex("initrd_end", images->initrd_end); + env_set_hex("initrd_start", images->initrd_start); + env_set_hex("initrd_end", images->initrd_end); } } #endif @@ -691,7 +603,7 @@ int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], #ifdef CONFIG_TRACE /* Pretend to run the OS, then run a user command */ if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) { - char *cmd_list = getenv("fakegocmd"); + char *cmd_list = env_get("fakegocmd"); ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO, images, boot_fn); @@ -724,7 +636,7 @@ err: return ret; } -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) /** * image_get_kernel - verify legacy format kernel image * @img_addr: in RAM address of the legacy format image to be verified @@ -793,7 +705,7 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], bootm_headers_t *images, ulong *os_data, ulong *os_len) { -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) image_header_t *hdr; #endif ulong img_addr; @@ -810,14 +722,11 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC); - /* copy from dataflash if needed */ - img_addr = genimg_get_image(img_addr); - /* check image type, for FIT images get FIT kernel node */ *os_data = *os_len = 0; buf = map_sysmem(img_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("## Booting kernel from Legacy Image at %08lx ...\n", img_addr); @@ -896,13 +805,19 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, return buf; } -#else /* USE_HOSTCC */ -void memmove_wd(void *to, void *from, size_t len, ulong chunksz) +/** + * switch_to_non_secure_mode() - switch to non-secure mode + * + * This routine is overridden by architectures requiring this feature. + */ +void __weak switch_to_non_secure_mode(void) { - memmove(to, from, len); } +#else /* USE_HOSTCC */ + +#if defined(CONFIG_FIT_SIGNATURE) static int bootm_host_load_image(const void *fit, int req_image_type) { const char *fit_uname_config = NULL; @@ -935,13 +850,16 @@ static int bootm_host_load_image(const void *fit, int req_image_type) /* 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); + ret = image_decomp(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; + if (ret) { + ret = handle_decomp_error(imape_comp, load_end - 0, ret); + if (ret != BOOTM_ERR_UNIMPLEMENTED) + return ret; + } return 0; } @@ -967,5 +885,6 @@ int bootm_host_load_images(const void *fit, int cfg_noffset) /* Return the first error we found */ return err; } +#endif #endif /* ndef USE_HOSTCC */