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;
249 static bool is_arm64_image;
252 static char lk_name[32] = "U-Boot";
254 /* NAND header selected by user */
255 static const union nand_boot_header *hdr_nand;
257 /* GFH header + 2 * 4KB pages of NAND */
258 static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
260 static int mtk_image_check_image_types(uint8_t type)
262 if (type == IH_TYPE_MTKIMAGE)
268 static int mtk_brom_parse_imagename(const char *imagename)
270 #define is_blank_char(c) \
271 ((c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == ' ')
273 char *buf = strdup(imagename), *key, *val, *end, *next;
276 /* User passed arguments from image name */
277 static const char *media = "";
278 static const char *nandinfo = "";
279 static const char *lk = "";
280 static const char *arm64_param = "";
284 next = strchr(key, ';');
288 val = strchr(key, '=');
293 while (is_blank_char(*key))
296 end = key + strlen(key) - 1;
297 while ((end >= key) && is_blank_char(*end))
301 if (is_blank_char(*end))
305 while (is_blank_char(*val))
308 end = val + strlen(val) - 1;
309 while ((end >= val) && is_blank_char(*end))
313 if (is_blank_char(*end))
316 /* record user passed arguments */
317 if (!strcmp(key, "media"))
320 if (!strcmp(key, "nandinfo"))
323 if (!strcmp(key, "lk"))
326 if (!strcmp(key, "lkname"))
327 snprintf(lk_name, sizeof(lk_name), "%s", val);
329 if (!strcmp(key, "arm64"))
339 /* if user specified LK image header, skip following checks */
340 if (lk && lk[0] == '1') {
346 /* parse media type */
347 for (i = 0; i < ARRAY_SIZE(brom_images); i++) {
348 if (!strcmp(brom_images[i].name, media)) {
349 hdr_media = brom_images[i].type;
354 /* parse nand header type */
355 for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
356 if (!strcmp(nand_headers[i].name, nandinfo)) {
357 hdr_nand = nand_headers[i].data;
362 if (arm64_param && arm64_param[0] == '1')
363 is_arm64_image = true;
367 if (hdr_media == BRLYT_TYPE_INVALID) {
368 fprintf(stderr, "Error: media type is invalid or missing.\n");
369 fprintf(stderr, " Please specify -n \"media=<type>\"\n");
373 if ((hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) &&
375 fprintf(stderr, "Error: nand info is invalid or missing.\n");
376 fprintf(stderr, " Please specify -n \"media=%s;"
377 "nandinfo=<info>\"\n", media);
384 static int mtk_image_check_params(struct image_tool_params *params)
387 fprintf(stderr, "Error: Load Address must be set.\n");
391 if (!params->imagename) {
392 fprintf(stderr, "Error: Image Name must be set.\n");
396 return mtk_brom_parse_imagename(params->imagename);
399 static int mtk_image_vrec_header(struct image_tool_params *params,
400 struct image_type_params *tparams)
403 tparams->header_size = sizeof(union lk_hdr);
404 tparams->hdr = &hdr_tmp;
405 memset(&hdr_tmp, 0xff, tparams->header_size);
409 if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
410 tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize);
412 tparams->header_size = sizeof(struct gen_device_header);
414 tparams->header_size += sizeof(struct gfh_header);
415 tparams->hdr = &hdr_tmp;
417 memset(&hdr_tmp, 0xff, tparams->header_size);
419 return SHA256_SUM_LEN;
422 static int mtk_image_verify_gen_header(const uint8_t *ptr, int print)
424 union gen_boot_header *gbh = (union gen_boot_header *)ptr;
425 struct brom_layout_header *bh;
426 struct gfh_header *gfh;
427 const char *bootmedia;
429 if (!strcmp(gbh->name, SF_BOOT_NAME))
430 bootmedia = "Serial NOR";
431 else if (!strcmp(gbh->name, EMMC_BOOT_NAME))
433 else if (!strcmp(gbh->name, SDMMC_BOOT_NAME))
434 bootmedia = "SD/MMC";
439 printf("Boot Media: %s\n", bootmedia);
441 if (le32_to_cpu(gbh->version) != 1 ||
442 le32_to_cpu(gbh->size) != sizeof(union gen_boot_header))
445 bh = (struct brom_layout_header *)(ptr + le32_to_cpu(gbh->size));
447 if (strcmp(bh->name, BRLYT_NAME))
450 if (le32_to_cpu(bh->magic) != BRLYT_MAGIC ||
451 (le32_to_cpu(bh->type) != BRLYT_TYPE_NOR &&
452 le32_to_cpu(bh->type) != BRLYT_TYPE_EMMC &&
453 le32_to_cpu(bh->type) != BRLYT_TYPE_SDMMC))
456 gfh = (struct gfh_header *)(ptr + le32_to_cpu(bh->header_size));
458 if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
461 if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_GEN)
465 printf("Load Address: %08x\n",
466 le32_to_cpu(gfh->file_info.load_addr) +
467 le32_to_cpu(gfh->file_info.jump_offset));
470 printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM");
475 static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
477 union nand_boot_header *nh = (union nand_boot_header *)ptr;
478 struct brom_layout_header *bh;
479 struct gfh_header *gfh;
480 const char *bootmedia;
482 if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
483 strcmp(nh->id, NAND_BOOT_ID))
486 bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize));
488 if (strcmp(bh->name, BRLYT_NAME))
491 if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) {
494 if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND)
495 bootmedia = "Parallel NAND";
496 else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND)
497 bootmedia = "Serial NAND";
503 printf("Boot Media: %s\n", bootmedia);
505 if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) {
507 (uint64_t)le16_to_cpu(nh->numblocks) *
508 (uint64_t)le16_to_cpu(nh->pages_of_block) *
509 (uint64_t)le16_to_cpu(nh->pagesize) * 8;
510 printf("Capacity: %dGb\n",
511 (uint32_t)(capacity >> 30));
514 if (le16_to_cpu(nh->pagesize) >= 1024)
515 printf("Page Size: %dKB\n",
516 le16_to_cpu(nh->pagesize) >> 10);
518 printf("Page Size: %dB\n",
519 le16_to_cpu(nh->pagesize));
521 printf("Spare Size: %dB\n", le16_to_cpu(nh->oobsize));
524 gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize));
526 if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
529 if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_NAND)
533 printf("Load Address: %08x\n",
534 le32_to_cpu(gfh->file_info.load_addr) +
535 le32_to_cpu(gfh->file_info.jump_offset));
538 printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM");
543 static int mtk_image_verify_header(unsigned char *ptr, int image_size,
544 struct image_tool_params *params)
546 union lk_hdr *lk = (union lk_hdr *)ptr;
548 /* nothing to verify for LK image header */
549 if (le32_to_cpu(lk->magic) == LK_PART_MAGIC)
552 if (!strcmp((char *)ptr, NAND_BOOT_NAME))
553 return mtk_image_verify_nand_header(ptr, 0);
555 return mtk_image_verify_gen_header(ptr, 0);
560 static void mtk_image_print_header(const void *ptr)
562 union lk_hdr *lk = (union lk_hdr *)ptr;
564 if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) {
565 printf("Image Type: MediaTek LK Image\n");
566 printf("Load Address: %08x\n", le32_to_cpu(lk->loadaddr));
570 printf("Image Type: MediaTek BootROM Loadable Image\n");
572 if (!strcmp((char *)ptr, NAND_BOOT_NAME))
573 mtk_image_verify_nand_header(ptr, 1);
575 mtk_image_verify_gen_header(ptr, 1);
578 static void put_brom_layout_header(struct brom_layout_header *hdr, int type)
580 strncpy(hdr->name, BRLYT_NAME, sizeof(hdr->name));
581 hdr->version = cpu_to_le32(1);
582 hdr->magic = cpu_to_le32(BRLYT_MAGIC);
583 hdr->type = cpu_to_le32(type);
586 static void put_ghf_common_header(struct gfh_common_header *gfh, int size,
589 memcpy(gfh->magic, GFH_HEADER_MAGIC, sizeof(gfh->magic));
591 gfh->size = cpu_to_le16(size);
592 gfh->type = cpu_to_le16(type);
595 static void put_ghf_header(struct gfh_header *gfh, int file_size,
596 int dev_hdr_size, int load_addr, int flash_type)
600 memset(gfh, 0, sizeof(struct gfh_header));
602 /* GFH_FILE_INFO header */
603 put_ghf_common_header(&gfh->file_info.gfh, sizeof(gfh->file_info),
604 GFH_TYPE_FILE_INFO, 1);
605 strncpy(gfh->file_info.name, GFH_FILE_INFO_NAME,
606 sizeof(gfh->file_info.name));
607 gfh->file_info.unused = cpu_to_le32(1);
608 gfh->file_info.file_type = cpu_to_le16(1);
609 gfh->file_info.flash_type = flash_type;
610 gfh->file_info.sig_type = GFH_SIG_TYPE_SHA256;
611 gfh->file_info.load_addr = cpu_to_le32(load_addr - sizeof(*gfh));
612 gfh->file_info.total_size = cpu_to_le32(file_size - dev_hdr_size);
613 gfh->file_info.max_size = cpu_to_le32(file_size);
614 gfh->file_info.hdr_size = sizeof(*gfh);
615 gfh->file_info.sig_size = SHA256_SUM_LEN;
616 gfh->file_info.jump_offset = sizeof(*gfh);
617 gfh->file_info.processed = cpu_to_le32(1);
619 /* GFH_BL_INFO header */
620 put_ghf_common_header(&gfh->bl_info.gfh, sizeof(gfh->bl_info),
621 GFH_TYPE_BL_INFO, 1);
622 gfh->bl_info.attr = cpu_to_le32(1);
624 /* GFH_BROM_CFG header */
625 put_ghf_common_header(&gfh->brom_cfg.gfh, sizeof(gfh->brom_cfg),
626 GFH_TYPE_BROM_CFG, 3);
627 cfg_bits = GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS |
628 GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN |
629 GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN;
630 gfh->brom_cfg.usbdl_by_kcol0_timeout_ms = cpu_to_le32(5000);
631 if (is_arm64_image) {
632 gfh->brom_cfg.jump_bl_arm64 = GFH_BROM_CFG_JUMP_BL_ARM64;
633 cfg_bits |= GFH_BROM_CFG_JUMP_BL_ARM64_EN;
635 gfh->brom_cfg.cfg_bits = cpu_to_le32(cfg_bits);
637 /* GFH_BL_SEC_KEY header */
638 put_ghf_common_header(&gfh->bl_sec_key.gfh, sizeof(gfh->bl_sec_key),
639 GFH_TYPE_BL_SEC_KEY, 1);
641 /* GFH_ANTI_CLONE header */
642 put_ghf_common_header(&gfh->anti_clone.gfh, sizeof(gfh->anti_clone),
643 GFH_TYPE_ANTI_CLONE, 1);
644 gfh->anti_clone.ac_offset = cpu_to_le32(0x10);
645 gfh->anti_clone.ac_len = cpu_to_le32(0x80);
647 /* GFH_BROM_SEC_CFG header */
648 put_ghf_common_header(&gfh->brom_sec_cfg.gfh,
649 sizeof(gfh->brom_sec_cfg),
650 GFH_TYPE_BROM_SEC_CFG, 1);
651 gfh->brom_sec_cfg.cfg_bits =
652 cpu_to_le32(BROM_SEC_CFG_JTAG_EN | BROM_SEC_CFG_UART_EN);
655 static void put_hash(uint8_t *buff, int size)
660 sha256_update(&ctx, buff, size);
661 sha256_finish(&ctx, buff + size);
664 static void mtk_image_set_gen_header(void *ptr, off_t filesize,
667 struct gen_device_header *hdr = (struct gen_device_header *)ptr;
668 struct gfh_header *gfh;
669 const char *bootname = NULL;
671 if (hdr_media == BRLYT_TYPE_NOR)
672 bootname = SF_BOOT_NAME;
673 else if (hdr_media == BRLYT_TYPE_EMMC)
674 bootname = EMMC_BOOT_NAME;
675 else if (hdr_media == BRLYT_TYPE_SDMMC)
676 bootname = SDMMC_BOOT_NAME;
678 /* Generic device header */
679 snprintf(hdr->boot.name, sizeof(hdr->boot.name), "%s", bootname);
680 hdr->boot.version = cpu_to_le32(1);
681 hdr->boot.size = cpu_to_le32(sizeof(hdr->boot));
684 put_brom_layout_header(&hdr->brlyt, hdr_media);
685 hdr->brlyt.header_size = cpu_to_le32(sizeof(struct gen_device_header));
686 hdr->brlyt.total_size = cpu_to_le32(filesize);
687 hdr->brlyt.header_size_2 = hdr->brlyt.header_size;
688 hdr->brlyt.total_size_2 = hdr->brlyt.total_size;
691 gfh = (struct gfh_header *)(ptr + sizeof(struct gen_device_header));
692 put_ghf_header(gfh, filesize, sizeof(struct gen_device_header),
693 loadaddr, GFH_FLASH_TYPE_GEN);
695 /* Generate SHA256 hash */
696 put_hash((uint8_t *)gfh,
697 filesize - sizeof(struct gen_device_header) - SHA256_SUM_LEN);
700 static void mtk_image_set_nand_header(void *ptr, off_t filesize,
703 union nand_boot_header *nh = (union nand_boot_header *)ptr;
704 struct brom_layout_header *brlyt;
705 struct gfh_header *gfh;
706 uint32_t payload_pages;
709 /* NAND device header, repeat 4 times */
710 for (i = 0; i < 4; i++)
711 memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
714 payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) /
715 le16_to_cpu(hdr_nand->pagesize);
716 brlyt = (struct brom_layout_header *)
717 (ptr + le16_to_cpu(hdr_nand->pagesize));
718 put_brom_layout_header(brlyt, hdr_media);
719 brlyt->header_size = cpu_to_le32(2);
720 brlyt->total_size = cpu_to_le32(payload_pages);
721 brlyt->header_size_2 = brlyt->header_size;
722 brlyt->total_size_2 = brlyt->total_size;
723 brlyt->unused = cpu_to_le32(1);
726 gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize));
727 put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize),
728 loadaddr, GFH_FLASH_TYPE_NAND);
730 /* Generate SHA256 hash */
731 put_hash((uint8_t *)gfh,
732 filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN);
735 static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd,
736 struct image_tool_params *params)
738 union lk_hdr *lk = (union lk_hdr *)ptr;
741 lk->magic = cpu_to_le32(LK_PART_MAGIC);
742 lk->size = cpu_to_le32(sbuf->st_size - sizeof(union lk_hdr));
743 lk->loadaddr = cpu_to_le32(params->addr);
744 lk->mode = 0xffffffff; /* must be non-zero */
745 memset(lk->name, 0, sizeof(lk->name));
746 strncpy(lk->name, lk_name, sizeof(lk->name));
750 if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
751 mtk_image_set_nand_header(ptr, sbuf->st_size, params->addr);
753 mtk_image_set_gen_header(ptr, sbuf->st_size, params->addr);
758 "MediaTek BootROM Loadable Image support",
761 mtk_image_check_params,
762 mtk_image_verify_header,
763 mtk_image_print_header,
764 mtk_image_set_header,
766 mtk_image_check_image_types,
768 mtk_image_vrec_header