1 /* 2 * Copyright (c) 2013, Google Inc. 3 * 4 * (C) Copyright 2008 Semihalf 5 * 6 * (C) Copyright 2000-2006 7 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 8 * 9 * See file CREDITS for list of people who contributed to this 10 * project. 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License as 14 * published by the Free Software Foundation; either version 2 of 15 * the License, or (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 25 * MA 02111-1307 USA 26 */ 27 28 #ifdef USE_HOSTCC 29 #include "mkimage.h" 30 #include <image.h> 31 #include <time.h> 32 #else 33 #include <common.h> 34 #include <errno.h> 35 #include <asm/io.h> 36 DECLARE_GLOBAL_DATA_PTR; 37 #endif /* !USE_HOSTCC*/ 38 39 #include <bootstage.h> 40 #include <sha1.h> 41 #include <u-boot/crc.h> 42 #include <u-boot/md5.h> 43 44 /*****************************************************************************/ 45 /* New uImage format routines */ 46 /*****************************************************************************/ 47 #ifndef USE_HOSTCC 48 static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr, 49 ulong *addr, const char **name) 50 { 51 const char *sep; 52 53 *addr = addr_curr; 54 *name = NULL; 55 56 sep = strchr(spec, sepc); 57 if (sep) { 58 if (sep - spec > 0) 59 *addr = simple_strtoul(spec, NULL, 16); 60 61 *name = sep + 1; 62 return 1; 63 } 64 65 return 0; 66 } 67 68 /** 69 * fit_parse_conf - parse FIT configuration spec 70 * @spec: input string, containing configuration spec 71 * @add_curr: current image address (to be used as a possible default) 72 * @addr: pointer to a ulong variable, will hold FIT image address of a given 73 * configuration 74 * @conf_name double pointer to a char, will hold pointer to a configuration 75 * unit name 76 * 77 * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>, 78 * where <addr> is a FIT image address that contains configuration 79 * with a <conf> unit name. 80 * 81 * Address part is optional, and if omitted default add_curr will 82 * be used instead. 83 * 84 * returns: 85 * 1 if spec is a valid configuration string, 86 * addr and conf_name are set accordingly 87 * 0 otherwise 88 */ 89 int fit_parse_conf(const char *spec, ulong addr_curr, 90 ulong *addr, const char **conf_name) 91 { 92 return fit_parse_spec(spec, '#', addr_curr, addr, conf_name); 93 } 94 95 /** 96 * fit_parse_subimage - parse FIT subimage spec 97 * @spec: input string, containing subimage spec 98 * @add_curr: current image address (to be used as a possible default) 99 * @addr: pointer to a ulong variable, will hold FIT image address of a given 100 * subimage 101 * @image_name: double pointer to a char, will hold pointer to a subimage name 102 * 103 * fit_parse_subimage() expects subimage spec in the for of 104 * [<addr>]:<subimage>, where <addr> is a FIT image address that contains 105 * subimage with a <subimg> unit name. 106 * 107 * Address part is optional, and if omitted default add_curr will 108 * be used instead. 109 * 110 * returns: 111 * 1 if spec is a valid subimage string, 112 * addr and image_name are set accordingly 113 * 0 otherwise 114 */ 115 int fit_parse_subimage(const char *spec, ulong addr_curr, 116 ulong *addr, const char **image_name) 117 { 118 return fit_parse_spec(spec, ':', addr_curr, addr, image_name); 119 } 120 #endif /* !USE_HOSTCC */ 121 122 static void fit_get_debug(const void *fit, int noffset, 123 char *prop_name, int err) 124 { 125 debug("Can't get '%s' property from FIT 0x%08lx, node: offset %d, name %s (%s)\n", 126 prop_name, (ulong)fit, noffset, fit_get_name(fit, noffset, NULL), 127 fdt_strerror(err)); 128 } 129 130 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT) 131 /** 132 * fit_print_contents - prints out the contents of the FIT format image 133 * @fit: pointer to the FIT format image header 134 * @p: pointer to prefix string 135 * 136 * fit_print_contents() formats a multi line FIT image contents description. 137 * The routine prints out FIT image properties (root node level) follwed by 138 * the details of each component image. 139 * 140 * returns: 141 * no returned results 142 */ 143 void fit_print_contents(const void *fit) 144 { 145 char *desc; 146 char *uname; 147 int images_noffset; 148 int confs_noffset; 149 int noffset; 150 int ndepth; 151 int count = 0; 152 int ret; 153 const char *p; 154 time_t timestamp; 155 156 /* Indent string is defined in header image.h */ 157 p = IMAGE_INDENT_STRING; 158 159 /* Root node properties */ 160 ret = fit_get_desc(fit, 0, &desc); 161 printf("%sFIT description: ", p); 162 if (ret) 163 printf("unavailable\n"); 164 else 165 printf("%s\n", desc); 166 167 if (IMAGE_ENABLE_TIMESTAMP) { 168 ret = fit_get_timestamp(fit, 0, ×tamp); 169 printf("%sCreated: ", p); 170 if (ret) 171 printf("unavailable\n"); 172 else 173 genimg_print_time(timestamp); 174 } 175 176 /* Find images parent node offset */ 177 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); 178 if (images_noffset < 0) { 179 printf("Can't find images parent node '%s' (%s)\n", 180 FIT_IMAGES_PATH, fdt_strerror(images_noffset)); 181 return; 182 } 183 184 /* Process its subnodes, print out component images details */ 185 for (ndepth = 0, count = 0, 186 noffset = fdt_next_node(fit, images_noffset, &ndepth); 187 (noffset >= 0) && (ndepth > 0); 188 noffset = fdt_next_node(fit, noffset, &ndepth)) { 189 if (ndepth == 1) { 190 /* 191 * Direct child node of the images parent node, 192 * i.e. component image node. 193 */ 194 printf("%s Image %u (%s)\n", p, count++, 195 fit_get_name(fit, noffset, NULL)); 196 197 fit_image_print(fit, noffset, p); 198 } 199 } 200 201 /* Find configurations parent node offset */ 202 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); 203 if (confs_noffset < 0) { 204 debug("Can't get configurations parent node '%s' (%s)\n", 205 FIT_CONFS_PATH, fdt_strerror(confs_noffset)); 206 return; 207 } 208 209 /* get default configuration unit name from default property */ 210 uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL); 211 if (uname) 212 printf("%s Default Configuration: '%s'\n", p, uname); 213 214 /* Process its subnodes, print out configurations details */ 215 for (ndepth = 0, count = 0, 216 noffset = fdt_next_node(fit, confs_noffset, &ndepth); 217 (noffset >= 0) && (ndepth > 0); 218 noffset = fdt_next_node(fit, noffset, &ndepth)) { 219 if (ndepth == 1) { 220 /* 221 * Direct child node of the configurations parent node, 222 * i.e. configuration node. 223 */ 224 printf("%s Configuration %u (%s)\n", p, count++, 225 fit_get_name(fit, noffset, NULL)); 226 227 fit_conf_print(fit, noffset, p); 228 } 229 } 230 } 231 232 /** 233 * fit_image_print_data() - prints out the hash node details 234 * @fit: pointer to the FIT format image header 235 * @noffset: offset of the hash node 236 * @p: pointer to prefix string 237 * @type: Type of information to print ("hash" or "sign") 238 * 239 * fit_image_print_data() lists properies for the processed hash node 240 * 241 * This function avoid using puts() since it prints a newline on the host 242 * but does not in U-Boot. 243 * 244 * returns: 245 * no returned results 246 */ 247 static void fit_image_print_data(const void *fit, int noffset, const char *p, 248 const char *type) 249 { 250 const char *keyname; 251 uint8_t *value; 252 int value_len; 253 char *algo; 254 int required; 255 int ret, i; 256 257 debug("%s %s node: '%s'\n", p, type, 258 fit_get_name(fit, noffset, NULL)); 259 printf("%s %s algo: ", p, type); 260 if (fit_image_hash_get_algo(fit, noffset, &algo)) { 261 printf("invalid/unsupported\n"); 262 return; 263 } 264 printf("%s", algo); 265 keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL); 266 required = fdt_getprop(fit, noffset, "required", NULL) != NULL; 267 if (keyname) 268 printf(":%s", keyname); 269 if (required) 270 printf(" (required)"); 271 printf("\n"); 272 273 ret = fit_image_hash_get_value(fit, noffset, &value, 274 &value_len); 275 printf("%s %s value: ", p, type); 276 if (ret) { 277 printf("unavailable\n"); 278 } else { 279 for (i = 0; i < value_len; i++) 280 printf("%02x", value[i]); 281 printf("\n"); 282 } 283 284 debug("%s %s len: %d\n", p, type, value_len); 285 286 /* Signatures have a time stamp */ 287 if (IMAGE_ENABLE_TIMESTAMP && keyname) { 288 time_t timestamp; 289 290 printf("%s Timestamp: ", p); 291 if (fit_get_timestamp(fit, noffset, ×tamp)) 292 printf("unavailable\n"); 293 else 294 genimg_print_time(timestamp); 295 } 296 } 297 298 /** 299 * fit_image_print_verification_data() - prints out the hash/signature details 300 * @fit: pointer to the FIT format image header 301 * @noffset: offset of the hash or signature node 302 * @p: pointer to prefix string 303 * 304 * This lists properies for the processed hash node 305 * 306 * returns: 307 * no returned results 308 */ 309 static void fit_image_print_verification_data(const void *fit, int noffset, 310 const char *p) 311 { 312 const char *name; 313 314 /* 315 * Check subnode name, must be equal to "hash" or "signature". 316 * Multiple hash/signature nodes require unique unit node 317 * names, e.g. hash@1, hash@2, signature@1, signature@2, etc. 318 */ 319 name = fit_get_name(fit, noffset, NULL); 320 if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) { 321 fit_image_print_data(fit, noffset, p, "Hash"); 322 } else if (!strncmp(name, FIT_SIG_NODENAME, 323 strlen(FIT_SIG_NODENAME))) { 324 fit_image_print_data(fit, noffset, p, "Sign"); 325 } 326 } 327 328 /** 329 * fit_image_print - prints out the FIT component image details 330 * @fit: pointer to the FIT format image header 331 * @image_noffset: offset of the component image node 332 * @p: pointer to prefix string 333 * 334 * fit_image_print() lists all mandatory properies for the processed component 335 * image. If present, hash nodes are printed out as well. Load 336 * address for images of type firmware is also printed out. Since the load 337 * address is not mandatory for firmware images, it will be output as 338 * "unavailable" when not present. 339 * 340 * returns: 341 * no returned results 342 */ 343 void fit_image_print(const void *fit, int image_noffset, const char *p) 344 { 345 char *desc; 346 uint8_t type, arch, os, comp; 347 size_t size; 348 ulong load, entry; 349 const void *data; 350 int noffset; 351 int ndepth; 352 int ret; 353 354 /* Mandatory properties */ 355 ret = fit_get_desc(fit, image_noffset, &desc); 356 printf("%s Description: ", p); 357 if (ret) 358 printf("unavailable\n"); 359 else 360 printf("%s\n", desc); 361 362 fit_image_get_type(fit, image_noffset, &type); 363 printf("%s Type: %s\n", p, genimg_get_type_name(type)); 364 365 fit_image_get_comp(fit, image_noffset, &comp); 366 printf("%s Compression: %s\n", p, genimg_get_comp_name(comp)); 367 368 ret = fit_image_get_data(fit, image_noffset, &data, &size); 369 370 #ifndef USE_HOSTCC 371 printf("%s Data Start: ", p); 372 if (ret) { 373 printf("unavailable\n"); 374 } else { 375 void *vdata = (void *)data; 376 377 printf("0x%08lx\n", (ulong)map_to_sysmem(vdata)); 378 } 379 #endif 380 381 printf("%s Data Size: ", p); 382 if (ret) 383 printf("unavailable\n"); 384 else 385 genimg_print_size(size); 386 387 /* Remaining, type dependent properties */ 388 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || 389 (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) || 390 (type == IH_TYPE_FLATDT)) { 391 fit_image_get_arch(fit, image_noffset, &arch); 392 printf("%s Architecture: %s\n", p, genimg_get_arch_name(arch)); 393 } 394 395 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK)) { 396 fit_image_get_os(fit, image_noffset, &os); 397 printf("%s OS: %s\n", p, genimg_get_os_name(os)); 398 } 399 400 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || 401 (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK)) { 402 ret = fit_image_get_load(fit, image_noffset, &load); 403 printf("%s Load Address: ", p); 404 if (ret) 405 printf("unavailable\n"); 406 else 407 printf("0x%08lx\n", load); 408 } 409 410 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || 411 (type == IH_TYPE_RAMDISK)) { 412 fit_image_get_entry(fit, image_noffset, &entry); 413 printf("%s Entry Point: ", p); 414 if (ret) 415 printf("unavailable\n"); 416 else 417 printf("0x%08lx\n", entry); 418 } 419 420 /* Process all hash subnodes of the component image node */ 421 for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth); 422 (noffset >= 0) && (ndepth > 0); 423 noffset = fdt_next_node(fit, noffset, &ndepth)) { 424 if (ndepth == 1) { 425 /* Direct child node of the component image node */ 426 fit_image_print_verification_data(fit, noffset, p); 427 } 428 } 429 } 430 #endif 431 432 /** 433 * fit_get_desc - get node description property 434 * @fit: pointer to the FIT format image header 435 * @noffset: node offset 436 * @desc: double pointer to the char, will hold pointer to the descrption 437 * 438 * fit_get_desc() reads description property from a given node, if 439 * description is found pointer to it is returened in third call argument. 440 * 441 * returns: 442 * 0, on success 443 * -1, on failure 444 */ 445 int fit_get_desc(const void *fit, int noffset, char **desc) 446 { 447 int len; 448 449 *desc = (char *)fdt_getprop(fit, noffset, FIT_DESC_PROP, &len); 450 if (*desc == NULL) { 451 fit_get_debug(fit, noffset, FIT_DESC_PROP, len); 452 return -1; 453 } 454 455 return 0; 456 } 457 458 /** 459 * fit_get_timestamp - get node timestamp property 460 * @fit: pointer to the FIT format image header 461 * @noffset: node offset 462 * @timestamp: pointer to the time_t, will hold read timestamp 463 * 464 * fit_get_timestamp() reads timestamp poperty from given node, if timestamp 465 * is found and has a correct size its value is retured in third call 466 * argument. 467 * 468 * returns: 469 * 0, on success 470 * -1, on property read failure 471 * -2, on wrong timestamp size 472 */ 473 int fit_get_timestamp(const void *fit, int noffset, time_t *timestamp) 474 { 475 int len; 476 const void *data; 477 478 data = fdt_getprop(fit, noffset, FIT_TIMESTAMP_PROP, &len); 479 if (data == NULL) { 480 fit_get_debug(fit, noffset, FIT_TIMESTAMP_PROP, len); 481 return -1; 482 } 483 if (len != sizeof(uint32_t)) { 484 debug("FIT timestamp with incorrect size of (%u)\n", len); 485 return -2; 486 } 487 488 *timestamp = uimage_to_cpu(*((uint32_t *)data)); 489 return 0; 490 } 491 492 /** 493 * fit_image_get_node - get node offset for component image of a given unit name 494 * @fit: pointer to the FIT format image header 495 * @image_uname: component image node unit name 496 * 497 * fit_image_get_node() finds a component image (withing the '/images' 498 * node) of a provided unit name. If image is found its node offset is 499 * returned to the caller. 500 * 501 * returns: 502 * image node offset when found (>=0) 503 * negative number on failure (FDT_ERR_* code) 504 */ 505 int fit_image_get_node(const void *fit, const char *image_uname) 506 { 507 int noffset, images_noffset; 508 509 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); 510 if (images_noffset < 0) { 511 debug("Can't find images parent node '%s' (%s)\n", 512 FIT_IMAGES_PATH, fdt_strerror(images_noffset)); 513 return images_noffset; 514 } 515 516 noffset = fdt_subnode_offset(fit, images_noffset, image_uname); 517 if (noffset < 0) { 518 debug("Can't get node offset for image unit name: '%s' (%s)\n", 519 image_uname, fdt_strerror(noffset)); 520 } 521 522 return noffset; 523 } 524 525 /** 526 * fit_image_get_os - get os id for a given component image node 527 * @fit: pointer to the FIT format image header 528 * @noffset: component image node offset 529 * @os: pointer to the uint8_t, will hold os numeric id 530 * 531 * fit_image_get_os() finds os property in a given component image node. 532 * If the property is found, its (string) value is translated to the numeric 533 * id which is returned to the caller. 534 * 535 * returns: 536 * 0, on success 537 * -1, on failure 538 */ 539 int fit_image_get_os(const void *fit, int noffset, uint8_t *os) 540 { 541 int len; 542 const void *data; 543 544 /* Get OS name from property data */ 545 data = fdt_getprop(fit, noffset, FIT_OS_PROP, &len); 546 if (data == NULL) { 547 fit_get_debug(fit, noffset, FIT_OS_PROP, len); 548 *os = -1; 549 return -1; 550 } 551 552 /* Translate OS name to id */ 553 *os = genimg_get_os_id(data); 554 return 0; 555 } 556 557 /** 558 * fit_image_get_arch - get arch id for a given component image node 559 * @fit: pointer to the FIT format image header 560 * @noffset: component image node offset 561 * @arch: pointer to the uint8_t, will hold arch numeric id 562 * 563 * fit_image_get_arch() finds arch property in a given component image node. 564 * If the property is found, its (string) value is translated to the numeric 565 * id which is returned to the caller. 566 * 567 * returns: 568 * 0, on success 569 * -1, on failure 570 */ 571 int fit_image_get_arch(const void *fit, int noffset, uint8_t *arch) 572 { 573 int len; 574 const void *data; 575 576 /* Get architecture name from property data */ 577 data = fdt_getprop(fit, noffset, FIT_ARCH_PROP, &len); 578 if (data == NULL) { 579 fit_get_debug(fit, noffset, FIT_ARCH_PROP, len); 580 *arch = -1; 581 return -1; 582 } 583 584 /* Translate architecture name to id */ 585 *arch = genimg_get_arch_id(data); 586 return 0; 587 } 588 589 /** 590 * fit_image_get_type - get type id for a given component image node 591 * @fit: pointer to the FIT format image header 592 * @noffset: component image node offset 593 * @type: pointer to the uint8_t, will hold type numeric id 594 * 595 * fit_image_get_type() finds type property in a given component image node. 596 * If the property is found, its (string) value is translated to the numeric 597 * id which is returned to the caller. 598 * 599 * returns: 600 * 0, on success 601 * -1, on failure 602 */ 603 int fit_image_get_type(const void *fit, int noffset, uint8_t *type) 604 { 605 int len; 606 const void *data; 607 608 /* Get image type name from property data */ 609 data = fdt_getprop(fit, noffset, FIT_TYPE_PROP, &len); 610 if (data == NULL) { 611 fit_get_debug(fit, noffset, FIT_TYPE_PROP, len); 612 *type = -1; 613 return -1; 614 } 615 616 /* Translate image type name to id */ 617 *type = genimg_get_type_id(data); 618 return 0; 619 } 620 621 /** 622 * fit_image_get_comp - get comp id for a given component image node 623 * @fit: pointer to the FIT format image header 624 * @noffset: component image node offset 625 * @comp: pointer to the uint8_t, will hold comp numeric id 626 * 627 * fit_image_get_comp() finds comp property in a given component image node. 628 * If the property is found, its (string) value is translated to the numeric 629 * id which is returned to the caller. 630 * 631 * returns: 632 * 0, on success 633 * -1, on failure 634 */ 635 int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp) 636 { 637 int len; 638 const void *data; 639 640 /* Get compression name from property data */ 641 data = fdt_getprop(fit, noffset, FIT_COMP_PROP, &len); 642 if (data == NULL) { 643 fit_get_debug(fit, noffset, FIT_COMP_PROP, len); 644 *comp = -1; 645 return -1; 646 } 647 648 /* Translate compression name to id */ 649 *comp = genimg_get_comp_id(data); 650 return 0; 651 } 652 653 /** 654 * fit_image_get_load() - get load addr property for given component image node 655 * @fit: pointer to the FIT format image header 656 * @noffset: component image node offset 657 * @load: pointer to the uint32_t, will hold load address 658 * 659 * fit_image_get_load() finds load address property in a given component 660 * image node. If the property is found, its value is returned to the caller. 661 * 662 * returns: 663 * 0, on success 664 * -1, on failure 665 */ 666 int fit_image_get_load(const void *fit, int noffset, ulong *load) 667 { 668 int len; 669 const uint32_t *data; 670 671 data = fdt_getprop(fit, noffset, FIT_LOAD_PROP, &len); 672 if (data == NULL) { 673 fit_get_debug(fit, noffset, FIT_LOAD_PROP, len); 674 return -1; 675 } 676 677 *load = uimage_to_cpu(*data); 678 return 0; 679 } 680 681 /** 682 * fit_image_get_entry() - get entry point address property 683 * @fit: pointer to the FIT format image header 684 * @noffset: component image node offset 685 * @entry: pointer to the uint32_t, will hold entry point address 686 * 687 * This gets the entry point address property for a given component image 688 * node. 689 * 690 * fit_image_get_entry() finds entry point address property in a given 691 * component image node. If the property is found, its value is returned 692 * to the caller. 693 * 694 * returns: 695 * 0, on success 696 * -1, on failure 697 */ 698 int fit_image_get_entry(const void *fit, int noffset, ulong *entry) 699 { 700 int len; 701 const uint32_t *data; 702 703 data = fdt_getprop(fit, noffset, FIT_ENTRY_PROP, &len); 704 if (data == NULL) { 705 fit_get_debug(fit, noffset, FIT_ENTRY_PROP, len); 706 return -1; 707 } 708 709 *entry = uimage_to_cpu(*data); 710 return 0; 711 } 712 713 /** 714 * fit_image_get_data - get data property and its size for a given component image node 715 * @fit: pointer to the FIT format image header 716 * @noffset: component image node offset 717 * @data: double pointer to void, will hold data property's data address 718 * @size: pointer to size_t, will hold data property's data size 719 * 720 * fit_image_get_data() finds data property in a given component image node. 721 * If the property is found its data start address and size are returned to 722 * the caller. 723 * 724 * returns: 725 * 0, on success 726 * -1, on failure 727 */ 728 int fit_image_get_data(const void *fit, int noffset, 729 const void **data, size_t *size) 730 { 731 int len; 732 733 *data = fdt_getprop(fit, noffset, FIT_DATA_PROP, &len); 734 if (*data == NULL) { 735 fit_get_debug(fit, noffset, FIT_DATA_PROP, len); 736 *size = 0; 737 return -1; 738 } 739 740 *size = len; 741 return 0; 742 } 743 744 /** 745 * fit_image_hash_get_algo - get hash algorithm name 746 * @fit: pointer to the FIT format image header 747 * @noffset: hash node offset 748 * @algo: double pointer to char, will hold pointer to the algorithm name 749 * 750 * fit_image_hash_get_algo() finds hash algorithm property in a given hash node. 751 * If the property is found its data start address is returned to the caller. 752 * 753 * returns: 754 * 0, on success 755 * -1, on failure 756 */ 757 int fit_image_hash_get_algo(const void *fit, int noffset, char **algo) 758 { 759 int len; 760 761 *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len); 762 if (*algo == NULL) { 763 fit_get_debug(fit, noffset, FIT_ALGO_PROP, len); 764 return -1; 765 } 766 767 return 0; 768 } 769 770 /** 771 * fit_image_hash_get_value - get hash value and length 772 * @fit: pointer to the FIT format image header 773 * @noffset: hash node offset 774 * @value: double pointer to uint8_t, will hold address of a hash value data 775 * @value_len: pointer to an int, will hold hash data length 776 * 777 * fit_image_hash_get_value() finds hash value property in a given hash node. 778 * If the property is found its data start address and size are returned to 779 * the caller. 780 * 781 * returns: 782 * 0, on success 783 * -1, on failure 784 */ 785 int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value, 786 int *value_len) 787 { 788 int len; 789 790 *value = (uint8_t *)fdt_getprop(fit, noffset, FIT_VALUE_PROP, &len); 791 if (*value == NULL) { 792 fit_get_debug(fit, noffset, FIT_VALUE_PROP, len); 793 *value_len = 0; 794 return -1; 795 } 796 797 *value_len = len; 798 return 0; 799 } 800 801 /** 802 * fit_image_hash_get_ignore - get hash ignore flag 803 * @fit: pointer to the FIT format image header 804 * @noffset: hash node offset 805 * @ignore: pointer to an int, will hold hash ignore flag 806 * 807 * fit_image_hash_get_ignore() finds hash ignore property in a given hash node. 808 * If the property is found and non-zero, the hash algorithm is not verified by 809 * u-boot automatically. 810 * 811 * returns: 812 * 0, on ignore not found 813 * value, on ignore found 814 */ 815 static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore) 816 { 817 int len; 818 int *value; 819 820 value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len); 821 if (value == NULL || len != sizeof(int)) 822 *ignore = 0; 823 else 824 *ignore = *value; 825 826 return 0; 827 } 828 829 /** 830 * fit_set_timestamp - set node timestamp property 831 * @fit: pointer to the FIT format image header 832 * @noffset: node offset 833 * @timestamp: timestamp value to be set 834 * 835 * fit_set_timestamp() attempts to set timestamp property in the requested 836 * node and returns operation status to the caller. 837 * 838 * returns: 839 * 0, on success 840 * -1, on property read failure 841 */ 842 int fit_set_timestamp(void *fit, int noffset, time_t timestamp) 843 { 844 uint32_t t; 845 int ret; 846 847 t = cpu_to_uimage(timestamp); 848 ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t, 849 sizeof(uint32_t)); 850 if (ret) { 851 printf("Can't set '%s' property for '%s' node (%s)\n", 852 FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL), 853 fdt_strerror(ret)); 854 return -1; 855 } 856 857 return 0; 858 } 859 860 /** 861 * calculate_hash - calculate and return hash for provided input data 862 * @data: pointer to the input data 863 * @data_len: data length 864 * @algo: requested hash algorithm 865 * @value: pointer to the char, will hold hash value data (caller must 866 * allocate enough free space) 867 * value_len: length of the calculated hash 868 * 869 * calculate_hash() computes input data hash according to the requested 870 * algorithm. 871 * Resulting hash value is placed in caller provided 'value' buffer, length 872 * of the calculated hash is returned via value_len pointer argument. 873 * 874 * returns: 875 * 0, on success 876 * -1, when algo is unsupported 877 */ 878 int calculate_hash(const void *data, int data_len, const char *algo, 879 uint8_t *value, int *value_len) 880 { 881 if (IMAGE_ENABLE_CRC32 && strcmp(algo, "crc32") == 0) { 882 *((uint32_t *)value) = crc32_wd(0, data, data_len, 883 CHUNKSZ_CRC32); 884 *((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value)); 885 *value_len = 4; 886 } else if (IMAGE_ENABLE_SHA1 && strcmp(algo, "sha1") == 0) { 887 sha1_csum_wd((unsigned char *)data, data_len, 888 (unsigned char *)value, CHUNKSZ_SHA1); 889 *value_len = 20; 890 } else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) { 891 md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5); 892 *value_len = 16; 893 } else { 894 debug("Unsupported hash alogrithm\n"); 895 return -1; 896 } 897 return 0; 898 } 899 900 static int fit_image_check_hash(const void *fit, int noffset, const void *data, 901 size_t size, char **err_msgp) 902 { 903 uint8_t value[FIT_MAX_HASH_LEN]; 904 int value_len; 905 char *algo; 906 uint8_t *fit_value; 907 int fit_value_len; 908 int ignore; 909 910 *err_msgp = NULL; 911 912 if (fit_image_hash_get_algo(fit, noffset, &algo)) { 913 *err_msgp = "Can't get hash algo property"; 914 return -1; 915 } 916 printf("%s", algo); 917 918 if (IMAGE_ENABLE_IGNORE) { 919 fit_image_hash_get_ignore(fit, noffset, &ignore); 920 if (ignore) { 921 printf("-skipped "); 922 return 0; 923 } 924 } 925 926 if (fit_image_hash_get_value(fit, noffset, &fit_value, 927 &fit_value_len)) { 928 *err_msgp = "Can't get hash value property"; 929 return -1; 930 } 931 932 if (calculate_hash(data, size, algo, value, &value_len)) { 933 *err_msgp = "Unsupported hash algorithm"; 934 return -1; 935 } 936 937 if (value_len != fit_value_len) { 938 *err_msgp = "Bad hash value len"; 939 return -1; 940 } else if (memcmp(value, fit_value, value_len) != 0) { 941 *err_msgp = "Bad hash value"; 942 return -1; 943 } 944 945 return 0; 946 } 947 948 /** 949 * fit_image_verify - verify data intergity 950 * @fit: pointer to the FIT format image header 951 * @image_noffset: component image node offset 952 * 953 * fit_image_verify() goes over component image hash nodes, 954 * re-calculates each data hash and compares with the value stored in hash 955 * node. 956 * 957 * returns: 958 * 1, if all hashes are valid 959 * 0, otherwise (or on error) 960 */ 961 int fit_image_verify(const void *fit, int image_noffset) 962 { 963 const void *data; 964 size_t size; 965 int noffset = 0; 966 char *err_msg = ""; 967 int verify_all = 1; 968 int ret; 969 970 /* Get image data and data length */ 971 if (fit_image_get_data(fit, image_noffset, &data, &size)) { 972 err_msg = "Can't get image data/size"; 973 goto error; 974 } 975 976 /* Verify all required signatures */ 977 if (IMAGE_ENABLE_VERIFY && 978 fit_image_verify_required_sigs(fit, image_noffset, data, size, 979 gd_fdt_blob(), &verify_all)) { 980 err_msg = "Unable to verify required signature"; 981 goto error; 982 } 983 984 /* Process all hash subnodes of the component image node */ 985 for (noffset = fdt_first_subnode(fit, image_noffset); 986 noffset >= 0; 987 noffset = fdt_next_subnode(fit, noffset)) { 988 const char *name = fit_get_name(fit, noffset, NULL); 989 990 /* 991 * Check subnode name, must be equal to "hash". 992 * Multiple hash nodes require unique unit node 993 * names, e.g. hash@1, hash@2, etc. 994 */ 995 if (!strncmp(name, FIT_HASH_NODENAME, 996 strlen(FIT_HASH_NODENAME))) { 997 if (fit_image_check_hash(fit, noffset, data, size, 998 &err_msg)) 999 goto error; 1000 puts("+ "); 1001 } else if (IMAGE_ENABLE_VERIFY && verify_all && 1002 !strncmp(name, FIT_SIG_NODENAME, 1003 strlen(FIT_SIG_NODENAME))) { 1004 ret = fit_image_check_sig(fit, noffset, data, 1005 size, -1, &err_msg); 1006 if (ret) 1007 puts("- "); 1008 else 1009 puts("+ "); 1010 } 1011 } 1012 1013 if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) { 1014 err_msg = "Corrupted or truncated tree"; 1015 goto error; 1016 } 1017 1018 return 1; 1019 1020 error: 1021 printf(" error!\n%s for '%s' hash node in '%s' image node\n", 1022 err_msg, fit_get_name(fit, noffset, NULL), 1023 fit_get_name(fit, image_noffset, NULL)); 1024 return 0; 1025 } 1026 1027 /** 1028 * fit_all_image_verify - verify data intergity for all images 1029 * @fit: pointer to the FIT format image header 1030 * 1031 * fit_all_image_verify() goes over all images in the FIT and 1032 * for every images checks if all it's hashes are valid. 1033 * 1034 * returns: 1035 * 1, if all hashes of all images are valid 1036 * 0, otherwise (or on error) 1037 */ 1038 int fit_all_image_verify(const void *fit) 1039 { 1040 int images_noffset; 1041 int noffset; 1042 int ndepth; 1043 int count; 1044 1045 /* Find images parent node offset */ 1046 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); 1047 if (images_noffset < 0) { 1048 printf("Can't find images parent node '%s' (%s)\n", 1049 FIT_IMAGES_PATH, fdt_strerror(images_noffset)); 1050 return 0; 1051 } 1052 1053 /* Process all image subnodes, check hashes for each */ 1054 printf("## Checking hash(es) for FIT Image at %08lx ...\n", 1055 (ulong)fit); 1056 for (ndepth = 0, count = 0, 1057 noffset = fdt_next_node(fit, images_noffset, &ndepth); 1058 (noffset >= 0) && (ndepth > 0); 1059 noffset = fdt_next_node(fit, noffset, &ndepth)) { 1060 if (ndepth == 1) { 1061 /* 1062 * Direct child node of the images parent node, 1063 * i.e. component image node. 1064 */ 1065 printf(" Hash(es) for Image %u (%s): ", count++, 1066 fit_get_name(fit, noffset, NULL)); 1067 1068 if (!fit_image_verify(fit, noffset)) 1069 return 0; 1070 printf("\n"); 1071 } 1072 } 1073 return 1; 1074 } 1075 1076 /** 1077 * fit_image_check_os - check whether image node is of a given os type 1078 * @fit: pointer to the FIT format image header 1079 * @noffset: component image node offset 1080 * @os: requested image os 1081 * 1082 * fit_image_check_os() reads image os property and compares its numeric 1083 * id with the requested os. Comparison result is returned to the caller. 1084 * 1085 * returns: 1086 * 1 if image is of given os type 1087 * 0 otherwise (or on error) 1088 */ 1089 int fit_image_check_os(const void *fit, int noffset, uint8_t os) 1090 { 1091 uint8_t image_os; 1092 1093 if (fit_image_get_os(fit, noffset, &image_os)) 1094 return 0; 1095 return (os == image_os); 1096 } 1097 1098 /** 1099 * fit_image_check_arch - check whether image node is of a given arch 1100 * @fit: pointer to the FIT format image header 1101 * @noffset: component image node offset 1102 * @arch: requested imagearch 1103 * 1104 * fit_image_check_arch() reads image arch property and compares its numeric 1105 * id with the requested arch. Comparison result is returned to the caller. 1106 * 1107 * returns: 1108 * 1 if image is of given arch 1109 * 0 otherwise (or on error) 1110 */ 1111 int fit_image_check_arch(const void *fit, int noffset, uint8_t arch) 1112 { 1113 uint8_t image_arch; 1114 1115 if (fit_image_get_arch(fit, noffset, &image_arch)) 1116 return 0; 1117 return (arch == image_arch); 1118 } 1119 1120 /** 1121 * fit_image_check_type - check whether image node is of a given type 1122 * @fit: pointer to the FIT format image header 1123 * @noffset: component image node offset 1124 * @type: requested image type 1125 * 1126 * fit_image_check_type() reads image type property and compares its numeric 1127 * id with the requested type. Comparison result is returned to the caller. 1128 * 1129 * returns: 1130 * 1 if image is of given type 1131 * 0 otherwise (or on error) 1132 */ 1133 int fit_image_check_type(const void *fit, int noffset, uint8_t type) 1134 { 1135 uint8_t image_type; 1136 1137 if (fit_image_get_type(fit, noffset, &image_type)) 1138 return 0; 1139 return (type == image_type); 1140 } 1141 1142 /** 1143 * fit_image_check_comp - check whether image node uses given compression 1144 * @fit: pointer to the FIT format image header 1145 * @noffset: component image node offset 1146 * @comp: requested image compression type 1147 * 1148 * fit_image_check_comp() reads image compression property and compares its 1149 * numeric id with the requested compression type. Comparison result is 1150 * returned to the caller. 1151 * 1152 * returns: 1153 * 1 if image uses requested compression 1154 * 0 otherwise (or on error) 1155 */ 1156 int fit_image_check_comp(const void *fit, int noffset, uint8_t comp) 1157 { 1158 uint8_t image_comp; 1159 1160 if (fit_image_get_comp(fit, noffset, &image_comp)) 1161 return 0; 1162 return (comp == image_comp); 1163 } 1164 1165 /** 1166 * fit_check_format - sanity check FIT image format 1167 * @fit: pointer to the FIT format image header 1168 * 1169 * fit_check_format() runs a basic sanity FIT image verification. 1170 * Routine checks for mandatory properties, nodes, etc. 1171 * 1172 * returns: 1173 * 1, on success 1174 * 0, on failure 1175 */ 1176 int fit_check_format(const void *fit) 1177 { 1178 /* mandatory / node 'description' property */ 1179 if (fdt_getprop(fit, 0, FIT_DESC_PROP, NULL) == NULL) { 1180 debug("Wrong FIT format: no description\n"); 1181 return 0; 1182 } 1183 1184 if (IMAGE_ENABLE_TIMESTAMP) { 1185 /* mandatory / node 'timestamp' property */ 1186 if (fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) { 1187 debug("Wrong FIT format: no timestamp\n"); 1188 return 0; 1189 } 1190 } 1191 1192 /* mandatory subimages parent '/images' node */ 1193 if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) { 1194 debug("Wrong FIT format: no images parent node\n"); 1195 return 0; 1196 } 1197 1198 return 1; 1199 } 1200 1201 1202 /** 1203 * fit_conf_find_compat 1204 * @fit: pointer to the FIT format image header 1205 * @fdt: pointer to the device tree to compare against 1206 * 1207 * fit_conf_find_compat() attempts to find the configuration whose fdt is the 1208 * most compatible with the passed in device tree. 1209 * 1210 * Example: 1211 * 1212 * / o image-tree 1213 * |-o images 1214 * | |-o fdt@1 1215 * | |-o fdt@2 1216 * | 1217 * |-o configurations 1218 * |-o config@1 1219 * | |-fdt = fdt@1 1220 * | 1221 * |-o config@2 1222 * |-fdt = fdt@2 1223 * 1224 * / o U-Boot fdt 1225 * |-compatible = "foo,bar", "bim,bam" 1226 * 1227 * / o kernel fdt1 1228 * |-compatible = "foo,bar", 1229 * 1230 * / o kernel fdt2 1231 * |-compatible = "bim,bam", "baz,biz" 1232 * 1233 * Configuration 1 would be picked because the first string in U-Boot's 1234 * compatible list, "foo,bar", matches a compatible string in the root of fdt1. 1235 * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1. 1236 * 1237 * returns: 1238 * offset to the configuration to use if one was found 1239 * -1 otherwise 1240 */ 1241 int fit_conf_find_compat(const void *fit, const void *fdt) 1242 { 1243 int ndepth = 0; 1244 int noffset, confs_noffset, images_noffset; 1245 const void *fdt_compat; 1246 int fdt_compat_len; 1247 int best_match_offset = 0; 1248 int best_match_pos = 0; 1249 1250 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); 1251 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); 1252 if (confs_noffset < 0 || images_noffset < 0) { 1253 debug("Can't find configurations or images nodes.\n"); 1254 return -1; 1255 } 1256 1257 fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len); 1258 if (!fdt_compat) { 1259 debug("Fdt for comparison has no \"compatible\" property.\n"); 1260 return -1; 1261 } 1262 1263 /* 1264 * Loop over the configurations in the FIT image. 1265 */ 1266 for (noffset = fdt_next_node(fit, confs_noffset, &ndepth); 1267 (noffset >= 0) && (ndepth > 0); 1268 noffset = fdt_next_node(fit, noffset, &ndepth)) { 1269 const void *kfdt; 1270 const char *kfdt_name; 1271 int kfdt_noffset; 1272 const char *cur_fdt_compat; 1273 int len; 1274 size_t size; 1275 int i; 1276 1277 if (ndepth > 1) 1278 continue; 1279 1280 kfdt_name = fdt_getprop(fit, noffset, "fdt", &len); 1281 if (!kfdt_name) { 1282 debug("No fdt property found.\n"); 1283 continue; 1284 } 1285 kfdt_noffset = fdt_subnode_offset(fit, images_noffset, 1286 kfdt_name); 1287 if (kfdt_noffset < 0) { 1288 debug("No image node named \"%s\" found.\n", 1289 kfdt_name); 1290 continue; 1291 } 1292 /* 1293 * Get a pointer to this configuration's fdt. 1294 */ 1295 if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) { 1296 debug("Failed to get fdt \"%s\".\n", kfdt_name); 1297 continue; 1298 } 1299 1300 len = fdt_compat_len; 1301 cur_fdt_compat = fdt_compat; 1302 /* 1303 * Look for a match for each U-Boot compatibility string in 1304 * turn in this configuration's fdt. 1305 */ 1306 for (i = 0; len > 0 && 1307 (!best_match_offset || best_match_pos > i); i++) { 1308 int cur_len = strlen(cur_fdt_compat) + 1; 1309 1310 if (!fdt_node_check_compatible(kfdt, 0, 1311 cur_fdt_compat)) { 1312 best_match_offset = noffset; 1313 best_match_pos = i; 1314 break; 1315 } 1316 len -= cur_len; 1317 cur_fdt_compat += cur_len; 1318 } 1319 } 1320 if (!best_match_offset) { 1321 debug("No match found.\n"); 1322 return -1; 1323 } 1324 1325 return best_match_offset; 1326 } 1327 1328 /** 1329 * fit_conf_get_node - get node offset for configuration of a given unit name 1330 * @fit: pointer to the FIT format image header 1331 * @conf_uname: configuration node unit name 1332 * 1333 * fit_conf_get_node() finds a configuration (withing the '/configurations' 1334 * parant node) of a provided unit name. If configuration is found its node 1335 * offset is returned to the caller. 1336 * 1337 * When NULL is provided in second argument fit_conf_get_node() will search 1338 * for a default configuration node instead. Default configuration node unit 1339 * name is retrived from FIT_DEFAULT_PROP property of the '/configurations' 1340 * node. 1341 * 1342 * returns: 1343 * configuration node offset when found (>=0) 1344 * negative number on failure (FDT_ERR_* code) 1345 */ 1346 int fit_conf_get_node(const void *fit, const char *conf_uname) 1347 { 1348 int noffset, confs_noffset; 1349 int len; 1350 1351 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); 1352 if (confs_noffset < 0) { 1353 debug("Can't find configurations parent node '%s' (%s)\n", 1354 FIT_CONFS_PATH, fdt_strerror(confs_noffset)); 1355 return confs_noffset; 1356 } 1357 1358 if (conf_uname == NULL) { 1359 /* get configuration unit name from the default property */ 1360 debug("No configuration specified, trying default...\n"); 1361 conf_uname = (char *)fdt_getprop(fit, confs_noffset, 1362 FIT_DEFAULT_PROP, &len); 1363 if (conf_uname == NULL) { 1364 fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP, 1365 len); 1366 return len; 1367 } 1368 debug("Found default configuration: '%s'\n", conf_uname); 1369 } 1370 1371 noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname); 1372 if (noffset < 0) { 1373 debug("Can't get node offset for configuration unit name: '%s' (%s)\n", 1374 conf_uname, fdt_strerror(noffset)); 1375 } 1376 1377 return noffset; 1378 } 1379 1380 int fit_conf_get_prop_node(const void *fit, int noffset, 1381 const char *prop_name) 1382 { 1383 char *uname; 1384 int len; 1385 1386 /* get kernel image unit name from configuration kernel property */ 1387 uname = (char *)fdt_getprop(fit, noffset, prop_name, &len); 1388 if (uname == NULL) 1389 return len; 1390 1391 return fit_image_get_node(fit, uname); 1392 } 1393 1394 /** 1395 * fit_conf_print - prints out the FIT configuration details 1396 * @fit: pointer to the FIT format image header 1397 * @noffset: offset of the configuration node 1398 * @p: pointer to prefix string 1399 * 1400 * fit_conf_print() lists all mandatory properies for the processed 1401 * configuration node. 1402 * 1403 * returns: 1404 * no returned results 1405 */ 1406 void fit_conf_print(const void *fit, int noffset, const char *p) 1407 { 1408 char *desc; 1409 char *uname; 1410 int ret; 1411 1412 /* Mandatory properties */ 1413 ret = fit_get_desc(fit, noffset, &desc); 1414 printf("%s Description: ", p); 1415 if (ret) 1416 printf("unavailable\n"); 1417 else 1418 printf("%s\n", desc); 1419 1420 uname = (char *)fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL); 1421 printf("%s Kernel: ", p); 1422 if (uname == NULL) 1423 printf("unavailable\n"); 1424 else 1425 printf("%s\n", uname); 1426 1427 /* Optional properties */ 1428 uname = (char *)fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL); 1429 if (uname) 1430 printf("%s Init Ramdisk: %s\n", p, uname); 1431 1432 uname = (char *)fdt_getprop(fit, noffset, FIT_FDT_PROP, NULL); 1433 if (uname) 1434 printf("%s FDT: %s\n", p, uname); 1435 } 1436 1437 int fit_image_select(const void *fit, int rd_noffset, int verify) 1438 { 1439 fit_image_print(fit, rd_noffset, " "); 1440 1441 if (verify) { 1442 puts(" Verifying Hash Integrity ... "); 1443 if (!fit_image_verify(fit, rd_noffset)) { 1444 puts("Bad Data Hash\n"); 1445 return -EACCES; 1446 } 1447 puts("OK\n"); 1448 } 1449 1450 return 0; 1451 } 1452 1453 int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name, 1454 ulong addr) 1455 { 1456 int cfg_noffset; 1457 void *fit_hdr; 1458 int noffset; 1459 1460 debug("* %s: using config '%s' from image at 0x%08lx\n", 1461 prop_name, images->fit_uname_cfg, addr); 1462 1463 /* Check whether configuration has this property defined */ 1464 fit_hdr = map_sysmem(addr, 0); 1465 cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg); 1466 if (cfg_noffset < 0) { 1467 debug("* %s: no such config\n", prop_name); 1468 return -ENOENT; 1469 } 1470 1471 noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name); 1472 if (noffset < 0) { 1473 debug("* %s: no '%s' in config\n", prop_name, prop_name); 1474 return -ENOLINK; 1475 } 1476 1477 return noffset; 1478 } 1479 1480 int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr, 1481 const char **fit_unamep, const char **fit_uname_configp, 1482 int arch, int image_type, int bootstage_id, 1483 enum fit_load_op load_op, ulong *datap, ulong *lenp) 1484 { 1485 int cfg_noffset, noffset; 1486 const char *fit_uname; 1487 const char *fit_uname_config; 1488 const void *fit; 1489 const void *buf; 1490 size_t size; 1491 int type_ok, os_ok; 1492 ulong load, data, len; 1493 int ret; 1494 1495 fit = map_sysmem(addr, 0); 1496 fit_uname = fit_unamep ? *fit_unamep : NULL; 1497 fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL; 1498 printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr); 1499 1500 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT); 1501 if (!fit_check_format(fit)) { 1502 printf("Bad FIT %s image format!\n", prop_name); 1503 bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT); 1504 return -ENOEXEC; 1505 } 1506 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK); 1507 if (fit_uname) { 1508 /* get ramdisk component image node offset */ 1509 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME); 1510 noffset = fit_image_get_node(fit, fit_uname); 1511 } else { 1512 /* 1513 * no image node unit name, try to get config 1514 * node first. If config unit node name is NULL 1515 * fit_conf_get_node() will try to find default config node 1516 */ 1517 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME); 1518 if (IMAGE_ENABLE_BEST_MATCH && !fit_uname_config) { 1519 cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob()); 1520 } else { 1521 cfg_noffset = fit_conf_get_node(fit, 1522 fit_uname_config); 1523 } 1524 if (cfg_noffset < 0) { 1525 puts("Could not find configuration node\n"); 1526 bootstage_error(bootstage_id + 1527 BOOTSTAGE_SUB_NO_UNIT_NAME); 1528 return -ENOENT; 1529 } 1530 fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL); 1531 printf(" Using '%s' configuration\n", fit_uname_config); 1532 if (image_type == IH_TYPE_KERNEL) { 1533 /* Remember (and possibly verify) this config */ 1534 images->fit_uname_cfg = fit_uname_config; 1535 if (IMAGE_ENABLE_VERIFY && images->verify) { 1536 puts(" Verifying Hash Integrity ... "); 1537 if (!fit_config_verify(fit, cfg_noffset)) { 1538 puts("Bad Data Hash\n"); 1539 bootstage_error(bootstage_id + 1540 BOOTSTAGE_SUB_HASH); 1541 return -EACCES; 1542 } 1543 puts("OK\n"); 1544 } 1545 bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG); 1546 } 1547 1548 noffset = fit_conf_get_prop_node(fit, cfg_noffset, 1549 prop_name); 1550 fit_uname = fit_get_name(fit, noffset, NULL); 1551 } 1552 if (noffset < 0) { 1553 puts("Could not find subimage node\n"); 1554 bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE); 1555 return -ENOENT; 1556 } 1557 1558 printf(" Trying '%s' %s subimage\n", fit_uname, prop_name); 1559 1560 ret = fit_image_select(fit, noffset, images->verify); 1561 if (ret) { 1562 bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH); 1563 return ret; 1564 } 1565 1566 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH); 1567 if (!fit_image_check_target_arch(fit, noffset)) { 1568 puts("Unsupported Architecture\n"); 1569 bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH); 1570 return -ENOEXEC; 1571 } 1572 1573 if (image_type == IH_TYPE_FLATDT && 1574 !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) { 1575 puts("FDT image is compressed"); 1576 return -EPROTONOSUPPORT; 1577 } 1578 1579 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL); 1580 type_ok = fit_image_check_type(fit, noffset, image_type) || 1581 (image_type == IH_TYPE_KERNEL && 1582 fit_image_check_type(fit, noffset, 1583 IH_TYPE_KERNEL_NOLOAD)); 1584 os_ok = image_type == IH_TYPE_FLATDT || 1585 fit_image_check_os(fit, noffset, IH_OS_LINUX); 1586 if (!type_ok || !os_ok) { 1587 printf("No Linux %s %s Image\n", genimg_get_arch_name(arch), 1588 genimg_get_type_name(image_type)); 1589 bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL); 1590 return -EIO; 1591 } 1592 1593 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK); 1594 1595 /* get image data address and length */ 1596 if (fit_image_get_data(fit, noffset, &buf, &size)) { 1597 printf("Could not find %s subimage data!\n", prop_name); 1598 bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA); 1599 return -ENOENT; 1600 } 1601 len = (ulong)size; 1602 1603 /* verify that image data is a proper FDT blob */ 1604 if (image_type == IH_TYPE_FLATDT && fdt_check_header((char *)buf)) { 1605 puts("Subimage data is not a FDT"); 1606 return -ENOEXEC; 1607 } 1608 1609 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK); 1610 1611 /* 1612 * Work-around for eldk-4.2 which gives this warning if we try to 1613 * case in the unmap_sysmem() call: 1614 * warning: initialization discards qualifiers from pointer target type 1615 */ 1616 { 1617 void *vbuf = (void *)buf; 1618 1619 data = map_to_sysmem(vbuf); 1620 } 1621 1622 if (load_op == FIT_LOAD_IGNORED) { 1623 /* Don't load */ 1624 } else if (fit_image_get_load(fit, noffset, &load)) { 1625 if (load_op == FIT_LOAD_REQUIRED) { 1626 printf("Can't get %s subimage load address!\n", 1627 prop_name); 1628 bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD); 1629 return -EBADF; 1630 } 1631 } else { 1632 ulong image_start, image_end; 1633 ulong load_end; 1634 void *dst; 1635 1636 /* 1637 * move image data to the load address, 1638 * make sure we don't overwrite initial image 1639 */ 1640 image_start = addr; 1641 image_end = addr + fit_get_size(fit); 1642 1643 load_end = load + len; 1644 if (image_type != IH_TYPE_KERNEL && 1645 load < image_end && load_end > image_start) { 1646 printf("Error: %s overwritten\n", prop_name); 1647 return -EXDEV; 1648 } 1649 1650 printf(" Loading %s from 0x%08lx to 0x%08lx\n", 1651 prop_name, data, load); 1652 1653 dst = map_sysmem(load, len); 1654 memmove(dst, buf, len); 1655 data = load; 1656 } 1657 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD); 1658 1659 *datap = data; 1660 *lenp = len; 1661 if (fit_unamep) 1662 *fit_unamep = (char *)fit_uname; 1663 if (fit_uname_configp) 1664 *fit_uname_configp = (char *)fit_uname_config; 1665 1666 return noffset; 1667 } 1668