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