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 <u-boot/crc.h> 25 #include <u-boot/md5.h> 26 #include <u-boot/sha1.h> 27 #include <u-boot/sha256.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 * -ENOSPC if no space in device tree, -1 for other error 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 ret == -FDT_ERR_NOSPACE ? -ENOSPC : -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 (arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64); 1119 } 1120 1121 /** 1122 * fit_image_check_type - check whether image node is of a given type 1123 * @fit: pointer to the FIT format image header 1124 * @noffset: component image node offset 1125 * @type: requested image type 1126 * 1127 * fit_image_check_type() reads image type property and compares its numeric 1128 * id with the requested type. Comparison result is returned to the caller. 1129 * 1130 * returns: 1131 * 1 if image is of given type 1132 * 0 otherwise (or on error) 1133 */ 1134 int fit_image_check_type(const void *fit, int noffset, uint8_t type) 1135 { 1136 uint8_t image_type; 1137 1138 if (fit_image_get_type(fit, noffset, &image_type)) 1139 return 0; 1140 return (type == image_type); 1141 } 1142 1143 /** 1144 * fit_image_check_comp - check whether image node uses given compression 1145 * @fit: pointer to the FIT format image header 1146 * @noffset: component image node offset 1147 * @comp: requested image compression type 1148 * 1149 * fit_image_check_comp() reads image compression property and compares its 1150 * numeric id with the requested compression type. Comparison result is 1151 * returned to the caller. 1152 * 1153 * returns: 1154 * 1 if image uses requested compression 1155 * 0 otherwise (or on error) 1156 */ 1157 int fit_image_check_comp(const void *fit, int noffset, uint8_t comp) 1158 { 1159 uint8_t image_comp; 1160 1161 if (fit_image_get_comp(fit, noffset, &image_comp)) 1162 return 0; 1163 return (comp == image_comp); 1164 } 1165 1166 /** 1167 * fit_check_format - sanity check FIT image format 1168 * @fit: pointer to the FIT format image header 1169 * 1170 * fit_check_format() runs a basic sanity FIT image verification. 1171 * Routine checks for mandatory properties, nodes, etc. 1172 * 1173 * returns: 1174 * 1, on success 1175 * 0, on failure 1176 */ 1177 int fit_check_format(const void *fit) 1178 { 1179 /* mandatory / node 'description' property */ 1180 if (fdt_getprop(fit, 0, FIT_DESC_PROP, NULL) == NULL) { 1181 debug("Wrong FIT format: no description\n"); 1182 return 0; 1183 } 1184 1185 if (IMAGE_ENABLE_TIMESTAMP) { 1186 /* mandatory / node 'timestamp' property */ 1187 if (fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) { 1188 debug("Wrong FIT format: no timestamp\n"); 1189 return 0; 1190 } 1191 } 1192 1193 /* mandatory subimages parent '/images' node */ 1194 if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) { 1195 debug("Wrong FIT format: no images parent node\n"); 1196 return 0; 1197 } 1198 1199 return 1; 1200 } 1201 1202 1203 /** 1204 * fit_conf_find_compat 1205 * @fit: pointer to the FIT format image header 1206 * @fdt: pointer to the device tree to compare against 1207 * 1208 * fit_conf_find_compat() attempts to find the configuration whose fdt is the 1209 * most compatible with the passed in device tree. 1210 * 1211 * Example: 1212 * 1213 * / o image-tree 1214 * |-o images 1215 * | |-o fdt@1 1216 * | |-o fdt@2 1217 * | 1218 * |-o configurations 1219 * |-o config@1 1220 * | |-fdt = fdt@1 1221 * | 1222 * |-o config@2 1223 * |-fdt = fdt@2 1224 * 1225 * / o U-Boot fdt 1226 * |-compatible = "foo,bar", "bim,bam" 1227 * 1228 * / o kernel fdt1 1229 * |-compatible = "foo,bar", 1230 * 1231 * / o kernel fdt2 1232 * |-compatible = "bim,bam", "baz,biz" 1233 * 1234 * Configuration 1 would be picked because the first string in U-Boot's 1235 * compatible list, "foo,bar", matches a compatible string in the root of fdt1. 1236 * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1. 1237 * 1238 * returns: 1239 * offset to the configuration to use if one was found 1240 * -1 otherwise 1241 */ 1242 int fit_conf_find_compat(const void *fit, const void *fdt) 1243 { 1244 int ndepth = 0; 1245 int noffset, confs_noffset, images_noffset; 1246 const void *fdt_compat; 1247 int fdt_compat_len; 1248 int best_match_offset = 0; 1249 int best_match_pos = 0; 1250 1251 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); 1252 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); 1253 if (confs_noffset < 0 || images_noffset < 0) { 1254 debug("Can't find configurations or images nodes.\n"); 1255 return -1; 1256 } 1257 1258 fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len); 1259 if (!fdt_compat) { 1260 debug("Fdt for comparison has no \"compatible\" property.\n"); 1261 return -1; 1262 } 1263 1264 /* 1265 * Loop over the configurations in the FIT image. 1266 */ 1267 for (noffset = fdt_next_node(fit, confs_noffset, &ndepth); 1268 (noffset >= 0) && (ndepth > 0); 1269 noffset = fdt_next_node(fit, noffset, &ndepth)) { 1270 const void *kfdt; 1271 const char *kfdt_name; 1272 int kfdt_noffset; 1273 const char *cur_fdt_compat; 1274 int len; 1275 size_t size; 1276 int i; 1277 1278 if (ndepth > 1) 1279 continue; 1280 1281 kfdt_name = fdt_getprop(fit, noffset, "fdt", &len); 1282 if (!kfdt_name) { 1283 debug("No fdt property found.\n"); 1284 continue; 1285 } 1286 kfdt_noffset = fdt_subnode_offset(fit, images_noffset, 1287 kfdt_name); 1288 if (kfdt_noffset < 0) { 1289 debug("No image node named \"%s\" found.\n", 1290 kfdt_name); 1291 continue; 1292 } 1293 /* 1294 * Get a pointer to this configuration's fdt. 1295 */ 1296 if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) { 1297 debug("Failed to get fdt \"%s\".\n", kfdt_name); 1298 continue; 1299 } 1300 1301 len = fdt_compat_len; 1302 cur_fdt_compat = fdt_compat; 1303 /* 1304 * Look for a match for each U-Boot compatibility string in 1305 * turn in this configuration's fdt. 1306 */ 1307 for (i = 0; len > 0 && 1308 (!best_match_offset || best_match_pos > i); i++) { 1309 int cur_len = strlen(cur_fdt_compat) + 1; 1310 1311 if (!fdt_node_check_compatible(kfdt, 0, 1312 cur_fdt_compat)) { 1313 best_match_offset = noffset; 1314 best_match_pos = i; 1315 break; 1316 } 1317 len -= cur_len; 1318 cur_fdt_compat += cur_len; 1319 } 1320 } 1321 if (!best_match_offset) { 1322 debug("No match found.\n"); 1323 return -1; 1324 } 1325 1326 return best_match_offset; 1327 } 1328 1329 /** 1330 * fit_conf_get_node - get node offset for configuration of a given unit name 1331 * @fit: pointer to the FIT format image header 1332 * @conf_uname: configuration node unit name 1333 * 1334 * fit_conf_get_node() finds a configuration (withing the '/configurations' 1335 * parant node) of a provided unit name. If configuration is found its node 1336 * offset is returned to the caller. 1337 * 1338 * When NULL is provided in second argument fit_conf_get_node() will search 1339 * for a default configuration node instead. Default configuration node unit 1340 * name is retrieved from FIT_DEFAULT_PROP property of the '/configurations' 1341 * node. 1342 * 1343 * returns: 1344 * configuration node offset when found (>=0) 1345 * negative number on failure (FDT_ERR_* code) 1346 */ 1347 int fit_conf_get_node(const void *fit, const char *conf_uname) 1348 { 1349 int noffset, confs_noffset; 1350 int len; 1351 1352 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); 1353 if (confs_noffset < 0) { 1354 debug("Can't find configurations parent node '%s' (%s)\n", 1355 FIT_CONFS_PATH, fdt_strerror(confs_noffset)); 1356 return confs_noffset; 1357 } 1358 1359 if (conf_uname == NULL) { 1360 /* get configuration unit name from the default property */ 1361 debug("No configuration specified, trying default...\n"); 1362 conf_uname = (char *)fdt_getprop(fit, confs_noffset, 1363 FIT_DEFAULT_PROP, &len); 1364 if (conf_uname == NULL) { 1365 fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP, 1366 len); 1367 return len; 1368 } 1369 debug("Found default configuration: '%s'\n", conf_uname); 1370 } 1371 1372 noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname); 1373 if (noffset < 0) { 1374 debug("Can't get node offset for configuration unit name: '%s' (%s)\n", 1375 conf_uname, fdt_strerror(noffset)); 1376 } 1377 1378 return noffset; 1379 } 1380 1381 int fit_conf_get_prop_node(const void *fit, int noffset, 1382 const char *prop_name) 1383 { 1384 char *uname; 1385 int len; 1386 1387 /* get kernel image unit name from configuration kernel property */ 1388 uname = (char *)fdt_getprop(fit, noffset, prop_name, &len); 1389 if (uname == NULL) 1390 return len; 1391 1392 return fit_image_get_node(fit, uname); 1393 } 1394 1395 /** 1396 * fit_conf_print - prints out the FIT configuration details 1397 * @fit: pointer to the FIT format image header 1398 * @noffset: offset of the configuration node 1399 * @p: pointer to prefix string 1400 * 1401 * fit_conf_print() lists all mandatory properies for the processed 1402 * configuration node. 1403 * 1404 * returns: 1405 * no returned results 1406 */ 1407 void fit_conf_print(const void *fit, int noffset, const char *p) 1408 { 1409 char *desc; 1410 char *uname; 1411 int ret; 1412 1413 /* Mandatory properties */ 1414 ret = fit_get_desc(fit, noffset, &desc); 1415 printf("%s Description: ", p); 1416 if (ret) 1417 printf("unavailable\n"); 1418 else 1419 printf("%s\n", desc); 1420 1421 uname = (char *)fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL); 1422 printf("%s Kernel: ", p); 1423 if (uname == NULL) 1424 printf("unavailable\n"); 1425 else 1426 printf("%s\n", uname); 1427 1428 /* Optional properties */ 1429 uname = (char *)fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL); 1430 if (uname) 1431 printf("%s Init Ramdisk: %s\n", p, uname); 1432 1433 uname = (char *)fdt_getprop(fit, noffset, FIT_FDT_PROP, NULL); 1434 if (uname) 1435 printf("%s FDT: %s\n", p, uname); 1436 } 1437 1438 static int fit_image_select(const void *fit, int rd_noffset, int verify) 1439 { 1440 fit_image_print(fit, rd_noffset, " "); 1441 1442 if (verify) { 1443 puts(" Verifying Hash Integrity ... "); 1444 if (!fit_image_verify(fit, rd_noffset)) { 1445 puts("Bad Data Hash\n"); 1446 return -EACCES; 1447 } 1448 puts("OK\n"); 1449 } 1450 1451 return 0; 1452 } 1453 1454 int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name, 1455 ulong addr) 1456 { 1457 int cfg_noffset; 1458 void *fit_hdr; 1459 int noffset; 1460 1461 debug("* %s: using config '%s' from image at 0x%08lx\n", 1462 prop_name, images->fit_uname_cfg, addr); 1463 1464 /* Check whether configuration has this property defined */ 1465 fit_hdr = map_sysmem(addr, 0); 1466 cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg); 1467 if (cfg_noffset < 0) { 1468 debug("* %s: no such config\n", prop_name); 1469 return -ENOENT; 1470 } 1471 1472 noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name); 1473 if (noffset < 0) { 1474 debug("* %s: no '%s' in config\n", prop_name, prop_name); 1475 return -ENOLINK; 1476 } 1477 1478 return noffset; 1479 } 1480 1481 /** 1482 * fit_get_image_type_property() - get property name for IH_TYPE_... 1483 * 1484 * @return the properly name where we expect to find the image in the 1485 * config node 1486 */ 1487 static const char *fit_get_image_type_property(int type) 1488 { 1489 /* 1490 * This is sort-of available in the uimage_type[] table in image.c 1491 * but we don't have access to the sohrt name, and "fdt" is different 1492 * anyway. So let's just keep it here. 1493 */ 1494 switch (type) { 1495 case IH_TYPE_FLATDT: 1496 return FIT_FDT_PROP; 1497 case IH_TYPE_KERNEL: 1498 return FIT_KERNEL_PROP; 1499 case IH_TYPE_RAMDISK: 1500 return FIT_RAMDISK_PROP; 1501 case IH_TYPE_X86_SETUP: 1502 return FIT_SETUP_PROP; 1503 } 1504 1505 return "unknown"; 1506 } 1507 1508 int fit_image_load(bootm_headers_t *images, ulong addr, 1509 const char **fit_unamep, const char **fit_uname_configp, 1510 int arch, int image_type, int bootstage_id, 1511 enum fit_load_op load_op, ulong *datap, ulong *lenp) 1512 { 1513 int cfg_noffset, noffset; 1514 const char *fit_uname; 1515 const char *fit_uname_config; 1516 const void *fit; 1517 const void *buf; 1518 size_t size; 1519 int type_ok, os_ok; 1520 ulong load, data, len; 1521 uint8_t os; 1522 const char *prop_name; 1523 int ret; 1524 1525 fit = map_sysmem(addr, 0); 1526 fit_uname = fit_unamep ? *fit_unamep : NULL; 1527 fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL; 1528 prop_name = fit_get_image_type_property(image_type); 1529 printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr); 1530 1531 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT); 1532 if (!fit_check_format(fit)) { 1533 printf("Bad FIT %s image format!\n", prop_name); 1534 bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT); 1535 return -ENOEXEC; 1536 } 1537 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK); 1538 if (fit_uname) { 1539 /* get FIT component image node offset */ 1540 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME); 1541 noffset = fit_image_get_node(fit, fit_uname); 1542 } else { 1543 /* 1544 * no image node unit name, try to get config 1545 * node first. If config unit node name is NULL 1546 * fit_conf_get_node() will try to find default config node 1547 */ 1548 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME); 1549 if (IMAGE_ENABLE_BEST_MATCH && !fit_uname_config) { 1550 cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob()); 1551 } else { 1552 cfg_noffset = fit_conf_get_node(fit, 1553 fit_uname_config); 1554 } 1555 if (cfg_noffset < 0) { 1556 puts("Could not find configuration node\n"); 1557 bootstage_error(bootstage_id + 1558 BOOTSTAGE_SUB_NO_UNIT_NAME); 1559 return -ENOENT; 1560 } 1561 fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL); 1562 printf(" Using '%s' configuration\n", fit_uname_config); 1563 if (image_type == IH_TYPE_KERNEL) { 1564 /* Remember (and possibly verify) this config */ 1565 images->fit_uname_cfg = fit_uname_config; 1566 if (IMAGE_ENABLE_VERIFY && images->verify) { 1567 puts(" Verifying Hash Integrity ... "); 1568 if (fit_config_verify(fit, cfg_noffset)) { 1569 puts("Bad Data Hash\n"); 1570 bootstage_error(bootstage_id + 1571 BOOTSTAGE_SUB_HASH); 1572 return -EACCES; 1573 } 1574 puts("OK\n"); 1575 } 1576 bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG); 1577 } 1578 1579 noffset = fit_conf_get_prop_node(fit, cfg_noffset, 1580 prop_name); 1581 fit_uname = fit_get_name(fit, noffset, NULL); 1582 } 1583 if (noffset < 0) { 1584 puts("Could not find subimage node\n"); 1585 bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE); 1586 return -ENOENT; 1587 } 1588 1589 printf(" Trying '%s' %s subimage\n", fit_uname, prop_name); 1590 1591 ret = fit_image_select(fit, noffset, images->verify); 1592 if (ret) { 1593 bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH); 1594 return ret; 1595 } 1596 1597 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH); 1598 #if !defined(USE_HOSTCC) && !defined(CONFIG_SANDBOX) 1599 if (!fit_image_check_target_arch(fit, noffset)) { 1600 puts("Unsupported Architecture\n"); 1601 bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH); 1602 return -ENOEXEC; 1603 } 1604 #endif 1605 if (image_type == IH_TYPE_FLATDT && 1606 !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) { 1607 puts("FDT image is compressed"); 1608 return -EPROTONOSUPPORT; 1609 } 1610 1611 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL); 1612 type_ok = fit_image_check_type(fit, noffset, image_type) || 1613 (image_type == IH_TYPE_KERNEL && 1614 fit_image_check_type(fit, noffset, 1615 IH_TYPE_KERNEL_NOLOAD)); 1616 1617 os_ok = image_type == IH_TYPE_FLATDT || 1618 fit_image_check_os(fit, noffset, IH_OS_LINUX) || 1619 fit_image_check_os(fit, noffset, IH_OS_OPENRTOS); 1620 if (!type_ok || !os_ok) { 1621 fit_image_get_os(fit, noffset, &os); 1622 printf("No %s %s %s Image\n", 1623 genimg_get_os_name(os), 1624 genimg_get_arch_name(arch), 1625 genimg_get_type_name(image_type)); 1626 bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL); 1627 return -EIO; 1628 } 1629 1630 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK); 1631 1632 /* get image data address and length */ 1633 if (fit_image_get_data(fit, noffset, &buf, &size)) { 1634 printf("Could not find %s subimage data!\n", prop_name); 1635 bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA); 1636 return -ENOENT; 1637 } 1638 len = (ulong)size; 1639 1640 /* verify that image data is a proper FDT blob */ 1641 if (image_type == IH_TYPE_FLATDT && fdt_check_header(buf)) { 1642 puts("Subimage data is not a FDT"); 1643 return -ENOEXEC; 1644 } 1645 1646 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK); 1647 1648 /* 1649 * Work-around for eldk-4.2 which gives this warning if we try to 1650 * cast in the unmap_sysmem() call: 1651 * warning: initialization discards qualifiers from pointer target type 1652 */ 1653 { 1654 void *vbuf = (void *)buf; 1655 1656 data = map_to_sysmem(vbuf); 1657 } 1658 1659 if (load_op == FIT_LOAD_IGNORED) { 1660 /* Don't load */ 1661 } else if (fit_image_get_load(fit, noffset, &load)) { 1662 if (load_op == FIT_LOAD_REQUIRED) { 1663 printf("Can't get %s subimage load address!\n", 1664 prop_name); 1665 bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD); 1666 return -EBADF; 1667 } 1668 } else if (load_op != FIT_LOAD_OPTIONAL_NON_ZERO || load) { 1669 ulong image_start, image_end; 1670 ulong load_end; 1671 void *dst; 1672 1673 /* 1674 * move image data to the load address, 1675 * make sure we don't overwrite initial image 1676 */ 1677 image_start = addr; 1678 image_end = addr + fit_get_size(fit); 1679 1680 load_end = load + len; 1681 if (image_type != IH_TYPE_KERNEL && 1682 load < image_end && load_end > image_start) { 1683 printf("Error: %s overwritten\n", prop_name); 1684 return -EXDEV; 1685 } 1686 1687 printf(" Loading %s from 0x%08lx to 0x%08lx\n", 1688 prop_name, data, load); 1689 1690 dst = map_sysmem(load, len); 1691 memmove(dst, buf, len); 1692 data = load; 1693 } 1694 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD); 1695 1696 *datap = data; 1697 *lenp = len; 1698 if (fit_unamep) 1699 *fit_unamep = (char *)fit_uname; 1700 if (fit_uname_configp) 1701 *fit_uname_configp = (char *)fit_uname_config; 1702 1703 return noffset; 1704 } 1705 1706 int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, 1707 ulong *setup_start, ulong *setup_len) 1708 { 1709 int noffset; 1710 ulong addr; 1711 ulong len; 1712 int ret; 1713 1714 addr = map_to_sysmem(images->fit_hdr_os); 1715 noffset = fit_get_node_from_config(images, FIT_SETUP_PROP, addr); 1716 if (noffset < 0) 1717 return noffset; 1718 1719 ret = fit_image_load(images, addr, NULL, NULL, arch, 1720 IH_TYPE_X86_SETUP, BOOTSTAGE_ID_FIT_SETUP_START, 1721 FIT_LOAD_REQUIRED, setup_start, &len); 1722 1723 return ret; 1724 } 1725