Return to image.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / elwix / tools / uboot_mkimage / common |
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 */