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 * SPDX-License-Identifier: GPL-2.0+ 10 */ 11 12 #ifdef USE_HOSTCC 13 #include "mkimage.h" 14 #include <image.h> 15 #include <time.h> 16 #else 17 #include <common.h> 18 #include <errno.h> 19 #include <asm/io.h> 20 DECLARE_GLOBAL_DATA_PTR; 21 #endif /* !USE_HOSTCC*/ 22 23 #include <bootstage.h> 24 #include <sha1.h> 25 #include <sha256.h> 26 #include <u-boot/crc.h> 27 #include <u-boot/md5.h> 28 29 /*****************************************************************************/ 30 /* New uImage format routines */ 31 /*****************************************************************************/ 32 #ifndef USE_HOSTCC 33 static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr, 34 ulong *addr, const char **name) 35 { 36 const char *sep; 37 38 *addr = addr_curr; 39 *name = NULL; 40 41 sep = strchr(spec, sepc); 42 if (sep) { 43 if (sep - spec > 0) 44 *addr = simple_strtoul(spec, NULL, 16); 45 46 *name = sep + 1; 47 return 1; 48 } 49 50 return 0; 51 } 52 53 /** 54 * fit_parse_conf - parse FIT configuration spec 55 * @spec: input string, containing configuration spec 56 * @add_curr: current image address (to be used as a possible default) 57 * @addr: pointer to a ulong variable, will hold FIT image address of a given 58 * configuration 59 * @conf_name double pointer to a char, will hold pointer to a configuration 60 * unit name 61 * 62 * fit_parse_conf() expects configuration spec in the form of [<addr>]#<conf>, 63 * where <addr> is a FIT image address that contains configuration 64 * with a <conf> unit name. 65 * 66 * Address part is optional, and if omitted default add_curr will 67 * be used instead. 68 * 69 * returns: 70 * 1 if spec is a valid configuration string, 71 * addr and conf_name are set accordingly 72 * 0 otherwise 73 */ 74 int fit_parse_conf(const char *spec, ulong addr_curr, 75 ulong *addr, const char **conf_name) 76 { 77 return fit_parse_spec(spec, '#', addr_curr, addr, conf_name); 78 } 79 80 /** 81 * fit_parse_subimage - parse FIT subimage spec 82 * @spec: input string, containing subimage spec 83 * @add_curr: current image address (to be used as a possible default) 84 * @addr: pointer to a ulong variable, will hold FIT image address of a given 85 * subimage 86 * @image_name: double pointer to a char, will hold pointer to a subimage name 87 * 88 * fit_parse_subimage() expects subimage spec in the form of 89 * [<addr>]:<subimage>, where <addr> is a FIT image address that contains 90 * subimage with a <subimg> unit name. 91 * 92 * Address part is optional, and if omitted default add_curr will 93 * be used instead. 94 * 95 * returns: 96 * 1 if spec is a valid subimage string, 97 * addr and image_name are set accordingly 98 * 0 otherwise 99 */ 100 int fit_parse_subimage(const char *spec, ulong addr_curr, 101 ulong *addr, const char **image_name) 102 { 103 return fit_parse_spec(spec, ':', addr_curr, addr, image_name); 104 } 105 #endif /* !USE_HOSTCC */ 106 107 static void fit_get_debug(const void *fit, int noffset, 108 char *prop_name, int err) 109 { 110 debug("Can't get '%s' property from FIT 0x%08lx, node: offset %d, name %s (%s)\n", 111 prop_name, (ulong)fit, noffset, fit_get_name(fit, noffset, NULL), 112 fdt_strerror(err)); 113 } 114 115 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT) 116 /** 117 * fit_print_contents - prints out the contents of the FIT format image 118 * @fit: pointer to the FIT format image header 119 * @p: pointer to prefix string 120 * 121 * fit_print_contents() formats a multi line FIT image contents description. 122 * The routine prints out FIT image properties (root node level) follwed by 123 * the details of each component image. 124 * 125 * returns: 126 * no returned results 127 */ 128 void fit_print_contents(const void *fit) 129 { 130 char *desc; 131 char *uname; 132 int images_noffset; 133 int confs_noffset; 134 int noffset; 135 int ndepth; 136 int count = 0; 137 int ret; 138 const char *p; 139 time_t timestamp; 140 141 /* Indent string is defined in header image.h */ 142 p = IMAGE_INDENT_STRING; 143 144 /* Root node properties */ 145 ret = fit_get_desc(fit, 0, &desc); 146 printf("%sFIT description: ", p); 147 if (ret) 148 printf("unavailable\n"); 149 else 150 printf("%s\n", desc); 151 152 if (IMAGE_ENABLE_TIMESTAMP) { 153 ret = fit_get_timestamp(fit, 0, ×tamp); 154 printf("%sCreated: ", p); 155 if (ret) 156 printf("unavailable\n"); 157 else 158 genimg_print_time(timestamp); 159 } 160 161 /* Find images parent node offset */ 162 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); 163 if (images_noffset < 0) { 164 printf("Can't find images parent node '%s' (%s)\n", 165 FIT_IMAGES_PATH, fdt_strerror(images_noffset)); 166 return; 167 } 168 169 /* Process its subnodes, print out component images details */ 170 for (ndepth = 0, count = 0, 171 noffset = fdt_next_node(fit, images_noffset, &ndepth); 172 (noffset >= 0) && (ndepth > 0); 173 noffset = fdt_next_node(fit, noffset, &ndepth)) { 174 if (ndepth == 1) { 175 /* 176 * Direct child node of the images parent node, 177 * i.e. component image node. 178 */ 179 printf("%s Image %u (%s)\n", p, count++, 180 fit_get_name(fit, noffset, NULL)); 181 182 fit_image_print(fit, noffset, p); 183 } 184 } 185 186 /* Find configurations parent node offset */ 187 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); 188 if (confs_noffset < 0) { 189 debug("Can't get configurations parent node '%s' (%s)\n", 190 FIT_CONFS_PATH, fdt_strerror(confs_noffset)); 191 return; 192 } 193 194 /* get default configuration unit name from default property */ 195 uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL); 196 if (uname) 197 printf("%s Default Configuration: '%s'\n", p, uname); 198 199 /* Process its subnodes, print out configurations details */ 200 for (ndepth = 0, count = 0, 201 noffset = fdt_next_node(fit, confs_noffset, &ndepth); 202 (noffset >= 0) && (ndepth > 0); 203 noffset = fdt_next_node(fit, noffset, &ndepth)) { 204 if (ndepth == 1) { 205 /* 206 * Direct child node of the configurations parent node, 207 * i.e. configuration node. 208 */ 209 printf("%s Configuration %u (%s)\n", p, count++, 210 fit_get_name(fit, noffset, NULL)); 211 212 fit_conf_print(fit, noffset, p); 213 } 214 } 215 } 216 217 /** 218 * fit_image_print_data() - prints out the hash node details 219 * @fit: pointer to the FIT format image header 220 * @noffset: offset of the hash node 221 * @p: pointer to prefix string 222 * @type: Type of information to print ("hash" or "sign") 223 * 224 * fit_image_print_data() lists properies for the processed hash node 225 * 226 * This function avoid using puts() since it prints a newline on the host 227 * but does not in U-Boot. 228 * 229 * returns: 230 * no returned results 231 */ 232 static void fit_image_print_data(const void *fit, int noffset, const char *p, 233 const char *type) 234 { 235 const char *keyname; 236 uint8_t *value; 237 int value_len; 238 char *algo; 239 int required; 240 int ret, i; 241 242 debug("%s %s node: '%s'\n", p, type, 243 fit_get_name(fit, noffset, NULL)); 244 printf("%s %s algo: ", p, type); 245 if (fit_image_hash_get_algo(fit, noffset, &algo)) { 246 printf("invalid/unsupported\n"); 247 return; 248 } 249 printf("%s", algo); 250 keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL); 251 required = fdt_getprop(fit, noffset, "required", NULL) != NULL; 252 if (keyname) 253 printf(":%s", keyname); 254 if (required) 255 printf(" (required)"); 256 printf("\n"); 257 258 ret = fit_image_hash_get_value(fit, noffset, &value, 259 &value_len); 260 printf("%s %s value: ", p, type); 261 if (ret) { 262 printf("unavailable\n"); 263 } else { 264 for (i = 0; i < value_len; i++) 265 printf("%02x", value[i]); 266 printf("\n"); 267 } 268 269 debug("%s %s len: %d\n", p, type, value_len); 270 271 /* Signatures have a time stamp */ 272 if (IMAGE_ENABLE_TIMESTAMP && keyname) { 273 time_t timestamp; 274 275 printf("%s Timestamp: ", p); 276 if (fit_get_timestamp(fit, noffset, ×tamp)) 277 printf("unavailable\n"); 278 else 279 genimg_print_time(timestamp); 280 } 281 } 282 283 /** 284 * fit_image_print_verification_data() - prints out the hash/signature details 285 * @fit: pointer to the FIT format image header 286 * @noffset: offset of the hash or signature node 287 * @p: pointer to prefix string 288 * 289 * This lists properies for the processed hash node 290 * 291 * returns: 292 * no returned results 293 */ 294 static void fit_image_print_verification_data(const void *fit, int noffset, 295 const char *p) 296 { 297 const char *name; 298 299 /* 300 * Check subnode name, must be equal to "hash" or "signature". 301 * Multiple hash/signature nodes require unique unit node 302 * names, e.g. hash@1, hash@2, signature@1, signature@2, etc. 303 */ 304 name = fit_get_name(fit, noffset, NULL); 305 if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) { 306 fit_image_print_data(fit, noffset, p, "Hash"); 307 } else if (!strncmp(name, FIT_SIG_NODENAME, 308 strlen(FIT_SIG_NODENAME))) { 309 fit_image_print_data(fit, noffset, p, "Sign"); 310 } 311 } 312 313 /** 314 * fit_image_print - prints out the FIT component image details 315 * @fit: pointer to the FIT format image header 316 * @image_noffset: offset of the component image node 317 * @p: pointer to prefix string 318 * 319 * fit_image_print() lists all mandatory properies for the processed component 320 * image. If present, hash nodes are printed out as well. Load 321 * address for images of type firmware is also printed out. Since the load 322 * address is not mandatory for firmware images, it will be output as 323 * "unavailable" when not present. 324 * 325 * returns: 326 * no returned results 327 */ 328 void fit_image_print(const void *fit, int image_noffset, const char *p) 329 { 330 char *desc; 331 uint8_t type, arch, os, comp; 332 size_t size; 333 ulong load, entry; 334 const void *data; 335 int noffset; 336 int ndepth; 337 int ret; 338 339 /* Mandatory properties */ 340 ret = fit_get_desc(fit, image_noffset, &desc); 341 printf("%s Description: ", p); 342 if (ret) 343 printf("unavailable\n"); 344 else 345 printf("%s\n", desc); 346 347 if (IMAGE_ENABLE_TIMESTAMP) { 348 time_t timestamp; 349 350 ret = fit_get_timestamp(fit, 0, ×tamp); 351 printf("%s Created: ", p); 352 if (ret) 353 printf("unavailable\n"); 354 else 355 genimg_print_time(timestamp); 356 } 357 358 fit_image_get_type(fit, image_noffset, &type); 359 printf("%s Type: %s\n", p, genimg_get_type_name(type)); 360 361 fit_image_get_comp(fit, image_noffset, &comp); 362 printf("%s Compression: %s\n", p, genimg_get_comp_name(comp)); 363 364 ret = fit_image_get_data(fit, image_noffset, &data, &size); 365 366 #ifndef USE_HOSTCC 367 printf("%s Data Start: ", p); 368 if (ret) { 369 printf("unavailable\n"); 370 } else { 371 void *vdata = (void *)data; 372 373 printf("0x%08lx\n", (ulong)map_to_sysmem(vdata)); 374 } 375 #endif 376 377 printf("%s Data Size: ", p); 378 if (ret) 379 printf("unavailable\n"); 380 else 381 genimg_print_size(size); 382 383 /* Remaining, type dependent properties */ 384 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || 385 (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) || 386 (type == IH_TYPE_FLATDT)) { 387 fit_image_get_arch(fit, image_noffset, &arch); 388 printf("%s Architecture: %s\n", p, genimg_get_arch_name(arch)); 389 } 390 391 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK)) { 392 fit_image_get_os(fit, image_noffset, &os); 393 printf("%s OS: %s\n", p, genimg_get_os_name(os)); 394 } 395 396 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || 397 (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK)) { 398 ret = fit_image_get_load(fit, image_noffset, &load); 399 printf("%s Load Address: ", p); 400 if (ret) 401 printf("unavailable\n"); 402 else 403 printf("0x%08lx\n", load); 404 } 405 406 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || 407 (type == IH_TYPE_RAMDISK)) { 408 fit_image_get_entry(fit, image_noffset, &entry); 409 printf("%s Entry Point: ", p); 410 if (ret) 411 printf("unavailable\n"); 412 else 413 printf("0x%08lx\n", entry); 414 } 415 416 /* Process all hash subnodes of the component image node */ 417 for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth); 418 (noffset >= 0) && (ndepth > 0); 419 noffset = fdt_next_node(fit, noffset, &ndepth)) { 420 if (ndepth == 1) { 421 /* Direct child node of the component image node */ 422 fit_image_print_verification_data(fit, noffset, p); 423 } 424 } 425 } 426 #endif 427 428 /** 429 * fit_get_desc - get node description property 430 * @fit: pointer to the FIT format image header 431 * @noffset: node offset 432 * @desc: double pointer to the char, will hold pointer to the descrption 433 * 434 * fit_get_desc() reads description property from a given node, if 435 * description is found pointer to it is returened in third call argument. 436 * 437 * returns: 438 * 0, on success 439 * -1, on failure 440 */ 441 int fit_get_desc(const void *fit, int noffset, char **desc) 442 { 443 int len; 444 445 *desc = (char *)fdt_getprop(fit, noffset, FIT_DESC_PROP, &len); 446 if (*desc == NULL) { 447 fit_get_debug(fit, noffset, FIT_DESC_PROP, len); 448 return -1; 449 } 450 451 return 0; 452 } 453 454 /** 455 * fit_get_timestamp - get node timestamp property 456 * @fit: pointer to the FIT format image header 457 * @noffset: node offset 458 * @timestamp: pointer to the time_t, will hold read timestamp 459 * 460 * fit_get_timestamp() reads timestamp poperty from given node, if timestamp 461 * is found and has a correct size its value is retured in third call 462 * argument. 463 * 464 * returns: 465 * 0, on success 466 * -1, on property read failure 467 * -2, on wrong timestamp size 468 */ 469 int fit_get_timestamp(const void *fit, int noffset, time_t *timestamp) 470 { 471 int len; 472 const void *data; 473 474 data = fdt_getprop(fit, noffset, FIT_TIMESTAMP_PROP, &len); 475 if (data == NULL) { 476 fit_get_debug(fit, noffset, FIT_TIMESTAMP_PROP, len); 477 return -1; 478 } 479 if (len != sizeof(uint32_t)) { 480 debug("FIT timestamp with incorrect size of (%u)\n", len); 481 return -2; 482 } 483 484 *timestamp = uimage_to_cpu(*((uint32_t *)data)); 485 return 0; 486 } 487 488 /** 489 * fit_image_get_node - get node offset for component image of a given unit name 490 * @fit: pointer to the FIT format image header 491 * @image_uname: component image node unit name 492 * 493 * fit_image_get_node() finds a component image (withing the '/images' 494 * node) of a provided unit name. If image is found its node offset is 495 * returned to the caller. 496 * 497 * returns: 498 * image node offset when found (>=0) 499 * negative number on failure (FDT_ERR_* code) 500 */ 501 int fit_image_get_node(const void *fit, const char *image_uname) 502 { 503 int noffset, images_noffset; 504 505 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); 506 if (images_noffset < 0) { 507 debug("Can't find images parent node '%s' (%s)\n", 508 FIT_IMAGES_PATH, fdt_strerror(images_noffset)); 509 return images_noffset; 510 } 511 512 noffset = fdt_subnode_offset(fit, images_noffset, image_uname); 513 if (noffset < 0) { 514 debug("Can't get node offset for image unit name: '%s' (%s)\n", 515 image_uname, fdt_strerror(noffset)); 516 } 517 518 return noffset; 519 } 520 521 /** 522 * fit_image_get_os - get os id for a given component image node 523 * @fit: pointer to the FIT format image header 524 * @noffset: component image node offset 525 * @os: pointer to the uint8_t, will hold os numeric id 526 * 527 * fit_image_get_os() finds os property in a given component image node. 528 * If the property is found, its (string) value is translated to the numeric 529 * id which is returned to the caller. 530 * 531 * returns: 532 * 0, on success 533 * -1, on failure 534 */ 535 int fit_image_get_os(const void *fit, int noffset, uint8_t *os) 536 { 537 int len; 538 const void *data; 539 540 /* Get OS name from property data */ 541 data = fdt_getprop(fit, noffset, FIT_OS_PROP, &len); 542 if (data == NULL) { 543 fit_get_debug(fit, noffset, FIT_OS_PROP, len); 544 *os = -1; 545 return -1; 546 } 547 548 /* Translate OS name to id */ 549 *os = genimg_get_os_id(data); 550 return 0; 551 } 552 553 /** 554 * fit_image_get_arch - get arch id for a given component image node 555 * @fit: pointer to the FIT format image header 556 * @noffset: component image node offset 557 * @arch: pointer to the uint8_t, will hold arch numeric id 558 * 559 * fit_image_get_arch() finds arch property in a given component image node. 560 * If the property is found, its (string) value is translated to the numeric 561 * id which is returned to the caller. 562 * 563 * returns: 564 * 0, on success 565 * -1, on failure 566 */ 567 int fit_image_get_arch(const void *fit, int noffset, uint8_t *arch) 568 { 569 int len; 570 const void *data; 571 572 /* Get architecture name from property data */ 573 data = fdt_getprop(fit, noffset, FIT_ARCH_PROP, &len); 574 if (data == NULL) { 575 fit_get_debug(fit, noffset, FIT_ARCH_PROP, len); 576 *arch = -1; 577 return -1; 578 } 579 580 /* Translate architecture name to id */ 581 *arch = genimg_get_arch_id(data); 582 return 0; 583 } 584 585 /** 586 * fit_image_get_type - get type id for a given component image node 587 * @fit: pointer to the FIT format image header 588 * @noffset: component image node offset 589 * @type: pointer to the uint8_t, will hold type numeric id 590 * 591 * fit_image_get_type() finds type property in a given component image node. 592 * If the property is found, its (string) value is translated to the numeric 593 * id which is returned to the caller. 594 * 595 * returns: 596 * 0, on success 597 * -1, on failure 598 */ 599 int fit_image_get_type(const void *fit, int noffset, uint8_t *type) 600 { 601 int len; 602 const void *data; 603 604 /* Get image type name from property data */ 605 data = fdt_getprop(fit, noffset, FIT_TYPE_PROP, &len); 606 if (data == NULL) { 607 fit_get_debug(fit, noffset, FIT_TYPE_PROP, len); 608 *type = -1; 609 return -1; 610 } 611 612 /* Translate image type name to id */ 613 *type = genimg_get_type_id(data); 614 return 0; 615 } 616 617 /** 618 * fit_image_get_comp - get comp id for a given component image node 619 * @fit: pointer to the FIT format image header 620 * @noffset: component image node offset 621 * @comp: pointer to the uint8_t, will hold comp numeric id 622 * 623 * fit_image_get_comp() finds comp property in a given component image node. 624 * If the property is found, its (string) value is translated to the numeric 625 * id which is returned to the caller. 626 * 627 * returns: 628 * 0, on success 629 * -1, on failure 630 */ 631 int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp) 632 { 633 int len; 634 const void *data; 635 636 /* Get compression name from property data */ 637 data = fdt_getprop(fit, noffset, FIT_COMP_PROP, &len); 638 if (data == NULL) { 639 fit_get_debug(fit, noffset, FIT_COMP_PROP, len); 640 *comp = -1; 641 return -1; 642 } 643 644 /* Translate compression name to id */ 645 *comp = genimg_get_comp_id(data); 646 return 0; 647 } 648 649 /** 650 * fit_image_get_load() - get load addr property for given component image node 651 * @fit: pointer to the FIT format image header 652 * @noffset: component image node offset 653 * @load: pointer to the uint32_t, will hold load address 654 * 655 * fit_image_get_load() finds load address property in a given component 656 * image node. If the property is found, its value is returned to the caller. 657 * 658 * returns: 659 * 0, on success 660 * -1, on failure 661 */ 662 int fit_image_get_load(const void *fit, int noffset, ulong *load) 663 { 664 int len; 665 const uint32_t *data; 666 667 data = fdt_getprop(fit, noffset, FIT_LOAD_PROP, &len); 668 if (data == NULL) { 669 fit_get_debug(fit, noffset, FIT_LOAD_PROP, len); 670 return -1; 671 } 672 673 *load = uimage_to_cpu(*data); 674 return 0; 675 } 676 677 /** 678 * fit_image_get_entry() - get entry point address property 679 * @fit: pointer to the FIT format image header 680 * @noffset: component image node offset 681 * @entry: pointer to the uint32_t, will hold entry point address 682 * 683 * This gets the entry point address property for a given component image 684 * node. 685 * 686 * fit_image_get_entry() finds entry point address property in a given 687 * component image node. If the property is found, its value is returned 688 * to the caller. 689 * 690 * returns: 691 * 0, on success 692 * -1, on failure 693 */ 694 int fit_image_get_entry(const void *fit, int noffset, ulong *entry) 695 { 696 int len; 697 const uint32_t *data; 698 699 data = fdt_getprop(fit, noffset, FIT_ENTRY_PROP, &len); 700 if (data == NULL) { 701 fit_get_debug(fit, noffset, FIT_ENTRY_PROP, len); 702 return -1; 703 } 704 705 *entry = uimage_to_cpu(*data); 706 return 0; 707 } 708 709 /** 710 * fit_image_get_data - get data property and its size for a given component image node 711 * @fit: pointer to the FIT format image header 712 * @noffset: component image node offset 713 * @data: double pointer to void, will hold data property's data address 714 * @size: pointer to size_t, will hold data property's data size 715 * 716 * fit_image_get_data() finds data property in a given component image node. 717 * If the property is found its data start address and size are returned to 718 * the caller. 719 * 720 * returns: 721 * 0, on success 722 * -1, on failure 723 */ 724 int fit_image_get_data(const void *fit, int noffset, 725 const void **data, size_t *size) 726 { 727 int len; 728 729 *data = fdt_getprop(fit, noffset, FIT_DATA_PROP, &len); 730 if (*data == NULL) { 731 fit_get_debug(fit, noffset, FIT_DATA_PROP, len); 732 *size = 0; 733 return -1; 734 } 735 736 *size = len; 737 return 0; 738 } 739 740 /** 741 * fit_image_hash_get_algo - get hash algorithm name 742 * @fit: pointer to the FIT format image header 743 * @noffset: hash node offset 744 * @algo: double pointer to char, will hold pointer to the algorithm name 745 * 746 * fit_image_hash_get_algo() finds hash algorithm property in a given hash node. 747 * If the property is found its data start address is returned to the caller. 748 * 749 * returns: 750 * 0, on success 751 * -1, on failure 752 */ 753 int fit_image_hash_get_algo(const void *fit, int noffset, char **algo) 754 { 755 int len; 756 757 *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len); 758 if (*algo == NULL) { 759 fit_get_debug(fit, noffset, FIT_ALGO_PROP, len); 760 return -1; 761 } 762 763 return 0; 764 } 765 766 /** 767 * fit_image_hash_get_value - get hash value and length 768 * @fit: pointer to the FIT format image header 769 * @noffset: hash node offset 770 * @value: double pointer to uint8_t, will hold address of a hash value data 771 * @value_len: pointer to an int, will hold hash data length 772 * 773 * fit_image_hash_get_value() finds hash value property in a given hash node. 774 * If the property is found its data start address and size are returned to 775 * the caller. 776 * 777 * returns: 778 * 0, on success 779 * -1, on failure 780 */ 781 int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value, 782 int *value_len) 783 { 784 int len; 785 786 *value = (uint8_t *)fdt_getprop(fit, noffset, FIT_VALUE_PROP, &len); 787 if (*value == NULL) { 788 fit_get_debug(fit, noffset, FIT_VALUE_PROP, len); 789 *value_len = 0; 790 return -1; 791 } 792 793 *value_len = len; 794 return 0; 795 } 796 797 /** 798 * fit_image_hash_get_ignore - get hash ignore flag 799 * @fit: pointer to the FIT format image header 800 * @noffset: hash node offset 801 * @ignore: pointer to an int, will hold hash ignore flag 802 * 803 * fit_image_hash_get_ignore() finds hash ignore property in a given hash node. 804 * If the property is found and non-zero, the hash algorithm is not verified by 805 * u-boot automatically. 806 * 807 * returns: 808 * 0, on ignore not found 809 * value, on ignore found 810 */ 811 static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore) 812 { 813 int len; 814 int *value; 815 816 value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len); 817 if (value == NULL || len != sizeof(int)) 818 *ignore = 0; 819 else 820 *ignore = *value; 821 822 return 0; 823 } 824 825 /** 826 * fit_set_timestamp - set node timestamp property 827 * @fit: pointer to the FIT format image header 828 * @noffset: node offset 829 * @timestamp: timestamp value to be set 830 * 831 * fit_set_timestamp() attempts to set timestamp property in the requested 832 * node and returns operation status to the caller. 833 * 834 * returns: 835 * 0, on success 836 * -1, on property read failure 837 */ 838 int fit_set_timestamp(void *fit, int noffset, time_t timestamp) 839 { 840 uint32_t t; 841 int ret; 842 843 t = cpu_to_uimage(timestamp); 844 ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t, 845 sizeof(uint32_t)); 846 if (ret) { 847 printf("Can't set '%s' property for '%s' node (%s)\n", 848 FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL), 849 fdt_strerror(ret)); 850 return -1; 851 } 852 853 return 0; 854 } 855 856 /** 857 * calculate_hash - calculate and return hash for provided input data 858 * @data: pointer to the input data 859 * @data_len: data length 860 * @algo: requested hash algorithm 861 * @value: pointer to the char, will hold hash value data (caller must 862 * allocate enough free space) 863 * value_len: length of the calculated hash 864 * 865 * calculate_hash() computes input data hash according to the requested 866 * algorithm. 867 * Resulting hash value is placed in caller provided 'value' buffer, length 868 * of the calculated hash is returned via value_len pointer argument. 869 * 870 * returns: 871 * 0, on success 872 * -1, when algo is unsupported 873 */ 874 int calculate_hash(const void *data, int data_len, const char *algo, 875 uint8_t *value, int *value_len) 876 { 877 if (IMAGE_ENABLE_CRC32 && strcmp(algo, "crc32") == 0) { 878 *((uint32_t *)value) = crc32_wd(0, data, data_len, 879 CHUNKSZ_CRC32); 880 *((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value)); 881 *value_len = 4; 882 } else if (IMAGE_ENABLE_SHA1 && strcmp(algo, "sha1") == 0) { 883 sha1_csum_wd((unsigned char *)data, data_len, 884 (unsigned char *)value, CHUNKSZ_SHA1); 885 *value_len = 20; 886 } else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) { 887 sha256_csum_wd((unsigned char *)data, data_len, 888 (unsigned char *)value, CHUNKSZ_SHA256); 889 *value_len = SHA256_SUM_LEN; 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 retrieved 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 FIT 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(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