]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/bootm.c
Merge branch 'master' of git://git.denx.de/u-boot-ti
[karo-tx-uboot.git] / common / bootm.c
index 338f647e419b9500ca20950ff4d6ea3cf5fe0064..ff81a271a559232c07e3f7c1cbebc4bf327731c3 100644 (file)
@@ -5,10 +5,10 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#ifndef USE_HOSTCC
 #include <common.h>
-#include <bootm.h>
+#include <bootstage.h>
 #include <bzlib.h>
-#include <image.h>
 #include <fdt_support.h>
 #include <lmb.h>
 #include <malloc.h>
 #include <lzma/LzmaTypes.h>
 #include <lzma/LzmaDec.h>
 #include <lzma/LzmaTools.h>
-
 #if defined(CONFIG_CMD_USB)
 #include <usb.h>
 #endif
+#else
+#include "mkimage.h"
+#endif
 
-DECLARE_GLOBAL_DATA_PTR;
+#include <command.h>
+#include <bootm.h>
+#include <image.h>
 
 #ifndef CONFIG_SYS_BOOTM_LEN
 /* use 8MByte as default max gunzip size */
@@ -31,6 +35,10 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #define IH_INITRD_ARCH IH_ARCH_DEFAULT
 
+#ifndef USE_HOSTCC
+
+DECLARE_GLOBAL_DATA_PTR;
+
 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);
@@ -236,33 +244,31 @@ static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc,
 
        return 0;
 }
+#endif /* USE_HOSTCC */
 
-static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
-                        int boot_progress)
+/**
+ * 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)
 {
-       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(type);
+       __attribute__((unused)) uint unc_len = CONFIG_SYS_BOOTM_LEN;
 
-       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);
+       *load_end = load;
        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);
@@ -274,8 +280,6 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
                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;
                }
 
@@ -296,8 +300,6 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
                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;
                }
 
@@ -307,6 +309,8 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
 #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,
@@ -325,6 +329,7 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
 #ifdef CONFIG_LZO
        case IH_COMP_LZO: {
                size_t size = unc_len;
+               int ret;
 
                printf("   Uncompressing %s ... ", type_name);
 
@@ -332,8 +337,6 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
                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;
                }
 
@@ -346,12 +349,40 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
                return BOOTM_ERR_UNIMPLEMENTED;
        }
 
+       puts("OK\n");
+
+       return 0;
+}
+
+#ifndef USE_HOSTCC
+static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
+                        int boot_progress)
+{
+       image_info_t os = images->os;
+       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;
+       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 = decomp_image(os.comp, load, os.image_start, os.type, load_buf,
+                          image_buf, image_len, load_end);
+       if (err) {
+               bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
+               return err;
+       }
        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);
 
+       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);
@@ -694,32 +725,15 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
 #endif
        ulong           img_addr;
        const void *buf;
-#if defined(CONFIG_FIT)
        const char      *fit_uname_config = NULL;
        const char      *fit_uname_kernel = NULL;
+#if defined(CONFIG_FIT)
        int             os_noffset;
 #endif
 
-       /* find out kernel image address */
-       if (argc < 1) {
-               img_addr = load_addr;
-               debug("*  kernel: default image load address = 0x%08lx\n",
-                     load_addr);
-#if defined(CONFIG_FIT)
-       } else if (fit_parse_conf(argv[0], load_addr, &img_addr,
-                                 &fit_uname_config)) {
-               debug("*  kernel: config '%s' from image at 0x%08lx\n",
-                     fit_uname_config, img_addr);
-       } else if (fit_parse_subimage(argv[0], load_addr, &img_addr,
-                                    &fit_uname_kernel)) {
-               debug("*  kernel: subimage '%s' from image at 0x%08lx\n",
-                     fit_uname_kernel, img_addr);
-#endif
-       } else {
-               img_addr = simple_strtoul(argv[0], NULL, 16);
-               debug("*  kernel: cmdline image address = 0x%08lx\n",
-                     img_addr);
-       }
+       img_addr = genimg_get_kernel_addr_fit(argc < 1 ? NULL : argv[0],
+                                             &fit_uname_config,
+                                             &fit_uname_kernel);
 
        bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);
 
@@ -793,7 +807,7 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
 #ifdef CONFIG_ANDROID_BOOT_IMAGE
        case IMAGE_FORMAT_ANDROID:
                printf("## Booting Android Image at 0x%08lx ...\n", img_addr);
-               if (android_image_get_kernel((void *)img_addr, images->verify,
+               if (android_image_get_kernel(buf, images->verify,
                                             os_data, os_len))
                        return NULL;
                break;
@@ -809,3 +823,74 @@ 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)
+{
+       memmove(to, from, len);
+}
+
+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 = decomp_image(imape_comp, 0, data, image_type, load_buf,
+                          (void *)data, len, &load_end);
+       free(load_buf);
+       if (ret && ret != BOOTM_ERR_UNIMPLEMENTED)
+               return ret;
+
+       return 0;
+}
+
+int bootm_host_load_images(const void *fit, int cfg_noffset)
+{
+       static uint8_t image_types[] = {
+               IH_TYPE_KERNEL,
+               IH_TYPE_FLATDT,
+               IH_TYPE_RAMDISK,
+       };
+       int err = 0;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(image_types); i++) {
+               int ret;
+
+               ret = bootm_host_load_image(fit, image_types[i]);
+               if (!err && ret && ret != -ENOENT)
+                       err = ret;
+       }
+
+       /* Return the first error we found */
+       return err;
+}
+
+#endif /* ndef USE_HOSTCC */