Annotation of elwix/tools/uboot_mkimage/common/image.c, revision 1.1
1.1 ! misho 1: /*
! 2: * (C) Copyright 2008 Semihalf
! 3: *
! 4: * (C) Copyright 2000-2006
! 5: * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
! 6: *
! 7: * See file CREDITS for list of people who contributed to this
! 8: * project.
! 9: *
! 10: * This program is free software; you can redistribute it and/or
! 11: * modify it under the terms of the GNU General Public License as
! 12: * published by the Free Software Foundation; either version 2 of
! 13: * the License, or (at your option) any later version.
! 14: *
! 15: * This program is distributed in the hope that it will be useful,
! 16: * but WITHOUT ANY WARRANTY; without even the implied warranty of
! 17: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 18: * GNU General Public License for more details.
! 19: *
! 20: * You should have received a copy of the GNU General Public License
! 21: * along with this program; if not, write to the Free Software
! 22: * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
! 23: * MA 02111-1307 USA
! 24: */
! 25:
! 26: #ifndef USE_HOSTCC
! 27: #include <common.h>
! 28: #include <watchdog.h>
! 29:
! 30: #ifdef CONFIG_SHOW_BOOT_PROGRESS
! 31: #include <status_led.h>
! 32: #endif
! 33:
! 34: #ifdef CONFIG_HAS_DATAFLASH
! 35: #include <dataflash.h>
! 36: #endif
! 37:
! 38: #ifdef CONFIG_LOGBUFFER
! 39: #include <logbuff.h>
! 40: #endif
! 41:
! 42: #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE)
! 43: #include <rtc.h>
! 44: #endif
! 45:
! 46: #include <image.h>
! 47:
! 48: #if defined(CONFIG_FIT) || defined (CONFIG_OF_LIBFDT)
! 49: #include <fdt.h>
! 50: #include <libfdt.h>
! 51: #include <fdt_support.h>
! 52: #endif
! 53:
! 54: #if defined(CONFIG_FIT)
! 55: #include <u-boot/md5.h>
! 56: #include <sha1.h>
! 57:
! 58: static int fit_check_ramdisk (const void *fit, int os_noffset,
! 59: uint8_t arch, int verify);
! 60: #endif
! 61:
! 62: #ifdef CONFIG_CMD_BDI
! 63: extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
! 64: #endif
! 65:
! 66: DECLARE_GLOBAL_DATA_PTR;
! 67:
! 68: static const image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
! 69: int verify);
! 70: #else
! 71: #include "mkimage.h"
! 72: #include <u-boot/md5.h>
! 73: #include <time.h>
! 74: #include <image.h>
! 75: #endif /* !USE_HOSTCC*/
! 76:
! 77: static table_entry_t uimage_arch[] = {
! 78: { IH_ARCH_INVALID, NULL, "Invalid ARCH", },
! 79: { IH_ARCH_ALPHA, "alpha", "Alpha", },
! 80: { IH_ARCH_ARM, "arm", "ARM", },
! 81: { IH_ARCH_I386, "x86", "Intel x86", },
! 82: { IH_ARCH_IA64, "ia64", "IA64", },
! 83: { IH_ARCH_M68K, "m68k", "M68K", },
! 84: { IH_ARCH_MICROBLAZE, "microblaze", "MicroBlaze", },
! 85: { IH_ARCH_MIPS, "mips", "MIPS", },
! 86: { IH_ARCH_MIPS64, "mips64", "MIPS 64 Bit", },
! 87: { IH_ARCH_NIOS2, "nios2", "NIOS II", },
! 88: { IH_ARCH_PPC, "powerpc", "PowerPC", },
! 89: { IH_ARCH_PPC, "ppc", "PowerPC", },
! 90: { IH_ARCH_S390, "s390", "IBM S390", },
! 91: { IH_ARCH_SH, "sh", "SuperH", },
! 92: { IH_ARCH_SPARC, "sparc", "SPARC", },
! 93: { IH_ARCH_SPARC64, "sparc64", "SPARC 64 Bit", },
! 94: { IH_ARCH_BLACKFIN, "blackfin", "Blackfin", },
! 95: { IH_ARCH_AVR32, "avr32", "AVR32", },
! 96: { -1, "", "", },
! 97: };
! 98:
! 99: static table_entry_t uimage_os[] = {
! 100: { IH_OS_INVALID, NULL, "Invalid OS", },
! 101: { IH_OS_LINUX, "linux", "Linux", },
! 102: #if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC)
! 103: { IH_OS_LYNXOS, "lynxos", "LynxOS", },
! 104: #endif
! 105: { IH_OS_NETBSD, "netbsd", "NetBSD", },
! 106: { IH_OS_OSE, "ose", "Enea OSE", },
! 107: { IH_OS_RTEMS, "rtems", "RTEMS", },
! 108: { IH_OS_U_BOOT, "u-boot", "U-Boot", },
! 109: #if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
! 110: { IH_OS_QNX, "qnx", "QNX", },
! 111: { IH_OS_VXWORKS, "vxworks", "VxWorks", },
! 112: #endif
! 113: #if defined(CONFIG_INTEGRITY) || defined(USE_HOSTCC)
! 114: { IH_OS_INTEGRITY,"integrity", "INTEGRITY", },
! 115: #endif
! 116: #ifdef USE_HOSTCC
! 117: { IH_OS_4_4BSD, "4_4bsd", "4_4BSD", },
! 118: { IH_OS_DELL, "dell", "Dell", },
! 119: { IH_OS_ESIX, "esix", "Esix", },
! 120: { IH_OS_FREEBSD, "freebsd", "FreeBSD", },
! 121: { IH_OS_IRIX, "irix", "Irix", },
! 122: { IH_OS_NCR, "ncr", "NCR", },
! 123: { IH_OS_OPENBSD, "openbsd", "OpenBSD", },
! 124: { IH_OS_PSOS, "psos", "pSOS", },
! 125: { IH_OS_SCO, "sco", "SCO", },
! 126: { IH_OS_SOLARIS, "solaris", "Solaris", },
! 127: { IH_OS_SVR4, "svr4", "SVR4", },
! 128: #endif
! 129: { -1, "", "", },
! 130: };
! 131:
! 132: static table_entry_t uimage_type[] = {
! 133: { IH_TYPE_INVALID, NULL, "Invalid Image", },
! 134: { IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", },
! 135: { IH_TYPE_FIRMWARE, "firmware", "Firmware", },
! 136: { IH_TYPE_KERNEL, "kernel", "Kernel Image", },
! 137: { IH_TYPE_MULTI, "multi", "Multi-File Image", },
! 138: { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", },
! 139: { IH_TYPE_SCRIPT, "script", "Script", },
! 140: { IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
! 141: { IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", },
! 142: { IH_TYPE_KWBIMAGE, "kwbimage", "Kirkwood Boot Image",},
! 143: { IH_TYPE_IMXIMAGE, "imximage", "Freescale i.MX Boot Image",},
! 144: { -1, "", "", },
! 145: };
! 146:
! 147: static table_entry_t uimage_comp[] = {
! 148: { IH_COMP_NONE, "none", "uncompressed", },
! 149: { IH_COMP_BZIP2, "bzip2", "bzip2 compressed", },
! 150: { IH_COMP_GZIP, "gzip", "gzip compressed", },
! 151: { IH_COMP_LZMA, "lzma", "lzma compressed", },
! 152: { IH_COMP_LZO, "lzo", "lzo compressed", },
! 153: { -1, "", "", },
! 154: };
! 155:
! 156: uint32_t crc32 (uint32_t, const unsigned char *, uint);
! 157: uint32_t crc32_wd (uint32_t, const unsigned char *, uint, uint);
! 158: #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
! 159: static void genimg_print_time (time_t timestamp);
! 160: #endif
! 161:
! 162: /*****************************************************************************/
! 163: /* Legacy format routines */
! 164: /*****************************************************************************/
! 165: int image_check_hcrc (const image_header_t *hdr)
! 166: {
! 167: ulong hcrc;
! 168: ulong len = image_get_header_size ();
! 169: image_header_t header;
! 170:
! 171: /* Copy header so we can blank CRC field for re-calculation */
! 172: memmove (&header, (char *)hdr, image_get_header_size ());
! 173: image_set_hcrc (&header, 0);
! 174:
! 175: hcrc = crc32 (0, (unsigned char *)&header, len);
! 176:
! 177: return (hcrc == image_get_hcrc (hdr));
! 178: }
! 179:
! 180: int image_check_dcrc (const image_header_t *hdr)
! 181: {
! 182: ulong data = image_get_data (hdr);
! 183: ulong len = image_get_data_size (hdr);
! 184: ulong dcrc = crc32_wd (0, (unsigned char *)data, len, CHUNKSZ_CRC32);
! 185:
! 186: return (dcrc == image_get_dcrc (hdr));
! 187: }
! 188:
! 189: /**
! 190: * image_multi_count - get component (sub-image) count
! 191: * @hdr: pointer to the header of the multi component image
! 192: *
! 193: * image_multi_count() returns number of components in a multi
! 194: * component image.
! 195: *
! 196: * Note: no checking of the image type is done, caller must pass
! 197: * a valid multi component image.
! 198: *
! 199: * returns:
! 200: * number of components
! 201: */
! 202: ulong image_multi_count (const image_header_t *hdr)
! 203: {
! 204: ulong i, count = 0;
! 205: uint32_t *size;
! 206:
! 207: /* get start of the image payload, which in case of multi
! 208: * component images that points to a table of component sizes */
! 209: size = (uint32_t *)image_get_data (hdr);
! 210:
! 211: /* count non empty slots */
! 212: for (i = 0; size[i]; ++i)
! 213: count++;
! 214:
! 215: return count;
! 216: }
! 217:
! 218: /**
! 219: * image_multi_getimg - get component data address and size
! 220: * @hdr: pointer to the header of the multi component image
! 221: * @idx: index of the requested component
! 222: * @data: pointer to a ulong variable, will hold component data address
! 223: * @len: pointer to a ulong variable, will hold component size
! 224: *
! 225: * image_multi_getimg() returns size and data address for the requested
! 226: * component in a multi component image.
! 227: *
! 228: * Note: no checking of the image type is done, caller must pass
! 229: * a valid multi component image.
! 230: *
! 231: * returns:
! 232: * data address and size of the component, if idx is valid
! 233: * 0 in data and len, if idx is out of range
! 234: */
! 235: void image_multi_getimg (const image_header_t *hdr, ulong idx,
! 236: ulong *data, ulong *len)
! 237: {
! 238: int i;
! 239: uint32_t *size;
! 240: ulong offset, count, img_data;
! 241:
! 242: /* get number of component */
! 243: count = image_multi_count (hdr);
! 244:
! 245: /* get start of the image payload, which in case of multi
! 246: * component images that points to a table of component sizes */
! 247: size = (uint32_t *)image_get_data (hdr);
! 248:
! 249: /* get address of the proper component data start, which means
! 250: * skipping sizes table (add 1 for last, null entry) */
! 251: img_data = image_get_data (hdr) + (count + 1) * sizeof (uint32_t);
! 252:
! 253: if (idx < count) {
! 254: *len = uimage_to_cpu (size[idx]);
! 255: offset = 0;
! 256:
! 257: /* go over all indices preceding requested component idx */
! 258: for (i = 0; i < idx; i++) {
! 259: /* add up i-th component size, rounding up to 4 bytes */
! 260: offset += (uimage_to_cpu (size[i]) + 3) & ~3 ;
! 261: }
! 262:
! 263: /* calculate idx-th component data address */
! 264: *data = img_data + offset;
! 265: } else {
! 266: *len = 0;
! 267: *data = 0;
! 268: }
! 269: }
! 270:
! 271: static void image_print_type (const image_header_t *hdr)
! 272: {
! 273: const char *os, *arch, *type, *comp;
! 274:
! 275: os = genimg_get_os_name (image_get_os (hdr));
! 276: arch = genimg_get_arch_name (image_get_arch (hdr));
! 277: type = genimg_get_type_name (image_get_type (hdr));
! 278: comp = genimg_get_comp_name (image_get_comp (hdr));
! 279:
! 280: printf ("%s %s %s (%s)\n", arch, os, type, comp);
! 281: }
! 282:
! 283: /**
! 284: * image_print_contents - prints out the contents of the legacy format image
! 285: * @ptr: pointer to the legacy format image header
! 286: * @p: pointer to prefix string
! 287: *
! 288: * image_print_contents() formats a multi line legacy image contents description.
! 289: * The routine prints out all header fields followed by the size/offset data
! 290: * for MULTI/SCRIPT images.
! 291: *
! 292: * returns:
! 293: * no returned results
! 294: */
! 295: void image_print_contents (const void *ptr)
! 296: {
! 297: const image_header_t *hdr = (const image_header_t *)ptr;
! 298: const char *p;
! 299:
! 300: #ifdef USE_HOSTCC
! 301: p = "";
! 302: #else
! 303: p = " ";
! 304: #endif
! 305:
! 306: printf ("%sImage Name: %.*s\n", p, IH_NMLEN, image_get_name (hdr));
! 307: #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
! 308: printf ("%sCreated: ", p);
! 309: genimg_print_time ((time_t)image_get_time (hdr));
! 310: #endif
! 311: printf ("%sImage Type: ", p);
! 312: image_print_type (hdr);
! 313: printf ("%sData Size: ", p);
! 314: genimg_print_size (image_get_data_size (hdr));
! 315: printf ("%sLoad Address: %08x\n", p, image_get_load (hdr));
! 316: printf ("%sEntry Point: %08x\n", p, image_get_ep (hdr));
! 317:
! 318: if (image_check_type (hdr, IH_TYPE_MULTI) ||
! 319: image_check_type (hdr, IH_TYPE_SCRIPT)) {
! 320: int i;
! 321: ulong data, len;
! 322: ulong count = image_multi_count (hdr);
! 323:
! 324: printf ("%sContents:\n", p);
! 325: for (i = 0; i < count; i++) {
! 326: image_multi_getimg (hdr, i, &data, &len);
! 327:
! 328: printf ("%s Image %d: ", p, i);
! 329: genimg_print_size (len);
! 330:
! 331: if (image_check_type (hdr, IH_TYPE_SCRIPT) && i > 0) {
! 332: /*
! 333: * the user may need to know offsets
! 334: * if planning to do something with
! 335: * multiple files
! 336: */
! 337: printf ("%s Offset = 0x%08lx\n", p, data);
! 338: }
! 339: }
! 340: }
! 341: }
! 342:
! 343:
! 344: #ifndef USE_HOSTCC
! 345: /**
! 346: * image_get_ramdisk - get and verify ramdisk image
! 347: * @rd_addr: ramdisk image start address
! 348: * @arch: expected ramdisk architecture
! 349: * @verify: checksum verification flag
! 350: *
! 351: * image_get_ramdisk() returns a pointer to the verified ramdisk image
! 352: * header. Routine receives image start address and expected architecture
! 353: * flag. Verification done covers data and header integrity and os/type/arch
! 354: * fields checking.
! 355: *
! 356: * If dataflash support is enabled routine checks for dataflash addresses
! 357: * and handles required dataflash reads.
! 358: *
! 359: * returns:
! 360: * pointer to a ramdisk image header, if image was found and valid
! 361: * otherwise, return NULL
! 362: */
! 363: static const image_header_t *image_get_ramdisk (ulong rd_addr, uint8_t arch,
! 364: int verify)
! 365: {
! 366: const image_header_t *rd_hdr = (const image_header_t *)rd_addr;
! 367:
! 368: if (!image_check_magic (rd_hdr)) {
! 369: puts ("Bad Magic Number\n");
! 370: show_boot_progress (-10);
! 371: return NULL;
! 372: }
! 373:
! 374: if (!image_check_hcrc (rd_hdr)) {
! 375: puts ("Bad Header Checksum\n");
! 376: show_boot_progress (-11);
! 377: return NULL;
! 378: }
! 379:
! 380: show_boot_progress (10);
! 381: image_print_contents (rd_hdr);
! 382:
! 383: if (verify) {
! 384: puts(" Verifying Checksum ... ");
! 385: if (!image_check_dcrc (rd_hdr)) {
! 386: puts ("Bad Data CRC\n");
! 387: show_boot_progress (-12);
! 388: return NULL;
! 389: }
! 390: puts("OK\n");
! 391: }
! 392:
! 393: show_boot_progress (11);
! 394:
! 395: if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
! 396: !image_check_arch (rd_hdr, arch) ||
! 397: !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
! 398: printf ("No Linux %s Ramdisk Image\n",
! 399: genimg_get_arch_name(arch));
! 400: show_boot_progress (-13);
! 401: return NULL;
! 402: }
! 403:
! 404: return rd_hdr;
! 405: }
! 406: #endif /* !USE_HOSTCC */
! 407:
! 408: /*****************************************************************************/
! 409: /* Shared dual-format routines */
! 410: /*****************************************************************************/
! 411: #ifndef USE_HOSTCC
! 412: int getenv_yesno (char *var)
! 413: {
! 414: char *s = getenv (var);
! 415: return (s && (*s == 'n')) ? 0 : 1;
! 416: }
! 417:
! 418: ulong getenv_bootm_low(void)
! 419: {
! 420: char *s = getenv ("bootm_low");
! 421: if (s) {
! 422: ulong tmp = simple_strtoul (s, NULL, 16);
! 423: return tmp;
! 424: }
! 425:
! 426: #if defined(CONFIG_SYS_SDRAM_BASE)
! 427: return CONFIG_SYS_SDRAM_BASE;
! 428: #elif defined(CONFIG_ARM)
! 429: return gd->bd->bi_dram[0].start;
! 430: #else
! 431: return 0;
! 432: #endif
! 433: }
! 434:
! 435: phys_size_t getenv_bootm_size(void)
! 436: {
! 437: phys_size_t tmp;
! 438: char *s = getenv ("bootm_size");
! 439: if (s) {
! 440: tmp = (phys_size_t)simple_strtoull (s, NULL, 16);
! 441: return tmp;
! 442: }
! 443: s = getenv("bootm_low");
! 444: if (s)
! 445: tmp = (phys_size_t)simple_strtoull (s, NULL, 16);
! 446: else
! 447: tmp = 0;
! 448:
! 449:
! 450: #if defined(CONFIG_ARM)
! 451: return gd->bd->bi_dram[0].size - tmp;
! 452: #else
! 453: return gd->bd->bi_memsize - tmp;
! 454: #endif
! 455: }
! 456:
! 457: void memmove_wd (void *to, void *from, size_t len, ulong chunksz)
! 458: {
! 459: if (to == from)
! 460: return;
! 461:
! 462: #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
! 463: while (len > 0) {
! 464: size_t tail = (len > chunksz) ? chunksz : len;
! 465: WATCHDOG_RESET ();
! 466: memmove (to, from, tail);
! 467: to += tail;
! 468: from += tail;
! 469: len -= tail;
! 470: }
! 471: #else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
! 472: memmove (to, from, len);
! 473: #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
! 474: }
! 475: #endif /* !USE_HOSTCC */
! 476:
! 477: void genimg_print_size (uint32_t size)
! 478: {
! 479: #ifndef USE_HOSTCC
! 480: printf ("%d Bytes = ", size);
! 481: print_size (size, "\n");
! 482: #else
! 483: printf ("%d Bytes = %.2f kB = %.2f MB\n",
! 484: size, (double)size / 1.024e3,
! 485: (double)size / 1.048576e6);
! 486: #endif
! 487: }
! 488:
! 489: #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
! 490: static void genimg_print_time (time_t timestamp)
! 491: {
! 492: #ifndef USE_HOSTCC
! 493: struct rtc_time tm;
! 494:
! 495: to_tm (timestamp, &tm);
! 496: printf ("%4d-%02d-%02d %2d:%02d:%02d UTC\n",
! 497: tm.tm_year, tm.tm_mon, tm.tm_mday,
! 498: tm.tm_hour, tm.tm_min, tm.tm_sec);
! 499: #else
! 500: printf ("%s", ctime(×tamp));
! 501: #endif
! 502: }
! 503: #endif /* CONFIG_TIMESTAMP || CONFIG_CMD_DATE || USE_HOSTCC */
! 504:
! 505: /**
! 506: * get_table_entry_name - translate entry id to long name
! 507: * @table: pointer to a translation table for entries of a specific type
! 508: * @msg: message to be returned when translation fails
! 509: * @id: entry id to be translated
! 510: *
! 511: * get_table_entry_name() will go over translation table trying to find
! 512: * entry that matches given id. If matching entry is found, its long
! 513: * name is returned to the caller.
! 514: *
! 515: * returns:
! 516: * long entry name if translation succeeds
! 517: * msg otherwise
! 518: */
! 519: char *get_table_entry_name (table_entry_t *table, char *msg, int id)
! 520: {
! 521: for (; table->id >= 0; ++table) {
! 522: if (table->id == id)
! 523: #if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
! 524: return table->lname;
! 525: #else
! 526: return table->lname + gd->reloc_off;
! 527: #endif
! 528: }
! 529: return (msg);
! 530: }
! 531:
! 532: const char *genimg_get_os_name (uint8_t os)
! 533: {
! 534: return (get_table_entry_name (uimage_os, "Unknown OS", os));
! 535: }
! 536:
! 537: const char *genimg_get_arch_name (uint8_t arch)
! 538: {
! 539: return (get_table_entry_name (uimage_arch, "Unknown Architecture", arch));
! 540: }
! 541:
! 542: const char *genimg_get_type_name (uint8_t type)
! 543: {
! 544: return (get_table_entry_name (uimage_type, "Unknown Image", type));
! 545: }
! 546:
! 547: const char *genimg_get_comp_name (uint8_t comp)
! 548: {
! 549: return (get_table_entry_name (uimage_comp, "Unknown Compression", comp));
! 550: }
! 551:
! 552: /**
! 553: * get_table_entry_id - translate short entry name to id
! 554: * @table: pointer to a translation table for entries of a specific type
! 555: * @table_name: to be used in case of error
! 556: * @name: entry short name to be translated
! 557: *
! 558: * get_table_entry_id() will go over translation table trying to find
! 559: * entry that matches given short name. If matching entry is found,
! 560: * its id returned to the caller.
! 561: *
! 562: * returns:
! 563: * entry id if translation succeeds
! 564: * -1 otherwise
! 565: */
! 566: int get_table_entry_id (table_entry_t *table,
! 567: const char *table_name, const char *name)
! 568: {
! 569: table_entry_t *t;
! 570: #ifdef USE_HOSTCC
! 571: int first = 1;
! 572:
! 573: for (t = table; t->id >= 0; ++t) {
! 574: if (t->sname && strcasecmp(t->sname, name) == 0)
! 575: return (t->id);
! 576: }
! 577:
! 578: fprintf (stderr, "\nInvalid %s Type - valid names are", table_name);
! 579: for (t = table; t->id >= 0; ++t) {
! 580: if (t->sname == NULL)
! 581: continue;
! 582: fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname);
! 583: first = 0;
! 584: }
! 585: fprintf (stderr, "\n");
! 586: #else
! 587: for (t = table; t->id >= 0; ++t) {
! 588: #ifdef CONFIG_NEEDS_MANUAL_RELOC
! 589: if (t->sname && strcmp(t->sname + gd->reloc_off, name) == 0)
! 590: #else
! 591: if (t->sname && strcmp(t->sname, name) == 0)
! 592: #endif
! 593: return (t->id);
! 594: }
! 595: debug ("Invalid %s Type: %s\n", table_name, name);
! 596: #endif /* USE_HOSTCC */
! 597: return (-1);
! 598: }
! 599:
! 600: int genimg_get_os_id (const char *name)
! 601: {
! 602: return (get_table_entry_id (uimage_os, "OS", name));
! 603: }
! 604:
! 605: int genimg_get_arch_id (const char *name)
! 606: {
! 607: return (get_table_entry_id (uimage_arch, "CPU", name));
! 608: }
! 609:
! 610: int genimg_get_type_id (const char *name)
! 611: {
! 612: return (get_table_entry_id (uimage_type, "Image", name));
! 613: }
! 614:
! 615: int genimg_get_comp_id (const char *name)
! 616: {
! 617: return (get_table_entry_id (uimage_comp, "Compression", name));
! 618: }
! 619:
! 620: #ifndef USE_HOSTCC
! 621: /**
! 622: * genimg_get_format - get image format type
! 623: * @img_addr: image start address
! 624: *
! 625: * genimg_get_format() checks whether provided address points to a valid
! 626: * legacy or FIT image.
! 627: *
! 628: * New uImage format and FDT blob are based on a libfdt. FDT blob
! 629: * may be passed directly or embedded in a FIT image. In both situations
! 630: * genimg_get_format() must be able to dectect libfdt header.
! 631: *
! 632: * returns:
! 633: * image format type or IMAGE_FORMAT_INVALID if no image is present
! 634: */
! 635: int genimg_get_format (void *img_addr)
! 636: {
! 637: ulong format = IMAGE_FORMAT_INVALID;
! 638: const image_header_t *hdr;
! 639: #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
! 640: char *fit_hdr;
! 641: #endif
! 642:
! 643: hdr = (const image_header_t *)img_addr;
! 644: if (image_check_magic(hdr))
! 645: format = IMAGE_FORMAT_LEGACY;
! 646: #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
! 647: else {
! 648: fit_hdr = (char *)img_addr;
! 649: if (fdt_check_header (fit_hdr) == 0)
! 650: format = IMAGE_FORMAT_FIT;
! 651: }
! 652: #endif
! 653:
! 654: return format;
! 655: }
! 656:
! 657: /**
! 658: * genimg_get_image - get image from special storage (if necessary)
! 659: * @img_addr: image start address
! 660: *
! 661: * genimg_get_image() checks if provided image start adddress is located
! 662: * in a dataflash storage. If so, image is moved to a system RAM memory.
! 663: *
! 664: * returns:
! 665: * image start address after possible relocation from special storage
! 666: */
! 667: ulong genimg_get_image (ulong img_addr)
! 668: {
! 669: ulong ram_addr = img_addr;
! 670:
! 671: #ifdef CONFIG_HAS_DATAFLASH
! 672: ulong h_size, d_size;
! 673:
! 674: if (addr_dataflash (img_addr)){
! 675: /* ger RAM address */
! 676: ram_addr = CONFIG_SYS_LOAD_ADDR;
! 677:
! 678: /* get header size */
! 679: h_size = image_get_header_size ();
! 680: #if defined(CONFIG_FIT)
! 681: if (sizeof(struct fdt_header) > h_size)
! 682: h_size = sizeof(struct fdt_header);
! 683: #endif
! 684:
! 685: /* read in header */
! 686: debug (" Reading image header from dataflash address "
! 687: "%08lx to RAM address %08lx\n", img_addr, ram_addr);
! 688:
! 689: read_dataflash (img_addr, h_size, (char *)ram_addr);
! 690:
! 691: /* get data size */
! 692: switch (genimg_get_format ((void *)ram_addr)) {
! 693: case IMAGE_FORMAT_LEGACY:
! 694: d_size = image_get_data_size ((const image_header_t *)ram_addr);
! 695: debug (" Legacy format image found at 0x%08lx, size 0x%08lx\n",
! 696: ram_addr, d_size);
! 697: break;
! 698: #if defined(CONFIG_FIT)
! 699: case IMAGE_FORMAT_FIT:
! 700: d_size = fit_get_size ((const void *)ram_addr) - h_size;
! 701: debug (" FIT/FDT format image found at 0x%08lx, size 0x%08lx\n",
! 702: ram_addr, d_size);
! 703: break;
! 704: #endif
! 705: default:
! 706: printf (" No valid image found at 0x%08lx\n", img_addr);
! 707: return ram_addr;
! 708: }
! 709:
! 710: /* read in image data */
! 711: debug (" Reading image remaining data from dataflash address "
! 712: "%08lx to RAM address %08lx\n", img_addr + h_size,
! 713: ram_addr + h_size);
! 714:
! 715: read_dataflash (img_addr + h_size, d_size,
! 716: (char *)(ram_addr + h_size));
! 717:
! 718: }
! 719: #endif /* CONFIG_HAS_DATAFLASH */
! 720:
! 721: return ram_addr;
! 722: }
! 723:
! 724: /**
! 725: * fit_has_config - check if there is a valid FIT configuration
! 726: * @images: pointer to the bootm command headers structure
! 727: *
! 728: * fit_has_config() checks if there is a FIT configuration in use
! 729: * (if FTI support is present).
! 730: *
! 731: * returns:
! 732: * 0, no FIT support or no configuration found
! 733: * 1, configuration found
! 734: */
! 735: int genimg_has_config (bootm_headers_t *images)
! 736: {
! 737: #if defined(CONFIG_FIT)
! 738: if (images->fit_uname_cfg)
! 739: return 1;
! 740: #endif
! 741: return 0;
! 742: }
! 743:
! 744: /**
! 745: * boot_get_ramdisk - main ramdisk handling routine
! 746: * @argc: command argument count
! 747: * @argv: command argument list
! 748: * @images: pointer to the bootm images structure
! 749: * @arch: expected ramdisk architecture
! 750: * @rd_start: pointer to a ulong variable, will hold ramdisk start address
! 751: * @rd_end: pointer to a ulong variable, will hold ramdisk end
! 752: *
! 753: * boot_get_ramdisk() is responsible for finding a valid ramdisk image.
! 754: * Curently supported are the following ramdisk sources:
! 755: * - multicomponent kernel/ramdisk image,
! 756: * - commandline provided address of decicated ramdisk image.
! 757: *
! 758: * returns:
! 759: * 0, if ramdisk image was found and valid, or skiped
! 760: * rd_start and rd_end are set to ramdisk start/end addresses if
! 761: * ramdisk image is found and valid
! 762: *
! 763: * 1, if ramdisk image is found but corrupted, or invalid
! 764: * rd_start and rd_end are set to 0 if no ramdisk exists
! 765: */
! 766: int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images,
! 767: uint8_t arch, ulong *rd_start, ulong *rd_end)
! 768: {
! 769: ulong rd_addr, rd_load;
! 770: ulong rd_data, rd_len;
! 771: const image_header_t *rd_hdr;
! 772: #if defined(CONFIG_FIT)
! 773: void *fit_hdr;
! 774: const char *fit_uname_config = NULL;
! 775: const char *fit_uname_ramdisk = NULL;
! 776: ulong default_addr;
! 777: int rd_noffset;
! 778: int cfg_noffset;
! 779: const void *data;
! 780: size_t size;
! 781: #endif
! 782:
! 783: *rd_start = 0;
! 784: *rd_end = 0;
! 785:
! 786: /*
! 787: * Look for a '-' which indicates to ignore the
! 788: * ramdisk argument
! 789: */
! 790: if ((argc >= 3) && (strcmp(argv[2], "-") == 0)) {
! 791: debug ("## Skipping init Ramdisk\n");
! 792: rd_len = rd_data = 0;
! 793: } else if (argc >= 3 || genimg_has_config (images)) {
! 794: #if defined(CONFIG_FIT)
! 795: if (argc >= 3) {
! 796: /*
! 797: * If the init ramdisk comes from the FIT image and
! 798: * the FIT image address is omitted in the command
! 799: * line argument, try to use os FIT image address or
! 800: * default load address.
! 801: */
! 802: if (images->fit_uname_os)
! 803: default_addr = (ulong)images->fit_hdr_os;
! 804: else
! 805: default_addr = load_addr;
! 806:
! 807: if (fit_parse_conf (argv[2], default_addr,
! 808: &rd_addr, &fit_uname_config)) {
! 809: debug ("* ramdisk: config '%s' from image at 0x%08lx\n",
! 810: fit_uname_config, rd_addr);
! 811: } else if (fit_parse_subimage (argv[2], default_addr,
! 812: &rd_addr, &fit_uname_ramdisk)) {
! 813: debug ("* ramdisk: subimage '%s' from image at 0x%08lx\n",
! 814: fit_uname_ramdisk, rd_addr);
! 815: } else
! 816: #endif
! 817: {
! 818: rd_addr = simple_strtoul(argv[2], NULL, 16);
! 819: debug ("* ramdisk: cmdline image address = 0x%08lx\n",
! 820: rd_addr);
! 821: }
! 822: #if defined(CONFIG_FIT)
! 823: } else {
! 824: /* use FIT configuration provided in first bootm
! 825: * command argument
! 826: */
! 827: rd_addr = (ulong)images->fit_hdr_os;
! 828: fit_uname_config = images->fit_uname_cfg;
! 829: debug ("* ramdisk: using config '%s' from image at 0x%08lx\n",
! 830: fit_uname_config, rd_addr);
! 831:
! 832: /*
! 833: * Check whether configuration has ramdisk defined,
! 834: * if not, don't try to use it, quit silently.
! 835: */
! 836: fit_hdr = (void *)rd_addr;
! 837: cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
! 838: if (cfg_noffset < 0) {
! 839: debug ("* ramdisk: no such config\n");
! 840: return 1;
! 841: }
! 842:
! 843: rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);
! 844: if (rd_noffset < 0) {
! 845: debug ("* ramdisk: no ramdisk in config\n");
! 846: return 0;
! 847: }
! 848: }
! 849: #endif
! 850:
! 851: /* copy from dataflash if needed */
! 852: rd_addr = genimg_get_image (rd_addr);
! 853:
! 854: /*
! 855: * Check if there is an initrd image at the
! 856: * address provided in the second bootm argument
! 857: * check image type, for FIT images get FIT node.
! 858: */
! 859: switch (genimg_get_format ((void *)rd_addr)) {
! 860: case IMAGE_FORMAT_LEGACY:
! 861: printf ("## Loading init Ramdisk from Legacy "
! 862: "Image at %08lx ...\n", rd_addr);
! 863:
! 864: show_boot_progress (9);
! 865: rd_hdr = image_get_ramdisk (rd_addr, arch,
! 866: images->verify);
! 867:
! 868: if (rd_hdr == NULL)
! 869: return 1;
! 870:
! 871: rd_data = image_get_data (rd_hdr);
! 872: rd_len = image_get_data_size (rd_hdr);
! 873: rd_load = image_get_load (rd_hdr);
! 874: break;
! 875: #if defined(CONFIG_FIT)
! 876: case IMAGE_FORMAT_FIT:
! 877: fit_hdr = (void *)rd_addr;
! 878: printf ("## Loading init Ramdisk from FIT "
! 879: "Image at %08lx ...\n", rd_addr);
! 880:
! 881: show_boot_progress (120);
! 882: if (!fit_check_format (fit_hdr)) {
! 883: puts ("Bad FIT ramdisk image format!\n");
! 884: show_boot_progress (-120);
! 885: return 1;
! 886: }
! 887: show_boot_progress (121);
! 888:
! 889: if (!fit_uname_ramdisk) {
! 890: /*
! 891: * no ramdisk image node unit name, try to get config
! 892: * node first. If config unit node name is NULL
! 893: * fit_conf_get_node() will try to find default config node
! 894: */
! 895: show_boot_progress (122);
! 896: cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
! 897: if (cfg_noffset < 0) {
! 898: puts ("Could not find configuration node\n");
! 899: show_boot_progress (-122);
! 900: return 1;
! 901: }
! 902: fit_uname_config = fdt_get_name (fit_hdr, cfg_noffset, NULL);
! 903: printf (" Using '%s' configuration\n", fit_uname_config);
! 904:
! 905: rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);
! 906: fit_uname_ramdisk = fit_get_name (fit_hdr, rd_noffset, NULL);
! 907: } else {
! 908: /* get ramdisk component image node offset */
! 909: show_boot_progress (123);
! 910: rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk);
! 911: }
! 912: if (rd_noffset < 0) {
! 913: puts ("Could not find subimage node\n");
! 914: show_boot_progress (-124);
! 915: return 1;
! 916: }
! 917:
! 918: printf (" Trying '%s' ramdisk subimage\n", fit_uname_ramdisk);
! 919:
! 920: show_boot_progress (125);
! 921: if (!fit_check_ramdisk (fit_hdr, rd_noffset, arch, images->verify))
! 922: return 1;
! 923:
! 924: /* get ramdisk image data address and length */
! 925: if (fit_image_get_data (fit_hdr, rd_noffset, &data, &size)) {
! 926: puts ("Could not find ramdisk subimage data!\n");
! 927: show_boot_progress (-127);
! 928: return 1;
! 929: }
! 930: show_boot_progress (128);
! 931:
! 932: rd_data = (ulong)data;
! 933: rd_len = size;
! 934:
! 935: if (fit_image_get_load (fit_hdr, rd_noffset, &rd_load)) {
! 936: puts ("Can't get ramdisk subimage load address!\n");
! 937: show_boot_progress (-129);
! 938: return 1;
! 939: }
! 940: show_boot_progress (129);
! 941:
! 942: images->fit_hdr_rd = fit_hdr;
! 943: images->fit_uname_rd = fit_uname_ramdisk;
! 944: images->fit_noffset_rd = rd_noffset;
! 945: break;
! 946: #endif
! 947: default:
! 948: puts ("Wrong Ramdisk Image Format\n");
! 949: rd_data = rd_len = rd_load = 0;
! 950: return 1;
! 951: }
! 952:
! 953: #if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)
! 954: /*
! 955: * We need to copy the ramdisk to SRAM to let Linux boot
! 956: */
! 957: if (rd_data) {
! 958: memmove ((void *)rd_load, (uchar *)rd_data, rd_len);
! 959: rd_data = rd_load;
! 960: }
! 961: #endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */
! 962:
! 963: } else if (images->legacy_hdr_valid &&
! 964: image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
! 965: /*
! 966: * Now check if we have a legacy mult-component image,
! 967: * get second entry data start address and len.
! 968: */
! 969: show_boot_progress (13);
! 970: printf ("## Loading init Ramdisk from multi component "
! 971: "Legacy Image at %08lx ...\n",
! 972: (ulong)images->legacy_hdr_os);
! 973:
! 974: image_multi_getimg (images->legacy_hdr_os, 1, &rd_data, &rd_len);
! 975: } else {
! 976: /*
! 977: * no initrd image
! 978: */
! 979: show_boot_progress (14);
! 980: rd_len = rd_data = 0;
! 981: }
! 982:
! 983: if (!rd_data) {
! 984: debug ("## No init Ramdisk\n");
! 985: } else {
! 986: *rd_start = rd_data;
! 987: *rd_end = rd_data + rd_len;
! 988: }
! 989: debug (" ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",
! 990: *rd_start, *rd_end);
! 991:
! 992: return 0;
! 993: }
! 994:
! 995: #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
! 996: /**
! 997: * boot_ramdisk_high - relocate init ramdisk
! 998: * @lmb: pointer to lmb handle, will be used for memory mgmt
! 999: * @rd_data: ramdisk data start address
! 1000: * @rd_len: ramdisk data length
! 1001: * @initrd_start: pointer to a ulong variable, will hold final init ramdisk
! 1002: * start address (after possible relocation)
! 1003: * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
! 1004: * end address (after possible relocation)
! 1005: *
! 1006: * boot_ramdisk_high() takes a relocation hint from "initrd_high" environement
! 1007: * variable and if requested ramdisk data is moved to a specified location.
! 1008: *
! 1009: * Initrd_start and initrd_end are set to final (after relocation) ramdisk
! 1010: * start/end addresses if ramdisk image start and len were provided,
! 1011: * otherwise set initrd_start and initrd_end set to zeros.
! 1012: *
! 1013: * returns:
! 1014: * 0 - success
! 1015: * -1 - failure
! 1016: */
! 1017: int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
! 1018: ulong *initrd_start, ulong *initrd_end)
! 1019: {
! 1020: char *s;
! 1021: ulong initrd_high;
! 1022: int initrd_copy_to_ram = 1;
! 1023:
! 1024: if ((s = getenv ("initrd_high")) != NULL) {
! 1025: /* a value of "no" or a similar string will act like 0,
! 1026: * turning the "load high" feature off. This is intentional.
! 1027: */
! 1028: initrd_high = simple_strtoul (s, NULL, 16);
! 1029: if (initrd_high == ~0)
! 1030: initrd_copy_to_ram = 0;
! 1031: } else {
! 1032: /* not set, no restrictions to load high */
! 1033: initrd_high = ~0;
! 1034: }
! 1035:
! 1036:
! 1037: #ifdef CONFIG_LOGBUFFER
! 1038: /* Prevent initrd from overwriting logbuffer */
! 1039: lmb_reserve(lmb, logbuffer_base() - LOGBUFF_OVERHEAD, LOGBUFF_RESERVE);
! 1040: #endif
! 1041:
! 1042: debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
! 1043: initrd_high, initrd_copy_to_ram);
! 1044:
! 1045: if (rd_data) {
! 1046: if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */
! 1047: debug (" in-place initrd\n");
! 1048: *initrd_start = rd_data;
! 1049: *initrd_end = rd_data + rd_len;
! 1050: lmb_reserve(lmb, rd_data, rd_len);
! 1051: } else {
! 1052: if (initrd_high)
! 1053: *initrd_start = (ulong)lmb_alloc_base (lmb, rd_len, 0x1000, initrd_high);
! 1054: else
! 1055: *initrd_start = (ulong)lmb_alloc (lmb, rd_len, 0x1000);
! 1056:
! 1057: if (*initrd_start == 0) {
! 1058: puts ("ramdisk - allocation error\n");
! 1059: goto error;
! 1060: }
! 1061: show_boot_progress (12);
! 1062:
! 1063: *initrd_end = *initrd_start + rd_len;
! 1064: printf (" Loading Ramdisk to %08lx, end %08lx ... ",
! 1065: *initrd_start, *initrd_end);
! 1066:
! 1067: memmove_wd ((void *)*initrd_start,
! 1068: (void *)rd_data, rd_len, CHUNKSZ);
! 1069:
! 1070: puts ("OK\n");
! 1071: }
! 1072: } else {
! 1073: *initrd_start = 0;
! 1074: *initrd_end = 0;
! 1075: }
! 1076: debug (" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
! 1077: *initrd_start, *initrd_end);
! 1078:
! 1079: return 0;
! 1080:
! 1081: error:
! 1082: return -1;
! 1083: }
! 1084: #endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */
! 1085:
! 1086: #ifdef CONFIG_OF_LIBFDT
! 1087: static void fdt_error (const char *msg)
! 1088: {
! 1089: puts ("ERROR: ");
! 1090: puts (msg);
! 1091: puts (" - must RESET the board to recover.\n");
! 1092: }
! 1093:
! 1094: static const image_header_t *image_get_fdt (ulong fdt_addr)
! 1095: {
! 1096: const image_header_t *fdt_hdr = (const image_header_t *)fdt_addr;
! 1097:
! 1098: image_print_contents (fdt_hdr);
! 1099:
! 1100: puts (" Verifying Checksum ... ");
! 1101: if (!image_check_hcrc (fdt_hdr)) {
! 1102: fdt_error ("fdt header checksum invalid");
! 1103: return NULL;
! 1104: }
! 1105:
! 1106: if (!image_check_dcrc (fdt_hdr)) {
! 1107: fdt_error ("fdt checksum invalid");
! 1108: return NULL;
! 1109: }
! 1110: puts ("OK\n");
! 1111:
! 1112: if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) {
! 1113: fdt_error ("uImage is not a fdt");
! 1114: return NULL;
! 1115: }
! 1116: if (image_get_comp (fdt_hdr) != IH_COMP_NONE) {
! 1117: fdt_error ("uImage is compressed");
! 1118: return NULL;
! 1119: }
! 1120: if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) {
! 1121: fdt_error ("uImage data is not a fdt");
! 1122: return NULL;
! 1123: }
! 1124: return fdt_hdr;
! 1125: }
! 1126:
! 1127: /**
! 1128: * fit_check_fdt - verify FIT format FDT subimage
! 1129: * @fit_hdr: pointer to the FIT header
! 1130: * fdt_noffset: FDT subimage node offset within FIT image
! 1131: * @verify: data CRC verification flag
! 1132: *
! 1133: * fit_check_fdt() verifies integrity of the FDT subimage and from
! 1134: * specified FIT image.
! 1135: *
! 1136: * returns:
! 1137: * 1, on success
! 1138: * 0, on failure
! 1139: */
! 1140: #if defined(CONFIG_FIT)
! 1141: static int fit_check_fdt (const void *fit, int fdt_noffset, int verify)
! 1142: {
! 1143: fit_image_print (fit, fdt_noffset, " ");
! 1144:
! 1145: if (verify) {
! 1146: puts (" Verifying Hash Integrity ... ");
! 1147: if (!fit_image_check_hashes (fit, fdt_noffset)) {
! 1148: fdt_error ("Bad Data Hash");
! 1149: return 0;
! 1150: }
! 1151: puts ("OK\n");
! 1152: }
! 1153:
! 1154: if (!fit_image_check_type (fit, fdt_noffset, IH_TYPE_FLATDT)) {
! 1155: fdt_error ("Not a FDT image");
! 1156: return 0;
! 1157: }
! 1158:
! 1159: if (!fit_image_check_comp (fit, fdt_noffset, IH_COMP_NONE)) {
! 1160: fdt_error ("FDT image is compressed");
! 1161: return 0;
! 1162: }
! 1163:
! 1164: return 1;
! 1165: }
! 1166: #endif /* CONFIG_FIT */
! 1167:
! 1168: #ifndef CONFIG_SYS_FDT_PAD
! 1169: #define CONFIG_SYS_FDT_PAD 0x3000
! 1170: #endif
! 1171:
! 1172: /**
! 1173: * boot_relocate_fdt - relocate flat device tree
! 1174: * @lmb: pointer to lmb handle, will be used for memory mgmt
! 1175: * @bootmap_base: base address of the bootmap region
! 1176: * @of_flat_tree: pointer to a char* variable, will hold fdt start address
! 1177: * @of_size: pointer to a ulong variable, will hold fdt length
! 1178: *
! 1179: * boot_relocate_fdt() allocates a region of memory within the bootmap and
! 1180: * relocates the of_flat_tree into that region, even if the fdt is already in
! 1181: * the bootmap. It also expands the size of the fdt by CONFIG_SYS_FDT_PAD
! 1182: * bytes.
! 1183: *
! 1184: * of_flat_tree and of_size are set to final (after relocation) values
! 1185: *
! 1186: * returns:
! 1187: * 0 - success
! 1188: * 1 - failure
! 1189: */
! 1190: #if defined(CONFIG_SYS_BOOTMAPSZ)
! 1191: int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
! 1192: char **of_flat_tree, ulong *of_size)
! 1193: {
! 1194: void *fdt_blob = *of_flat_tree;
! 1195: void *of_start = 0;
! 1196: ulong of_len = 0;
! 1197: int err;
! 1198:
! 1199: /* nothing to do */
! 1200: if (*of_size == 0)
! 1201: return 0;
! 1202:
! 1203: if (fdt_check_header (fdt_blob) != 0) {
! 1204: fdt_error ("image is not a fdt");
! 1205: goto error;
! 1206: }
! 1207:
! 1208: /* position on a 4K boundary before the alloc_current */
! 1209: /* Pad the FDT by a specified amount */
! 1210: of_len = *of_size + CONFIG_SYS_FDT_PAD;
! 1211: of_start = (void *)(unsigned long)lmb_alloc_base(lmb, of_len, 0x1000,
! 1212: (CONFIG_SYS_BOOTMAPSZ + bootmap_base));
! 1213:
! 1214: if (of_start == 0) {
! 1215: puts("device tree - allocation error\n");
! 1216: goto error;
! 1217: }
! 1218:
! 1219: debug ("## device tree at %p ... %p (len=%ld [0x%lX])\n",
! 1220: fdt_blob, fdt_blob + *of_size - 1, of_len, of_len);
! 1221:
! 1222: printf (" Loading Device Tree to %p, end %p ... ",
! 1223: of_start, of_start + of_len - 1);
! 1224:
! 1225: err = fdt_open_into (fdt_blob, of_start, of_len);
! 1226: if (err != 0) {
! 1227: fdt_error ("fdt move failed");
! 1228: goto error;
! 1229: }
! 1230: puts ("OK\n");
! 1231:
! 1232: *of_flat_tree = of_start;
! 1233: *of_size = of_len;
! 1234:
! 1235: set_working_fdt_addr(*of_flat_tree);
! 1236: return 0;
! 1237:
! 1238: error:
! 1239: return 1;
! 1240: }
! 1241: #endif /* CONFIG_SYS_BOOTMAPSZ */
! 1242:
! 1243: /**
! 1244: * boot_get_fdt - main fdt handling routine
! 1245: * @argc: command argument count
! 1246: * @argv: command argument list
! 1247: * @images: pointer to the bootm images structure
! 1248: * @of_flat_tree: pointer to a char* variable, will hold fdt start address
! 1249: * @of_size: pointer to a ulong variable, will hold fdt length
! 1250: *
! 1251: * boot_get_fdt() is responsible for finding a valid flat device tree image.
! 1252: * Curently supported are the following ramdisk sources:
! 1253: * - multicomponent kernel/ramdisk image,
! 1254: * - commandline provided address of decicated ramdisk image.
! 1255: *
! 1256: * returns:
! 1257: * 0, if fdt image was found and valid, or skipped
! 1258: * of_flat_tree and of_size are set to fdt start address and length if
! 1259: * fdt image is found and valid
! 1260: *
! 1261: * 1, if fdt image is found but corrupted
! 1262: * of_flat_tree and of_size are set to 0 if no fdt exists
! 1263: */
! 1264: int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *images,
! 1265: char **of_flat_tree, ulong *of_size)
! 1266: {
! 1267: const image_header_t *fdt_hdr;
! 1268: ulong fdt_addr;
! 1269: char *fdt_blob = NULL;
! 1270: ulong image_start, image_end;
! 1271: ulong load_start, load_end;
! 1272: #if defined(CONFIG_FIT)
! 1273: void *fit_hdr;
! 1274: const char *fit_uname_config = NULL;
! 1275: const char *fit_uname_fdt = NULL;
! 1276: ulong default_addr;
! 1277: int cfg_noffset;
! 1278: int fdt_noffset;
! 1279: const void *data;
! 1280: size_t size;
! 1281: #endif
! 1282:
! 1283: *of_flat_tree = NULL;
! 1284: *of_size = 0;
! 1285:
! 1286: if (argc > 3 || genimg_has_config (images)) {
! 1287: #if defined(CONFIG_FIT)
! 1288: if (argc > 3) {
! 1289: /*
! 1290: * If the FDT blob comes from the FIT image and the
! 1291: * FIT image address is omitted in the command line
! 1292: * argument, try to use ramdisk or os FIT image
! 1293: * address or default load address.
! 1294: */
! 1295: if (images->fit_uname_rd)
! 1296: default_addr = (ulong)images->fit_hdr_rd;
! 1297: else if (images->fit_uname_os)
! 1298: default_addr = (ulong)images->fit_hdr_os;
! 1299: else
! 1300: default_addr = load_addr;
! 1301:
! 1302: if (fit_parse_conf (argv[3], default_addr,
! 1303: &fdt_addr, &fit_uname_config)) {
! 1304: debug ("* fdt: config '%s' from image at 0x%08lx\n",
! 1305: fit_uname_config, fdt_addr);
! 1306: } else if (fit_parse_subimage (argv[3], default_addr,
! 1307: &fdt_addr, &fit_uname_fdt)) {
! 1308: debug ("* fdt: subimage '%s' from image at 0x%08lx\n",
! 1309: fit_uname_fdt, fdt_addr);
! 1310: } else
! 1311: #endif
! 1312: {
! 1313: fdt_addr = simple_strtoul(argv[3], NULL, 16);
! 1314: debug ("* fdt: cmdline image address = 0x%08lx\n",
! 1315: fdt_addr);
! 1316: }
! 1317: #if defined(CONFIG_FIT)
! 1318: } else {
! 1319: /* use FIT configuration provided in first bootm
! 1320: * command argument
! 1321: */
! 1322: fdt_addr = (ulong)images->fit_hdr_os;
! 1323: fit_uname_config = images->fit_uname_cfg;
! 1324: debug ("* fdt: using config '%s' from image at 0x%08lx\n",
! 1325: fit_uname_config, fdt_addr);
! 1326:
! 1327: /*
! 1328: * Check whether configuration has FDT blob defined,
! 1329: * if not quit silently.
! 1330: */
! 1331: fit_hdr = (void *)fdt_addr;
! 1332: cfg_noffset = fit_conf_get_node (fit_hdr,
! 1333: fit_uname_config);
! 1334: if (cfg_noffset < 0) {
! 1335: debug ("* fdt: no such config\n");
! 1336: return 0;
! 1337: }
! 1338:
! 1339: fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
! 1340: cfg_noffset);
! 1341: if (fdt_noffset < 0) {
! 1342: debug ("* fdt: no fdt in config\n");
! 1343: return 0;
! 1344: }
! 1345: }
! 1346: #endif
! 1347:
! 1348: debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n",
! 1349: fdt_addr);
! 1350:
! 1351: /* copy from dataflash if needed */
! 1352: fdt_addr = genimg_get_image (fdt_addr);
! 1353:
! 1354: /*
! 1355: * Check if there is an FDT image at the
! 1356: * address provided in the second bootm argument
! 1357: * check image type, for FIT images get a FIT node.
! 1358: */
! 1359: switch (genimg_get_format ((void *)fdt_addr)) {
! 1360: case IMAGE_FORMAT_LEGACY:
! 1361: /* verify fdt_addr points to a valid image header */
! 1362: printf ("## Flattened Device Tree from Legacy Image at %08lx\n",
! 1363: fdt_addr);
! 1364: fdt_hdr = image_get_fdt (fdt_addr);
! 1365: if (!fdt_hdr)
! 1366: goto error;
! 1367:
! 1368: /*
! 1369: * move image data to the load address,
! 1370: * make sure we don't overwrite initial image
! 1371: */
! 1372: image_start = (ulong)fdt_hdr;
! 1373: image_end = image_get_image_end (fdt_hdr);
! 1374:
! 1375: load_start = image_get_load (fdt_hdr);
! 1376: load_end = load_start + image_get_data_size (fdt_hdr);
! 1377:
! 1378: if ((load_start < image_end) && (load_end > image_start)) {
! 1379: fdt_error ("fdt overwritten");
! 1380: goto error;
! 1381: }
! 1382:
! 1383: debug (" Loading FDT from 0x%08lx to 0x%08lx\n",
! 1384: image_get_data (fdt_hdr), load_start);
! 1385:
! 1386: memmove ((void *)load_start,
! 1387: (void *)image_get_data (fdt_hdr),
! 1388: image_get_data_size (fdt_hdr));
! 1389:
! 1390: fdt_blob = (char *)load_start;
! 1391: break;
! 1392: case IMAGE_FORMAT_FIT:
! 1393: /*
! 1394: * This case will catch both: new uImage format
! 1395: * (libfdt based) and raw FDT blob (also libfdt
! 1396: * based).
! 1397: */
! 1398: #if defined(CONFIG_FIT)
! 1399: /* check FDT blob vs FIT blob */
! 1400: if (fit_check_format ((const void *)fdt_addr)) {
! 1401: /*
! 1402: * FIT image
! 1403: */
! 1404: fit_hdr = (void *)fdt_addr;
! 1405: printf ("## Flattened Device Tree from FIT Image at %08lx\n",
! 1406: fdt_addr);
! 1407:
! 1408: if (!fit_uname_fdt) {
! 1409: /*
! 1410: * no FDT blob image node unit name,
! 1411: * try to get config node first. If
! 1412: * config unit node name is NULL
! 1413: * fit_conf_get_node() will try to
! 1414: * find default config node
! 1415: */
! 1416: cfg_noffset = fit_conf_get_node (fit_hdr,
! 1417: fit_uname_config);
! 1418:
! 1419: if (cfg_noffset < 0) {
! 1420: fdt_error ("Could not find configuration node\n");
! 1421: goto error;
! 1422: }
! 1423:
! 1424: fit_uname_config = fdt_get_name (fit_hdr,
! 1425: cfg_noffset, NULL);
! 1426: printf (" Using '%s' configuration\n",
! 1427: fit_uname_config);
! 1428:
! 1429: fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
! 1430: cfg_noffset);
! 1431: fit_uname_fdt = fit_get_name (fit_hdr,
! 1432: fdt_noffset, NULL);
! 1433: } else {
! 1434: /* get FDT component image node offset */
! 1435: fdt_noffset = fit_image_get_node (fit_hdr,
! 1436: fit_uname_fdt);
! 1437: }
! 1438: if (fdt_noffset < 0) {
! 1439: fdt_error ("Could not find subimage node\n");
! 1440: goto error;
! 1441: }
! 1442:
! 1443: printf (" Trying '%s' FDT blob subimage\n",
! 1444: fit_uname_fdt);
! 1445:
! 1446: if (!fit_check_fdt (fit_hdr, fdt_noffset,
! 1447: images->verify))
! 1448: goto error;
! 1449:
! 1450: /* get ramdisk image data address and length */
! 1451: if (fit_image_get_data (fit_hdr, fdt_noffset,
! 1452: &data, &size)) {
! 1453: fdt_error ("Could not find FDT subimage data");
! 1454: goto error;
! 1455: }
! 1456:
! 1457: /* verift that image data is a proper FDT blob */
! 1458: if (fdt_check_header ((char *)data) != 0) {
! 1459: fdt_error ("Subimage data is not a FTD");
! 1460: goto error;
! 1461: }
! 1462:
! 1463: /*
! 1464: * move image data to the load address,
! 1465: * make sure we don't overwrite initial image
! 1466: */
! 1467: image_start = (ulong)fit_hdr;
! 1468: image_end = fit_get_end (fit_hdr);
! 1469:
! 1470: if (fit_image_get_load (fit_hdr, fdt_noffset,
! 1471: &load_start) == 0) {
! 1472: load_end = load_start + size;
! 1473:
! 1474: if ((load_start < image_end) &&
! 1475: (load_end > image_start)) {
! 1476: fdt_error ("FDT overwritten");
! 1477: goto error;
! 1478: }
! 1479:
! 1480: printf (" Loading FDT from 0x%08lx to 0x%08lx\n",
! 1481: (ulong)data, load_start);
! 1482:
! 1483: memmove ((void *)load_start,
! 1484: (void *)data, size);
! 1485:
! 1486: fdt_blob = (char *)load_start;
! 1487: } else {
! 1488: fdt_blob = (char *)data;
! 1489: }
! 1490:
! 1491: images->fit_hdr_fdt = fit_hdr;
! 1492: images->fit_uname_fdt = fit_uname_fdt;
! 1493: images->fit_noffset_fdt = fdt_noffset;
! 1494: break;
! 1495: } else
! 1496: #endif
! 1497: {
! 1498: /*
! 1499: * FDT blob
! 1500: */
! 1501: fdt_blob = (char *)fdt_addr;
! 1502: debug ("* fdt: raw FDT blob\n");
! 1503: printf ("## Flattened Device Tree blob at %08lx\n", (long)fdt_blob);
! 1504: }
! 1505: break;
! 1506: default:
! 1507: puts ("ERROR: Did not find a cmdline Flattened Device Tree\n");
! 1508: goto error;
! 1509: }
! 1510:
! 1511: printf (" Booting using the fdt blob at 0x%x\n", (int)fdt_blob);
! 1512:
! 1513: } else if (images->legacy_hdr_valid &&
! 1514: image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
! 1515:
! 1516: ulong fdt_data, fdt_len;
! 1517:
! 1518: /*
! 1519: * Now check if we have a legacy multi-component image,
! 1520: * get second entry data start address and len.
! 1521: */
! 1522: printf ("## Flattened Device Tree from multi "
! 1523: "component Image at %08lX\n",
! 1524: (ulong)images->legacy_hdr_os);
! 1525:
! 1526: image_multi_getimg (images->legacy_hdr_os, 2, &fdt_data, &fdt_len);
! 1527: if (fdt_len) {
! 1528:
! 1529: fdt_blob = (char *)fdt_data;
! 1530: printf (" Booting using the fdt at 0x%x\n", (int)fdt_blob);
! 1531:
! 1532: if (fdt_check_header (fdt_blob) != 0) {
! 1533: fdt_error ("image is not a fdt");
! 1534: goto error;
! 1535: }
! 1536:
! 1537: if (fdt_totalsize(fdt_blob) != fdt_len) {
! 1538: fdt_error ("fdt size != image size");
! 1539: goto error;
! 1540: }
! 1541: } else {
! 1542: debug ("## No Flattened Device Tree\n");
! 1543: return 0;
! 1544: }
! 1545: } else {
! 1546: debug ("## No Flattened Device Tree\n");
! 1547: return 0;
! 1548: }
! 1549:
! 1550: *of_flat_tree = fdt_blob;
! 1551: *of_size = fdt_totalsize(fdt_blob);
! 1552: debug (" of_flat_tree at 0x%08lx size 0x%08lx\n",
! 1553: (ulong)*of_flat_tree, *of_size);
! 1554:
! 1555: return 0;
! 1556:
! 1557: error:
! 1558: *of_flat_tree = 0;
! 1559: *of_size = 0;
! 1560: return 1;
! 1561: }
! 1562: #endif /* CONFIG_OF_LIBFDT */
! 1563:
! 1564: #ifdef CONFIG_SYS_BOOT_GET_CMDLINE
! 1565: /**
! 1566: * boot_get_cmdline - allocate and initialize kernel cmdline
! 1567: * @lmb: pointer to lmb handle, will be used for memory mgmt
! 1568: * @cmd_start: pointer to a ulong variable, will hold cmdline start
! 1569: * @cmd_end: pointer to a ulong variable, will hold cmdline end
! 1570: * @bootmap_base: ulong variable, holds offset in physical memory to
! 1571: * base of bootmap
! 1572: *
! 1573: * boot_get_cmdline() allocates space for kernel command line below
! 1574: * BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt
! 1575: * variable is present its contents is copied to allocated kernel
! 1576: * command line.
! 1577: *
! 1578: * returns:
! 1579: * 0 - success
! 1580: * -1 - failure
! 1581: */
! 1582: int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
! 1583: ulong bootmap_base)
! 1584: {
! 1585: char *cmdline;
! 1586: char *s;
! 1587:
! 1588: cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf,
! 1589: CONFIG_SYS_BOOTMAPSZ + bootmap_base);
! 1590:
! 1591: if (cmdline == NULL)
! 1592: return -1;
! 1593:
! 1594: if ((s = getenv("bootargs")) == NULL)
! 1595: s = "";
! 1596:
! 1597: strcpy(cmdline, s);
! 1598:
! 1599: *cmd_start = (ulong) & cmdline[0];
! 1600: *cmd_end = *cmd_start + strlen(cmdline);
! 1601:
! 1602: debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
! 1603:
! 1604: return 0;
! 1605: }
! 1606: #endif /* CONFIG_SYS_BOOT_GET_CMDLINE */
! 1607:
! 1608: #ifdef CONFIG_SYS_BOOT_GET_KBD
! 1609: /**
! 1610: * boot_get_kbd - allocate and initialize kernel copy of board info
! 1611: * @lmb: pointer to lmb handle, will be used for memory mgmt
! 1612: * @kbd: double pointer to board info data
! 1613: * @bootmap_base: ulong variable, holds offset in physical memory to
! 1614: * base of bootmap
! 1615: *
! 1616: * boot_get_kbd() allocates space for kernel copy of board info data below
! 1617: * BOOTMAPSZ + bootmap_base address and kernel board info is initialized with
! 1618: * the current u-boot board info data.
! 1619: *
! 1620: * returns:
! 1621: * 0 - success
! 1622: * -1 - failure
! 1623: */
! 1624: int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base)
! 1625: {
! 1626: *kbd = (bd_t *)(ulong)lmb_alloc_base(lmb, sizeof(bd_t), 0xf,
! 1627: CONFIG_SYS_BOOTMAPSZ + bootmap_base);
! 1628: if (*kbd == NULL)
! 1629: return -1;
! 1630:
! 1631: **kbd = *(gd->bd);
! 1632:
! 1633: debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd);
! 1634:
! 1635: #if defined(DEBUG) && defined(CONFIG_CMD_BDI)
! 1636: do_bdinfo(NULL, 0, 0, NULL);
! 1637: #endif
! 1638:
! 1639: return 0;
! 1640: }
! 1641: #endif /* CONFIG_SYS_BOOT_GET_KBD */
! 1642: #endif /* !USE_HOSTCC */
! 1643:
! 1644: #if defined(CONFIG_FIT)
! 1645: /*****************************************************************************/
! 1646: /* New uImage format routines */
! 1647: /*****************************************************************************/
! 1648: #ifndef USE_HOSTCC
! 1649: static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr,
! 1650: ulong *addr, const char **name)
! 1651: {
! 1652: const char *sep;
! 1653:
! 1654: *addr = addr_curr;
! 1655: *name = NULL;
! 1656:
! 1657: sep = strchr (spec, sepc);
! 1658: if (sep) {
! 1659: if (sep - spec > 0)
! 1660: *addr = simple_strtoul (spec, NULL, 16);
! 1661:
! 1662: *name = sep + 1;
! 1663: return 1;
! 1664: }
! 1665:
! 1666: return 0;
! 1667: }
! 1668:
! 1669: /**
! 1670: * fit_parse_conf - parse FIT configuration spec
! 1671: * @spec: input string, containing configuration spec
! 1672: * @add_curr: current image address (to be used as a possible default)
! 1673: * @addr: pointer to a ulong variable, will hold FIT image address of a given
! 1674: * configuration
! 1675: * @conf_name double pointer to a char, will hold pointer to a configuration
! 1676: * unit name
! 1677: *
! 1678: * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>,
! 1679: * where <addr> is a FIT image address that contains configuration
! 1680: * with a <conf> unit name.
! 1681: *
! 1682: * Address part is optional, and if omitted default add_curr will
! 1683: * be used instead.
! 1684: *
! 1685: * returns:
! 1686: * 1 if spec is a valid configuration string,
! 1687: * addr and conf_name are set accordingly
! 1688: * 0 otherwise
! 1689: */
! 1690: inline int fit_parse_conf (const char *spec, ulong addr_curr,
! 1691: ulong *addr, const char **conf_name)
! 1692: {
! 1693: return fit_parse_spec (spec, '#', addr_curr, addr, conf_name);
! 1694: }
! 1695:
! 1696: /**
! 1697: * fit_parse_subimage - parse FIT subimage spec
! 1698: * @spec: input string, containing subimage spec
! 1699: * @add_curr: current image address (to be used as a possible default)
! 1700: * @addr: pointer to a ulong variable, will hold FIT image address of a given
! 1701: * subimage
! 1702: * @image_name: double pointer to a char, will hold pointer to a subimage name
! 1703: *
! 1704: * fit_parse_subimage() expects subimage spec in the for of
! 1705: * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
! 1706: * subimage with a <subimg> unit name.
! 1707: *
! 1708: * Address part is optional, and if omitted default add_curr will
! 1709: * be used instead.
! 1710: *
! 1711: * returns:
! 1712: * 1 if spec is a valid subimage string,
! 1713: * addr and image_name are set accordingly
! 1714: * 0 otherwise
! 1715: */
! 1716: inline int fit_parse_subimage (const char *spec, ulong addr_curr,
! 1717: ulong *addr, const char **image_name)
! 1718: {
! 1719: return fit_parse_spec (spec, ':', addr_curr, addr, image_name);
! 1720: }
! 1721: #endif /* !USE_HOSTCC */
! 1722:
! 1723: static void fit_get_debug (const void *fit, int noffset,
! 1724: char *prop_name, int err)
! 1725: {
! 1726: debug ("Can't get '%s' property from FIT 0x%08lx, "
! 1727: "node: offset %d, name %s (%s)\n",
! 1728: prop_name, (ulong)fit, noffset,
! 1729: fit_get_name (fit, noffset, NULL),
! 1730: fdt_strerror (err));
! 1731: }
! 1732:
! 1733: /**
! 1734: * fit_print_contents - prints out the contents of the FIT format image
! 1735: * @fit: pointer to the FIT format image header
! 1736: * @p: pointer to prefix string
! 1737: *
! 1738: * fit_print_contents() formats a multi line FIT image contents description.
! 1739: * The routine prints out FIT image properties (root node level) follwed by
! 1740: * the details of each component image.
! 1741: *
! 1742: * returns:
! 1743: * no returned results
! 1744: */
! 1745: void fit_print_contents (const void *fit)
! 1746: {
! 1747: char *desc;
! 1748: char *uname;
! 1749: int images_noffset;
! 1750: int confs_noffset;
! 1751: int noffset;
! 1752: int ndepth;
! 1753: int count = 0;
! 1754: int ret;
! 1755: const char *p;
! 1756: #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
! 1757: time_t timestamp;
! 1758: #endif
! 1759:
! 1760: #ifdef USE_HOSTCC
! 1761: p = "";
! 1762: #else
! 1763: p = " ";
! 1764: #endif
! 1765:
! 1766: /* Root node properties */
! 1767: ret = fit_get_desc (fit, 0, &desc);
! 1768: printf ("%sFIT description: ", p);
! 1769: if (ret)
! 1770: printf ("unavailable\n");
! 1771: else
! 1772: printf ("%s\n", desc);
! 1773:
! 1774: #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
! 1775: ret = fit_get_timestamp (fit, 0, ×tamp);
! 1776: printf ("%sCreated: ", p);
! 1777: if (ret)
! 1778: printf ("unavailable\n");
! 1779: else
! 1780: genimg_print_time (timestamp);
! 1781: #endif
! 1782:
! 1783: /* Find images parent node offset */
! 1784: images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
! 1785: if (images_noffset < 0) {
! 1786: printf ("Can't find images parent node '%s' (%s)\n",
! 1787: FIT_IMAGES_PATH, fdt_strerror (images_noffset));
! 1788: return;
! 1789: }
! 1790:
! 1791: /* Process its subnodes, print out component images details */
! 1792: for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);
! 1793: (noffset >= 0) && (ndepth > 0);
! 1794: noffset = fdt_next_node (fit, noffset, &ndepth)) {
! 1795: if (ndepth == 1) {
! 1796: /*
! 1797: * Direct child node of the images parent node,
! 1798: * i.e. component image node.
! 1799: */
! 1800: printf ("%s Image %u (%s)\n", p, count++,
! 1801: fit_get_name(fit, noffset, NULL));
! 1802:
! 1803: fit_image_print (fit, noffset, p);
! 1804: }
! 1805: }
! 1806:
! 1807: /* Find configurations parent node offset */
! 1808: confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);
! 1809: if (confs_noffset < 0) {
! 1810: debug ("Can't get configurations parent node '%s' (%s)\n",
! 1811: FIT_CONFS_PATH, fdt_strerror (confs_noffset));
! 1812: return;
! 1813: }
! 1814:
! 1815: /* get default configuration unit name from default property */
! 1816: uname = (char *)fdt_getprop (fit, noffset, FIT_DEFAULT_PROP, NULL);
! 1817: if (uname)
! 1818: printf ("%s Default Configuration: '%s'\n", p, uname);
! 1819:
! 1820: /* Process its subnodes, print out configurations details */
! 1821: for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, confs_noffset, &ndepth);
! 1822: (noffset >= 0) && (ndepth > 0);
! 1823: noffset = fdt_next_node (fit, noffset, &ndepth)) {
! 1824: if (ndepth == 1) {
! 1825: /*
! 1826: * Direct child node of the configurations parent node,
! 1827: * i.e. configuration node.
! 1828: */
! 1829: printf ("%s Configuration %u (%s)\n", p, count++,
! 1830: fit_get_name(fit, noffset, NULL));
! 1831:
! 1832: fit_conf_print (fit, noffset, p);
! 1833: }
! 1834: }
! 1835: }
! 1836:
! 1837: /**
! 1838: * fit_image_print - prints out the FIT component image details
! 1839: * @fit: pointer to the FIT format image header
! 1840: * @image_noffset: offset of the component image node
! 1841: * @p: pointer to prefix string
! 1842: *
! 1843: * fit_image_print() lists all mandatory properies for the processed component
! 1844: * image. If present, hash nodes are printed out as well. Load
! 1845: * address for images of type firmware is also printed out. Since the load
! 1846: * address is not mandatory for firmware images, it will be output as
! 1847: * "unavailable" when not present.
! 1848: *
! 1849: * returns:
! 1850: * no returned results
! 1851: */
! 1852: void fit_image_print (const void *fit, int image_noffset, const char *p)
! 1853: {
! 1854: char *desc;
! 1855: uint8_t type, arch, os, comp;
! 1856: size_t size;
! 1857: ulong load, entry;
! 1858: const void *data;
! 1859: int noffset;
! 1860: int ndepth;
! 1861: int ret;
! 1862:
! 1863: /* Mandatory properties */
! 1864: ret = fit_get_desc (fit, image_noffset, &desc);
! 1865: printf ("%s Description: ", p);
! 1866: if (ret)
! 1867: printf ("unavailable\n");
! 1868: else
! 1869: printf ("%s\n", desc);
! 1870:
! 1871: fit_image_get_type (fit, image_noffset, &type);
! 1872: printf ("%s Type: %s\n", p, genimg_get_type_name (type));
! 1873:
! 1874: fit_image_get_comp (fit, image_noffset, &comp);
! 1875: printf ("%s Compression: %s\n", p, genimg_get_comp_name (comp));
! 1876:
! 1877: ret = fit_image_get_data (fit, image_noffset, &data, &size);
! 1878:
! 1879: #ifndef USE_HOSTCC
! 1880: printf ("%s Data Start: ", p);
! 1881: if (ret)
! 1882: printf ("unavailable\n");
! 1883: else
! 1884: printf ("0x%08lx\n", (ulong)data);
! 1885: #endif
! 1886:
! 1887: printf ("%s Data Size: ", p);
! 1888: if (ret)
! 1889: printf ("unavailable\n");
! 1890: else
! 1891: genimg_print_size (size);
! 1892:
! 1893: /* Remaining, type dependent properties */
! 1894: if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
! 1895: (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
! 1896: (type == IH_TYPE_FLATDT)) {
! 1897: fit_image_get_arch (fit, image_noffset, &arch);
! 1898: printf ("%s Architecture: %s\n", p, genimg_get_arch_name (arch));
! 1899: }
! 1900:
! 1901: if (type == IH_TYPE_KERNEL) {
! 1902: fit_image_get_os (fit, image_noffset, &os);
! 1903: printf ("%s OS: %s\n", p, genimg_get_os_name (os));
! 1904: }
! 1905:
! 1906: if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
! 1907: (type == IH_TYPE_FIRMWARE)) {
! 1908: ret = fit_image_get_load (fit, image_noffset, &load);
! 1909: printf ("%s Load Address: ", p);
! 1910: if (ret)
! 1911: printf ("unavailable\n");
! 1912: else
! 1913: printf ("0x%08lx\n", load);
! 1914: }
! 1915:
! 1916: if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE)) {
! 1917: fit_image_get_entry (fit, image_noffset, &entry);
! 1918: printf ("%s Entry Point: ", p);
! 1919: if (ret)
! 1920: printf ("unavailable\n");
! 1921: else
! 1922: printf ("0x%08lx\n", entry);
! 1923: }
! 1924:
! 1925: /* Process all hash subnodes of the component image node */
! 1926: for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
! 1927: (noffset >= 0) && (ndepth > 0);
! 1928: noffset = fdt_next_node (fit, noffset, &ndepth)) {
! 1929: if (ndepth == 1) {
! 1930: /* Direct child node of the component image node */
! 1931: fit_image_print_hash (fit, noffset, p);
! 1932: }
! 1933: }
! 1934: }
! 1935:
! 1936: /**
! 1937: * fit_image_print_hash - prints out the hash node details
! 1938: * @fit: pointer to the FIT format image header
! 1939: * @noffset: offset of the hash node
! 1940: * @p: pointer to prefix string
! 1941: *
! 1942: * fit_image_print_hash() lists properies for the processed hash node
! 1943: *
! 1944: * returns:
! 1945: * no returned results
! 1946: */
! 1947: void fit_image_print_hash (const void *fit, int noffset, const char *p)
! 1948: {
! 1949: char *algo;
! 1950: uint8_t *value;
! 1951: int value_len;
! 1952: int i, ret;
! 1953:
! 1954: /*
! 1955: * Check subnode name, must be equal to "hash".
! 1956: * Multiple hash nodes require unique unit node
! 1957: * names, e.g. hash@1, hash@2, etc.
! 1958: */
! 1959: if (strncmp (fit_get_name(fit, noffset, NULL),
! 1960: FIT_HASH_NODENAME,
! 1961: strlen(FIT_HASH_NODENAME)) != 0)
! 1962: return;
! 1963:
! 1964: debug ("%s Hash node: '%s'\n", p,
! 1965: fit_get_name (fit, noffset, NULL));
! 1966:
! 1967: printf ("%s Hash algo: ", p);
! 1968: if (fit_image_hash_get_algo (fit, noffset, &algo)) {
! 1969: printf ("invalid/unsupported\n");
! 1970: return;
! 1971: }
! 1972: printf ("%s\n", algo);
! 1973:
! 1974: ret = fit_image_hash_get_value (fit, noffset, &value,
! 1975: &value_len);
! 1976: printf ("%s Hash value: ", p);
! 1977: if (ret) {
! 1978: printf ("unavailable\n");
! 1979: } else {
! 1980: for (i = 0; i < value_len; i++)
! 1981: printf ("%02x", value[i]);
! 1982: printf ("\n");
! 1983: }
! 1984:
! 1985: debug ("%s Hash len: %d\n", p, value_len);
! 1986: }
! 1987:
! 1988: /**
! 1989: * fit_get_desc - get node description property
! 1990: * @fit: pointer to the FIT format image header
! 1991: * @noffset: node offset
! 1992: * @desc: double pointer to the char, will hold pointer to the descrption
! 1993: *
! 1994: * fit_get_desc() reads description property from a given node, if
! 1995: * description is found pointer to it is returened in third call argument.
! 1996: *
! 1997: * returns:
! 1998: * 0, on success
! 1999: * -1, on failure
! 2000: */
! 2001: int fit_get_desc (const void *fit, int noffset, char **desc)
! 2002: {
! 2003: int len;
! 2004:
! 2005: *desc = (char *)fdt_getprop (fit, noffset, FIT_DESC_PROP, &len);
! 2006: if (*desc == NULL) {
! 2007: fit_get_debug (fit, noffset, FIT_DESC_PROP, len);
! 2008: return -1;
! 2009: }
! 2010:
! 2011: return 0;
! 2012: }
! 2013:
! 2014: /**
! 2015: * fit_get_timestamp - get node timestamp property
! 2016: * @fit: pointer to the FIT format image header
! 2017: * @noffset: node offset
! 2018: * @timestamp: pointer to the time_t, will hold read timestamp
! 2019: *
! 2020: * fit_get_timestamp() reads timestamp poperty from given node, if timestamp
! 2021: * is found and has a correct size its value is retured in third call
! 2022: * argument.
! 2023: *
! 2024: * returns:
! 2025: * 0, on success
! 2026: * -1, on property read failure
! 2027: * -2, on wrong timestamp size
! 2028: */
! 2029: int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp)
! 2030: {
! 2031: int len;
! 2032: const void *data;
! 2033:
! 2034: data = fdt_getprop (fit, noffset, FIT_TIMESTAMP_PROP, &len);
! 2035: if (data == NULL) {
! 2036: fit_get_debug (fit, noffset, FIT_TIMESTAMP_PROP, len);
! 2037: return -1;
! 2038: }
! 2039: if (len != sizeof (uint32_t)) {
! 2040: debug ("FIT timestamp with incorrect size of (%u)\n", len);
! 2041: return -2;
! 2042: }
! 2043:
! 2044: *timestamp = uimage_to_cpu (*((uint32_t *)data));
! 2045: return 0;
! 2046: }
! 2047:
! 2048: /**
! 2049: * fit_image_get_node - get node offset for component image of a given unit name
! 2050: * @fit: pointer to the FIT format image header
! 2051: * @image_uname: component image node unit name
! 2052: *
! 2053: * fit_image_get_node() finds a component image (withing the '/images'
! 2054: * node) of a provided unit name. If image is found its node offset is
! 2055: * returned to the caller.
! 2056: *
! 2057: * returns:
! 2058: * image node offset when found (>=0)
! 2059: * negative number on failure (FDT_ERR_* code)
! 2060: */
! 2061: int fit_image_get_node (const void *fit, const char *image_uname)
! 2062: {
! 2063: int noffset, images_noffset;
! 2064:
! 2065: images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
! 2066: if (images_noffset < 0) {
! 2067: debug ("Can't find images parent node '%s' (%s)\n",
! 2068: FIT_IMAGES_PATH, fdt_strerror (images_noffset));
! 2069: return images_noffset;
! 2070: }
! 2071:
! 2072: noffset = fdt_subnode_offset (fit, images_noffset, image_uname);
! 2073: if (noffset < 0) {
! 2074: debug ("Can't get node offset for image unit name: '%s' (%s)\n",
! 2075: image_uname, fdt_strerror (noffset));
! 2076: }
! 2077:
! 2078: return noffset;
! 2079: }
! 2080:
! 2081: /**
! 2082: * fit_image_get_os - get os id for a given component image node
! 2083: * @fit: pointer to the FIT format image header
! 2084: * @noffset: component image node offset
! 2085: * @os: pointer to the uint8_t, will hold os numeric id
! 2086: *
! 2087: * fit_image_get_os() finds os property in a given component image node.
! 2088: * If the property is found, its (string) value is translated to the numeric
! 2089: * id which is returned to the caller.
! 2090: *
! 2091: * returns:
! 2092: * 0, on success
! 2093: * -1, on failure
! 2094: */
! 2095: int fit_image_get_os (const void *fit, int noffset, uint8_t *os)
! 2096: {
! 2097: int len;
! 2098: const void *data;
! 2099:
! 2100: /* Get OS name from property data */
! 2101: data = fdt_getprop (fit, noffset, FIT_OS_PROP, &len);
! 2102: if (data == NULL) {
! 2103: fit_get_debug (fit, noffset, FIT_OS_PROP, len);
! 2104: *os = -1;
! 2105: return -1;
! 2106: }
! 2107:
! 2108: /* Translate OS name to id */
! 2109: *os = genimg_get_os_id (data);
! 2110: return 0;
! 2111: }
! 2112:
! 2113: /**
! 2114: * fit_image_get_arch - get arch id for a given component image node
! 2115: * @fit: pointer to the FIT format image header
! 2116: * @noffset: component image node offset
! 2117: * @arch: pointer to the uint8_t, will hold arch numeric id
! 2118: *
! 2119: * fit_image_get_arch() finds arch property in a given component image node.
! 2120: * If the property is found, its (string) value is translated to the numeric
! 2121: * id which is returned to the caller.
! 2122: *
! 2123: * returns:
! 2124: * 0, on success
! 2125: * -1, on failure
! 2126: */
! 2127: int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch)
! 2128: {
! 2129: int len;
! 2130: const void *data;
! 2131:
! 2132: /* Get architecture name from property data */
! 2133: data = fdt_getprop (fit, noffset, FIT_ARCH_PROP, &len);
! 2134: if (data == NULL) {
! 2135: fit_get_debug (fit, noffset, FIT_ARCH_PROP, len);
! 2136: *arch = -1;
! 2137: return -1;
! 2138: }
! 2139:
! 2140: /* Translate architecture name to id */
! 2141: *arch = genimg_get_arch_id (data);
! 2142: return 0;
! 2143: }
! 2144:
! 2145: /**
! 2146: * fit_image_get_type - get type id for a given component image node
! 2147: * @fit: pointer to the FIT format image header
! 2148: * @noffset: component image node offset
! 2149: * @type: pointer to the uint8_t, will hold type numeric id
! 2150: *
! 2151: * fit_image_get_type() finds type property in a given component image node.
! 2152: * If the property is found, its (string) value is translated to the numeric
! 2153: * id which is returned to the caller.
! 2154: *
! 2155: * returns:
! 2156: * 0, on success
! 2157: * -1, on failure
! 2158: */
! 2159: int fit_image_get_type (const void *fit, int noffset, uint8_t *type)
! 2160: {
! 2161: int len;
! 2162: const void *data;
! 2163:
! 2164: /* Get image type name from property data */
! 2165: data = fdt_getprop (fit, noffset, FIT_TYPE_PROP, &len);
! 2166: if (data == NULL) {
! 2167: fit_get_debug (fit, noffset, FIT_TYPE_PROP, len);
! 2168: *type = -1;
! 2169: return -1;
! 2170: }
! 2171:
! 2172: /* Translate image type name to id */
! 2173: *type = genimg_get_type_id (data);
! 2174: return 0;
! 2175: }
! 2176:
! 2177: /**
! 2178: * fit_image_get_comp - get comp id for a given component image node
! 2179: * @fit: pointer to the FIT format image header
! 2180: * @noffset: component image node offset
! 2181: * @comp: pointer to the uint8_t, will hold comp numeric id
! 2182: *
! 2183: * fit_image_get_comp() finds comp property in a given component image node.
! 2184: * If the property is found, its (string) value is translated to the numeric
! 2185: * id which is returned to the caller.
! 2186: *
! 2187: * returns:
! 2188: * 0, on success
! 2189: * -1, on failure
! 2190: */
! 2191: int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp)
! 2192: {
! 2193: int len;
! 2194: const void *data;
! 2195:
! 2196: /* Get compression name from property data */
! 2197: data = fdt_getprop (fit, noffset, FIT_COMP_PROP, &len);
! 2198: if (data == NULL) {
! 2199: fit_get_debug (fit, noffset, FIT_COMP_PROP, len);
! 2200: *comp = -1;
! 2201: return -1;
! 2202: }
! 2203:
! 2204: /* Translate compression name to id */
! 2205: *comp = genimg_get_comp_id (data);
! 2206: return 0;
! 2207: }
! 2208:
! 2209: /**
! 2210: * fit_image_get_load - get load address property for a given component image node
! 2211: * @fit: pointer to the FIT format image header
! 2212: * @noffset: component image node offset
! 2213: * @load: pointer to the uint32_t, will hold load address
! 2214: *
! 2215: * fit_image_get_load() finds load address property in a given component image node.
! 2216: * If the property is found, its value is returned to the caller.
! 2217: *
! 2218: * returns:
! 2219: * 0, on success
! 2220: * -1, on failure
! 2221: */
! 2222: int fit_image_get_load (const void *fit, int noffset, ulong *load)
! 2223: {
! 2224: int len;
! 2225: const uint32_t *data;
! 2226:
! 2227: data = fdt_getprop (fit, noffset, FIT_LOAD_PROP, &len);
! 2228: if (data == NULL) {
! 2229: fit_get_debug (fit, noffset, FIT_LOAD_PROP, len);
! 2230: return -1;
! 2231: }
! 2232:
! 2233: *load = uimage_to_cpu (*data);
! 2234: return 0;
! 2235: }
! 2236:
! 2237: /**
! 2238: * fit_image_get_entry - get entry point address property for a given component image node
! 2239: * @fit: pointer to the FIT format image header
! 2240: * @noffset: component image node offset
! 2241: * @entry: pointer to the uint32_t, will hold entry point address
! 2242: *
! 2243: * fit_image_get_entry() finds entry point address property in a given component image node.
! 2244: * If the property is found, its value is returned to the caller.
! 2245: *
! 2246: * returns:
! 2247: * 0, on success
! 2248: * -1, on failure
! 2249: */
! 2250: int fit_image_get_entry (const void *fit, int noffset, ulong *entry)
! 2251: {
! 2252: int len;
! 2253: const uint32_t *data;
! 2254:
! 2255: data = fdt_getprop (fit, noffset, FIT_ENTRY_PROP, &len);
! 2256: if (data == NULL) {
! 2257: fit_get_debug (fit, noffset, FIT_ENTRY_PROP, len);
! 2258: return -1;
! 2259: }
! 2260:
! 2261: *entry = uimage_to_cpu (*data);
! 2262: return 0;
! 2263: }
! 2264:
! 2265: /**
! 2266: * fit_image_get_data - get data property and its size for a given component image node
! 2267: * @fit: pointer to the FIT format image header
! 2268: * @noffset: component image node offset
! 2269: * @data: double pointer to void, will hold data property's data address
! 2270: * @size: pointer to size_t, will hold data property's data size
! 2271: *
! 2272: * fit_image_get_data() finds data property in a given component image node.
! 2273: * If the property is found its data start address and size are returned to
! 2274: * the caller.
! 2275: *
! 2276: * returns:
! 2277: * 0, on success
! 2278: * -1, on failure
! 2279: */
! 2280: int fit_image_get_data (const void *fit, int noffset,
! 2281: const void **data, size_t *size)
! 2282: {
! 2283: int len;
! 2284:
! 2285: *data = fdt_getprop (fit, noffset, FIT_DATA_PROP, &len);
! 2286: if (*data == NULL) {
! 2287: fit_get_debug (fit, noffset, FIT_DATA_PROP, len);
! 2288: *size = 0;
! 2289: return -1;
! 2290: }
! 2291:
! 2292: *size = len;
! 2293: return 0;
! 2294: }
! 2295:
! 2296: /**
! 2297: * fit_image_hash_get_algo - get hash algorithm name
! 2298: * @fit: pointer to the FIT format image header
! 2299: * @noffset: hash node offset
! 2300: * @algo: double pointer to char, will hold pointer to the algorithm name
! 2301: *
! 2302: * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
! 2303: * If the property is found its data start address is returned to the caller.
! 2304: *
! 2305: * returns:
! 2306: * 0, on success
! 2307: * -1, on failure
! 2308: */
! 2309: int fit_image_hash_get_algo (const void *fit, int noffset, char **algo)
! 2310: {
! 2311: int len;
! 2312:
! 2313: *algo = (char *)fdt_getprop (fit, noffset, FIT_ALGO_PROP, &len);
! 2314: if (*algo == NULL) {
! 2315: fit_get_debug (fit, noffset, FIT_ALGO_PROP, len);
! 2316: return -1;
! 2317: }
! 2318:
! 2319: return 0;
! 2320: }
! 2321:
! 2322: /**
! 2323: * fit_image_hash_get_value - get hash value and length
! 2324: * @fit: pointer to the FIT format image header
! 2325: * @noffset: hash node offset
! 2326: * @value: double pointer to uint8_t, will hold address of a hash value data
! 2327: * @value_len: pointer to an int, will hold hash data length
! 2328: *
! 2329: * fit_image_hash_get_value() finds hash value property in a given hash node.
! 2330: * If the property is found its data start address and size are returned to
! 2331: * the caller.
! 2332: *
! 2333: * returns:
! 2334: * 0, on success
! 2335: * -1, on failure
! 2336: */
! 2337: int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value,
! 2338: int *value_len)
! 2339: {
! 2340: int len;
! 2341:
! 2342: *value = (uint8_t *)fdt_getprop (fit, noffset, FIT_VALUE_PROP, &len);
! 2343: if (*value == NULL) {
! 2344: fit_get_debug (fit, noffset, FIT_VALUE_PROP, len);
! 2345: *value_len = 0;
! 2346: return -1;
! 2347: }
! 2348:
! 2349: *value_len = len;
! 2350: return 0;
! 2351: }
! 2352:
! 2353: /**
! 2354: * fit_set_timestamp - set node timestamp property
! 2355: * @fit: pointer to the FIT format image header
! 2356: * @noffset: node offset
! 2357: * @timestamp: timestamp value to be set
! 2358: *
! 2359: * fit_set_timestamp() attempts to set timestamp property in the requested
! 2360: * node and returns operation status to the caller.
! 2361: *
! 2362: * returns:
! 2363: * 0, on success
! 2364: * -1, on property read failure
! 2365: */
! 2366: int fit_set_timestamp (void *fit, int noffset, time_t timestamp)
! 2367: {
! 2368: uint32_t t;
! 2369: int ret;
! 2370:
! 2371: t = cpu_to_uimage (timestamp);
! 2372: ret = fdt_setprop (fit, noffset, FIT_TIMESTAMP_PROP, &t,
! 2373: sizeof (uint32_t));
! 2374: if (ret) {
! 2375: printf ("Can't set '%s' property for '%s' node (%s)\n",
! 2376: FIT_TIMESTAMP_PROP, fit_get_name (fit, noffset, NULL),
! 2377: fdt_strerror (ret));
! 2378: return -1;
! 2379: }
! 2380:
! 2381: return 0;
! 2382: }
! 2383:
! 2384: /**
! 2385: * calculate_hash - calculate and return hash for provided input data
! 2386: * @data: pointer to the input data
! 2387: * @data_len: data length
! 2388: * @algo: requested hash algorithm
! 2389: * @value: pointer to the char, will hold hash value data (caller must
! 2390: * allocate enough free space)
! 2391: * value_len: length of the calculated hash
! 2392: *
! 2393: * calculate_hash() computes input data hash according to the requested algorithm.
! 2394: * Resulting hash value is placed in caller provided 'value' buffer, length
! 2395: * of the calculated hash is returned via value_len pointer argument.
! 2396: *
! 2397: * returns:
! 2398: * 0, on success
! 2399: * -1, when algo is unsupported
! 2400: */
! 2401: static int calculate_hash (const void *data, int data_len, const char *algo,
! 2402: uint8_t *value, int *value_len)
! 2403: {
! 2404: if (strcmp (algo, "crc32") == 0 ) {
! 2405: *((uint32_t *)value) = crc32_wd (0, data, data_len,
! 2406: CHUNKSZ_CRC32);
! 2407: *((uint32_t *)value) = cpu_to_uimage (*((uint32_t *)value));
! 2408: *value_len = 4;
! 2409: } else if (strcmp (algo, "sha1") == 0 ) {
! 2410: sha1_csum_wd ((unsigned char *) data, data_len,
! 2411: (unsigned char *) value, CHUNKSZ_SHA1);
! 2412: *value_len = 20;
! 2413: } else if (strcmp (algo, "md5") == 0 ) {
! 2414: md5_wd ((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
! 2415: *value_len = 16;
! 2416: } else {
! 2417: debug ("Unsupported hash alogrithm\n");
! 2418: return -1;
! 2419: }
! 2420: return 0;
! 2421: }
! 2422:
! 2423: #ifdef USE_HOSTCC
! 2424: /**
! 2425: * fit_set_hashes - process FIT component image nodes and calculate hashes
! 2426: * @fit: pointer to the FIT format image header
! 2427: *
! 2428: * fit_set_hashes() adds hash values for all component images in the FIT blob.
! 2429: * Hashes are calculated for all component images which have hash subnodes
! 2430: * with algorithm property set to one of the supported hash algorithms.
! 2431: *
! 2432: * returns
! 2433: * 0, on success
! 2434: * libfdt error code, on failure
! 2435: */
! 2436: int fit_set_hashes (void *fit)
! 2437: {
! 2438: int images_noffset;
! 2439: int noffset;
! 2440: int ndepth;
! 2441: int ret;
! 2442:
! 2443: /* Find images parent node offset */
! 2444: images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
! 2445: if (images_noffset < 0) {
! 2446: printf ("Can't find images parent node '%s' (%s)\n",
! 2447: FIT_IMAGES_PATH, fdt_strerror (images_noffset));
! 2448: return images_noffset;
! 2449: }
! 2450:
! 2451: /* Process its subnodes, print out component images details */
! 2452: for (ndepth = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);
! 2453: (noffset >= 0) && (ndepth > 0);
! 2454: noffset = fdt_next_node (fit, noffset, &ndepth)) {
! 2455: if (ndepth == 1) {
! 2456: /*
! 2457: * Direct child node of the images parent node,
! 2458: * i.e. component image node.
! 2459: */
! 2460: ret = fit_image_set_hashes (fit, noffset);
! 2461: if (ret)
! 2462: return ret;
! 2463: }
! 2464: }
! 2465:
! 2466: return 0;
! 2467: }
! 2468:
! 2469: /**
! 2470: * fit_image_set_hashes - calculate/set hashes for given component image node
! 2471: * @fit: pointer to the FIT format image header
! 2472: * @image_noffset: requested component image node
! 2473: *
! 2474: * fit_image_set_hashes() adds hash values for an component image node. All
! 2475: * existing hash subnodes are checked, if algorithm property is set to one of
! 2476: * the supported hash algorithms, hash value is computed and corresponding
! 2477: * hash node property is set, for example:
! 2478: *
! 2479: * Input component image node structure:
! 2480: *
! 2481: * o image@1 (at image_noffset)
! 2482: * | - data = [binary data]
! 2483: * o hash@1
! 2484: * |- algo = "sha1"
! 2485: *
! 2486: * Output component image node structure:
! 2487: *
! 2488: * o image@1 (at image_noffset)
! 2489: * | - data = [binary data]
! 2490: * o hash@1
! 2491: * |- algo = "sha1"
! 2492: * |- value = sha1(data)
! 2493: *
! 2494: * returns:
! 2495: * 0 on sucess
! 2496: * <0 on failure
! 2497: */
! 2498: int fit_image_set_hashes (void *fit, int image_noffset)
! 2499: {
! 2500: const void *data;
! 2501: size_t size;
! 2502: char *algo;
! 2503: uint8_t value[FIT_MAX_HASH_LEN];
! 2504: int value_len;
! 2505: int noffset;
! 2506: int ndepth;
! 2507:
! 2508: /* Get image data and data length */
! 2509: if (fit_image_get_data (fit, image_noffset, &data, &size)) {
! 2510: printf ("Can't get image data/size\n");
! 2511: return -1;
! 2512: }
! 2513:
! 2514: /* Process all hash subnodes of the component image node */
! 2515: for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
! 2516: (noffset >= 0) && (ndepth > 0);
! 2517: noffset = fdt_next_node (fit, noffset, &ndepth)) {
! 2518: if (ndepth == 1) {
! 2519: /* Direct child node of the component image node */
! 2520:
! 2521: /*
! 2522: * Check subnode name, must be equal to "hash".
! 2523: * Multiple hash nodes require unique unit node
! 2524: * names, e.g. hash@1, hash@2, etc.
! 2525: */
! 2526: if (strncmp (fit_get_name(fit, noffset, NULL),
! 2527: FIT_HASH_NODENAME,
! 2528: strlen(FIT_HASH_NODENAME)) != 0) {
! 2529: /* Not a hash subnode, skip it */
! 2530: continue;
! 2531: }
! 2532:
! 2533: if (fit_image_hash_get_algo (fit, noffset, &algo)) {
! 2534: printf ("Can't get hash algo property for "
! 2535: "'%s' hash node in '%s' image node\n",
! 2536: fit_get_name (fit, noffset, NULL),
! 2537: fit_get_name (fit, image_noffset, NULL));
! 2538: return -1;
! 2539: }
! 2540:
! 2541: if (calculate_hash (data, size, algo, value, &value_len)) {
! 2542: printf ("Unsupported hash algorithm (%s) for "
! 2543: "'%s' hash node in '%s' image node\n",
! 2544: algo, fit_get_name (fit, noffset, NULL),
! 2545: fit_get_name (fit, image_noffset, NULL));
! 2546: return -1;
! 2547: }
! 2548:
! 2549: if (fit_image_hash_set_value (fit, noffset, value,
! 2550: value_len)) {
! 2551: printf ("Can't set hash value for "
! 2552: "'%s' hash node in '%s' image node\n",
! 2553: fit_get_name (fit, noffset, NULL),
! 2554: fit_get_name (fit, image_noffset, NULL));
! 2555: return -1;
! 2556: }
! 2557: }
! 2558: }
! 2559:
! 2560: return 0;
! 2561: }
! 2562:
! 2563: /**
! 2564: * fit_image_hash_set_value - set hash value in requested has node
! 2565: * @fit: pointer to the FIT format image header
! 2566: * @noffset: hash node offset
! 2567: * @value: hash value to be set
! 2568: * @value_len: hash value length
! 2569: *
! 2570: * fit_image_hash_set_value() attempts to set hash value in a node at offset
! 2571: * given and returns operation status to the caller.
! 2572: *
! 2573: * returns
! 2574: * 0, on success
! 2575: * -1, on failure
! 2576: */
! 2577: int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value,
! 2578: int value_len)
! 2579: {
! 2580: int ret;
! 2581:
! 2582: ret = fdt_setprop (fit, noffset, FIT_VALUE_PROP, value, value_len);
! 2583: if (ret) {
! 2584: printf ("Can't set hash '%s' property for '%s' node (%s)\n",
! 2585: FIT_VALUE_PROP, fit_get_name (fit, noffset, NULL),
! 2586: fdt_strerror (ret));
! 2587: return -1;
! 2588: }
! 2589:
! 2590: return 0;
! 2591: }
! 2592: #endif /* USE_HOSTCC */
! 2593:
! 2594: /**
! 2595: * fit_image_check_hashes - verify data intergity
! 2596: * @fit: pointer to the FIT format image header
! 2597: * @image_noffset: component image node offset
! 2598: *
! 2599: * fit_image_check_hashes() goes over component image hash nodes,
! 2600: * re-calculates each data hash and compares with the value stored in hash
! 2601: * node.
! 2602: *
! 2603: * returns:
! 2604: * 1, if all hashes are valid
! 2605: * 0, otherwise (or on error)
! 2606: */
! 2607: int fit_image_check_hashes (const void *fit, int image_noffset)
! 2608: {
! 2609: const void *data;
! 2610: size_t size;
! 2611: char *algo;
! 2612: uint8_t *fit_value;
! 2613: int fit_value_len;
! 2614: uint8_t value[FIT_MAX_HASH_LEN];
! 2615: int value_len;
! 2616: int noffset;
! 2617: int ndepth;
! 2618: char *err_msg = "";
! 2619:
! 2620: /* Get image data and data length */
! 2621: if (fit_image_get_data (fit, image_noffset, &data, &size)) {
! 2622: printf ("Can't get image data/size\n");
! 2623: return 0;
! 2624: }
! 2625:
! 2626: /* Process all hash subnodes of the component image node */
! 2627: for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
! 2628: (noffset >= 0) && (ndepth > 0);
! 2629: noffset = fdt_next_node (fit, noffset, &ndepth)) {
! 2630: if (ndepth == 1) {
! 2631: /* Direct child node of the component image node */
! 2632:
! 2633: /*
! 2634: * Check subnode name, must be equal to "hash".
! 2635: * Multiple hash nodes require unique unit node
! 2636: * names, e.g. hash@1, hash@2, etc.
! 2637: */
! 2638: if (strncmp (fit_get_name(fit, noffset, NULL),
! 2639: FIT_HASH_NODENAME,
! 2640: strlen(FIT_HASH_NODENAME)) != 0)
! 2641: continue;
! 2642:
! 2643: if (fit_image_hash_get_algo (fit, noffset, &algo)) {
! 2644: err_msg = " error!\nCan't get hash algo "
! 2645: "property";
! 2646: goto error;
! 2647: }
! 2648: printf ("%s", algo);
! 2649:
! 2650: if (fit_image_hash_get_value (fit, noffset, &fit_value,
! 2651: &fit_value_len)) {
! 2652: err_msg = " error!\nCan't get hash value "
! 2653: "property";
! 2654: goto error;
! 2655: }
! 2656:
! 2657: if (calculate_hash (data, size, algo, value, &value_len)) {
! 2658: err_msg = " error!\nUnsupported hash algorithm";
! 2659: goto error;
! 2660: }
! 2661:
! 2662: if (value_len != fit_value_len) {
! 2663: err_msg = " error !\nBad hash value len";
! 2664: goto error;
! 2665: } else if (memcmp (value, fit_value, value_len) != 0) {
! 2666: err_msg = " error!\nBad hash value";
! 2667: goto error;
! 2668: }
! 2669: printf ("+ ");
! 2670: }
! 2671: }
! 2672:
! 2673: return 1;
! 2674:
! 2675: error:
! 2676: printf ("%s for '%s' hash node in '%s' image node\n",
! 2677: err_msg, fit_get_name (fit, noffset, NULL),
! 2678: fit_get_name (fit, image_noffset, NULL));
! 2679: return 0;
! 2680: }
! 2681:
! 2682: /**
! 2683: * fit_all_image_check_hashes - verify data intergity for all images
! 2684: * @fit: pointer to the FIT format image header
! 2685: *
! 2686: * fit_all_image_check_hashes() goes over all images in the FIT and
! 2687: * for every images checks if all it's hashes are valid.
! 2688: *
! 2689: * returns:
! 2690: * 1, if all hashes of all images are valid
! 2691: * 0, otherwise (or on error)
! 2692: */
! 2693: int fit_all_image_check_hashes (const void *fit)
! 2694: {
! 2695: int images_noffset;
! 2696: int noffset;
! 2697: int ndepth;
! 2698: int count;
! 2699:
! 2700: /* Find images parent node offset */
! 2701: images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
! 2702: if (images_noffset < 0) {
! 2703: printf ("Can't find images parent node '%s' (%s)\n",
! 2704: FIT_IMAGES_PATH, fdt_strerror (images_noffset));
! 2705: return 0;
! 2706: }
! 2707:
! 2708: /* Process all image subnodes, check hashes for each */
! 2709: printf ("## Checking hash(es) for FIT Image at %08lx ...\n",
! 2710: (ulong)fit);
! 2711: for (ndepth = 0, count = 0,
! 2712: noffset = fdt_next_node (fit, images_noffset, &ndepth);
! 2713: (noffset >= 0) && (ndepth > 0);
! 2714: noffset = fdt_next_node (fit, noffset, &ndepth)) {
! 2715: if (ndepth == 1) {
! 2716: /*
! 2717: * Direct child node of the images parent node,
! 2718: * i.e. component image node.
! 2719: */
! 2720: printf (" Hash(es) for Image %u (%s): ", count++,
! 2721: fit_get_name (fit, noffset, NULL));
! 2722:
! 2723: if (!fit_image_check_hashes (fit, noffset))
! 2724: return 0;
! 2725: printf ("\n");
! 2726: }
! 2727: }
! 2728: return 1;
! 2729: }
! 2730:
! 2731: /**
! 2732: * fit_image_check_os - check whether image node is of a given os type
! 2733: * @fit: pointer to the FIT format image header
! 2734: * @noffset: component image node offset
! 2735: * @os: requested image os
! 2736: *
! 2737: * fit_image_check_os() reads image os property and compares its numeric
! 2738: * id with the requested os. Comparison result is returned to the caller.
! 2739: *
! 2740: * returns:
! 2741: * 1 if image is of given os type
! 2742: * 0 otherwise (or on error)
! 2743: */
! 2744: int fit_image_check_os (const void *fit, int noffset, uint8_t os)
! 2745: {
! 2746: uint8_t image_os;
! 2747:
! 2748: if (fit_image_get_os (fit, noffset, &image_os))
! 2749: return 0;
! 2750: return (os == image_os);
! 2751: }
! 2752:
! 2753: /**
! 2754: * fit_image_check_arch - check whether image node is of a given arch
! 2755: * @fit: pointer to the FIT format image header
! 2756: * @noffset: component image node offset
! 2757: * @arch: requested imagearch
! 2758: *
! 2759: * fit_image_check_arch() reads image arch property and compares its numeric
! 2760: * id with the requested arch. Comparison result is returned to the caller.
! 2761: *
! 2762: * returns:
! 2763: * 1 if image is of given arch
! 2764: * 0 otherwise (or on error)
! 2765: */
! 2766: int fit_image_check_arch (const void *fit, int noffset, uint8_t arch)
! 2767: {
! 2768: uint8_t image_arch;
! 2769:
! 2770: if (fit_image_get_arch (fit, noffset, &image_arch))
! 2771: return 0;
! 2772: return (arch == image_arch);
! 2773: }
! 2774:
! 2775: /**
! 2776: * fit_image_check_type - check whether image node is of a given type
! 2777: * @fit: pointer to the FIT format image header
! 2778: * @noffset: component image node offset
! 2779: * @type: requested image type
! 2780: *
! 2781: * fit_image_check_type() reads image type property and compares its numeric
! 2782: * id with the requested type. Comparison result is returned to the caller.
! 2783: *
! 2784: * returns:
! 2785: * 1 if image is of given type
! 2786: * 0 otherwise (or on error)
! 2787: */
! 2788: int fit_image_check_type (const void *fit, int noffset, uint8_t type)
! 2789: {
! 2790: uint8_t image_type;
! 2791:
! 2792: if (fit_image_get_type (fit, noffset, &image_type))
! 2793: return 0;
! 2794: return (type == image_type);
! 2795: }
! 2796:
! 2797: /**
! 2798: * fit_image_check_comp - check whether image node uses given compression
! 2799: * @fit: pointer to the FIT format image header
! 2800: * @noffset: component image node offset
! 2801: * @comp: requested image compression type
! 2802: *
! 2803: * fit_image_check_comp() reads image compression property and compares its
! 2804: * numeric id with the requested compression type. Comparison result is
! 2805: * returned to the caller.
! 2806: *
! 2807: * returns:
! 2808: * 1 if image uses requested compression
! 2809: * 0 otherwise (or on error)
! 2810: */
! 2811: int fit_image_check_comp (const void *fit, int noffset, uint8_t comp)
! 2812: {
! 2813: uint8_t image_comp;
! 2814:
! 2815: if (fit_image_get_comp (fit, noffset, &image_comp))
! 2816: return 0;
! 2817: return (comp == image_comp);
! 2818: }
! 2819:
! 2820: /**
! 2821: * fit_check_format - sanity check FIT image format
! 2822: * @fit: pointer to the FIT format image header
! 2823: *
! 2824: * fit_check_format() runs a basic sanity FIT image verification.
! 2825: * Routine checks for mandatory properties, nodes, etc.
! 2826: *
! 2827: * returns:
! 2828: * 1, on success
! 2829: * 0, on failure
! 2830: */
! 2831: int fit_check_format (const void *fit)
! 2832: {
! 2833: /* mandatory / node 'description' property */
! 2834: if (fdt_getprop (fit, 0, FIT_DESC_PROP, NULL) == NULL) {
! 2835: debug ("Wrong FIT format: no description\n");
! 2836: return 0;
! 2837: }
! 2838:
! 2839: #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
! 2840: /* mandatory / node 'timestamp' property */
! 2841: if (fdt_getprop (fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) {
! 2842: debug ("Wrong FIT format: no timestamp\n");
! 2843: return 0;
! 2844: }
! 2845: #endif
! 2846:
! 2847: /* mandatory subimages parent '/images' node */
! 2848: if (fdt_path_offset (fit, FIT_IMAGES_PATH) < 0) {
! 2849: debug ("Wrong FIT format: no images parent node\n");
! 2850: return 0;
! 2851: }
! 2852:
! 2853: return 1;
! 2854: }
! 2855:
! 2856: /**
! 2857: * fit_conf_get_node - get node offset for configuration of a given unit name
! 2858: * @fit: pointer to the FIT format image header
! 2859: * @conf_uname: configuration node unit name
! 2860: *
! 2861: * fit_conf_get_node() finds a configuration (withing the '/configurations'
! 2862: * parant node) of a provided unit name. If configuration is found its node offset
! 2863: * is returned to the caller.
! 2864: *
! 2865: * When NULL is provided in second argument fit_conf_get_node() will search
! 2866: * for a default configuration node instead. Default configuration node unit name
! 2867: * is retrived from FIT_DEFAULT_PROP property of the '/configurations' node.
! 2868: *
! 2869: * returns:
! 2870: * configuration node offset when found (>=0)
! 2871: * negative number on failure (FDT_ERR_* code)
! 2872: */
! 2873: int fit_conf_get_node (const void *fit, const char *conf_uname)
! 2874: {
! 2875: int noffset, confs_noffset;
! 2876: int len;
! 2877:
! 2878: confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);
! 2879: if (confs_noffset < 0) {
! 2880: debug ("Can't find configurations parent node '%s' (%s)\n",
! 2881: FIT_CONFS_PATH, fdt_strerror (confs_noffset));
! 2882: return confs_noffset;
! 2883: }
! 2884:
! 2885: if (conf_uname == NULL) {
! 2886: /* get configuration unit name from the default property */
! 2887: debug ("No configuration specified, trying default...\n");
! 2888: conf_uname = (char *)fdt_getprop (fit, confs_noffset, FIT_DEFAULT_PROP, &len);
! 2889: if (conf_uname == NULL) {
! 2890: fit_get_debug (fit, confs_noffset, FIT_DEFAULT_PROP, len);
! 2891: return len;
! 2892: }
! 2893: debug ("Found default configuration: '%s'\n", conf_uname);
! 2894: }
! 2895:
! 2896: noffset = fdt_subnode_offset (fit, confs_noffset, conf_uname);
! 2897: if (noffset < 0) {
! 2898: debug ("Can't get node offset for configuration unit name: '%s' (%s)\n",
! 2899: conf_uname, fdt_strerror (noffset));
! 2900: }
! 2901:
! 2902: return noffset;
! 2903: }
! 2904:
! 2905: static int __fit_conf_get_prop_node (const void *fit, int noffset,
! 2906: const char *prop_name)
! 2907: {
! 2908: char *uname;
! 2909: int len;
! 2910:
! 2911: /* get kernel image unit name from configuration kernel property */
! 2912: uname = (char *)fdt_getprop (fit, noffset, prop_name, &len);
! 2913: if (uname == NULL)
! 2914: return len;
! 2915:
! 2916: return fit_image_get_node (fit, uname);
! 2917: }
! 2918:
! 2919: /**
! 2920: * fit_conf_get_kernel_node - get kernel image node offset that corresponds to
! 2921: * a given configuration
! 2922: * @fit: pointer to the FIT format image header
! 2923: * @noffset: configuration node offset
! 2924: *
! 2925: * fit_conf_get_kernel_node() retrives kernel image node unit name from
! 2926: * configuration FIT_KERNEL_PROP property and translates it to the node
! 2927: * offset.
! 2928: *
! 2929: * returns:
! 2930: * image node offset when found (>=0)
! 2931: * negative number on failure (FDT_ERR_* code)
! 2932: */
! 2933: int fit_conf_get_kernel_node (const void *fit, int noffset)
! 2934: {
! 2935: return __fit_conf_get_prop_node (fit, noffset, FIT_KERNEL_PROP);
! 2936: }
! 2937:
! 2938: /**
! 2939: * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to
! 2940: * a given configuration
! 2941: * @fit: pointer to the FIT format image header
! 2942: * @noffset: configuration node offset
! 2943: *
! 2944: * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from
! 2945: * configuration FIT_KERNEL_PROP property and translates it to the node
! 2946: * offset.
! 2947: *
! 2948: * returns:
! 2949: * image node offset when found (>=0)
! 2950: * negative number on failure (FDT_ERR_* code)
! 2951: */
! 2952: int fit_conf_get_ramdisk_node (const void *fit, int noffset)
! 2953: {
! 2954: return __fit_conf_get_prop_node (fit, noffset, FIT_RAMDISK_PROP);
! 2955: }
! 2956:
! 2957: /**
! 2958: * fit_conf_get_fdt_node - get fdt image node offset that corresponds to
! 2959: * a given configuration
! 2960: * @fit: pointer to the FIT format image header
! 2961: * @noffset: configuration node offset
! 2962: *
! 2963: * fit_conf_get_fdt_node() retrives fdt image node unit name from
! 2964: * configuration FIT_KERNEL_PROP property and translates it to the node
! 2965: * offset.
! 2966: *
! 2967: * returns:
! 2968: * image node offset when found (>=0)
! 2969: * negative number on failure (FDT_ERR_* code)
! 2970: */
! 2971: int fit_conf_get_fdt_node (const void *fit, int noffset)
! 2972: {
! 2973: return __fit_conf_get_prop_node (fit, noffset, FIT_FDT_PROP);
! 2974: }
! 2975:
! 2976: /**
! 2977: * fit_conf_print - prints out the FIT configuration details
! 2978: * @fit: pointer to the FIT format image header
! 2979: * @noffset: offset of the configuration node
! 2980: * @p: pointer to prefix string
! 2981: *
! 2982: * fit_conf_print() lists all mandatory properies for the processed
! 2983: * configuration node.
! 2984: *
! 2985: * returns:
! 2986: * no returned results
! 2987: */
! 2988: void fit_conf_print (const void *fit, int noffset, const char *p)
! 2989: {
! 2990: char *desc;
! 2991: char *uname;
! 2992: int ret;
! 2993:
! 2994: /* Mandatory properties */
! 2995: ret = fit_get_desc (fit, noffset, &desc);
! 2996: printf ("%s Description: ", p);
! 2997: if (ret)
! 2998: printf ("unavailable\n");
! 2999: else
! 3000: printf ("%s\n", desc);
! 3001:
! 3002: uname = (char *)fdt_getprop (fit, noffset, FIT_KERNEL_PROP, NULL);
! 3003: printf ("%s Kernel: ", p);
! 3004: if (uname == NULL)
! 3005: printf ("unavailable\n");
! 3006: else
! 3007: printf ("%s\n", uname);
! 3008:
! 3009: /* Optional properties */
! 3010: uname = (char *)fdt_getprop (fit, noffset, FIT_RAMDISK_PROP, NULL);
! 3011: if (uname)
! 3012: printf ("%s Init Ramdisk: %s\n", p, uname);
! 3013:
! 3014: uname = (char *)fdt_getprop (fit, noffset, FIT_FDT_PROP, NULL);
! 3015: if (uname)
! 3016: printf ("%s FDT: %s\n", p, uname);
! 3017: }
! 3018:
! 3019: /**
! 3020: * fit_check_ramdisk - verify FIT format ramdisk subimage
! 3021: * @fit_hdr: pointer to the FIT ramdisk header
! 3022: * @rd_noffset: ramdisk subimage node offset within FIT image
! 3023: * @arch: requested ramdisk image architecture type
! 3024: * @verify: data CRC verification flag
! 3025: *
! 3026: * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from
! 3027: * specified FIT image.
! 3028: *
! 3029: * returns:
! 3030: * 1, on success
! 3031: * 0, on failure
! 3032: */
! 3033: #ifndef USE_HOSTCC
! 3034: static int fit_check_ramdisk (const void *fit, int rd_noffset, uint8_t arch, int verify)
! 3035: {
! 3036: fit_image_print (fit, rd_noffset, " ");
! 3037:
! 3038: if (verify) {
! 3039: puts (" Verifying Hash Integrity ... ");
! 3040: if (!fit_image_check_hashes (fit, rd_noffset)) {
! 3041: puts ("Bad Data Hash\n");
! 3042: show_boot_progress (-125);
! 3043: return 0;
! 3044: }
! 3045: puts ("OK\n");
! 3046: }
! 3047:
! 3048: show_boot_progress (126);
! 3049: if (!fit_image_check_os (fit, rd_noffset, IH_OS_LINUX) ||
! 3050: !fit_image_check_arch (fit, rd_noffset, arch) ||
! 3051: !fit_image_check_type (fit, rd_noffset, IH_TYPE_RAMDISK)) {
! 3052: printf ("No Linux %s Ramdisk Image\n",
! 3053: genimg_get_arch_name(arch));
! 3054: show_boot_progress (-126);
! 3055: return 0;
! 3056: }
! 3057:
! 3058: show_boot_progress (127);
! 3059: return 1;
! 3060: }
! 3061: #endif /* USE_HOSTCC */
! 3062: #endif /* CONFIG_FIT */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>