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