uboot/common/image.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2008 Semihalf
   3 *
   4 * (C) Copyright 2000-2006
   5 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   6 *
   7 * SPDX-License-Identifier:     GPL-2.0+
   8 */
   9
  10#ifndef USE_HOSTCC
  11#include <common.h>
  12#include <watchdog.h>
  13
  14#ifdef CONFIG_SHOW_BOOT_PROGRESS
  15#include <status_led.h>
  16#endif
  17
  18#ifdef CONFIG_HAS_DATAFLASH
  19#include <dataflash.h>
  20#endif
  21
  22#ifdef CONFIG_LOGBUFFER
  23#include <logbuff.h>
  24#endif
  25
  26#include <rtc.h>
  27
  28#include <environment.h>
  29#include <image.h>
  30#include <mapmem.h>
  31
  32#if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT
  33#include <libfdt.h>
  34#include <fdt_support.h>
  35#endif
  36
  37#include <u-boot/md5.h>
  38#include <u-boot/sha1.h>
  39#include <asm/errno.h>
  40#include <asm/io.h>
  41
  42#ifdef CONFIG_CMD_BDI
  43extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
  44#endif
  45
  46DECLARE_GLOBAL_DATA_PTR;
  47
  48#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
  49static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch,
  50                                                int verify);
  51#endif
  52#else
  53#include "mkimage.h"
  54#include <u-boot/md5.h>
  55#include <time.h>
  56#include <image.h>
  57
  58#ifndef __maybe_unused
  59# define __maybe_unused         /* unimplemented */
  60#endif
  61#endif /* !USE_HOSTCC*/
  62
  63#include <u-boot/crc.h>
  64
  65#ifndef CONFIG_SYS_BARGSIZE
  66#define CONFIG_SYS_BARGSIZE 512
  67#endif
  68
  69static const table_entry_t uimage_arch[] = {
  70        {       IH_ARCH_INVALID,        NULL,           "Invalid ARCH", },
  71        {       IH_ARCH_ALPHA,          "alpha",        "Alpha",        },
  72        {       IH_ARCH_ARM,            "arm",          "ARM",          },
  73        {       IH_ARCH_I386,           "x86",          "Intel x86",    },
  74        {       IH_ARCH_IA64,           "ia64",         "IA64",         },
  75        {       IH_ARCH_M68K,           "m68k",         "M68K",         },
  76        {       IH_ARCH_MICROBLAZE,     "microblaze",   "MicroBlaze",   },
  77        {       IH_ARCH_MIPS,           "mips",         "MIPS",         },
  78        {       IH_ARCH_MIPS64,         "mips64",       "MIPS 64 Bit",  },
  79        {       IH_ARCH_NIOS2,          "nios2",        "NIOS II",      },
  80        {       IH_ARCH_PPC,            "powerpc",      "PowerPC",      },
  81        {       IH_ARCH_PPC,            "ppc",          "PowerPC",      },
  82        {       IH_ARCH_S390,           "s390",         "IBM S390",     },
  83        {       IH_ARCH_SH,             "sh",           "SuperH",       },
  84        {       IH_ARCH_SPARC,          "sparc",        "SPARC",        },
  85        {       IH_ARCH_SPARC64,        "sparc64",      "SPARC 64 Bit", },
  86        {       IH_ARCH_BLACKFIN,       "blackfin",     "Blackfin",     },
  87        {       IH_ARCH_AVR32,          "avr32",        "AVR32",        },
  88        {       IH_ARCH_NDS32,          "nds32",        "NDS32",        },
  89        {       IH_ARCH_OPENRISC,       "or1k",         "OpenRISC 1000",},
  90        {       IH_ARCH_SANDBOX,        "sandbox",      "Sandbox",      },
  91        {       IH_ARCH_ARM64,          "arm64",        "AArch64",      },
  92        {       IH_ARCH_ARC,            "arc",          "ARC",          },
  93        {       IH_ARCH_X86_64,         "x86_64",       "AMD x86_64",   },
  94        {       -1,                     "",             "",             },
  95};
  96
  97static const table_entry_t uimage_os[] = {
  98        {       IH_OS_INVALID,  NULL,           "Invalid OS",           },
  99        {       IH_OS_LINUX,    "linux",        "Linux",                },
 100#if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC)
 101        {       IH_OS_LYNXOS,   "lynxos",       "LynxOS",               },
 102#endif
 103        {       IH_OS_NETBSD,   "netbsd",       "NetBSD",               },
 104        {       IH_OS_OSE,      "ose",          "Enea OSE",             },
 105        {       IH_OS_PLAN9,    "plan9",        "Plan 9",               },
 106        {       IH_OS_RTEMS,    "rtems",        "RTEMS",                },
 107        {       IH_OS_U_BOOT,   "u-boot",       "U-Boot",               },
 108        {       IH_OS_VXWORKS,  "vxworks",      "VxWorks",              },
 109#if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
 110        {       IH_OS_QNX,      "qnx",          "QNX",                  },
 111#endif
 112#if defined(CONFIG_INTEGRITY) || defined(USE_HOSTCC)
 113        {       IH_OS_INTEGRITY,"integrity",    "INTEGRITY",            },
 114#endif
 115#ifdef USE_HOSTCC
 116        {       IH_OS_4_4BSD,   "4_4bsd",       "4_4BSD",               },
 117        {       IH_OS_DELL,     "dell",         "Dell",                 },
 118        {       IH_OS_ESIX,     "esix",         "Esix",                 },
 119        {       IH_OS_FREEBSD,  "freebsd",      "FreeBSD",              },
 120        {       IH_OS_IRIX,     "irix",         "Irix",                 },
 121        {       IH_OS_NCR,      "ncr",          "NCR",                  },
 122        {       IH_OS_OPENBSD,  "openbsd",      "OpenBSD",              },
 123        {       IH_OS_PSOS,     "psos",         "pSOS",                 },
 124        {       IH_OS_SCO,      "sco",          "SCO",                  },
 125        {       IH_OS_SOLARIS,  "solaris",      "Solaris",              },
 126        {       IH_OS_SVR4,     "svr4",         "SVR4",                 },
 127#endif
 128#if defined(CONFIG_BOOTM_OPENRTOS) || defined(USE_HOSTCC)
 129        {       IH_OS_OPENRTOS, "openrtos",     "OpenRTOS",             },
 130#endif
 131
 132        {       -1,             "",             "",                     },
 133};
 134
 135static const table_entry_t uimage_type[] = {
 136        {       IH_TYPE_AISIMAGE,   "aisimage",   "Davinci AIS image",},
 137        {       IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image",   },
 138        {       IH_TYPE_FIRMWARE,   "firmware",   "Firmware",           },
 139        {       IH_TYPE_FLATDT,     "flat_dt",    "Flat Device Tree",   },
 140        {       IH_TYPE_GPIMAGE,    "gpimage",    "TI Keystone SPL Image",},
 141        {       IH_TYPE_KERNEL,     "kernel",     "Kernel Image",       },
 142        {       IH_TYPE_KERNEL_NOLOAD, "kernel_noload",  "Kernel Image (no loading done)", },
 143        {       IH_TYPE_KWBIMAGE,   "kwbimage",   "Kirkwood Boot Image",},
 144        {       IH_TYPE_IMXIMAGE,   "imximage",   "Freescale i.MX Boot Image",},
 145        {       IH_TYPE_INVALID,    NULL,         "Invalid Image",      },
 146        {       IH_TYPE_MULTI,      "multi",      "Multi-File Image",   },
 147        {       IH_TYPE_OMAPIMAGE,  "omapimage",  "TI OMAP SPL With GP CH",},
 148        {       IH_TYPE_PBLIMAGE,   "pblimage",   "Freescale PBL Boot Image",},
 149        {       IH_TYPE_RAMDISK,    "ramdisk",    "RAMDisk Image",      },
 150        {       IH_TYPE_SCRIPT,     "script",     "Script",             },
 151        {       IH_TYPE_SOCFPGAIMAGE, "socfpgaimage", "Altera SOCFPGA preloader",},
 152        {       IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
 153        {       IH_TYPE_UBLIMAGE,   "ublimage",   "Davinci UBL image",},
 154        {       IH_TYPE_MXSIMAGE,   "mxsimage",   "Freescale MXS Boot Image",},
 155        {       IH_TYPE_ATMELIMAGE, "atmelimage", "ATMEL ROM-Boot Image",},
 156        {       IH_TYPE_X86_SETUP,  "x86_setup",  "x86 setup.bin",    },
 157        {       IH_TYPE_LPC32XXIMAGE, "lpc32xximage",  "LPC32XX Boot Image", },
 158        {       IH_TYPE_RKIMAGE,    "rkimage",    "Rockchip Boot Image" },
 159        {       IH_TYPE_RKSD,       "rksd",       "Rockchip SD Boot Image" },
 160        {       IH_TYPE_RKSPI,      "rkspi",      "Rockchip SPI Boot Image" },
 161        {       IH_TYPE_ZYNQIMAGE,  "zynqimage",  "Xilinx Zynq Boot Image" },
 162        {       -1,                 "",           "",                   },
 163};
 164
 165static const table_entry_t uimage_comp[] = {
 166        {       IH_COMP_NONE,   "none",         "uncompressed",         },
 167        {       IH_COMP_BZIP2,  "bzip2",        "bzip2 compressed",     },
 168        {       IH_COMP_GZIP,   "gzip",         "gzip compressed",      },
 169        {       IH_COMP_LZMA,   "lzma",         "lzma compressed",      },
 170        {       IH_COMP_LZO,    "lzo",          "lzo compressed",       },
 171        {       IH_COMP_LZ4,    "lz4",          "lz4 compressed",       },
 172        {       -1,             "",             "",                     },
 173};
 174
 175/*****************************************************************************/
 176/* Legacy format routines */
 177/*****************************************************************************/
 178int image_check_hcrc(const image_header_t *hdr)
 179{
 180        ulong hcrc;
 181        ulong len = image_get_header_size();
 182        image_header_t header;
 183
 184        /* Copy header so we can blank CRC field for re-calculation */
 185        memmove(&header, (char *)hdr, image_get_header_size());
 186        image_set_hcrc(&header, 0);
 187
 188        hcrc = crc32(0, (unsigned char *)&header, len);
 189
 190        return (hcrc == image_get_hcrc(hdr));
 191}
 192
 193int image_check_dcrc(const image_header_t *hdr)
 194{
 195        ulong data = image_get_data(hdr);
 196        ulong len = image_get_data_size(hdr);
 197        ulong dcrc = crc32_wd(0, (unsigned char *)data, len, CHUNKSZ_CRC32);
 198
 199        return (dcrc == image_get_dcrc(hdr));
 200}
 201
 202/**
 203 * image_multi_count - get component (sub-image) count
 204 * @hdr: pointer to the header of the multi component image
 205 *
 206 * image_multi_count() returns number of components in a multi
 207 * component image.
 208 *
 209 * Note: no checking of the image type is done, caller must pass
 210 * a valid multi component image.
 211 *
 212 * returns:
 213 *     number of components
 214 */
 215ulong image_multi_count(const image_header_t *hdr)
 216{
 217        ulong i, count = 0;
 218        uint32_t *size;
 219
 220        /* get start of the image payload, which in case of multi
 221         * component images that points to a table of component sizes */
 222        size = (uint32_t *)image_get_data(hdr);
 223
 224        /* count non empty slots */
 225        for (i = 0; size[i]; ++i)
 226                count++;
 227
 228        return count;
 229}
 230
 231/**
 232 * image_multi_getimg - get component data address and size
 233 * @hdr: pointer to the header of the multi component image
 234 * @idx: index of the requested component
 235 * @data: pointer to a ulong variable, will hold component data address
 236 * @len: pointer to a ulong variable, will hold component size
 237 *
 238 * image_multi_getimg() returns size and data address for the requested
 239 * component in a multi component image.
 240 *
 241 * Note: no checking of the image type is done, caller must pass
 242 * a valid multi component image.
 243 *
 244 * returns:
 245 *     data address and size of the component, if idx is valid
 246 *     0 in data and len, if idx is out of range
 247 */
 248void image_multi_getimg(const image_header_t *hdr, ulong idx,
 249                        ulong *data, ulong *len)
 250{
 251        int i;
 252        uint32_t *size;
 253        ulong offset, count, img_data;
 254
 255        /* get number of component */
 256        count = image_multi_count(hdr);
 257
 258        /* get start of the image payload, which in case of multi
 259         * component images that points to a table of component sizes */
 260        size = (uint32_t *)image_get_data(hdr);
 261
 262        /* get address of the proper component data start, which means
 263         * skipping sizes table (add 1 for last, null entry) */
 264        img_data = image_get_data(hdr) + (count + 1) * sizeof(uint32_t);
 265
 266        if (idx < count) {
 267                *len = uimage_to_cpu(size[idx]);
 268                offset = 0;
 269
 270                /* go over all indices preceding requested component idx */
 271                for (i = 0; i < idx; i++) {
 272                        /* add up i-th component size, rounding up to 4 bytes */
 273                        offset += (uimage_to_cpu(size[i]) + 3) & ~3 ;
 274                }
 275
 276                /* calculate idx-th component data address */
 277                *data = img_data + offset;
 278        } else {
 279                *len = 0;
 280                *data = 0;
 281        }
 282}
 283
 284static void image_print_type(const image_header_t *hdr)
 285{
 286        const char __maybe_unused *os, *arch, *type, *comp;
 287
 288        os = genimg_get_os_name(image_get_os(hdr));
 289        arch = genimg_get_arch_name(image_get_arch(hdr));
 290        type = genimg_get_type_name(image_get_type(hdr));
 291        comp = genimg_get_comp_name(image_get_comp(hdr));
 292
 293        printf("%s %s %s (%s)\n", arch, os, type, comp);
 294}
 295
 296/**
 297 * image_print_contents - prints out the contents of the legacy format image
 298 * @ptr: pointer to the legacy format image header
 299 * @p: pointer to prefix string
 300 *
 301 * image_print_contents() formats a multi line legacy image contents description.
 302 * The routine prints out all header fields followed by the size/offset data
 303 * for MULTI/SCRIPT images.
 304 *
 305 * returns:
 306 *     no returned results
 307 */
 308void image_print_contents(const void *ptr)
 309{
 310        const image_header_t *hdr = (const image_header_t *)ptr;
 311        const char __maybe_unused *p;
 312
 313        p = IMAGE_INDENT_STRING;
 314        printf("%sImage Name:   %.*s\n", p, IH_NMLEN, image_get_name(hdr));
 315        if (IMAGE_ENABLE_TIMESTAMP) {
 316                printf("%sCreated:      ", p);
 317                genimg_print_time((time_t)image_get_time(hdr));
 318        }
 319        printf("%sImage Type:   ", p);
 320        image_print_type(hdr);
 321        printf("%sData Size:    ", p);
 322        genimg_print_size(image_get_data_size(hdr));
 323        printf("%sLoad Address: %08x\n", p, image_get_load(hdr));
 324        printf("%sEntry Point:  %08x\n", p, image_get_ep(hdr));
 325
 326        if (image_check_type(hdr, IH_TYPE_MULTI) ||
 327                        image_check_type(hdr, IH_TYPE_SCRIPT)) {
 328                int i;
 329                ulong data, len;
 330                ulong count = image_multi_count(hdr);
 331
 332                printf("%sContents:\n", p);
 333                for (i = 0; i < count; i++) {
 334                        image_multi_getimg(hdr, i, &data, &len);
 335
 336                        printf("%s   Image %d: ", p, i);
 337                        genimg_print_size(len);
 338
 339                        if (image_check_type(hdr, IH_TYPE_SCRIPT) && i > 0) {
 340                                /*
 341                                 * the user may need to know offsets
 342                                 * if planning to do something with
 343                                 * multiple files
 344                                 */
 345                                printf("%s    Offset = 0x%08lx\n", p, data);
 346                        }
 347                }
 348        }
 349}
 350
 351
 352#ifndef USE_HOSTCC
 353#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
 354/**
 355 * image_get_ramdisk - get and verify ramdisk image
 356 * @rd_addr: ramdisk image start address
 357 * @arch: expected ramdisk architecture
 358 * @verify: checksum verification flag
 359 *
 360 * image_get_ramdisk() returns a pointer to the verified ramdisk image
 361 * header. Routine receives image start address and expected architecture
 362 * flag. Verification done covers data and header integrity and os/type/arch
 363 * fields checking.
 364 *
 365 * If dataflash support is enabled routine checks for dataflash addresses
 366 * and handles required dataflash reads.
 367 *
 368 * returns:
 369 *     pointer to a ramdisk image header, if image was found and valid
 370 *     otherwise, return NULL
 371 */
 372static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch,
 373                                                int verify)
 374{
 375        const image_header_t *rd_hdr = (const image_header_t *)rd_addr;
 376
 377        if (!image_check_magic(rd_hdr)) {
 378                puts("Bad Magic Number\n");
 379                bootstage_error(BOOTSTAGE_ID_RD_MAGIC);
 380                return NULL;
 381        }
 382
 383        if (!image_check_hcrc(rd_hdr)) {
 384                puts("Bad Header Checksum\n");
 385                bootstage_error(BOOTSTAGE_ID_RD_HDR_CHECKSUM);
 386                return NULL;
 387        }
 388
 389        bootstage_mark(BOOTSTAGE_ID_RD_MAGIC);
 390        image_print_contents(rd_hdr);
 391
 392        if (verify) {
 393                puts("   Verifying Checksum ... ");
 394                if (!image_check_dcrc(rd_hdr)) {
 395                        puts("Bad Data CRC\n");
 396                        bootstage_error(BOOTSTAGE_ID_RD_CHECKSUM);
 397                        return NULL;
 398                }
 399                puts("OK\n");
 400        }
 401
 402        bootstage_mark(BOOTSTAGE_ID_RD_HDR_CHECKSUM);
 403
 404        if (!image_check_os(rd_hdr, IH_OS_LINUX) ||
 405            !image_check_arch(rd_hdr, arch) ||
 406            !image_check_type(rd_hdr, IH_TYPE_RAMDISK)) {
 407                printf("No Linux %s Ramdisk Image\n",
 408                                genimg_get_arch_name(arch));
 409                bootstage_error(BOOTSTAGE_ID_RAMDISK);
 410                return NULL;
 411        }
 412
 413        return rd_hdr;
 414}
 415#endif
 416#endif /* !USE_HOSTCC */
 417
 418/*****************************************************************************/
 419/* Shared dual-format routines */
 420/*****************************************************************************/
 421#ifndef USE_HOSTCC
 422ulong load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */
 423ulong save_addr;                        /* Default Save Address */
 424ulong save_size;                        /* Default Save Size (in bytes) */
 425
 426static int on_loadaddr(const char *name, const char *value, enum env_op op,
 427        int flags)
 428{
 429        switch (op) {
 430        case env_op_create:
 431        case env_op_overwrite:
 432                load_addr = simple_strtoul(value, NULL, 16);
 433                break;
 434        default:
 435                break;
 436        }
 437
 438        return 0;
 439}
 440U_BOOT_ENV_CALLBACK(loadaddr, on_loadaddr);
 441
 442ulong getenv_bootm_low(void)
 443{
 444        char *s = getenv("bootm_low");
 445        if (s) {
 446                ulong tmp = simple_strtoul(s, NULL, 16);
 447                return tmp;
 448        }
 449
 450#if defined(CONFIG_SYS_SDRAM_BASE)
 451        return CONFIG_SYS_SDRAM_BASE;
 452#elif defined(CONFIG_ARM)
 453        return gd->bd->bi_dram[0].start;
 454#else
 455        return 0;
 456#endif
 457}
 458
 459phys_size_t getenv_bootm_size(void)
 460{
 461        phys_size_t tmp, size;
 462        phys_addr_t start;
 463        char *s = getenv("bootm_size");
 464        if (s) {
 465                tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
 466                return tmp;
 467        }
 468
 469#if defined(CONFIG_ARM) && defined(CONFIG_NR_DRAM_BANKS)
 470        start = gd->bd->bi_dram[0].start;
 471        size = gd->bd->bi_dram[0].size;
 472#else
 473        start = gd->bd->bi_memstart;
 474        size = gd->bd->bi_memsize;
 475#endif
 476
 477        s = getenv("bootm_low");
 478        if (s)
 479                tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
 480        else
 481                tmp = start;
 482
 483        return size - (tmp - start);
 484}
 485
 486phys_size_t getenv_bootm_mapsize(void)
 487{
 488        phys_size_t tmp;
 489        char *s = getenv("bootm_mapsize");
 490        if (s) {
 491                tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
 492                return tmp;
 493        }
 494
 495#if defined(CONFIG_SYS_BOOTMAPSZ)
 496        return CONFIG_SYS_BOOTMAPSZ;
 497#else
 498        return getenv_bootm_size();
 499#endif
 500}
 501
 502void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
 503{
 504        if (to == from)
 505                return;
 506
 507#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
 508        if (to > from) {
 509                from += len;
 510                to += len;
 511        }
 512        while (len > 0) {
 513                size_t tail = (len > chunksz) ? chunksz : len;
 514                WATCHDOG_RESET();
 515                if (to > from) {
 516                        to -= tail;
 517                        from -= tail;
 518                }
 519                memmove(to, from, tail);
 520                if (to < from) {
 521                        to += tail;
 522                        from += tail;
 523                }
 524                len -= tail;
 525        }
 526#else   /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
 527        memmove(to, from, len);
 528#endif  /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
 529}
 530#endif /* !USE_HOSTCC */
 531
 532void genimg_print_size(uint32_t size)
 533{
 534#ifndef USE_HOSTCC
 535        printf("%d Bytes = ", size);
 536        print_size(size, "\n");
 537#else
 538        printf("%d Bytes = %.2f kB = %.2f MB\n",
 539                        size, (double)size / 1.024e3,
 540                        (double)size / 1.048576e6);
 541#endif
 542}
 543
 544#if IMAGE_ENABLE_TIMESTAMP
 545void genimg_print_time(time_t timestamp)
 546{
 547#ifndef USE_HOSTCC
 548        struct rtc_time tm;
 549
 550        rtc_to_tm(timestamp, &tm);
 551        printf("%4d-%02d-%02d  %2d:%02d:%02d UTC\n",
 552                        tm.tm_year, tm.tm_mon, tm.tm_mday,
 553                        tm.tm_hour, tm.tm_min, tm.tm_sec);
 554#else
 555        printf("%s", ctime(&timestamp));
 556#endif
 557}
 558#endif
 559
 560const table_entry_t *get_table_entry(const table_entry_t *table, int id)
 561{
 562        for (; table->id >= 0; ++table) {
 563                if (table->id == id)
 564                        return table;
 565        }
 566        return NULL;
 567}
 568
 569/**
 570 * get_table_entry_name - translate entry id to long name
 571 * @table: pointer to a translation table for entries of a specific type
 572 * @msg: message to be returned when translation fails
 573 * @id: entry id to be translated
 574 *
 575 * get_table_entry_name() will go over translation table trying to find
 576 * entry that matches given id. If matching entry is found, its long
 577 * name is returned to the caller.
 578 *
 579 * returns:
 580 *     long entry name if translation succeeds
 581 *     msg otherwise
 582 */
 583char *get_table_entry_name(const table_entry_t *table, char *msg, int id)
 584{
 585        table = get_table_entry(table, id);
 586        if (!table)
 587                return msg;
 588#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
 589        return table->lname;
 590#else
 591        return table->lname + gd->reloc_off;
 592#endif
 593}
 594
 595const char *genimg_get_os_name(uint8_t os)
 596{
 597        return (get_table_entry_name(uimage_os, "Unknown OS", os));
 598}
 599
 600const char *genimg_get_arch_name(uint8_t arch)
 601{
 602        return (get_table_entry_name(uimage_arch, "Unknown Architecture",
 603                                        arch));
 604}
 605
 606const char *genimg_get_type_name(uint8_t type)
 607{
 608        return (get_table_entry_name(uimage_type, "Unknown Image", type));
 609}
 610
 611static const char *genimg_get_short_name(const table_entry_t *table, int val)
 612{
 613        table = get_table_entry(table, val);
 614        if (!table)
 615                return "unknown";
 616#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
 617        return table->sname;
 618#else
 619        return table->sname + gd->reloc_off;
 620#endif
 621}
 622
 623const char *genimg_get_type_short_name(uint8_t type)
 624{
 625        return genimg_get_short_name(uimage_type, type);
 626}
 627
 628const char *genimg_get_comp_name(uint8_t comp)
 629{
 630        return (get_table_entry_name(uimage_comp, "Unknown Compression",
 631                                        comp));
 632}
 633
 634const char *genimg_get_comp_short_name(uint8_t comp)
 635{
 636        return genimg_get_short_name(uimage_comp, comp);
 637}
 638
 639const char *genimg_get_os_short_name(uint8_t os)
 640{
 641        return genimg_get_short_name(uimage_os, os);
 642}
 643
 644const char *genimg_get_arch_short_name(uint8_t arch)
 645{
 646        return genimg_get_short_name(uimage_arch, arch);
 647}
 648
 649/**
 650 * get_table_entry_id - translate short entry name to id
 651 * @table: pointer to a translation table for entries of a specific type
 652 * @table_name: to be used in case of error
 653 * @name: entry short name to be translated
 654 *
 655 * get_table_entry_id() will go over translation table trying to find
 656 * entry that matches given short name. If matching entry is found,
 657 * its id returned to the caller.
 658 *
 659 * returns:
 660 *     entry id if translation succeeds
 661 *     -1 otherwise
 662 */
 663int get_table_entry_id(const table_entry_t *table,
 664                const char *table_name, const char *name)
 665{
 666        const table_entry_t *t;
 667
 668        for (t = table; t->id >= 0; ++t) {
 669#ifdef CONFIG_NEEDS_MANUAL_RELOC
 670                if (t->sname && strcasecmp(t->sname + gd->reloc_off, name) == 0)
 671#else
 672                if (t->sname && strcasecmp(t->sname, name) == 0)
 673#endif
 674                        return (t->id);
 675        }
 676        debug("Invalid %s Type: %s\n", table_name, name);
 677
 678        return -1;
 679}
 680
 681int genimg_get_os_id(const char *name)
 682{
 683        return (get_table_entry_id(uimage_os, "OS", name));
 684}
 685
 686int genimg_get_arch_id(const char *name)
 687{
 688        return (get_table_entry_id(uimage_arch, "CPU", name));
 689}
 690
 691int genimg_get_type_id(const char *name)
 692{
 693        return (get_table_entry_id(uimage_type, "Image", name));
 694}
 695
 696int genimg_get_comp_id(const char *name)
 697{
 698        return (get_table_entry_id(uimage_comp, "Compression", name));
 699}
 700
 701#ifndef USE_HOSTCC
 702/**
 703 * genimg_get_kernel_addr_fit - get the real kernel address and return 2
 704 *                              FIT strings
 705 * @img_addr: a string might contain real image address
 706 * @fit_uname_config: double pointer to a char, will hold pointer to a
 707 *                    configuration unit name
 708 * @fit_uname_kernel: double pointer to a char, will hold pointer to a subimage
 709 *                    name
 710 *
 711 * genimg_get_kernel_addr_fit get the real kernel start address from a string
 712 * which is normally the first argv of bootm/bootz
 713 *
 714 * returns:
 715 *     kernel start address
 716 */
 717ulong genimg_get_kernel_addr_fit(char * const img_addr,
 718                             const char **fit_uname_config,
 719                             const char **fit_uname_kernel)
 720{
 721        ulong kernel_addr;
 722
 723        /* find out kernel image address */
 724        if (!img_addr) {
 725                kernel_addr = load_addr;
 726                debug("*  kernel: default image load address = 0x%08lx\n",
 727                      load_addr);
 728#if CONFIG_IS_ENABLED(FIT)
 729        } else if (fit_parse_conf(img_addr, load_addr, &kernel_addr,
 730                                  fit_uname_config)) {
 731                debug("*  kernel: config '%s' from image at 0x%08lx\n",
 732                      *fit_uname_config, kernel_addr);
 733        } else if (fit_parse_subimage(img_addr, load_addr, &kernel_addr,
 734                                     fit_uname_kernel)) {
 735                debug("*  kernel: subimage '%s' from image at 0x%08lx\n",
 736                      *fit_uname_kernel, kernel_addr);
 737#endif
 738        } else {
 739                kernel_addr = simple_strtoul(img_addr, NULL, 16);
 740                debug("*  kernel: cmdline image address = 0x%08lx\n",
 741                      kernel_addr);
 742        }
 743
 744        return kernel_addr;
 745}
 746
 747/**
 748 * genimg_get_kernel_addr() is the simple version of
 749 * genimg_get_kernel_addr_fit(). It ignores those return FIT strings
 750 */
 751ulong genimg_get_kernel_addr(char * const img_addr)
 752{
 753        const char *fit_uname_config = NULL;
 754        const char *fit_uname_kernel = NULL;
 755
 756        return genimg_get_kernel_addr_fit(img_addr, &fit_uname_config,
 757                                          &fit_uname_kernel);
 758}
 759
 760/**
 761 * genimg_get_format - get image format type
 762 * @img_addr: image start address
 763 *
 764 * genimg_get_format() checks whether provided address points to a valid
 765 * legacy or FIT image.
 766 *
 767 * New uImage format and FDT blob are based on a libfdt. FDT blob
 768 * may be passed directly or embedded in a FIT image. In both situations
 769 * genimg_get_format() must be able to dectect libfdt header.
 770 *
 771 * returns:
 772 *     image format type or IMAGE_FORMAT_INVALID if no image is present
 773 */
 774int genimg_get_format(const void *img_addr)
 775{
 776#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
 777        const image_header_t *hdr;
 778
 779        hdr = (const image_header_t *)img_addr;
 780        if (image_check_magic(hdr))
 781                return IMAGE_FORMAT_LEGACY;
 782#endif
 783#if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT
 784        if (fdt_check_header(img_addr) == 0)
 785                return IMAGE_FORMAT_FIT;
 786#endif
 787#ifdef CONFIG_ANDROID_BOOT_IMAGE
 788        if (android_image_check_header(img_addr) == 0)
 789                return IMAGE_FORMAT_ANDROID;
 790#endif
 791
 792        return IMAGE_FORMAT_INVALID;
 793}
 794
 795/**
 796 * genimg_get_image - get image from special storage (if necessary)
 797 * @img_addr: image start address
 798 *
 799 * genimg_get_image() checks if provided image start address is located
 800 * in a dataflash storage. If so, image is moved to a system RAM memory.
 801 *
 802 * returns:
 803 *     image start address after possible relocation from special storage
 804 */
 805ulong genimg_get_image(ulong img_addr)
 806{
 807        ulong ram_addr = img_addr;
 808
 809#ifdef CONFIG_HAS_DATAFLASH
 810        ulong h_size, d_size;
 811
 812        if (addr_dataflash(img_addr)) {
 813                void *buf;
 814
 815                /* ger RAM address */
 816                ram_addr = CONFIG_SYS_LOAD_ADDR;
 817
 818                /* get header size */
 819                h_size = image_get_header_size();
 820#if IMAGE_ENABLE_FIT
 821                if (sizeof(struct fdt_header) > h_size)
 822                        h_size = sizeof(struct fdt_header);
 823#endif
 824
 825                /* read in header */
 826                debug("   Reading image header from dataflash address "
 827                        "%08lx to RAM address %08lx\n", img_addr, ram_addr);
 828
 829                buf = map_sysmem(ram_addr, 0);
 830                read_dataflash(img_addr, h_size, buf);
 831
 832                /* get data size */
 833                switch (genimg_get_format(buf)) {
 834#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
 835                case IMAGE_FORMAT_LEGACY:
 836                        d_size = image_get_data_size(buf);
 837                        debug("   Legacy format image found at 0x%08lx, "
 838                                        "size 0x%08lx\n",
 839                                        ram_addr, d_size);
 840                        break;
 841#endif
 842#if IMAGE_ENABLE_FIT
 843                case IMAGE_FORMAT_FIT:
 844                        d_size = fit_get_size(buf) - h_size;
 845                        debug("   FIT/FDT format image found at 0x%08lx, "
 846                                        "size 0x%08lx\n",
 847                                        ram_addr, d_size);
 848                        break;
 849#endif
 850                default:
 851                        printf("   No valid image found at 0x%08lx\n",
 852                                img_addr);
 853                        return ram_addr;
 854                }
 855
 856                /* read in image data */
 857                debug("   Reading image remaining data from dataflash address "
 858                        "%08lx to RAM address %08lx\n", img_addr + h_size,
 859                        ram_addr + h_size);
 860
 861                read_dataflash(img_addr + h_size, d_size,
 862                                (char *)(buf + h_size));
 863
 864        }
 865#endif /* CONFIG_HAS_DATAFLASH */
 866
 867        return ram_addr;
 868}
 869
 870/**
 871 * fit_has_config - check if there is a valid FIT configuration
 872 * @images: pointer to the bootm command headers structure
 873 *
 874 * fit_has_config() checks if there is a FIT configuration in use
 875 * (if FTI support is present).
 876 *
 877 * returns:
 878 *     0, no FIT support or no configuration found
 879 *     1, configuration found
 880 */
 881int genimg_has_config(bootm_headers_t *images)
 882{
 883#if IMAGE_ENABLE_FIT
 884        if (images->fit_uname_cfg)
 885                return 1;
 886#endif
 887        return 0;
 888}
 889
 890/**
 891 * boot_get_ramdisk - main ramdisk handling routine
 892 * @argc: command argument count
 893 * @argv: command argument list
 894 * @images: pointer to the bootm images structure
 895 * @arch: expected ramdisk architecture
 896 * @rd_start: pointer to a ulong variable, will hold ramdisk start address
 897 * @rd_end: pointer to a ulong variable, will hold ramdisk end
 898 *
 899 * boot_get_ramdisk() is responsible for finding a valid ramdisk image.
 900 * Curently supported are the following ramdisk sources:
 901 *      - multicomponent kernel/ramdisk image,
 902 *      - commandline provided address of decicated ramdisk image.
 903 *
 904 * returns:
 905 *     0, if ramdisk image was found and valid, or skiped
 906 *     rd_start and rd_end are set to ramdisk start/end addresses if
 907 *     ramdisk image is found and valid
 908 *
 909 *     1, if ramdisk image is found but corrupted, or invalid
 910 *     rd_start and rd_end are set to 0 if no ramdisk exists
 911 */
 912int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
 913                uint8_t arch, ulong *rd_start, ulong *rd_end)
 914{
 915        ulong rd_addr, rd_load;
 916        ulong rd_data, rd_len;
 917#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
 918        const image_header_t *rd_hdr;
 919#endif
 920        void *buf;
 921#ifdef CONFIG_SUPPORT_RAW_INITRD
 922        char *end;
 923#endif
 924#if IMAGE_ENABLE_FIT
 925        const char      *fit_uname_config = images->fit_uname_cfg;
 926        const char      *fit_uname_ramdisk = NULL;
 927        ulong           default_addr;
 928        int             rd_noffset;
 929#endif
 930        const char *select = NULL;
 931
 932        *rd_start = 0;
 933        *rd_end = 0;
 934
 935#ifdef CONFIG_ANDROID_BOOT_IMAGE
 936        /*
 937         * Look for an Android boot image.
 938         */
 939        buf = map_sysmem(images->os.start, 0);
 940        if (buf && genimg_get_format(buf) == IMAGE_FORMAT_ANDROID)
 941                select = argv[0];
 942#endif
 943
 944        if (argc >= 2)
 945                select = argv[1];
 946
 947        /*
 948         * Look for a '-' which indicates to ignore the
 949         * ramdisk argument
 950         */
 951        if (select && strcmp(select, "-") ==  0) {
 952                debug("## Skipping init Ramdisk\n");
 953                rd_len = rd_data = 0;
 954        } else if (select || genimg_has_config(images)) {
 955#if IMAGE_ENABLE_FIT
 956                if (select) {
 957                        /*
 958                         * If the init ramdisk comes from the FIT image and
 959                         * the FIT image address is omitted in the command
 960                         * line argument, try to use os FIT image address or
 961                         * default load address.
 962                         */
 963                        if (images->fit_uname_os)
 964                                default_addr = (ulong)images->fit_hdr_os;
 965                        else
 966                                default_addr = load_addr;
 967
 968                        if (fit_parse_conf(select, default_addr,
 969                                           &rd_addr, &fit_uname_config)) {
 970                                debug("*  ramdisk: config '%s' from image at "
 971                                                "0x%08lx\n",
 972                                                fit_uname_config, rd_addr);
 973                        } else if (fit_parse_subimage(select, default_addr,
 974                                                &rd_addr, &fit_uname_ramdisk)) {
 975                                debug("*  ramdisk: subimage '%s' from image at "
 976                                                "0x%08lx\n",
 977                                                fit_uname_ramdisk, rd_addr);
 978                        } else
 979#endif
 980                        {
 981                                rd_addr = simple_strtoul(select, NULL, 16);
 982                                debug("*  ramdisk: cmdline image address = "
 983                                                "0x%08lx\n",
 984                                                rd_addr);
 985                        }
 986#if IMAGE_ENABLE_FIT
 987                } else {
 988                        /* use FIT configuration provided in first bootm
 989                         * command argument. If the property is not defined,
 990                         * quit silently.
 991                         */
 992                        rd_addr = map_to_sysmem(images->fit_hdr_os);
 993                        rd_noffset = fit_get_node_from_config(images,
 994                                        FIT_RAMDISK_PROP, rd_addr);
 995                        if (rd_noffset == -ENOLINK)
 996                                return 0;
 997                        else if (rd_noffset < 0)
 998                                return 1;
 999                }
1000#endif
1001
1002                /* copy from dataflash if needed */
1003                rd_addr = genimg_get_image(rd_addr);
1004
1005                /*
1006                 * Check if there is an initrd image at the
1007                 * address provided in the second bootm argument
1008                 * check image type, for FIT images get FIT node.
1009                 */
1010                buf = map_sysmem(rd_addr, 0);
1011                switch (genimg_get_format(buf)) {
1012#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
1013                case IMAGE_FORMAT_LEGACY:
1014                        printf("## Loading init Ramdisk from Legacy "
1015                                        "Image at %08lx ...\n", rd_addr);
1016
1017                        bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK);
1018                        rd_hdr = image_get_ramdisk(rd_addr, arch,
1019                                                        images->verify);
1020
1021                        if (rd_hdr == NULL)
1022                                return 1;
1023
1024                        rd_data = image_get_data(rd_hdr);
1025                        rd_len = image_get_data_size(rd_hdr);
1026                        rd_load = image_get_load(rd_hdr);
1027                        break;
1028#endif
1029#if IMAGE_ENABLE_FIT
1030                case IMAGE_FORMAT_FIT:
1031                        rd_noffset = fit_image_load(images,
1032                                        rd_addr, &fit_uname_ramdisk,
1033                                        &fit_uname_config, arch,
1034                                        IH_TYPE_RAMDISK,
1035                                        BOOTSTAGE_ID_FIT_RD_START,
1036                                        FIT_LOAD_OPTIONAL_NON_ZERO,
1037                                        &rd_data, &rd_len);
1038                        if (rd_noffset < 0)
1039                                return 1;
1040
1041                        images->fit_hdr_rd = map_sysmem(rd_addr, 0);
1042                        images->fit_uname_rd = fit_uname_ramdisk;
1043                        images->fit_noffset_rd = rd_noffset;
1044                        break;
1045#endif
1046#ifdef CONFIG_ANDROID_BOOT_IMAGE
1047                case IMAGE_FORMAT_ANDROID:
1048                        android_image_get_ramdisk((void *)images->os.start,
1049                                &rd_data, &rd_len);
1050                        break;
1051#endif
1052                default:
1053#ifdef CONFIG_SUPPORT_RAW_INITRD
1054                        end = NULL;
1055                        if (select)
1056                                end = strchr(select, ':');
1057                        if (end) {
1058                                rd_len = simple_strtoul(++end, NULL, 16);
1059                                rd_data = rd_addr;
1060                        } else
1061#endif
1062                        {
1063                                puts("Wrong Ramdisk Image Format\n");
1064                                rd_data = rd_len = rd_load = 0;
1065                                return 1;
1066                        }
1067                }
1068        } else if (images->legacy_hdr_valid &&
1069                        image_check_type(&images->legacy_hdr_os_copy,
1070                                                IH_TYPE_MULTI)) {
1071
1072                /*
1073                 * Now check if we have a legacy mult-component image,
1074                 * get second entry data start address and len.
1075                 */
1076                bootstage_mark(BOOTSTAGE_ID_RAMDISK);
1077                printf("## Loading init Ramdisk from multi component "
1078                                "Legacy Image at %08lx ...\n",
1079                                (ulong)images->legacy_hdr_os);
1080
1081                image_multi_getimg(images->legacy_hdr_os, 1, &rd_data, &rd_len);
1082        } else {
1083                /*
1084                 * no initrd image
1085                 */
1086                bootstage_mark(BOOTSTAGE_ID_NO_RAMDISK);
1087                rd_len = rd_data = 0;
1088        }
1089
1090        if (!rd_data) {
1091                debug("## No init Ramdisk\n");
1092        } else {
1093                *rd_start = rd_data;
1094                *rd_end = rd_data + rd_len;
1095        }
1096        debug("   ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",
1097                        *rd_start, *rd_end);
1098
1099        return 0;
1100}
1101
1102#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
1103/**
1104 * boot_ramdisk_high - relocate init ramdisk
1105 * @lmb: pointer to lmb handle, will be used for memory mgmt
1106 * @rd_data: ramdisk data start address
1107 * @rd_len: ramdisk data length
1108 * @initrd_start: pointer to a ulong variable, will hold final init ramdisk
1109 *      start address (after possible relocation)
1110 * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
1111 *      end address (after possible relocation)
1112 *
1113 * boot_ramdisk_high() takes a relocation hint from "initrd_high" environment
1114 * variable and if requested ramdisk data is moved to a specified location.
1115 *
1116 * Initrd_start and initrd_end are set to final (after relocation) ramdisk
1117 * start/end addresses if ramdisk image start and len were provided,
1118 * otherwise set initrd_start and initrd_end set to zeros.
1119 *
1120 * returns:
1121 *      0 - success
1122 *     -1 - failure
1123 */
1124int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
1125                  ulong *initrd_start, ulong *initrd_end)
1126{
1127        char    *s;
1128        ulong   initrd_high;
1129        int     initrd_copy_to_ram = 1;
1130
1131        if ((s = getenv("initrd_high")) != NULL) {
1132                /* a value of "no" or a similar string will act like 0,
1133                 * turning the "load high" feature off. This is intentional.
1134                 */
1135                initrd_high = simple_strtoul(s, NULL, 16);
1136                if (initrd_high == ~0)
1137                        initrd_copy_to_ram = 0;
1138        } else {
1139                initrd_high = getenv_bootm_mapsize() + getenv_bootm_low();
1140        }
1141
1142
1143#ifdef CONFIG_LOGBUFFER
1144        /* Prevent initrd from overwriting logbuffer */
1145        lmb_reserve(lmb, logbuffer_base() - LOGBUFF_OVERHEAD, LOGBUFF_RESERVE);
1146#endif
1147
1148        debug("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
1149                        initrd_high, initrd_copy_to_ram);
1150
1151        if (rd_data) {
1152                if (!initrd_copy_to_ram) {      /* zero-copy ramdisk support */
1153                        debug("   in-place initrd\n");
1154                        *initrd_start = rd_data;
1155                        *initrd_end = rd_data + rd_len;
1156                        lmb_reserve(lmb, rd_data, rd_len);
1157                } else {
1158                        if (initrd_high)
1159                                *initrd_start = (ulong)lmb_alloc_base(lmb,
1160                                                rd_len, 0x1000, initrd_high);
1161                        else
1162                                *initrd_start = (ulong)lmb_alloc(lmb, rd_len,
1163                                                                 0x1000);
1164
1165                        if (*initrd_start == 0) {
1166                                puts("ramdisk - allocation error\n");
1167                                goto error;
1168                        }
1169                        bootstage_mark(BOOTSTAGE_ID_COPY_RAMDISK);
1170
1171                        *initrd_end = *initrd_start + rd_len;
1172                        printf("   Loading Ramdisk to %08lx, end %08lx ... ",
1173                                        *initrd_start, *initrd_end);
1174
1175                        memmove_wd((void *)*initrd_start,
1176                                        (void *)rd_data, rd_len, CHUNKSZ);
1177
1178#ifdef CONFIG_MP
1179                        /*
1180                         * Ensure the image is flushed to memory to handle
1181                         * AMP boot scenarios in which we might not be
1182                         * HW cache coherent
1183                         */
1184                        flush_cache((unsigned long)*initrd_start, rd_len);
1185#endif
1186                        puts("OK\n");
1187                }
1188        } else {
1189                *initrd_start = 0;
1190                *initrd_end = 0;
1191        }
1192        debug("   ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
1193                        *initrd_start, *initrd_end);
1194
1195        return 0;
1196
1197error:
1198        return -1;
1199}
1200#endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */
1201
1202int boot_get_setup(bootm_headers_t *images, uint8_t arch,
1203                   ulong *setup_start, ulong *setup_len)
1204{
1205#if IMAGE_ENABLE_FIT
1206        return boot_get_setup_fit(images, arch, setup_start, setup_len);
1207#else
1208        return -ENOENT;
1209#endif
1210}
1211
1212#if IMAGE_ENABLE_FIT
1213int boot_get_loadable(int argc, char * const argv[], bootm_headers_t *images,
1214                uint8_t arch, const ulong *ld_start, ulong * const ld_len)
1215{
1216        /*
1217         * These variables are used to hold the current image location
1218         * in system memory.
1219         */
1220        ulong tmp_img_addr;
1221        /*
1222         * These two variables are requirements for fit_image_load, but
1223         * their values are not used
1224         */
1225        ulong img_data, img_len;
1226        void *buf;
1227        int loadables_index;
1228        int conf_noffset;
1229        int fit_img_result;
1230        char *uname;
1231
1232        /* Check to see if the images struct has a FIT configuration */
1233        if (!genimg_has_config(images)) {
1234                debug("## FIT configuration was not specified\n");
1235                return 0;
1236        }
1237
1238        /*
1239         * Obtain the os FIT header from the images struct
1240         * copy from dataflash if needed
1241         */
1242        tmp_img_addr = map_to_sysmem(images->fit_hdr_os);
1243        tmp_img_addr = genimg_get_image(tmp_img_addr);
1244        buf = map_sysmem(tmp_img_addr, 0);
1245        /*
1246         * Check image type. For FIT images get FIT node
1247         * and attempt to locate a generic binary.
1248         */
1249        switch (genimg_get_format(buf)) {
1250        case IMAGE_FORMAT_FIT:
1251                conf_noffset = fit_conf_get_node(buf, images->fit_uname_cfg);
1252
1253                for (loadables_index = 0;
1254                     fdt_get_string_index(buf, conf_noffset,
1255                                FIT_LOADABLE_PROP,
1256                                loadables_index,
1257                                (const char **)&uname) == 0;
1258                     loadables_index++)
1259                {
1260                        fit_img_result = fit_image_load(images,
1261                                tmp_img_addr,
1262                                (const char **)&uname,
1263                                &(images->fit_uname_cfg), arch,
1264                                IH_TYPE_LOADABLE,
1265                                BOOTSTAGE_ID_FIT_LOADABLE_START,
1266                                FIT_LOAD_OPTIONAL_NON_ZERO,
1267                                &img_data, &img_len);
1268                        if (fit_img_result < 0) {
1269                                /* Something went wrong! */
1270                                return fit_img_result;
1271                        }
1272                }
1273                break;
1274        default:
1275                printf("The given image format is not supported (corrupt?)\n");
1276                return 1;
1277        }
1278
1279        return 0;
1280}
1281#endif
1282
1283#ifdef CONFIG_SYS_BOOT_GET_CMDLINE
1284/**
1285 * boot_get_cmdline - allocate and initialize kernel cmdline
1286 * @lmb: pointer to lmb handle, will be used for memory mgmt
1287 * @cmd_start: pointer to a ulong variable, will hold cmdline start
1288 * @cmd_end: pointer to a ulong variable, will hold cmdline end
1289 *
1290 * boot_get_cmdline() allocates space for kernel command line below
1291 * BOOTMAPSZ + getenv_bootm_low() address. If "bootargs" U-Boot environemnt
1292 * variable is present its contents is copied to allocated kernel
1293 * command line.
1294 *
1295 * returns:
1296 *      0 - success
1297 *     -1 - failure
1298 */
1299int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end)
1300{
1301        char *cmdline;
1302        char *s;
1303
1304        cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf,
1305                                getenv_bootm_mapsize() + getenv_bootm_low());
1306
1307        if (cmdline == NULL)
1308                return -1;
1309
1310        if ((s = getenv("bootargs")) == NULL)
1311                s = "";
1312
1313        strcpy(cmdline, s);
1314
1315        *cmd_start = (ulong) & cmdline[0];
1316        *cmd_end = *cmd_start + strlen(cmdline);
1317
1318        debug("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
1319
1320        return 0;
1321}
1322#endif /* CONFIG_SYS_BOOT_GET_CMDLINE */
1323
1324#ifdef CONFIG_SYS_BOOT_GET_KBD
1325/**
1326 * boot_get_kbd - allocate and initialize kernel copy of board info
1327 * @lmb: pointer to lmb handle, will be used for memory mgmt
1328 * @kbd: double pointer to board info data
1329 *
1330 * boot_get_kbd() allocates space for kernel copy of board info data below
1331 * BOOTMAPSZ + getenv_bootm_low() address and kernel board info is initialized
1332 * with the current u-boot board info data.
1333 *
1334 * returns:
1335 *      0 - success
1336 *     -1 - failure
1337 */
1338int boot_get_kbd(struct lmb *lmb, bd_t **kbd)
1339{
1340        *kbd = (bd_t *)(ulong)lmb_alloc_base(lmb, sizeof(bd_t), 0xf,
1341                                getenv_bootm_mapsize() + getenv_bootm_low());
1342        if (*kbd == NULL)
1343                return -1;
1344
1345        **kbd = *(gd->bd);
1346
1347        debug("## kernel board info at 0x%08lx\n", (ulong)*kbd);
1348
1349#if defined(DEBUG) && defined(CONFIG_CMD_BDI)
1350        do_bdinfo(NULL, 0, 0, NULL);
1351#endif
1352
1353        return 0;
1354}
1355#endif /* CONFIG_SYS_BOOT_GET_KBD */
1356
1357#ifdef CONFIG_LMB
1358int image_setup_linux(bootm_headers_t *images)
1359{
1360        ulong of_size = images->ft_len;
1361        char **of_flat_tree = &images->ft_addr;
1362        ulong *initrd_start = &images->initrd_start;
1363        ulong *initrd_end = &images->initrd_end;
1364        struct lmb *lmb = &images->lmb;
1365        ulong rd_len;
1366        int ret;
1367
1368        if (IMAGE_ENABLE_OF_LIBFDT)
1369                boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
1370
1371        if (IMAGE_BOOT_GET_CMDLINE) {
1372                ret = boot_get_cmdline(lmb, &images->cmdline_start,
1373                                &images->cmdline_end);
1374                if (ret) {
1375                        puts("ERROR with allocation of cmdline\n");
1376                        return ret;
1377                }
1378        }
1379        if (IMAGE_ENABLE_RAMDISK_HIGH) {
1380                rd_len = images->rd_end - images->rd_start;
1381                ret = boot_ramdisk_high(lmb, images->rd_start, rd_len,
1382                                initrd_start, initrd_end);
1383                if (ret)
1384                        return ret;
1385        }
1386
1387        if (IMAGE_ENABLE_OF_LIBFDT) {
1388                ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
1389                if (ret)
1390                        return ret;
1391        }
1392
1393        if (IMAGE_ENABLE_OF_LIBFDT && of_size) {
1394                ret = image_setup_libfdt(images, *of_flat_tree, of_size, lmb);
1395                if (ret)
1396                        return ret;
1397        }
1398
1399        return 0;
1400}
1401#endif /* CONFIG_LMB */
1402#endif /* !USE_HOSTCC */
1403