1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Generate MediaTek BootROM header for SPL/U-Boot images 4 * 5 * Copyright (C) 2018 MediaTek Inc. 6 * Author: Weijie Gao <weijie.gao@mediatek.com> 7 */ 8 9#include <time.h> 10#include <image.h> 11#include <u-boot/crc.h> 12#include <u-boot/sha256.h> 13#include "imagetool.h" 14#include "mtk_image.h" 15#include "mtk_nand_headers.h" 16 17static const struct brom_img_type { 18 const char *name; 19 enum brlyt_img_type type; 20} brom_images[] = { 21 { 22 .name = "nand", 23 .type = BRLYT_TYPE_NAND 24 }, { 25 .name = "emmc", 26 .type = BRLYT_TYPE_EMMC 27 }, { 28 .name = "nor", 29 .type = BRLYT_TYPE_NOR 30 }, { 31 .name = "sdmmc", 32 .type = BRLYT_TYPE_SDMMC 33 }, { 34 .name = "snand", 35 .type = BRLYT_TYPE_SNAND 36 }, { 37 .name = "spim-nand", 38 .type = BRLYT_TYPE_SNAND 39 } 40}; 41 42/* Indicates whether we're generating or verifying */ 43static bool img_gen; 44static uint32_t img_size; 45 46/* Image type selected by user */ 47static enum brlyt_img_type hdr_media; 48static uint32_t hdr_offset; 49static int use_lk_hdr; 50static int use_mt7621_hdr; 51static bool is_arm64_image; 52 53/* LK image name */ 54static char lk_name[32] = "U-Boot"; 55 56/* CRC32 normal table required by MT7621 image */ 57static uint32_t crc32tbl[256]; 58 59/* NAND header selected by user */ 60static const struct nand_header_type *hdr_nand; 61static uint32_t hdr_nand_size; 62 63/* GFH header + 2 * 4KB pages of NAND */ 64static char hdr_tmp[sizeof(struct gfh_header) + 0x2000]; 65 66static uint32_t crc32_normal_cal(uint32_t crc, const void *data, size_t length, 67 const uint32_t *crc32c_table) 68{ 69 const uint8_t *p = data; 70 71 while (length--) 72 crc = crc32c_table[(uint8_t)((crc >> 24) ^ *p++)] ^ (crc << 8); 73 74 return crc; 75} 76 77static void crc32_normal_init(uint32_t *crc32c_table, uint32_t poly) 78{ 79 uint32_t v, i, j; 80 81 for (i = 0; i < 256; i++) { 82 v = i << 24; 83 for (j = 0; j < 8; j++) 84 v = (v << 1) ^ ((v & (1 << 31)) ? poly : 0); 85 86 crc32c_table[i] = v; 87 } 88} 89 90static int mtk_image_check_image_types(uint8_t type) 91{ 92 if (type == IH_TYPE_MTKIMAGE) 93 return EXIT_SUCCESS; 94 else 95 return EXIT_FAILURE; 96} 97 98static int mtk_brom_parse_imagename(const char *imagename) 99{ 100#define is_blank_char(c) \ 101 ((c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == ' ') 102 103 char *buf = strdup(imagename), *key, *val, *end, *next; 104 int i; 105 106 /* User passed arguments from image name */ 107 static const char *media = ""; 108 static const char *hdr_offs = ""; 109 static const char *nandinfo = ""; 110 static const char *lk = ""; 111 static const char *mt7621 = ""; 112 static const char *arm64_param = ""; 113 114 key = buf; 115 while (key) { 116 next = strchr(key, ';'); 117 if (next) 118 *next = 0; 119 120 val = strchr(key, '='); 121 if (val) { 122 *val++ = 0; 123 124 /* Trim key */ 125 while (is_blank_char(*key)) 126 key++; 127 128 end = key + strlen(key) - 1; 129 while ((end >= key) && is_blank_char(*end)) 130 end--; 131 end++; 132 133 if (is_blank_char(*end)) 134 *end = 0; 135 136 /* Trim value */ 137 while (is_blank_char(*val)) 138 val++; 139 140 end = val + strlen(val) - 1; 141 while ((end >= val) && is_blank_char(*end)) 142 end--; 143 end++; 144 145 if (is_blank_char(*end)) 146 *end = 0; 147 148 /* record user passed arguments */ 149 if (!strcmp(key, "media")) 150 media = val; 151 152 if (!strcmp(key, "hdroffset")) 153 hdr_offs = val; 154 155 if (!strcmp(key, "nandinfo")) 156 nandinfo = val; 157 158 if (!strcmp(key, "lk")) 159 lk = val; 160 161 if (!strcmp(key, "mt7621")) 162 mt7621 = val; 163 164 if (!strcmp(key, "lkname")) 165 snprintf(lk_name, sizeof(lk_name), "%s", val); 166 167 if (!strcmp(key, "arm64")) 168 arm64_param = val; 169 } 170 171 if (next) 172 key = next + 1; 173 else 174 break; 175 } 176 177 /* if user specified LK image header, skip following checks */ 178 if (lk && lk[0] == '1') { 179 use_lk_hdr = 1; 180 free(buf); 181 return 0; 182 } 183 184 /* if user specified MT7621 image header, skip following checks */ 185 if (mt7621 && mt7621[0] == '1') { 186 use_mt7621_hdr = 1; 187 free(buf); 188 return 0; 189 } 190 191 /* parse media type */ 192 for (i = 0; i < ARRAY_SIZE(brom_images); i++) { 193 if (!strcmp(brom_images[i].name, media)) { 194 hdr_media = brom_images[i].type; 195 break; 196 } 197 } 198 199 /* parse nand header type */ 200 hdr_nand = mtk_nand_header_find(nandinfo); 201 202 /* parse device header offset */ 203 if (hdr_offs && hdr_offs[0]) 204 hdr_offset = strtoul(hdr_offs, NULL, 0); 205 206 if (arm64_param && arm64_param[0] == '1') 207 is_arm64_image = true; 208 209 free(buf); 210 211 if (hdr_media == BRLYT_TYPE_INVALID) { 212 fprintf(stderr, "Error: media type is invalid or missing.\n"); 213 fprintf(stderr, " Please specify -n \"media=<type>\"\n"); 214 return -EINVAL; 215 } 216 217 if ((hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) && 218 !hdr_nand) { 219 fprintf(stderr, "Error: nand info is invalid or missing.\n"); 220 fprintf(stderr, " Please specify -n \"media=%s;" 221 "nandinfo=<info>\"\n", media); 222 return -EINVAL; 223 } 224 225 if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) 226 hdr_nand_size = mtk_nand_header_size(hdr_nand); 227 228 return 0; 229} 230 231static int mtk_image_check_params(struct image_tool_params *params) 232{ 233 if (!params->addr) { 234 fprintf(stderr, "Error: Load Address must be set.\n"); 235 return -EINVAL; 236 } 237 238 if (!params->imagename) { 239 fprintf(stderr, "Error: Image Name must be set.\n"); 240 return -EINVAL; 241 } 242 243 return mtk_brom_parse_imagename(params->imagename); 244} 245 246static int mtk_image_vrec_header(struct image_tool_params *params, 247 struct image_type_params *tparams) 248{ 249 if (use_lk_hdr) { 250 tparams->header_size = sizeof(union lk_hdr); 251 tparams->hdr = &hdr_tmp; 252 memset(&hdr_tmp, 0xff, tparams->header_size); 253 return 0; 254 } 255 256 if (use_mt7621_hdr) { 257 tparams->header_size = image_get_header_size(); 258 tparams->hdr = &hdr_tmp; 259 memset(&hdr_tmp, 0, tparams->header_size); 260 return 0; 261 } 262 263 if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) 264 tparams->header_size = hdr_nand_size; 265 else 266 tparams->header_size = sizeof(struct gen_device_header); 267 268 tparams->header_size += sizeof(struct gfh_header); 269 tparams->hdr = &hdr_tmp; 270 271 memset(&hdr_tmp, 0xff, tparams->header_size); 272 273 return SHA256_SUM_LEN; 274} 275 276static int mtk_image_verify_gfh(struct gfh_header *gfh, uint32_t type, int print) 277{ 278 if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME)) 279 return -1; 280 281 if (le32_to_cpu(gfh->file_info.flash_type) != type) 282 return -1; 283 284 if (print) 285 printf("Load Address: %08x\n", 286 le32_to_cpu(gfh->file_info.load_addr) + 287 le32_to_cpu(gfh->file_info.jump_offset)); 288 289 if (print) 290 printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); 291 292 return 0; 293} 294 295static int mtk_image_verify_gen_header(const uint8_t *ptr, int print) 296{ 297 union gen_boot_header *gbh = (union gen_boot_header *)ptr; 298 uint32_t gfh_offset, total_size, devh_size; 299 struct brom_layout_header *bh; 300 struct gfh_header *gfh; 301 const char *bootmedia; 302 303 if (!strcmp(gbh->name, SF_BOOT_NAME)) 304 bootmedia = "Serial NOR"; 305 else if (!strcmp(gbh->name, EMMC_BOOT_NAME)) 306 bootmedia = "eMMC"; 307 else if (!strcmp(gbh->name, SDMMC_BOOT_NAME)) 308 bootmedia = "SD/MMC"; 309 else 310 return -1; 311 312 if (print) 313 printf("Boot Media: %s\n", bootmedia); 314 315 if (le32_to_cpu(gbh->version) != 1 || 316 le32_to_cpu(gbh->size) != sizeof(union gen_boot_header)) 317 return -1; 318 319 bh = (struct brom_layout_header *)(ptr + le32_to_cpu(gbh->size)); 320 321 if (strcmp(bh->name, BRLYT_NAME)) 322 return -1; 323 324 if (le32_to_cpu(bh->magic) != BRLYT_MAGIC || 325 (le32_to_cpu(bh->type) != BRLYT_TYPE_NOR && 326 le32_to_cpu(bh->type) != BRLYT_TYPE_EMMC && 327 le32_to_cpu(bh->type) != BRLYT_TYPE_SDMMC)) 328 return -1; 329 330 devh_size = sizeof(struct gen_device_header); 331 332 if (img_gen) { 333 gfh_offset = devh_size; 334 } else { 335 gfh_offset = le32_to_cpu(bh->header_size); 336 337 if (gfh_offset + sizeof(struct gfh_header) > img_size) { 338 /* 339 * This may happen if the hdr_offset used to generate 340 * this image is not zero. 341 * Since device header size is not fixed, we can't 342 * cover all possible cases. 343 * Assuming the image is valid only if the real 344 * device header size equals to devh_size. 345 */ 346 total_size = le32_to_cpu(bh->total_size); 347 348 if (total_size - gfh_offset > img_size - devh_size) 349 return -1; 350 351 gfh_offset = devh_size; 352 } 353 } 354 355 gfh = (struct gfh_header *)(ptr + gfh_offset); 356 357 return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_GEN, print); 358} 359 360static int mtk_image_verify_nand_header(const uint8_t *ptr, int print) 361{ 362 struct brom_layout_header *bh; 363 struct nand_header_info info; 364 struct gfh_header *gfh; 365 const char *bootmedia; 366 int ret; 367 368 ret = mtk_nand_header_info(ptr, &info); 369 if (ret < 0) 370 return ret; 371 372 if (!ret) { 373 bh = (struct brom_layout_header *)(ptr + info.page_size); 374 375 if (strcmp(bh->name, BRLYT_NAME)) 376 return -1; 377 378 if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) 379 return -1; 380 381 if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) 382 bootmedia = "Parallel NAND"; 383 else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND) 384 bootmedia = "Serial NAND (SNFI/AP)"; 385 else 386 return -1; 387 } else { 388 if (info.snfi) 389 bootmedia = "Serial NAND (SNFI/HSM)"; 390 else 391 bootmedia = "Serial NAND (SPIM)"; 392 } 393 394 if (print) { 395 printf("Boot Media: %s\n", bootmedia); 396 397 if (info.page_size >= 1024) 398 printf("Page Size: %dKB\n", info.page_size >> 10); 399 else 400 printf("Page Size: %dB\n", info.page_size); 401 402 printf("Spare Size: %dB\n", info.spare_size); 403 } 404 405 gfh = (struct gfh_header *)(ptr + info.gfh_offset); 406 407 return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_NAND, print); 408} 409 410static uint32_t crc32be_cal(const void *data, size_t length) 411{ 412 uint32_t crc = 0; 413 uint8_t c; 414 415 if (crc32tbl[1] != MT7621_IH_CRC_POLYNOMIAL) 416 crc32_normal_init(crc32tbl, MT7621_IH_CRC_POLYNOMIAL); 417 418 crc = crc32_normal_cal(crc, data, length, crc32tbl); 419 420 for (; length; length >>= 8) { 421 c = length & 0xff; 422 crc = crc32_normal_cal(crc, &c, 1, crc32tbl); 423 } 424 425 return ~crc; 426} 427 428static int mtk_image_verify_mt7621_header(const uint8_t *ptr, int print) 429{ 430 const struct legacy_img_hdr *hdr = (const struct legacy_img_hdr *)ptr; 431 struct mt7621_nand_header *nhdr; 432 uint32_t spl_size, crcval; 433 struct legacy_img_hdr header; 434 int ret; 435 436 spl_size = image_get_size(hdr); 437 438 if (spl_size > img_size) { 439 if (print) 440 printf("Incomplete SPL image\n"); 441 return -1; 442 } 443 444 ret = image_check_hcrc(hdr); 445 if (!ret) { 446 if (print) 447 printf("Bad header CRC\n"); 448 return -1; 449 } 450 451 ret = image_check_dcrc(hdr); 452 if (!ret) { 453 if (print) 454 printf("Bad data CRC\n"); 455 return -1; 456 } 457 458 /* Copy header so we can blank CRC field for re-calculation */ 459 memmove(&header, hdr, image_get_header_size()); 460 image_set_hcrc(&header, 0); 461 462 nhdr = (struct mt7621_nand_header *)header.ih_name; 463 crcval = be32_to_cpu(nhdr->crc); 464 nhdr->crc = 0; 465 466 if (crcval != crc32be_cal(&header, image_get_header_size())) { 467 if (print) 468 printf("Bad NAND header CRC\n"); 469 return -1; 470 } 471 472 if (print) { 473 printf("Load Address: %08x\n", image_get_load(hdr)); 474 475 printf("Image Name: %.*s\n", MT7621_IH_NMLEN, 476 image_get_name(hdr)); 477 478 if (IMAGE_ENABLE_TIMESTAMP) { 479 printf("Created: "); 480 genimg_print_time((time_t)image_get_time(hdr)); 481 } 482 483 printf("Data Size: "); 484 genimg_print_size(image_get_data_size(hdr)); 485 } 486 487 return 0; 488} 489 490static int mtk_image_verify_header(unsigned char *ptr, int image_size, 491 struct image_tool_params *params) 492{ 493 struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; 494 union lk_hdr *lk = (union lk_hdr *)ptr; 495 496 /* nothing to verify for LK image header */ 497 if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) 498 return 0; 499 500 img_size = image_size; 501 502 if (image_get_magic(hdr) == IH_MAGIC) 503 return mtk_image_verify_mt7621_header(ptr, 0); 504 505 if (is_mtk_nand_header(ptr)) 506 return mtk_image_verify_nand_header(ptr, 0); 507 else 508 return mtk_image_verify_gen_header(ptr, 0); 509 510 return -1; 511} 512 513static void mtk_image_print_header(const void *ptr, struct image_tool_params *params) 514{ 515 struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; 516 union lk_hdr *lk = (union lk_hdr *)ptr; 517 518 if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) { 519 printf("Image Type: MediaTek LK Image\n"); 520 printf("Load Address: %08x\n", le32_to_cpu(lk->loadaddr)); 521 return; 522 } 523 524 printf("Image Type: MediaTek BootROM Loadable Image\n"); 525 526 if (image_get_magic(hdr) == IH_MAGIC) { 527 mtk_image_verify_mt7621_header(ptr, 1); 528 return; 529 } 530 531 if (is_mtk_nand_header(ptr)) 532 mtk_image_verify_nand_header(ptr, 1); 533 else 534 mtk_image_verify_gen_header(ptr, 1); 535} 536 537static void put_brom_layout_header(struct brom_layout_header *hdr, int type) 538{ 539 strncpy(hdr->name, BRLYT_NAME, sizeof(hdr->name)); 540 hdr->version = cpu_to_le32(1); 541 hdr->magic = cpu_to_le32(BRLYT_MAGIC); 542 hdr->type = cpu_to_le32(type); 543} 544 545static void put_ghf_common_header(struct gfh_common_header *gfh, uint16_t size, 546 uint16_t type, uint8_t ver) 547{ 548 uint32_t magic_version = GFH_HEADER_MAGIC | 549 (uint32_t)ver << GFH_HEADER_VERSION_SHIFT; 550 551 gfh->magic_version = cpu_to_le32(magic_version); 552 gfh->size = cpu_to_le16(size); 553 gfh->type = cpu_to_le16(type); 554} 555 556static void put_ghf_header(struct gfh_header *gfh, int file_size, 557 int dev_hdr_size, int load_addr, int flash_type) 558{ 559 uint32_t cfg_bits; 560 561 memset(gfh, 0, sizeof(struct gfh_header)); 562 563 /* GFH_FILE_INFO header */ 564 put_ghf_common_header(&gfh->file_info.gfh, sizeof(gfh->file_info), 565 GFH_TYPE_FILE_INFO, 1); 566 strncpy(gfh->file_info.name, GFH_FILE_INFO_NAME, 567 sizeof(gfh->file_info.name)); 568 gfh->file_info.unused = cpu_to_le32(1); 569 gfh->file_info.file_type = cpu_to_le16(1); 570 gfh->file_info.flash_type = flash_type; 571 gfh->file_info.sig_type = GFH_SIG_TYPE_SHA256; 572 gfh->file_info.load_addr = cpu_to_le32(load_addr - sizeof(*gfh)); 573 gfh->file_info.total_size = cpu_to_le32(file_size - dev_hdr_size); 574 gfh->file_info.max_size = cpu_to_le32(file_size); 575 gfh->file_info.hdr_size = sizeof(*gfh); 576 gfh->file_info.sig_size = SHA256_SUM_LEN; 577 gfh->file_info.jump_offset = sizeof(*gfh); 578 gfh->file_info.processed = cpu_to_le32(1); 579 580 /* GFH_BL_INFO header */ 581 put_ghf_common_header(&gfh->bl_info.gfh, sizeof(gfh->bl_info), 582 GFH_TYPE_BL_INFO, 1); 583 gfh->bl_info.attr = cpu_to_le32(1); 584 585 /* GFH_BROM_CFG header */ 586 put_ghf_common_header(&gfh->brom_cfg.gfh, sizeof(gfh->brom_cfg), 587 GFH_TYPE_BROM_CFG, 3); 588 cfg_bits = GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS | 589 GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN | 590 GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN; 591 gfh->brom_cfg.usbdl_by_kcol0_timeout_ms = cpu_to_le32(5000); 592 if (is_arm64_image) { 593 gfh->brom_cfg.jump_bl_arm64 = GFH_BROM_CFG_JUMP_BL_ARM64; 594 cfg_bits |= GFH_BROM_CFG_JUMP_BL_ARM64_EN; 595 } 596 gfh->brom_cfg.cfg_bits = cpu_to_le32(cfg_bits); 597 598 /* GFH_BL_SEC_KEY header */ 599 put_ghf_common_header(&gfh->bl_sec_key.gfh, sizeof(gfh->bl_sec_key), 600 GFH_TYPE_BL_SEC_KEY, 1); 601 602 /* GFH_ANTI_CLONE header */ 603 put_ghf_common_header(&gfh->anti_clone.gfh, sizeof(gfh->anti_clone), 604 GFH_TYPE_ANTI_CLONE, 1); 605 gfh->anti_clone.ac_offset = cpu_to_le32(0x10); 606 gfh->anti_clone.ac_len = cpu_to_le32(0x80); 607 608 /* GFH_BROM_SEC_CFG header */ 609 put_ghf_common_header(&gfh->brom_sec_cfg.gfh, 610 sizeof(gfh->brom_sec_cfg), 611 GFH_TYPE_BROM_SEC_CFG, 1); 612 gfh->brom_sec_cfg.cfg_bits = 613 cpu_to_le32(BROM_SEC_CFG_JTAG_EN | BROM_SEC_CFG_UART_EN); 614} 615 616static void put_hash(uint8_t *buff, int size) 617{ 618 sha256_context ctx; 619 620 sha256_starts(&ctx); 621 sha256_update(&ctx, buff, size); 622 sha256_finish(&ctx, buff + size); 623} 624 625static void mtk_image_set_gen_header(void *ptr, off_t filesize, 626 uint32_t loadaddr) 627{ 628 struct gen_device_header *hdr = (struct gen_device_header *)ptr; 629 struct gfh_header *gfh; 630 const char *bootname = NULL; 631 632 if (hdr_media == BRLYT_TYPE_NOR) 633 bootname = SF_BOOT_NAME; 634 else if (hdr_media == BRLYT_TYPE_EMMC) 635 bootname = EMMC_BOOT_NAME; 636 else if (hdr_media == BRLYT_TYPE_SDMMC) 637 bootname = SDMMC_BOOT_NAME; 638 639 /* Generic device header */ 640 snprintf(hdr->boot.name, sizeof(hdr->boot.name), "%s", bootname); 641 hdr->boot.version = cpu_to_le32(1); 642 hdr->boot.size = cpu_to_le32(sizeof(hdr->boot)); 643 644 /* BRLYT header */ 645 put_brom_layout_header(&hdr->brlyt, hdr_media); 646 hdr->brlyt.header_size = cpu_to_le32(hdr_offset + sizeof(*hdr)); 647 hdr->brlyt.total_size = cpu_to_le32(hdr_offset + filesize); 648 hdr->brlyt.header_size_2 = hdr->brlyt.header_size; 649 hdr->brlyt.total_size_2 = hdr->brlyt.total_size; 650 651 /* GFH header */ 652 gfh = (struct gfh_header *)(ptr + sizeof(struct gen_device_header)); 653 put_ghf_header(gfh, filesize, sizeof(struct gen_device_header), 654 loadaddr, GFH_FLASH_TYPE_GEN); 655 656 /* Generate SHA256 hash */ 657 put_hash((uint8_t *)gfh, 658 filesize - sizeof(struct gen_device_header) - SHA256_SUM_LEN); 659} 660 661static void mtk_image_set_nand_header(void *ptr, off_t filesize, 662 uint32_t loadaddr) 663{ 664 struct brom_layout_header *brlyt; 665 struct gfh_header *gfh; 666 uint32_t payload_pages, nand_page_size; 667 668 /* NAND header */ 669 nand_page_size = mtk_nand_header_put(hdr_nand, ptr); 670 671 if (nand_page_size) { 672 /* BRLYT header */ 673 payload_pages = (filesize + nand_page_size - 1) / 674 nand_page_size; 675 brlyt = (struct brom_layout_header *)(ptr + nand_page_size); 676 put_brom_layout_header(brlyt, hdr_media); 677 brlyt->header_size = cpu_to_le32(2); 678 brlyt->total_size = cpu_to_le32(payload_pages); 679 brlyt->header_size_2 = brlyt->header_size; 680 brlyt->total_size_2 = brlyt->total_size; 681 brlyt->unused = cpu_to_le32(1); 682 } 683 684 /* GFH header */ 685 gfh = (struct gfh_header *)(ptr + hdr_nand_size); 686 put_ghf_header(gfh, filesize, hdr_nand_size, loadaddr, 687 GFH_FLASH_TYPE_NAND); 688 689 /* Generate SHA256 hash */ 690 put_hash((uint8_t *)gfh, filesize - hdr_nand_size - SHA256_SUM_LEN); 691} 692 693static void mtk_image_set_mt7621_header(void *ptr, off_t filesize, 694 uint32_t loadaddr) 695{ 696 struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; 697 struct mt7621_stage1_header *shdr; 698 struct mt7621_nand_header *nhdr; 699 uint32_t datasize, crcval; 700 701 datasize = filesize - image_get_header_size(); 702 nhdr = (struct mt7621_nand_header *)hdr->ih_name; 703 shdr = (struct mt7621_stage1_header *)(ptr + image_get_header_size()); 704 705 shdr->ep = cpu_to_be32(loadaddr); 706 shdr->stage_size = cpu_to_be32(datasize); 707 708 image_set_magic(hdr, IH_MAGIC); 709 image_set_time(hdr, time(NULL)); 710 image_set_size(hdr, datasize); 711 image_set_load(hdr, loadaddr); 712 image_set_ep(hdr, loadaddr); 713 image_set_os(hdr, IH_OS_U_BOOT); 714 image_set_arch(hdr, IH_ARCH_MIPS); 715 image_set_type(hdr, IH_TYPE_STANDALONE); 716 image_set_comp(hdr, IH_COMP_NONE); 717 718 crcval = crc32(0, (uint8_t *)shdr, datasize); 719 image_set_dcrc(hdr, crcval); 720 721 strncpy(nhdr->ih_name, "MT7621 NAND", MT7621_IH_NMLEN); 722 723 nhdr->ih_stage_offset = cpu_to_be32(image_get_header_size()); 724 725 crcval = crc32be_cal(hdr, image_get_header_size()); 726 nhdr->crc = cpu_to_be32(crcval); 727 728 crcval = crc32(0, (uint8_t *)hdr, image_get_header_size()); 729 image_set_hcrc(hdr, crcval); 730} 731 732static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd, 733 struct image_tool_params *params) 734{ 735 union lk_hdr *lk = (union lk_hdr *)ptr; 736 737 if (use_lk_hdr) { 738 lk->magic = cpu_to_le32(LK_PART_MAGIC); 739 lk->size = cpu_to_le32(sbuf->st_size - sizeof(union lk_hdr)); 740 lk->loadaddr = cpu_to_le32(params->addr); 741 lk->mode = 0xffffffff; /* must be non-zero */ 742 memset(lk->name, 0, sizeof(lk->name)); 743 strncpy(lk->name, lk_name, sizeof(lk->name)); 744 return; 745 } 746 747 img_gen = true; 748 img_size = sbuf->st_size; 749 750 if (use_mt7621_hdr) { 751 mtk_image_set_mt7621_header(ptr, sbuf->st_size, params->addr); 752 return; 753 } 754 755 if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) 756 mtk_image_set_nand_header(ptr, sbuf->st_size, params->addr); 757 else 758 mtk_image_set_gen_header(ptr, sbuf->st_size, params->addr); 759} 760 761U_BOOT_IMAGE_TYPE( 762 mtk_image, 763 "MediaTek BootROM Loadable Image support", 764 0, 765 NULL, 766 mtk_image_check_params, 767 mtk_image_verify_header, 768 mtk_image_print_header, 769 mtk_image_set_header, 770 NULL, 771 mtk_image_check_image_types, 772 NULL, 773 mtk_image_vrec_header 774); 775