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