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