1 // SPDX-License-Identifier: GPL-2.0+
3 * Generate MediaTek BootROM header for SPL/U-Boot images
5 * Copyright (C) 2018 MediaTek Inc.
6 * Author: Weijie Gao <weijie.gao@mediatek.com>
10 #include <u-boot/sha256.h>
11 #include "imagetool.h"
12 #include "mtk_image.h"
14 /* NAND header for SPI-NAND with 2KB page + 64B spare */
15 static const union nand_boot_header snand_hdr_2k_64_data = {
17 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
18 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
19 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
20 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
21 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
22 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
26 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29 0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
30 0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
31 0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
32 0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
36 /* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
37 static const union nand_boot_header snand_hdr_2k_128_data = {
39 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
40 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
41 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
42 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
43 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
52 0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
53 0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
54 0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
58 /* NAND header for SPI-NAND with 4KB page + 256B spare */
59 static const union nand_boot_header snand_hdr_4k_256_data = {
61 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
62 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
63 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
64 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
65 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
74 0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
75 0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
76 0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
80 /* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
81 static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
83 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
84 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
85 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
86 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
87 0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
96 0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
97 0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
98 0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
102 /* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
103 static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
105 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
106 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
107 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
108 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
109 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
118 0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
119 0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
120 0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
124 /* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
125 static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
127 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
128 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
129 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
130 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
131 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
140 0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
141 0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
142 0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
146 /* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
147 static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
149 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
150 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
151 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
152 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
153 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
162 0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
163 0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
164 0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
168 /* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
169 static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
171 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
172 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
173 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
174 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
175 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
184 0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
185 0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
186 0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
190 static const struct nand_header_type {
192 const union nand_boot_header *data;
196 .data = &snand_hdr_2k_64_data
199 .data = &snand_hdr_2k_128_data
202 .data = &snand_hdr_2k_128_data
205 .data = &snand_hdr_4k_256_data
208 .data = &nand_hdr_1gb_2k_64_data
211 .data = &nand_hdr_2gb_2k_64_data
214 .data = &nand_hdr_4gb_2k_64_data
217 .data = &nand_hdr_2gb_2k_128_data
220 .data = &nand_hdr_4gb_2k_128_data
224 static const struct brom_img_type {
226 enum brlyt_img_type type;
230 .type = BRLYT_TYPE_NAND
233 .type = BRLYT_TYPE_EMMC
236 .type = BRLYT_TYPE_NOR
239 .type = BRLYT_TYPE_SDMMC
242 .type = BRLYT_TYPE_SNAND
246 /* Image type selected by user */
247 static enum brlyt_img_type hdr_media;
248 static int use_lk_hdr;
251 static char lk_name[32] = "U-Boot";
253 /* NAND header selected by user */
254 static const union nand_boot_header *hdr_nand;
256 /* GFH header + 2 * 4KB pages of NAND */
257 static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
259 static int mtk_image_check_image_types(uint8_t type)
261 if (type == IH_TYPE_MTKIMAGE)
267 static int mtk_brom_parse_imagename(const char *imagename)
269 #define is_blank_char(c) \
270 ((c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == ' ')
272 char *buf = strdup(imagename), *key, *val, *end, *next;
275 /* User passed arguments from image name */
276 static const char *media = "";
277 static const char *nandinfo = "";
278 static const char *lk = "";
282 next = strchr(key, ';');
286 val = strchr(key, '=');
291 while (is_blank_char(*key))
294 end = key + strlen(key) - 1;
295 while ((end >= key) && is_blank_char(*end))
299 if (is_blank_char(*end))
303 while (is_blank_char(*val))
306 end = val + strlen(val) - 1;
307 while ((end >= val) && is_blank_char(*end))
311 if (is_blank_char(*end))
314 /* record user passed arguments */
315 if (!strcmp(key, "media"))
318 if (!strcmp(key, "nandinfo"))
321 if (!strcmp(key, "lk"))
324 if (!strcmp(key, "lkname"))
325 snprintf(lk_name, sizeof(lk_name), "%s", val);
334 /* if user specified LK image header, skip following checks */
335 if (lk && lk[0] == '1') {
341 /* parse media type */
342 for (i = 0; i < ARRAY_SIZE(brom_images); i++) {
343 if (!strcmp(brom_images[i].name, media)) {
344 hdr_media = brom_images[i].type;
349 /* parse nand header type */
350 for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
351 if (!strcmp(nand_headers[i].name, nandinfo)) {
352 hdr_nand = nand_headers[i].data;
359 if (hdr_media == BRLYT_TYPE_INVALID) {
360 fprintf(stderr, "Error: media type is invalid or missing.\n");
361 fprintf(stderr, " Please specify -n \"media=<type>\"\n");
365 if ((hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) &&
367 fprintf(stderr, "Error: nand info is invalid or missing.\n");
368 fprintf(stderr, " Please specify -n \"media=%s;"
369 "nandinfo=<info>\"\n", media);
376 static int mtk_image_check_params(struct image_tool_params *params)
379 fprintf(stderr, "Error: Load Address must be set.\n");
383 if (!params->imagename) {
384 fprintf(stderr, "Error: Image Name must be set.\n");
388 return mtk_brom_parse_imagename(params->imagename);
391 static int mtk_image_vrec_header(struct image_tool_params *params,
392 struct image_type_params *tparams)
395 tparams->header_size = sizeof(union lk_hdr);
396 tparams->hdr = &hdr_tmp;
397 memset(&hdr_tmp, 0xff, tparams->header_size);
401 if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
402 tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize);
404 tparams->header_size = sizeof(struct gen_device_header);
406 tparams->header_size += sizeof(struct gfh_header);
407 tparams->hdr = &hdr_tmp;
409 memset(&hdr_tmp, 0xff, tparams->header_size);
411 return SHA256_SUM_LEN;
414 static int mtk_image_verify_gen_header(const uint8_t *ptr, int print)
416 union gen_boot_header *gbh = (union gen_boot_header *)ptr;
417 struct brom_layout_header *bh;
418 struct gfh_header *gfh;
419 const char *bootmedia;
421 if (!strcmp(gbh->name, SF_BOOT_NAME))
422 bootmedia = "Serial NOR";
423 else if (!strcmp(gbh->name, EMMC_BOOT_NAME))
425 else if (!strcmp(gbh->name, SDMMC_BOOT_NAME))
426 bootmedia = "SD/MMC";
431 printf("Boot Media: %s\n", bootmedia);
433 if (le32_to_cpu(gbh->version) != 1 ||
434 le32_to_cpu(gbh->size) != sizeof(union gen_boot_header))
437 bh = (struct brom_layout_header *)(ptr + le32_to_cpu(gbh->size));
439 if (strcmp(bh->name, BRLYT_NAME))
442 if (le32_to_cpu(bh->magic) != BRLYT_MAGIC ||
443 (le32_to_cpu(bh->type) != BRLYT_TYPE_NOR &&
444 le32_to_cpu(bh->type) != BRLYT_TYPE_EMMC &&
445 le32_to_cpu(bh->type) != BRLYT_TYPE_SDMMC))
448 gfh = (struct gfh_header *)(ptr + le32_to_cpu(bh->header_size));
450 if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
453 if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_GEN)
457 printf("Load Address: %08x\n",
458 le32_to_cpu(gfh->file_info.load_addr) +
459 le32_to_cpu(gfh->file_info.jump_offset));
464 static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
466 union nand_boot_header *nh = (union nand_boot_header *)ptr;
467 struct brom_layout_header *bh;
468 struct gfh_header *gfh;
469 const char *bootmedia;
471 if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
472 strcmp(nh->id, NAND_BOOT_ID))
475 bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize));
477 if (strcmp(bh->name, BRLYT_NAME))
480 if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) {
483 if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND)
484 bootmedia = "Parallel NAND";
485 else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND)
486 bootmedia = "Serial NAND";
492 printf("Boot Media: %s\n", bootmedia);
494 if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) {
496 (uint64_t)le16_to_cpu(nh->numblocks) *
497 (uint64_t)le16_to_cpu(nh->pages_of_block) *
498 (uint64_t)le16_to_cpu(nh->pagesize) * 8;
499 printf("Capacity: %dGb\n",
500 (uint32_t)(capacity >> 30));
503 if (le16_to_cpu(nh->pagesize) >= 1024)
504 printf("Page Size: %dKB\n",
505 le16_to_cpu(nh->pagesize) >> 10);
507 printf("Page Size: %dB\n",
508 le16_to_cpu(nh->pagesize));
510 printf("Spare Size: %dB\n", le16_to_cpu(nh->oobsize));
513 gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize));
515 if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
518 if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_NAND)
522 printf("Load Address: %08x\n",
523 le32_to_cpu(gfh->file_info.load_addr) +
524 le32_to_cpu(gfh->file_info.jump_offset));
529 static int mtk_image_verify_header(unsigned char *ptr, int image_size,
530 struct image_tool_params *params)
532 union lk_hdr *lk = (union lk_hdr *)ptr;
534 /* nothing to verify for LK image header */
535 if (le32_to_cpu(lk->magic) == LK_PART_MAGIC)
538 if (!strcmp((char *)ptr, NAND_BOOT_NAME))
539 return mtk_image_verify_nand_header(ptr, 0);
541 return mtk_image_verify_gen_header(ptr, 0);
546 static void mtk_image_print_header(const void *ptr)
548 union lk_hdr *lk = (union lk_hdr *)ptr;
550 if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) {
551 printf("Image Type: MediaTek LK Image\n");
552 printf("Load Address: %08x\n", le32_to_cpu(lk->loadaddr));
556 printf("Image Type: MediaTek BootROM Loadable Image\n");
558 if (!strcmp((char *)ptr, NAND_BOOT_NAME))
559 mtk_image_verify_nand_header(ptr, 1);
561 mtk_image_verify_gen_header(ptr, 1);
564 static void put_brom_layout_header(struct brom_layout_header *hdr, int type)
566 strncpy(hdr->name, BRLYT_NAME, sizeof(hdr->name));
567 hdr->version = cpu_to_le32(1);
568 hdr->magic = cpu_to_le32(BRLYT_MAGIC);
569 hdr->type = cpu_to_le32(type);
572 static void put_ghf_common_header(struct gfh_common_header *gfh, int size,
575 memcpy(gfh->magic, GFH_HEADER_MAGIC, sizeof(gfh->magic));
577 gfh->size = cpu_to_le16(size);
578 gfh->type = cpu_to_le16(type);
581 static void put_ghf_header(struct gfh_header *gfh, int file_size,
582 int dev_hdr_size, int load_addr, int flash_type)
584 memset(gfh, 0, sizeof(struct gfh_header));
586 /* GFH_FILE_INFO header */
587 put_ghf_common_header(&gfh->file_info.gfh, sizeof(gfh->file_info),
588 GFH_TYPE_FILE_INFO, 1);
589 strncpy(gfh->file_info.name, GFH_FILE_INFO_NAME,
590 sizeof(gfh->file_info.name));
591 gfh->file_info.unused = cpu_to_le32(1);
592 gfh->file_info.file_type = cpu_to_le16(1);
593 gfh->file_info.flash_type = flash_type;
594 gfh->file_info.sig_type = GFH_SIG_TYPE_SHA256;
595 gfh->file_info.load_addr = cpu_to_le32(load_addr - sizeof(*gfh));
596 gfh->file_info.total_size = cpu_to_le32(file_size - dev_hdr_size);
597 gfh->file_info.max_size = cpu_to_le32(file_size);
598 gfh->file_info.hdr_size = sizeof(*gfh);
599 gfh->file_info.sig_size = SHA256_SUM_LEN;
600 gfh->file_info.jump_offset = sizeof(*gfh);
601 gfh->file_info.processed = cpu_to_le32(1);
603 /* GFH_BL_INFO header */
604 put_ghf_common_header(&gfh->bl_info.gfh, sizeof(gfh->bl_info),
605 GFH_TYPE_BL_INFO, 1);
606 gfh->bl_info.attr = cpu_to_le32(1);
608 /* GFH_BROM_CFG header */
609 put_ghf_common_header(&gfh->brom_cfg.gfh, sizeof(gfh->brom_cfg),
610 GFH_TYPE_BROM_CFG, 3);
611 gfh->brom_cfg.cfg_bits = cpu_to_le32(
612 GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS |
613 GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN |
614 GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN);
615 gfh->brom_cfg.usbdl_by_kcol0_timeout_ms = cpu_to_le32(5000);
617 /* GFH_BL_SEC_KEY header */
618 put_ghf_common_header(&gfh->bl_sec_key.gfh, sizeof(gfh->bl_sec_key),
619 GFH_TYPE_BL_SEC_KEY, 1);
621 /* GFH_ANTI_CLONE header */
622 put_ghf_common_header(&gfh->anti_clone.gfh, sizeof(gfh->anti_clone),
623 GFH_TYPE_ANTI_CLONE, 1);
624 gfh->anti_clone.ac_offset = cpu_to_le32(0x10);
625 gfh->anti_clone.ac_len = cpu_to_le32(0x80);
627 /* GFH_BROM_SEC_CFG header */
628 put_ghf_common_header(&gfh->brom_sec_cfg.gfh,
629 sizeof(gfh->brom_sec_cfg),
630 GFH_TYPE_BROM_SEC_CFG, 1);
631 gfh->brom_sec_cfg.cfg_bits =
632 cpu_to_le32(BROM_SEC_CFG_JTAG_EN | BROM_SEC_CFG_UART_EN);
635 static void put_hash(uint8_t *buff, int size)
640 sha256_update(&ctx, buff, size);
641 sha256_finish(&ctx, buff + size);
644 static void mtk_image_set_gen_header(void *ptr, off_t filesize,
647 struct gen_device_header *hdr = (struct gen_device_header *)ptr;
648 struct gfh_header *gfh;
649 const char *bootname = NULL;
651 if (hdr_media == BRLYT_TYPE_NOR)
652 bootname = SF_BOOT_NAME;
653 else if (hdr_media == BRLYT_TYPE_EMMC)
654 bootname = EMMC_BOOT_NAME;
655 else if (hdr_media == BRLYT_TYPE_SDMMC)
656 bootname = SDMMC_BOOT_NAME;
658 /* Generic device header */
659 snprintf(hdr->boot.name, sizeof(hdr->boot.name), "%s", bootname);
660 hdr->boot.version = cpu_to_le32(1);
661 hdr->boot.size = cpu_to_le32(sizeof(hdr->boot));
664 put_brom_layout_header(&hdr->brlyt, hdr_media);
665 hdr->brlyt.header_size = cpu_to_le32(sizeof(struct gen_device_header));
666 hdr->brlyt.total_size = cpu_to_le32(filesize);
667 hdr->brlyt.header_size_2 = hdr->brlyt.header_size;
668 hdr->brlyt.total_size_2 = hdr->brlyt.total_size;
671 gfh = (struct gfh_header *)(ptr + sizeof(struct gen_device_header));
672 put_ghf_header(gfh, filesize, sizeof(struct gen_device_header),
673 loadaddr, GFH_FLASH_TYPE_GEN);
675 /* Generate SHA256 hash */
676 put_hash((uint8_t *)gfh,
677 filesize - sizeof(struct gen_device_header) - SHA256_SUM_LEN);
680 static void mtk_image_set_nand_header(void *ptr, off_t filesize,
683 union nand_boot_header *nh = (union nand_boot_header *)ptr;
684 struct brom_layout_header *brlyt;
685 struct gfh_header *gfh;
686 uint32_t payload_pages;
689 /* NAND device header, repeat 4 times */
690 for (i = 0; i < 4; i++)
691 memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
694 payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) /
695 le16_to_cpu(hdr_nand->pagesize);
696 brlyt = (struct brom_layout_header *)
697 (ptr + le16_to_cpu(hdr_nand->pagesize));
698 put_brom_layout_header(brlyt, hdr_media);
699 brlyt->header_size = cpu_to_le32(2);
700 brlyt->total_size = cpu_to_le32(payload_pages);
701 brlyt->header_size_2 = brlyt->header_size;
702 brlyt->total_size_2 = brlyt->total_size;
703 brlyt->unused = cpu_to_le32(1);
706 gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize));
707 put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize),
708 loadaddr, GFH_FLASH_TYPE_NAND);
710 /* Generate SHA256 hash */
711 put_hash((uint8_t *)gfh,
712 filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN);
715 static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd,
716 struct image_tool_params *params)
718 union lk_hdr *lk = (union lk_hdr *)ptr;
721 lk->magic = cpu_to_le32(LK_PART_MAGIC);
722 lk->size = cpu_to_le32(sbuf->st_size - sizeof(union lk_hdr));
723 lk->loadaddr = cpu_to_le32(params->addr);
724 lk->mode = 0xffffffff; /* must be non-zero */
725 memset(lk->name, 0, sizeof(lk->name));
726 strncpy(lk->name, lk_name, sizeof(lk->name));
730 if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
731 mtk_image_set_nand_header(ptr, sbuf->st_size, params->addr);
733 mtk_image_set_gen_header(ptr, sbuf->st_size, params->addr);
738 "MediaTek BootROM Loadable Image support",
741 mtk_image_check_params,
742 mtk_image_verify_header,
743 mtk_image_print_header,
744 mtk_image_set_header,
746 mtk_image_check_image_types,
748 mtk_image_vrec_header