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 /* Indicates whether we're generating or verifying */
248 static uint32_t img_size;
250 /* Image type selected by user */
251 static enum brlyt_img_type hdr_media;
252 static uint32_t hdr_offset;
253 static int use_lk_hdr;
254 static bool is_arm64_image;
257 static char lk_name[32] = "U-Boot";
259 /* NAND header selected by user */
260 static const union nand_boot_header *hdr_nand;
262 /* GFH header + 2 * 4KB pages of NAND */
263 static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
265 static int mtk_image_check_image_types(uint8_t type)
267 if (type == IH_TYPE_MTKIMAGE)
273 static int mtk_brom_parse_imagename(const char *imagename)
275 #define is_blank_char(c) \
276 ((c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == ' ')
278 char *buf = strdup(imagename), *key, *val, *end, *next;
281 /* User passed arguments from image name */
282 static const char *media = "";
283 static const char *hdr_offs = "";
284 static const char *nandinfo = "";
285 static const char *lk = "";
286 static const char *arm64_param = "";
290 next = strchr(key, ';');
294 val = strchr(key, '=');
299 while (is_blank_char(*key))
302 end = key + strlen(key) - 1;
303 while ((end >= key) && is_blank_char(*end))
307 if (is_blank_char(*end))
311 while (is_blank_char(*val))
314 end = val + strlen(val) - 1;
315 while ((end >= val) && is_blank_char(*end))
319 if (is_blank_char(*end))
322 /* record user passed arguments */
323 if (!strcmp(key, "media"))
326 if (!strcmp(key, "hdroffset"))
329 if (!strcmp(key, "nandinfo"))
332 if (!strcmp(key, "lk"))
335 if (!strcmp(key, "lkname"))
336 snprintf(lk_name, sizeof(lk_name), "%s", val);
338 if (!strcmp(key, "arm64"))
348 /* if user specified LK image header, skip following checks */
349 if (lk && lk[0] == '1') {
355 /* parse media type */
356 for (i = 0; i < ARRAY_SIZE(brom_images); i++) {
357 if (!strcmp(brom_images[i].name, media)) {
358 hdr_media = brom_images[i].type;
363 /* parse nand header type */
364 for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
365 if (!strcmp(nand_headers[i].name, nandinfo)) {
366 hdr_nand = nand_headers[i].data;
371 /* parse device header offset */
372 if (hdr_offs && hdr_offs[0])
373 hdr_offset = strtoul(hdr_offs, NULL, 0);
375 if (arm64_param && arm64_param[0] == '1')
376 is_arm64_image = true;
380 if (hdr_media == BRLYT_TYPE_INVALID) {
381 fprintf(stderr, "Error: media type is invalid or missing.\n");
382 fprintf(stderr, " Please specify -n \"media=<type>\"\n");
386 if ((hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) &&
388 fprintf(stderr, "Error: nand info is invalid or missing.\n");
389 fprintf(stderr, " Please specify -n \"media=%s;"
390 "nandinfo=<info>\"\n", media);
397 static int mtk_image_check_params(struct image_tool_params *params)
400 fprintf(stderr, "Error: Load Address must be set.\n");
404 if (!params->imagename) {
405 fprintf(stderr, "Error: Image Name must be set.\n");
409 return mtk_brom_parse_imagename(params->imagename);
412 static int mtk_image_vrec_header(struct image_tool_params *params,
413 struct image_type_params *tparams)
416 tparams->header_size = sizeof(union lk_hdr);
417 tparams->hdr = &hdr_tmp;
418 memset(&hdr_tmp, 0xff, tparams->header_size);
422 if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
423 tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize);
425 tparams->header_size = sizeof(struct gen_device_header);
427 tparams->header_size += sizeof(struct gfh_header);
428 tparams->hdr = &hdr_tmp;
430 memset(&hdr_tmp, 0xff, tparams->header_size);
432 return SHA256_SUM_LEN;
435 static int mtk_image_verify_gen_header(const uint8_t *ptr, int print)
437 union gen_boot_header *gbh = (union gen_boot_header *)ptr;
438 uint32_t gfh_offset, total_size, devh_size;
439 struct brom_layout_header *bh;
440 struct gfh_header *gfh;
441 const char *bootmedia;
443 if (!strcmp(gbh->name, SF_BOOT_NAME))
444 bootmedia = "Serial NOR";
445 else if (!strcmp(gbh->name, EMMC_BOOT_NAME))
447 else if (!strcmp(gbh->name, SDMMC_BOOT_NAME))
448 bootmedia = "SD/MMC";
453 printf("Boot Media: %s\n", bootmedia);
455 if (le32_to_cpu(gbh->version) != 1 ||
456 le32_to_cpu(gbh->size) != sizeof(union gen_boot_header))
459 bh = (struct brom_layout_header *)(ptr + le32_to_cpu(gbh->size));
461 if (strcmp(bh->name, BRLYT_NAME))
464 if (le32_to_cpu(bh->magic) != BRLYT_MAGIC ||
465 (le32_to_cpu(bh->type) != BRLYT_TYPE_NOR &&
466 le32_to_cpu(bh->type) != BRLYT_TYPE_EMMC &&
467 le32_to_cpu(bh->type) != BRLYT_TYPE_SDMMC))
470 devh_size = sizeof(struct gen_device_header);
473 gfh_offset = devh_size;
475 gfh_offset = le32_to_cpu(bh->header_size);
477 if (gfh_offset + sizeof(struct gfh_header) > img_size) {
479 * This may happen if the hdr_offset used to generate
480 * this image is not zero.
481 * Since device header size is not fixed, we can't
482 * cover all possible cases.
483 * Assuming the image is valid only if the real
484 * device header size equals to devh_size.
486 total_size = le32_to_cpu(bh->total_size);
488 if (total_size - gfh_offset > img_size - devh_size)
491 gfh_offset = devh_size;
495 gfh = (struct gfh_header *)(ptr + gfh_offset);
497 if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
500 if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_GEN)
504 printf("Load Address: %08x\n",
505 le32_to_cpu(gfh->file_info.load_addr) +
506 le32_to_cpu(gfh->file_info.jump_offset));
509 printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM");
514 static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
516 union nand_boot_header *nh = (union nand_boot_header *)ptr;
517 struct brom_layout_header *bh;
518 struct gfh_header *gfh;
519 const char *bootmedia;
521 if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
522 strcmp(nh->id, NAND_BOOT_ID))
525 bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize));
527 if (strcmp(bh->name, BRLYT_NAME))
530 if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) {
533 if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND)
534 bootmedia = "Parallel NAND";
535 else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND)
536 bootmedia = "Serial NAND";
542 printf("Boot Media: %s\n", bootmedia);
544 if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) {
546 (uint64_t)le16_to_cpu(nh->numblocks) *
547 (uint64_t)le16_to_cpu(nh->pages_of_block) *
548 (uint64_t)le16_to_cpu(nh->pagesize) * 8;
549 printf("Capacity: %dGb\n",
550 (uint32_t)(capacity >> 30));
553 if (le16_to_cpu(nh->pagesize) >= 1024)
554 printf("Page Size: %dKB\n",
555 le16_to_cpu(nh->pagesize) >> 10);
557 printf("Page Size: %dB\n",
558 le16_to_cpu(nh->pagesize));
560 printf("Spare Size: %dB\n", le16_to_cpu(nh->oobsize));
563 gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize));
565 if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
568 if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_NAND)
572 printf("Load Address: %08x\n",
573 le32_to_cpu(gfh->file_info.load_addr) +
574 le32_to_cpu(gfh->file_info.jump_offset));
577 printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM");
582 static int mtk_image_verify_header(unsigned char *ptr, int image_size,
583 struct image_tool_params *params)
585 union lk_hdr *lk = (union lk_hdr *)ptr;
587 /* nothing to verify for LK image header */
588 if (le32_to_cpu(lk->magic) == LK_PART_MAGIC)
591 img_size = image_size;
593 if (!strcmp((char *)ptr, NAND_BOOT_NAME))
594 return mtk_image_verify_nand_header(ptr, 0);
596 return mtk_image_verify_gen_header(ptr, 0);
601 static void mtk_image_print_header(const void *ptr)
603 union lk_hdr *lk = (union lk_hdr *)ptr;
605 if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) {
606 printf("Image Type: MediaTek LK Image\n");
607 printf("Load Address: %08x\n", le32_to_cpu(lk->loadaddr));
611 printf("Image Type: MediaTek BootROM Loadable Image\n");
613 if (!strcmp((char *)ptr, NAND_BOOT_NAME))
614 mtk_image_verify_nand_header(ptr, 1);
616 mtk_image_verify_gen_header(ptr, 1);
619 static void put_brom_layout_header(struct brom_layout_header *hdr, int type)
621 strncpy(hdr->name, BRLYT_NAME, sizeof(hdr->name));
622 hdr->version = cpu_to_le32(1);
623 hdr->magic = cpu_to_le32(BRLYT_MAGIC);
624 hdr->type = cpu_to_le32(type);
627 static void put_ghf_common_header(struct gfh_common_header *gfh, int size,
630 memcpy(gfh->magic, GFH_HEADER_MAGIC, sizeof(gfh->magic));
632 gfh->size = cpu_to_le16(size);
633 gfh->type = cpu_to_le16(type);
636 static void put_ghf_header(struct gfh_header *gfh, int file_size,
637 int dev_hdr_size, int load_addr, int flash_type)
641 memset(gfh, 0, sizeof(struct gfh_header));
643 /* GFH_FILE_INFO header */
644 put_ghf_common_header(&gfh->file_info.gfh, sizeof(gfh->file_info),
645 GFH_TYPE_FILE_INFO, 1);
646 strncpy(gfh->file_info.name, GFH_FILE_INFO_NAME,
647 sizeof(gfh->file_info.name));
648 gfh->file_info.unused = cpu_to_le32(1);
649 gfh->file_info.file_type = cpu_to_le16(1);
650 gfh->file_info.flash_type = flash_type;
651 gfh->file_info.sig_type = GFH_SIG_TYPE_SHA256;
652 gfh->file_info.load_addr = cpu_to_le32(load_addr - sizeof(*gfh));
653 gfh->file_info.total_size = cpu_to_le32(file_size - dev_hdr_size);
654 gfh->file_info.max_size = cpu_to_le32(file_size);
655 gfh->file_info.hdr_size = sizeof(*gfh);
656 gfh->file_info.sig_size = SHA256_SUM_LEN;
657 gfh->file_info.jump_offset = sizeof(*gfh);
658 gfh->file_info.processed = cpu_to_le32(1);
660 /* GFH_BL_INFO header */
661 put_ghf_common_header(&gfh->bl_info.gfh, sizeof(gfh->bl_info),
662 GFH_TYPE_BL_INFO, 1);
663 gfh->bl_info.attr = cpu_to_le32(1);
665 /* GFH_BROM_CFG header */
666 put_ghf_common_header(&gfh->brom_cfg.gfh, sizeof(gfh->brom_cfg),
667 GFH_TYPE_BROM_CFG, 3);
668 cfg_bits = GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS |
669 GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN |
670 GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN;
671 gfh->brom_cfg.usbdl_by_kcol0_timeout_ms = cpu_to_le32(5000);
672 if (is_arm64_image) {
673 gfh->brom_cfg.jump_bl_arm64 = GFH_BROM_CFG_JUMP_BL_ARM64;
674 cfg_bits |= GFH_BROM_CFG_JUMP_BL_ARM64_EN;
676 gfh->brom_cfg.cfg_bits = cpu_to_le32(cfg_bits);
678 /* GFH_BL_SEC_KEY header */
679 put_ghf_common_header(&gfh->bl_sec_key.gfh, sizeof(gfh->bl_sec_key),
680 GFH_TYPE_BL_SEC_KEY, 1);
682 /* GFH_ANTI_CLONE header */
683 put_ghf_common_header(&gfh->anti_clone.gfh, sizeof(gfh->anti_clone),
684 GFH_TYPE_ANTI_CLONE, 1);
685 gfh->anti_clone.ac_offset = cpu_to_le32(0x10);
686 gfh->anti_clone.ac_len = cpu_to_le32(0x80);
688 /* GFH_BROM_SEC_CFG header */
689 put_ghf_common_header(&gfh->brom_sec_cfg.gfh,
690 sizeof(gfh->brom_sec_cfg),
691 GFH_TYPE_BROM_SEC_CFG, 1);
692 gfh->brom_sec_cfg.cfg_bits =
693 cpu_to_le32(BROM_SEC_CFG_JTAG_EN | BROM_SEC_CFG_UART_EN);
696 static void put_hash(uint8_t *buff, int size)
701 sha256_update(&ctx, buff, size);
702 sha256_finish(&ctx, buff + size);
705 static void mtk_image_set_gen_header(void *ptr, off_t filesize,
708 struct gen_device_header *hdr = (struct gen_device_header *)ptr;
709 struct gfh_header *gfh;
710 const char *bootname = NULL;
712 if (hdr_media == BRLYT_TYPE_NOR)
713 bootname = SF_BOOT_NAME;
714 else if (hdr_media == BRLYT_TYPE_EMMC)
715 bootname = EMMC_BOOT_NAME;
716 else if (hdr_media == BRLYT_TYPE_SDMMC)
717 bootname = SDMMC_BOOT_NAME;
719 /* Generic device header */
720 snprintf(hdr->boot.name, sizeof(hdr->boot.name), "%s", bootname);
721 hdr->boot.version = cpu_to_le32(1);
722 hdr->boot.size = cpu_to_le32(sizeof(hdr->boot));
725 put_brom_layout_header(&hdr->brlyt, hdr_media);
726 hdr->brlyt.header_size = cpu_to_le32(hdr_offset + sizeof(*hdr));
727 hdr->brlyt.total_size = cpu_to_le32(hdr_offset + filesize);
728 hdr->brlyt.header_size_2 = hdr->brlyt.header_size;
729 hdr->brlyt.total_size_2 = hdr->brlyt.total_size;
732 gfh = (struct gfh_header *)(ptr + sizeof(struct gen_device_header));
733 put_ghf_header(gfh, filesize, sizeof(struct gen_device_header),
734 loadaddr, GFH_FLASH_TYPE_GEN);
736 /* Generate SHA256 hash */
737 put_hash((uint8_t *)gfh,
738 filesize - sizeof(struct gen_device_header) - SHA256_SUM_LEN);
741 static void mtk_image_set_nand_header(void *ptr, off_t filesize,
744 union nand_boot_header *nh = (union nand_boot_header *)ptr;
745 struct brom_layout_header *brlyt;
746 struct gfh_header *gfh;
747 uint32_t payload_pages;
750 /* NAND device header, repeat 4 times */
751 for (i = 0; i < 4; i++)
752 memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
755 payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) /
756 le16_to_cpu(hdr_nand->pagesize);
757 brlyt = (struct brom_layout_header *)
758 (ptr + le16_to_cpu(hdr_nand->pagesize));
759 put_brom_layout_header(brlyt, hdr_media);
760 brlyt->header_size = cpu_to_le32(2);
761 brlyt->total_size = cpu_to_le32(payload_pages);
762 brlyt->header_size_2 = brlyt->header_size;
763 brlyt->total_size_2 = brlyt->total_size;
764 brlyt->unused = cpu_to_le32(1);
767 gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize));
768 put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize),
769 loadaddr, GFH_FLASH_TYPE_NAND);
771 /* Generate SHA256 hash */
772 put_hash((uint8_t *)gfh,
773 filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN);
776 static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd,
777 struct image_tool_params *params)
779 union lk_hdr *lk = (union lk_hdr *)ptr;
782 lk->magic = cpu_to_le32(LK_PART_MAGIC);
783 lk->size = cpu_to_le32(sbuf->st_size - sizeof(union lk_hdr));
784 lk->loadaddr = cpu_to_le32(params->addr);
785 lk->mode = 0xffffffff; /* must be non-zero */
786 memset(lk->name, 0, sizeof(lk->name));
787 strncpy(lk->name, lk_name, sizeof(lk->name));
792 img_size = sbuf->st_size;
794 if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
795 mtk_image_set_nand_header(ptr, sbuf->st_size, params->addr);
797 mtk_image_set_gen_header(ptr, sbuf->st_size, params->addr);
802 "MediaTek BootROM Loadable Image support",
805 mtk_image_check_params,
806 mtk_image_verify_header,
807 mtk_image_print_header,
808 mtk_image_set_header,
810 mtk_image_check_image_types,
812 mtk_image_vrec_header