Commit 3d3bb6708a3c41723b899f7186ae79b4e9b6baa1
1 parent
59ca4318ab
Exists in
smarc-imx-l5.0.0_1.0.0-ga
MLK-9714 imx: imximage tool: Fixed the bootdata.size calculation
The bootdata.size should contain the IVT offset part, but the calculation for bootdata.size in imximage tool does not. This will cause some data at the end of image not be loaded into memory. Signed-off-by: Ye.Li <B37916@freescale.com>
Showing 1 changed file with 1 additions and 1 deletions Inline Diff
tools/imximage.c
1 | /* | 1 | /* |
2 | * (C) Copyright 2009 | 2 | * (C) Copyright 2009 |
3 | * Stefano Babic, DENX Software Engineering, sbabic@denx.de. | 3 | * Stefano Babic, DENX Software Engineering, sbabic@denx.de. |
4 | * | 4 | * |
5 | * (C) Copyright 2008 | 5 | * (C) Copyright 2008 |
6 | * Marvell Semiconductor <www.marvell.com> | 6 | * Marvell Semiconductor <www.marvell.com> |
7 | * Written-by: Prafulla Wadaskar <prafulla@marvell.com> | 7 | * Written-by: Prafulla Wadaskar <prafulla@marvell.com> |
8 | * | 8 | * |
9 | * Copyright (C) 2014 Freescale Semiconductor, Inc. | 9 | * Copyright (C) 2014 Freescale Semiconductor, Inc. |
10 | * | 10 | * |
11 | * SPDX-License-Identifier: GPL-2.0+ | 11 | * SPDX-License-Identifier: GPL-2.0+ |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "imagetool.h" | 14 | #include "imagetool.h" |
15 | #include <image.h> | 15 | #include <image.h> |
16 | #include "imximage.h" | 16 | #include "imximage.h" |
17 | 17 | ||
18 | #define UNDEFINED 0xFFFFFFFF | 18 | #define UNDEFINED 0xFFFFFFFF |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * Supported commands for configuration file | 21 | * Supported commands for configuration file |
22 | */ | 22 | */ |
23 | static table_entry_t imximage_cmds[] = { | 23 | static table_entry_t imximage_cmds[] = { |
24 | {CMD_BOOT_FROM, "BOOT_FROM", "boot command", }, | 24 | {CMD_BOOT_FROM, "BOOT_FROM", "boot command", }, |
25 | {CMD_BOOT_OFFSET, "BOOT_OFFSET", "Boot offset", }, | 25 | {CMD_BOOT_OFFSET, "BOOT_OFFSET", "Boot offset", }, |
26 | {CMD_DATA, "DATA", "Reg Write Data", }, | 26 | {CMD_DATA, "DATA", "Reg Write Data", }, |
27 | {CMD_CSF, "CSF", "Command Sequence File", }, | 27 | {CMD_CSF, "CSF", "Command Sequence File", }, |
28 | {CMD_IMAGE_VERSION, "IMAGE_VERSION", "image version", }, | 28 | {CMD_IMAGE_VERSION, "IMAGE_VERSION", "image version", }, |
29 | #ifdef CONFIG_USE_PLUGIN | 29 | #ifdef CONFIG_USE_PLUGIN |
30 | {CMD_PLUGIN, "PLUGIN", "file plugin_addr", }, | 30 | {CMD_PLUGIN, "PLUGIN", "file plugin_addr", }, |
31 | #endif | 31 | #endif |
32 | {-1, "", "", }, | 32 | {-1, "", "", }, |
33 | }; | 33 | }; |
34 | 34 | ||
35 | /* | 35 | /* |
36 | * Supported Boot options for configuration file | 36 | * Supported Boot options for configuration file |
37 | * this is needed to set the correct flash offset | 37 | * this is needed to set the correct flash offset |
38 | */ | 38 | */ |
39 | static table_entry_t imximage_boot_offset[] = { | 39 | static table_entry_t imximage_boot_offset[] = { |
40 | {FLASH_OFFSET_ONENAND, "onenand", "OneNAND Flash",}, | 40 | {FLASH_OFFSET_ONENAND, "onenand", "OneNAND Flash",}, |
41 | {FLASH_OFFSET_NAND, "nand", "NAND Flash", }, | 41 | {FLASH_OFFSET_NAND, "nand", "NAND Flash", }, |
42 | {FLASH_OFFSET_NOR, "nor", "NOR Flash", }, | 42 | {FLASH_OFFSET_NOR, "nor", "NOR Flash", }, |
43 | {FLASH_OFFSET_SATA, "sata", "SATA Disk", }, | 43 | {FLASH_OFFSET_SATA, "sata", "SATA Disk", }, |
44 | {FLASH_OFFSET_SD, "sd", "SD Card", }, | 44 | {FLASH_OFFSET_SD, "sd", "SD Card", }, |
45 | {FLASH_OFFSET_SPI, "spi", "SPI Flash", }, | 45 | {FLASH_OFFSET_SPI, "spi", "SPI Flash", }, |
46 | {FLASH_OFFSET_QSPI, "qspi", "QSPI Flash", }, | 46 | {FLASH_OFFSET_QSPI, "qspi", "QSPI Flash", }, |
47 | {-1, "", "Invalid", }, | 47 | {-1, "", "Invalid", }, |
48 | }; | 48 | }; |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Supported Boot options for configuration file | 51 | * Supported Boot options for configuration file |
52 | * this is needed to determine the initial load size | 52 | * this is needed to determine the initial load size |
53 | */ | 53 | */ |
54 | static table_entry_t imximage_boot_loadsize[] = { | 54 | static table_entry_t imximage_boot_loadsize[] = { |
55 | {FLASH_LOADSIZE_ONENAND, "onenand", "OneNAND Flash",}, | 55 | {FLASH_LOADSIZE_ONENAND, "onenand", "OneNAND Flash",}, |
56 | {FLASH_LOADSIZE_NAND, "nand", "NAND Flash", }, | 56 | {FLASH_LOADSIZE_NAND, "nand", "NAND Flash", }, |
57 | {FLASH_LOADSIZE_NOR, "nor", "NOR Flash", }, | 57 | {FLASH_LOADSIZE_NOR, "nor", "NOR Flash", }, |
58 | {FLASH_LOADSIZE_SATA, "sata", "SATA Disk", }, | 58 | {FLASH_LOADSIZE_SATA, "sata", "SATA Disk", }, |
59 | {FLASH_LOADSIZE_SD, "sd", "SD Card", }, | 59 | {FLASH_LOADSIZE_SD, "sd", "SD Card", }, |
60 | {FLASH_LOADSIZE_SPI, "spi", "SPI Flash", }, | 60 | {FLASH_LOADSIZE_SPI, "spi", "SPI Flash", }, |
61 | {FLASH_LOADSIZE_QSPI, "qspi", "QSPI Flash", }, | 61 | {FLASH_LOADSIZE_QSPI, "qspi", "QSPI Flash", }, |
62 | {-1, "", "Invalid", }, | 62 | {-1, "", "Invalid", }, |
63 | }; | 63 | }; |
64 | 64 | ||
65 | /* | 65 | /* |
66 | * IMXIMAGE version definition for i.MX chips | 66 | * IMXIMAGE version definition for i.MX chips |
67 | */ | 67 | */ |
68 | static table_entry_t imximage_versions[] = { | 68 | static table_entry_t imximage_versions[] = { |
69 | {IMXIMAGE_V1, "", " (i.MX25/35/51 compatible)", }, | 69 | {IMXIMAGE_V1, "", " (i.MX25/35/51 compatible)", }, |
70 | {IMXIMAGE_V2, "", " (i.MX53/6 compatible)", }, | 70 | {IMXIMAGE_V2, "", " (i.MX53/6 compatible)", }, |
71 | {-1, "", " (Invalid)", }, | 71 | {-1, "", " (Invalid)", }, |
72 | }; | 72 | }; |
73 | 73 | ||
74 | static struct imx_header imximage_header; | 74 | static struct imx_header imximage_header; |
75 | static uint32_t imximage_version; | 75 | static uint32_t imximage_version; |
76 | /* | 76 | /* |
77 | * Image Vector Table Offset | 77 | * Image Vector Table Offset |
78 | * Initialized to a wrong not 4-bytes aligned address to | 78 | * Initialized to a wrong not 4-bytes aligned address to |
79 | * check if it is was set by the cfg file. | 79 | * check if it is was set by the cfg file. |
80 | */ | 80 | */ |
81 | static uint32_t imximage_ivt_offset = UNDEFINED; | 81 | static uint32_t imximage_ivt_offset = UNDEFINED; |
82 | static uint32_t imximage_csf_size = UNDEFINED; | 82 | static uint32_t imximage_csf_size = UNDEFINED; |
83 | /* Initial Load Region Size */ | 83 | /* Initial Load Region Size */ |
84 | static uint32_t imximage_init_loadsize; | 84 | static uint32_t imximage_init_loadsize; |
85 | static uint32_t imximage_iram_free_start; | 85 | static uint32_t imximage_iram_free_start; |
86 | static uint32_t imximage_plugin_size; | 86 | static uint32_t imximage_plugin_size; |
87 | 87 | ||
88 | static set_dcd_val_t set_dcd_val; | 88 | static set_dcd_val_t set_dcd_val; |
89 | static set_dcd_rst_t set_dcd_rst; | 89 | static set_dcd_rst_t set_dcd_rst; |
90 | static set_imx_hdr_t set_imx_hdr; | 90 | static set_imx_hdr_t set_imx_hdr; |
91 | static uint32_t max_dcd_entries; | 91 | static uint32_t max_dcd_entries; |
92 | static uint32_t *header_size_ptr; | 92 | static uint32_t *header_size_ptr; |
93 | static uint32_t *csf_ptr; | 93 | static uint32_t *csf_ptr; |
94 | 94 | ||
95 | static uint32_t get_cfg_value(char *token, char *name, int linenr) | 95 | static uint32_t get_cfg_value(char *token, char *name, int linenr) |
96 | { | 96 | { |
97 | char *endptr; | 97 | char *endptr; |
98 | uint32_t value; | 98 | uint32_t value; |
99 | 99 | ||
100 | errno = 0; | 100 | errno = 0; |
101 | value = strtoul(token, &endptr, 16); | 101 | value = strtoul(token, &endptr, 16); |
102 | if (errno || (token == endptr)) { | 102 | if (errno || (token == endptr)) { |
103 | fprintf(stderr, "Error: %s[%d] - Invalid hex data(%s)\n", | 103 | fprintf(stderr, "Error: %s[%d] - Invalid hex data(%s)\n", |
104 | name, linenr, token); | 104 | name, linenr, token); |
105 | exit(EXIT_FAILURE); | 105 | exit(EXIT_FAILURE); |
106 | } | 106 | } |
107 | return value; | 107 | return value; |
108 | } | 108 | } |
109 | 109 | ||
110 | static uint32_t detect_imximage_version(struct imx_header *imx_hdr) | 110 | static uint32_t detect_imximage_version(struct imx_header *imx_hdr) |
111 | { | 111 | { |
112 | imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1; | 112 | imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1; |
113 | imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2; | 113 | imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2; |
114 | flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr; | 114 | flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr; |
115 | flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr; | 115 | flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr; |
116 | 116 | ||
117 | /* Try to detect V1 */ | 117 | /* Try to detect V1 */ |
118 | if ((fhdr_v1->app_code_barker == APP_CODE_BARKER) && | 118 | if ((fhdr_v1->app_code_barker == APP_CODE_BARKER) && |
119 | (hdr_v1->dcd_table.preamble.barker == DCD_BARKER)) | 119 | (hdr_v1->dcd_table.preamble.barker == DCD_BARKER)) |
120 | return IMXIMAGE_V1; | 120 | return IMXIMAGE_V1; |
121 | 121 | ||
122 | /* Try to detect V2 */ | 122 | /* Try to detect V2 */ |
123 | if ((fhdr_v2->header.tag == IVT_HEADER_TAG) && | 123 | if ((fhdr_v2->header.tag == IVT_HEADER_TAG) && |
124 | (hdr_v2->data.dcd_table.header.tag == DCD_HEADER_TAG)) | 124 | (hdr_v2->data.dcd_table.header.tag == DCD_HEADER_TAG)) |
125 | return IMXIMAGE_V2; | 125 | return IMXIMAGE_V2; |
126 | 126 | ||
127 | if ((fhdr_v2->header.tag == IVT_HEADER_TAG) && | 127 | if ((fhdr_v2->header.tag == IVT_HEADER_TAG) && |
128 | hdr_v2->boot_data.plugin) | 128 | hdr_v2->boot_data.plugin) |
129 | return IMXIMAGE_V2; | 129 | return IMXIMAGE_V2; |
130 | 130 | ||
131 | return IMXIMAGE_VER_INVALID; | 131 | return IMXIMAGE_VER_INVALID; |
132 | } | 132 | } |
133 | 133 | ||
134 | static void err_imximage_version(int version) | 134 | static void err_imximage_version(int version) |
135 | { | 135 | { |
136 | fprintf(stderr, | 136 | fprintf(stderr, |
137 | "Error: Unsupported imximage version:%d\n", version); | 137 | "Error: Unsupported imximage version:%d\n", version); |
138 | 138 | ||
139 | exit(EXIT_FAILURE); | 139 | exit(EXIT_FAILURE); |
140 | } | 140 | } |
141 | 141 | ||
142 | static void set_dcd_val_v1(struct imx_header *imxhdr, char *name, int lineno, | 142 | static void set_dcd_val_v1(struct imx_header *imxhdr, char *name, int lineno, |
143 | int fld, uint32_t value, uint32_t off) | 143 | int fld, uint32_t value, uint32_t off) |
144 | { | 144 | { |
145 | dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table; | 145 | dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table; |
146 | 146 | ||
147 | switch (fld) { | 147 | switch (fld) { |
148 | case CFG_REG_SIZE: | 148 | case CFG_REG_SIZE: |
149 | /* Byte, halfword, word */ | 149 | /* Byte, halfword, word */ |
150 | if ((value != 1) && (value != 2) && (value != 4)) { | 150 | if ((value != 1) && (value != 2) && (value != 4)) { |
151 | fprintf(stderr, "Error: %s[%d] - " | 151 | fprintf(stderr, "Error: %s[%d] - " |
152 | "Invalid register size " "(%d)\n", | 152 | "Invalid register size " "(%d)\n", |
153 | name, lineno, value); | 153 | name, lineno, value); |
154 | exit(EXIT_FAILURE); | 154 | exit(EXIT_FAILURE); |
155 | } | 155 | } |
156 | dcd_v1->addr_data[off].type = value; | 156 | dcd_v1->addr_data[off].type = value; |
157 | break; | 157 | break; |
158 | case CFG_REG_ADDRESS: | 158 | case CFG_REG_ADDRESS: |
159 | dcd_v1->addr_data[off].addr = value; | 159 | dcd_v1->addr_data[off].addr = value; |
160 | break; | 160 | break; |
161 | case CFG_REG_VALUE: | 161 | case CFG_REG_VALUE: |
162 | dcd_v1->addr_data[off].value = value; | 162 | dcd_v1->addr_data[off].value = value; |
163 | break; | 163 | break; |
164 | default: | 164 | default: |
165 | break; | 165 | break; |
166 | 166 | ||
167 | } | 167 | } |
168 | } | 168 | } |
169 | 169 | ||
170 | static void set_dcd_val_v2(struct imx_header *imxhdr, char *name, int lineno, | 170 | static void set_dcd_val_v2(struct imx_header *imxhdr, char *name, int lineno, |
171 | int fld, uint32_t value, uint32_t off) | 171 | int fld, uint32_t value, uint32_t off) |
172 | { | 172 | { |
173 | dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.data.dcd_table; | 173 | dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.data.dcd_table; |
174 | 174 | ||
175 | switch (fld) { | 175 | switch (fld) { |
176 | case CFG_REG_ADDRESS: | 176 | case CFG_REG_ADDRESS: |
177 | dcd_v2->addr_data[off].addr = cpu_to_be32(value); | 177 | dcd_v2->addr_data[off].addr = cpu_to_be32(value); |
178 | break; | 178 | break; |
179 | case CFG_REG_VALUE: | 179 | case CFG_REG_VALUE: |
180 | dcd_v2->addr_data[off].value = cpu_to_be32(value); | 180 | dcd_v2->addr_data[off].value = cpu_to_be32(value); |
181 | break; | 181 | break; |
182 | default: | 182 | default: |
183 | break; | 183 | break; |
184 | 184 | ||
185 | } | 185 | } |
186 | } | 186 | } |
187 | 187 | ||
188 | /* | 188 | /* |
189 | * Complete setting up the rest field of DCD of V1 | 189 | * Complete setting up the rest field of DCD of V1 |
190 | * such as barker code and DCD data length. | 190 | * such as barker code and DCD data length. |
191 | */ | 191 | */ |
192 | static void set_dcd_rst_v1(struct imx_header *imxhdr, uint32_t dcd_len, | 192 | static void set_dcd_rst_v1(struct imx_header *imxhdr, uint32_t dcd_len, |
193 | char *name, int lineno) | 193 | char *name, int lineno) |
194 | { | 194 | { |
195 | dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table; | 195 | dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table; |
196 | 196 | ||
197 | dcd_v1->preamble.barker = DCD_BARKER; | 197 | dcd_v1->preamble.barker = DCD_BARKER; |
198 | dcd_v1->preamble.length = dcd_len * sizeof(dcd_type_addr_data_t); | 198 | dcd_v1->preamble.length = dcd_len * sizeof(dcd_type_addr_data_t); |
199 | } | 199 | } |
200 | 200 | ||
201 | /* | 201 | /* |
202 | * Complete setting up the reset field of DCD of V2 | 202 | * Complete setting up the reset field of DCD of V2 |
203 | * such as DCD tag, version, length, etc. | 203 | * such as DCD tag, version, length, etc. |
204 | */ | 204 | */ |
205 | static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, | 205 | static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, |
206 | char *name, int lineno) | 206 | char *name, int lineno) |
207 | { | 207 | { |
208 | if (!imxhdr->header.hdr_v2.boot_data.plugin) { | 208 | if (!imxhdr->header.hdr_v2.boot_data.plugin) { |
209 | dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.data.dcd_table; | 209 | dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.data.dcd_table; |
210 | 210 | ||
211 | dcd_v2->header.tag = DCD_HEADER_TAG; | 211 | dcd_v2->header.tag = DCD_HEADER_TAG; |
212 | dcd_v2->header.length = cpu_to_be16( | 212 | dcd_v2->header.length = cpu_to_be16( |
213 | dcd_len * sizeof(dcd_addr_data_t) + 8); | 213 | dcd_len * sizeof(dcd_addr_data_t) + 8); |
214 | dcd_v2->header.version = DCD_VERSION; | 214 | dcd_v2->header.version = DCD_VERSION; |
215 | dcd_v2->write_dcd_command.tag = DCD_COMMAND_TAG; | 215 | dcd_v2->write_dcd_command.tag = DCD_COMMAND_TAG; |
216 | dcd_v2->write_dcd_command.length = cpu_to_be16( | 216 | dcd_v2->write_dcd_command.length = cpu_to_be16( |
217 | dcd_len * sizeof(dcd_addr_data_t) + 4); | 217 | dcd_len * sizeof(dcd_addr_data_t) + 4); |
218 | dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM; | 218 | dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM; |
219 | } | 219 | } |
220 | } | 220 | } |
221 | 221 | ||
222 | static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len, | 222 | static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len, |
223 | uint32_t entry_point, uint32_t flash_offset) | 223 | uint32_t entry_point, uint32_t flash_offset) |
224 | { | 224 | { |
225 | imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1; | 225 | imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1; |
226 | flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr; | 226 | flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr; |
227 | dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table; | 227 | dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table; |
228 | uint32_t hdr_base; | 228 | uint32_t hdr_base; |
229 | uint32_t header_length = (((char *)&dcd_v1->addr_data[dcd_len].addr) | 229 | uint32_t header_length = (((char *)&dcd_v1->addr_data[dcd_len].addr) |
230 | - ((char *)imxhdr)); | 230 | - ((char *)imxhdr)); |
231 | 231 | ||
232 | /* Set magic number */ | 232 | /* Set magic number */ |
233 | fhdr_v1->app_code_barker = APP_CODE_BARKER; | 233 | fhdr_v1->app_code_barker = APP_CODE_BARKER; |
234 | 234 | ||
235 | /* TODO: check i.MX image V1 handling, for now use 'old' style */ | 235 | /* TODO: check i.MX image V1 handling, for now use 'old' style */ |
236 | hdr_base = entry_point - 4096; | 236 | hdr_base = entry_point - 4096; |
237 | fhdr_v1->app_dest_ptr = hdr_base - flash_offset; | 237 | fhdr_v1->app_dest_ptr = hdr_base - flash_offset; |
238 | fhdr_v1->app_code_jump_vector = entry_point; | 238 | fhdr_v1->app_code_jump_vector = entry_point; |
239 | 239 | ||
240 | fhdr_v1->dcd_ptr_ptr = hdr_base + offsetof(flash_header_v1_t, dcd_ptr); | 240 | fhdr_v1->dcd_ptr_ptr = hdr_base + offsetof(flash_header_v1_t, dcd_ptr); |
241 | fhdr_v1->dcd_ptr = hdr_base + offsetof(imx_header_v1_t, dcd_table); | 241 | fhdr_v1->dcd_ptr = hdr_base + offsetof(imx_header_v1_t, dcd_table); |
242 | 242 | ||
243 | /* Security feature are not supported */ | 243 | /* Security feature are not supported */ |
244 | fhdr_v1->app_code_csf = 0; | 244 | fhdr_v1->app_code_csf = 0; |
245 | fhdr_v1->super_root_key = 0; | 245 | fhdr_v1->super_root_key = 0; |
246 | header_size_ptr = (uint32_t *)(((char *)imxhdr) + header_length - 4); | 246 | header_size_ptr = (uint32_t *)(((char *)imxhdr) + header_length - 4); |
247 | } | 247 | } |
248 | 248 | ||
249 | static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len, | 249 | static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len, |
250 | uint32_t entry_point, uint32_t flash_offset) | 250 | uint32_t entry_point, uint32_t flash_offset) |
251 | { | 251 | { |
252 | imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2; | 252 | imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2; |
253 | flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr; | 253 | flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr; |
254 | uint32_t hdr_base; | 254 | uint32_t hdr_base; |
255 | 255 | ||
256 | /* Set magic number */ | 256 | /* Set magic number */ |
257 | fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */ | 257 | fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */ |
258 | fhdr_v2->header.length = cpu_to_be16(sizeof(flash_header_v2_t)); | 258 | fhdr_v2->header.length = cpu_to_be16(sizeof(flash_header_v2_t)); |
259 | fhdr_v2->header.version = IVT_VERSION; /* 0x40 */ | 259 | fhdr_v2->header.version = IVT_VERSION; /* 0x40 */ |
260 | 260 | ||
261 | if (!hdr_v2->boot_data.plugin) { | 261 | if (!hdr_v2->boot_data.plugin) { |
262 | fhdr_v2->entry = entry_point; | 262 | fhdr_v2->entry = entry_point; |
263 | fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0; | 263 | fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0; |
264 | hdr_base = entry_point - imximage_init_loadsize + | 264 | hdr_base = entry_point - imximage_init_loadsize + |
265 | flash_offset; | 265 | flash_offset; |
266 | fhdr_v2->self = hdr_base; | 266 | fhdr_v2->self = hdr_base; |
267 | fhdr_v2->dcd_ptr = hdr_base + offsetof(imx_header_v2_t, data); | 267 | fhdr_v2->dcd_ptr = hdr_base + offsetof(imx_header_v2_t, data); |
268 | fhdr_v2->boot_data_ptr = hdr_base | 268 | fhdr_v2->boot_data_ptr = hdr_base |
269 | + offsetof(imx_header_v2_t, boot_data); | 269 | + offsetof(imx_header_v2_t, boot_data); |
270 | hdr_v2->boot_data.start = entry_point - imximage_init_loadsize; | 270 | hdr_v2->boot_data.start = entry_point - imximage_init_loadsize; |
271 | 271 | ||
272 | fhdr_v2->csf = 0; | 272 | fhdr_v2->csf = 0; |
273 | 273 | ||
274 | header_size_ptr = &hdr_v2->boot_data.size; | 274 | header_size_ptr = &hdr_v2->boot_data.size; |
275 | csf_ptr = &fhdr_v2->csf; | 275 | csf_ptr = &fhdr_v2->csf; |
276 | } else { | 276 | } else { |
277 | imx_header_v2_t *next_hdr_v2; | 277 | imx_header_v2_t *next_hdr_v2; |
278 | flash_header_v2_t *next_fhdr_v2; | 278 | flash_header_v2_t *next_fhdr_v2; |
279 | 279 | ||
280 | if(imximage_csf_size != 0) { | 280 | if(imximage_csf_size != 0) { |
281 | fprintf(stderr, "Error: Header v2: SECURE_BOOT" | 281 | fprintf(stderr, "Error: Header v2: SECURE_BOOT" |
282 | "is only supported in DCD mode!"); | 282 | "is only supported in DCD mode!"); |
283 | exit(EXIT_FAILURE); | 283 | exit(EXIT_FAILURE); |
284 | } | 284 | } |
285 | 285 | ||
286 | fhdr_v2->entry = imximage_iram_free_start + | 286 | fhdr_v2->entry = imximage_iram_free_start + |
287 | flash_offset + sizeof(flash_header_v2_t) + | 287 | flash_offset + sizeof(flash_header_v2_t) + |
288 | sizeof(boot_data_t); | 288 | sizeof(boot_data_t); |
289 | 289 | ||
290 | fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0; | 290 | fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0; |
291 | fhdr_v2->self = imximage_iram_free_start + flash_offset; | 291 | fhdr_v2->self = imximage_iram_free_start + flash_offset; |
292 | 292 | ||
293 | fhdr_v2->dcd_ptr = 0; | 293 | fhdr_v2->dcd_ptr = 0; |
294 | 294 | ||
295 | fhdr_v2->boot_data_ptr = fhdr_v2->self + | 295 | fhdr_v2->boot_data_ptr = fhdr_v2->self + |
296 | offsetof(imx_header_v2_t, boot_data); | 296 | offsetof(imx_header_v2_t, boot_data); |
297 | 297 | ||
298 | hdr_v2->boot_data.start = imximage_iram_free_start; | 298 | hdr_v2->boot_data.start = imximage_iram_free_start; |
299 | /* | 299 | /* |
300 | * The actural size of plugin image is "imximage_plugin_size + | 300 | * The actural size of plugin image is "imximage_plugin_size + |
301 | * sizeof(flash_header_v2_t) + sizeof(boot_data_t)", plus the | 301 | * sizeof(flash_header_v2_t) + sizeof(boot_data_t)", plus the |
302 | * flash_offset space.The ROM code only need to copy this size | 302 | * flash_offset space.The ROM code only need to copy this size |
303 | * to run the plugin code. However, later when copy the whole | 303 | * to run the plugin code. However, later when copy the whole |
304 | * U-Boot image to DDR, the ROM code use memcpy to copy the | 304 | * U-Boot image to DDR, the ROM code use memcpy to copy the |
305 | * first part of the image, and use the storage read function | 305 | * first part of the image, and use the storage read function |
306 | * to get the remaining part. This requires the dividing point | 306 | * to get the remaining part. This requires the dividing point |
307 | * must be multiple of storage sector size. Here we set the | 307 | * must be multiple of storage sector size. Here we set the |
308 | * first section to be 16KB for this purpose. | 308 | * first section to be 16KB for this purpose. |
309 | */ | 309 | */ |
310 | hdr_v2->boot_data.size = MAX_PLUGIN_CODE_SIZE; | 310 | hdr_v2->boot_data.size = MAX_PLUGIN_CODE_SIZE; |
311 | 311 | ||
312 | /* Security feature are not supported */ | 312 | /* Security feature are not supported */ |
313 | fhdr_v2->csf = 0; | 313 | fhdr_v2->csf = 0; |
314 | 314 | ||
315 | next_hdr_v2 = (imx_header_v2_t *)((char*)hdr_v2 + | 315 | next_hdr_v2 = (imx_header_v2_t *)((char*)hdr_v2 + |
316 | imximage_plugin_size); | 316 | imximage_plugin_size); |
317 | 317 | ||
318 | next_fhdr_v2 = &next_hdr_v2->fhdr; | 318 | next_fhdr_v2 = &next_hdr_v2->fhdr; |
319 | 319 | ||
320 | next_fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */ | 320 | next_fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */ |
321 | next_fhdr_v2->header.length = | 321 | next_fhdr_v2->header.length = |
322 | cpu_to_be16(sizeof(flash_header_v2_t)); | 322 | cpu_to_be16(sizeof(flash_header_v2_t)); |
323 | next_fhdr_v2->header.version = IVT_VERSION; /* 0x40 */ | 323 | next_fhdr_v2->header.version = IVT_VERSION; /* 0x40 */ |
324 | 324 | ||
325 | next_fhdr_v2->entry = entry_point; | 325 | next_fhdr_v2->entry = entry_point; |
326 | hdr_base = entry_point - sizeof(struct imx_header); | 326 | hdr_base = entry_point - sizeof(struct imx_header); |
327 | next_fhdr_v2->reserved1 = next_fhdr_v2->reserved2 = 0; | 327 | next_fhdr_v2->reserved1 = next_fhdr_v2->reserved2 = 0; |
328 | next_fhdr_v2->self = hdr_base + imximage_plugin_size; | 328 | next_fhdr_v2->self = hdr_base + imximage_plugin_size; |
329 | 329 | ||
330 | next_fhdr_v2->dcd_ptr = 0; | 330 | next_fhdr_v2->dcd_ptr = 0; |
331 | next_fhdr_v2->boot_data_ptr = next_fhdr_v2->self + | 331 | next_fhdr_v2->boot_data_ptr = next_fhdr_v2->self + |
332 | offsetof(imx_header_v2_t, boot_data); | 332 | offsetof(imx_header_v2_t, boot_data); |
333 | 333 | ||
334 | next_hdr_v2->boot_data.start = hdr_base - flash_offset; | 334 | next_hdr_v2->boot_data.start = hdr_base - flash_offset; |
335 | 335 | ||
336 | header_size_ptr = &next_hdr_v2->boot_data.size; | 336 | header_size_ptr = &next_hdr_v2->boot_data.size; |
337 | 337 | ||
338 | next_hdr_v2->boot_data.plugin = 0; | 338 | next_hdr_v2->boot_data.plugin = 0; |
339 | 339 | ||
340 | next_fhdr_v2->csf = 0; | 340 | next_fhdr_v2->csf = 0; |
341 | } | 341 | } |
342 | } | 342 | } |
343 | 343 | ||
344 | static void set_hdr_func(void) | 344 | static void set_hdr_func(void) |
345 | { | 345 | { |
346 | switch (imximage_version) { | 346 | switch (imximage_version) { |
347 | case IMXIMAGE_V1: | 347 | case IMXIMAGE_V1: |
348 | set_dcd_val = set_dcd_val_v1; | 348 | set_dcd_val = set_dcd_val_v1; |
349 | set_dcd_rst = set_dcd_rst_v1; | 349 | set_dcd_rst = set_dcd_rst_v1; |
350 | set_imx_hdr = set_imx_hdr_v1; | 350 | set_imx_hdr = set_imx_hdr_v1; |
351 | max_dcd_entries = MAX_HW_CFG_SIZE_V1; | 351 | max_dcd_entries = MAX_HW_CFG_SIZE_V1; |
352 | break; | 352 | break; |
353 | case IMXIMAGE_V2: | 353 | case IMXIMAGE_V2: |
354 | set_dcd_val = set_dcd_val_v2; | 354 | set_dcd_val = set_dcd_val_v2; |
355 | set_dcd_rst = set_dcd_rst_v2; | 355 | set_dcd_rst = set_dcd_rst_v2; |
356 | set_imx_hdr = set_imx_hdr_v2; | 356 | set_imx_hdr = set_imx_hdr_v2; |
357 | max_dcd_entries = MAX_HW_CFG_SIZE_V2; | 357 | max_dcd_entries = MAX_HW_CFG_SIZE_V2; |
358 | break; | 358 | break; |
359 | default: | 359 | default: |
360 | err_imximage_version(imximage_version); | 360 | err_imximage_version(imximage_version); |
361 | break; | 361 | break; |
362 | } | 362 | } |
363 | } | 363 | } |
364 | 364 | ||
365 | static void print_hdr_v1(struct imx_header *imx_hdr) | 365 | static void print_hdr_v1(struct imx_header *imx_hdr) |
366 | { | 366 | { |
367 | imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1; | 367 | imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1; |
368 | flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr; | 368 | flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr; |
369 | dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table; | 369 | dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table; |
370 | uint32_t size, length, ver; | 370 | uint32_t size, length, ver; |
371 | 371 | ||
372 | size = dcd_v1->preamble.length; | 372 | size = dcd_v1->preamble.length; |
373 | if (size > (MAX_HW_CFG_SIZE_V1 * sizeof(dcd_type_addr_data_t))) { | 373 | if (size > (MAX_HW_CFG_SIZE_V1 * sizeof(dcd_type_addr_data_t))) { |
374 | fprintf(stderr, | 374 | fprintf(stderr, |
375 | "Error: Image corrupt DCD size %d exceed maximum %d\n", | 375 | "Error: Image corrupt DCD size %d exceed maximum %d\n", |
376 | (uint32_t)(size / sizeof(dcd_type_addr_data_t)), | 376 | (uint32_t)(size / sizeof(dcd_type_addr_data_t)), |
377 | MAX_HW_CFG_SIZE_V1); | 377 | MAX_HW_CFG_SIZE_V1); |
378 | exit(EXIT_FAILURE); | 378 | exit(EXIT_FAILURE); |
379 | } | 379 | } |
380 | 380 | ||
381 | length = dcd_v1->preamble.length / sizeof(dcd_type_addr_data_t); | 381 | length = dcd_v1->preamble.length / sizeof(dcd_type_addr_data_t); |
382 | ver = detect_imximage_version(imx_hdr); | 382 | ver = detect_imximage_version(imx_hdr); |
383 | 383 | ||
384 | printf("Image Type: Freescale IMX Boot Image\n"); | 384 | printf("Image Type: Freescale IMX Boot Image\n"); |
385 | printf("Image Ver: %x", ver); | 385 | printf("Image Ver: %x", ver); |
386 | printf("%s\n", get_table_entry_name(imximage_versions, NULL, ver)); | 386 | printf("%s\n", get_table_entry_name(imximage_versions, NULL, ver)); |
387 | printf("Data Size: "); | 387 | printf("Data Size: "); |
388 | genimg_print_size(dcd_v1->addr_data[length].type); | 388 | genimg_print_size(dcd_v1->addr_data[length].type); |
389 | printf("Load Address: %08x\n", (uint32_t)fhdr_v1->app_dest_ptr); | 389 | printf("Load Address: %08x\n", (uint32_t)fhdr_v1->app_dest_ptr); |
390 | printf("Entry Point: %08x\n", (uint32_t)fhdr_v1->app_code_jump_vector); | 390 | printf("Entry Point: %08x\n", (uint32_t)fhdr_v1->app_code_jump_vector); |
391 | } | 391 | } |
392 | 392 | ||
393 | static void print_hdr_v2(struct imx_header *imx_hdr) | 393 | static void print_hdr_v2(struct imx_header *imx_hdr) |
394 | { | 394 | { |
395 | imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2; | 395 | imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2; |
396 | flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr; | 396 | flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr; |
397 | dcd_v2_t *dcd_v2 = &hdr_v2->data.dcd_table; | 397 | dcd_v2_t *dcd_v2 = &hdr_v2->data.dcd_table; |
398 | uint32_t size, version, plugin; | 398 | uint32_t size, version, plugin; |
399 | 399 | ||
400 | plugin = hdr_v2->boot_data.plugin; | 400 | plugin = hdr_v2->boot_data.plugin; |
401 | if (!plugin) { | 401 | if (!plugin) { |
402 | size = be16_to_cpu(dcd_v2->header.length) - 8; | 402 | size = be16_to_cpu(dcd_v2->header.length) - 8; |
403 | if (size > (MAX_HW_CFG_SIZE_V2 * sizeof(dcd_addr_data_t))) { | 403 | if (size > (MAX_HW_CFG_SIZE_V2 * sizeof(dcd_addr_data_t))) { |
404 | fprintf(stderr, | 404 | fprintf(stderr, |
405 | "Error: Image corrupt DCD size %d exceed maximum %d\n", | 405 | "Error: Image corrupt DCD size %d exceed maximum %d\n", |
406 | (uint32_t)(size / sizeof(dcd_addr_data_t)), | 406 | (uint32_t)(size / sizeof(dcd_addr_data_t)), |
407 | MAX_HW_CFG_SIZE_V2); | 407 | MAX_HW_CFG_SIZE_V2); |
408 | exit(EXIT_FAILURE); | 408 | exit(EXIT_FAILURE); |
409 | } | 409 | } |
410 | } | 410 | } |
411 | 411 | ||
412 | version = detect_imximage_version(imx_hdr); | 412 | version = detect_imximage_version(imx_hdr); |
413 | 413 | ||
414 | printf("Image Type: Freescale IMX Boot Image\n"); | 414 | printf("Image Type: Freescale IMX Boot Image\n"); |
415 | printf("Image Ver: %x", version); | 415 | printf("Image Ver: %x", version); |
416 | printf("%s\n", get_table_entry_name(imximage_versions, NULL, version)); | 416 | printf("%s\n", get_table_entry_name(imximage_versions, NULL, version)); |
417 | printf("Mode: %s\n", plugin ? "PLUGIN" : "DCD"); | 417 | printf("Mode: %s\n", plugin ? "PLUGIN" : "DCD"); |
418 | if (!plugin) { | 418 | if (!plugin) { |
419 | printf("Data Size: "); | 419 | printf("Data Size: "); |
420 | genimg_print_size(hdr_v2->boot_data.size); | 420 | genimg_print_size(hdr_v2->boot_data.size); |
421 | printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr); | 421 | printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr); |
422 | printf("Entry Point: %08x\n", (uint32_t)fhdr_v2->entry); | 422 | printf("Entry Point: %08x\n", (uint32_t)fhdr_v2->entry); |
423 | if (fhdr_v2->csf && (imximage_ivt_offset != UNDEFINED) && | 423 | if (fhdr_v2->csf && (imximage_ivt_offset != UNDEFINED) && |
424 | (imximage_csf_size != UNDEFINED)) { | 424 | (imximage_csf_size != UNDEFINED)) { |
425 | printf("HAB Blocks: %08x %08x %08x\n", | 425 | printf("HAB Blocks: %08x %08x %08x\n", |
426 | (uint32_t)fhdr_v2->self, 0, | 426 | (uint32_t)fhdr_v2->self, 0, |
427 | hdr_v2->boot_data.size - imximage_ivt_offset - | 427 | hdr_v2->boot_data.size - imximage_ivt_offset - |
428 | imximage_csf_size); | 428 | imximage_csf_size); |
429 | } | 429 | } |
430 | } else { | 430 | } else { |
431 | imx_header_v2_t *next_hdr_v2; | 431 | imx_header_v2_t *next_hdr_v2; |
432 | flash_header_v2_t *next_fhdr_v2; | 432 | flash_header_v2_t *next_fhdr_v2; |
433 | 433 | ||
434 | /*First Header*/ | 434 | /*First Header*/ |
435 | printf("Plugin Data Size: "); | 435 | printf("Plugin Data Size: "); |
436 | genimg_print_size(hdr_v2->boot_data.size); | 436 | genimg_print_size(hdr_v2->boot_data.size); |
437 | printf("Plugin Code Size: "); | 437 | printf("Plugin Code Size: "); |
438 | genimg_print_size(imximage_plugin_size); | 438 | genimg_print_size(imximage_plugin_size); |
439 | printf("Plugin Load Address: %08x\n", hdr_v2->boot_data.start); | 439 | printf("Plugin Load Address: %08x\n", hdr_v2->boot_data.start); |
440 | printf("Plugin Entry Point: %08x\n", | 440 | printf("Plugin Entry Point: %08x\n", |
441 | (uint32_t)fhdr_v2->entry); | 441 | (uint32_t)fhdr_v2->entry); |
442 | 442 | ||
443 | /*Second Header*/ | 443 | /*Second Header*/ |
444 | next_hdr_v2 = (imx_header_v2_t *)((char*)hdr_v2 + | 444 | next_hdr_v2 = (imx_header_v2_t *)((char*)hdr_v2 + |
445 | imximage_plugin_size); | 445 | imximage_plugin_size); |
446 | next_fhdr_v2 = &next_hdr_v2->fhdr; | 446 | next_fhdr_v2 = &next_hdr_v2->fhdr; |
447 | printf("U-Boot Data Size: "); | 447 | printf("U-Boot Data Size: "); |
448 | genimg_print_size(next_hdr_v2->boot_data.size); | 448 | genimg_print_size(next_hdr_v2->boot_data.size); |
449 | printf("U-Boot Load Address: %08x\n", next_hdr_v2->boot_data.start); | 449 | printf("U-Boot Load Address: %08x\n", next_hdr_v2->boot_data.start); |
450 | printf("U-Boot Entry Point: %08x\n", | 450 | printf("U-Boot Entry Point: %08x\n", |
451 | (uint32_t)next_fhdr_v2->entry); | 451 | (uint32_t)next_fhdr_v2->entry); |
452 | } | 452 | } |
453 | } | 453 | } |
454 | 454 | ||
455 | #ifdef CONFIG_USE_PLUGIN | 455 | #ifdef CONFIG_USE_PLUGIN |
456 | static void copy_plugin_code(struct imx_header *imxhdr, char *plugin_file) | 456 | static void copy_plugin_code(struct imx_header *imxhdr, char *plugin_file) |
457 | { | 457 | { |
458 | int ifd = -1; | 458 | int ifd = -1; |
459 | struct stat sbuf; | 459 | struct stat sbuf; |
460 | char *plugin_buf = imxhdr->header.hdr_v2.data.plugin_code; | 460 | char *plugin_buf = imxhdr->header.hdr_v2.data.plugin_code; |
461 | char *ptr; | 461 | char *ptr; |
462 | 462 | ||
463 | ifd = open(plugin_file, O_RDONLY|O_BINARY); | 463 | ifd = open(plugin_file, O_RDONLY|O_BINARY); |
464 | if (fstat(ifd, &sbuf) < 0) { | 464 | if (fstat(ifd, &sbuf) < 0) { |
465 | fprintf(stderr, "Can't stat %s: %s\n", | 465 | fprintf(stderr, "Can't stat %s: %s\n", |
466 | plugin_file, | 466 | plugin_file, |
467 | strerror(errno)); | 467 | strerror(errno)); |
468 | exit(EXIT_FAILURE); | 468 | exit(EXIT_FAILURE); |
469 | } | 469 | } |
470 | 470 | ||
471 | ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0); | 471 | ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0); |
472 | if (ptr == MAP_FAILED) { | 472 | if (ptr == MAP_FAILED) { |
473 | fprintf(stderr, "Can't read %s: %s\n", | 473 | fprintf(stderr, "Can't read %s: %s\n", |
474 | plugin_file, | 474 | plugin_file, |
475 | strerror(errno)); | 475 | strerror(errno)); |
476 | exit(EXIT_FAILURE); | 476 | exit(EXIT_FAILURE); |
477 | } | 477 | } |
478 | 478 | ||
479 | if (sbuf.st_size > MAX_PLUGIN_CODE_SIZE) { | 479 | if (sbuf.st_size > MAX_PLUGIN_CODE_SIZE) { |
480 | printf("plugin binary size too large\n"); | 480 | printf("plugin binary size too large\n"); |
481 | exit(EXIT_FAILURE); | 481 | exit(EXIT_FAILURE); |
482 | } | 482 | } |
483 | 483 | ||
484 | memcpy(plugin_buf, ptr, sbuf.st_size); | 484 | memcpy(plugin_buf, ptr, sbuf.st_size); |
485 | imximage_plugin_size = sbuf.st_size; | 485 | imximage_plugin_size = sbuf.st_size; |
486 | 486 | ||
487 | (void) munmap((void *)ptr, sbuf.st_size); | 487 | (void) munmap((void *)ptr, sbuf.st_size); |
488 | (void) close(ifd); | 488 | (void) close(ifd); |
489 | 489 | ||
490 | imxhdr->header.hdr_v2.boot_data.plugin = 1; | 490 | imxhdr->header.hdr_v2.boot_data.plugin = 1; |
491 | } | 491 | } |
492 | #endif | 492 | #endif |
493 | 493 | ||
494 | static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token, | 494 | static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token, |
495 | char *name, int lineno, int fld, int dcd_len) | 495 | char *name, int lineno, int fld, int dcd_len) |
496 | { | 496 | { |
497 | int value; | 497 | int value; |
498 | static int cmd_ver_first = ~0; | 498 | static int cmd_ver_first = ~0; |
499 | 499 | ||
500 | switch (cmd) { | 500 | switch (cmd) { |
501 | case CMD_IMAGE_VERSION: | 501 | case CMD_IMAGE_VERSION: |
502 | imximage_version = get_cfg_value(token, name, lineno); | 502 | imximage_version = get_cfg_value(token, name, lineno); |
503 | if (cmd_ver_first == 0) { | 503 | if (cmd_ver_first == 0) { |
504 | fprintf(stderr, "Error: %s[%d] - IMAGE_VERSION " | 504 | fprintf(stderr, "Error: %s[%d] - IMAGE_VERSION " |
505 | "command need be the first before other " | 505 | "command need be the first before other " |
506 | "valid command in the file\n", name, lineno); | 506 | "valid command in the file\n", name, lineno); |
507 | exit(EXIT_FAILURE); | 507 | exit(EXIT_FAILURE); |
508 | } | 508 | } |
509 | cmd_ver_first = 1; | 509 | cmd_ver_first = 1; |
510 | set_hdr_func(); | 510 | set_hdr_func(); |
511 | break; | 511 | break; |
512 | case CMD_BOOT_FROM: | 512 | case CMD_BOOT_FROM: |
513 | imximage_ivt_offset = get_table_entry_id(imximage_boot_offset, | 513 | imximage_ivt_offset = get_table_entry_id(imximage_boot_offset, |
514 | "imximage boot option", token); | 514 | "imximage boot option", token); |
515 | if (imximage_ivt_offset == -1) { | 515 | if (imximage_ivt_offset == -1) { |
516 | fprintf(stderr, "Error: %s[%d] -Invalid boot device" | 516 | fprintf(stderr, "Error: %s[%d] -Invalid boot device" |
517 | "(%s)\n", name, lineno, token); | 517 | "(%s)\n", name, lineno, token); |
518 | exit(EXIT_FAILURE); | 518 | exit(EXIT_FAILURE); |
519 | } | 519 | } |
520 | 520 | ||
521 | imximage_init_loadsize = | 521 | imximage_init_loadsize = |
522 | get_table_entry_id(imximage_boot_loadsize, | 522 | get_table_entry_id(imximage_boot_loadsize, |
523 | "imximage boot option", token); | 523 | "imximage boot option", token); |
524 | 524 | ||
525 | if (imximage_init_loadsize == -1) { | 525 | if (imximage_init_loadsize == -1) { |
526 | fprintf(stderr, | 526 | fprintf(stderr, |
527 | "Error: %s[%d] -Invalid boot device(%s)\n", | 527 | "Error: %s[%d] -Invalid boot device(%s)\n", |
528 | name, lineno, token); | 528 | name, lineno, token); |
529 | exit(EXIT_FAILURE); | 529 | exit(EXIT_FAILURE); |
530 | } | 530 | } |
531 | 531 | ||
532 | /* | 532 | /* |
533 | * The SOC loads from the storage starting at address 0 | 533 | * The SOC loads from the storage starting at address 0 |
534 | * then ensures that the load size contains the offset | 534 | * then ensures that the load size contains the offset |
535 | */ | 535 | */ |
536 | if (imximage_init_loadsize < imximage_ivt_offset) | 536 | if (imximage_init_loadsize < imximage_ivt_offset) |
537 | imximage_init_loadsize = imximage_ivt_offset; | 537 | imximage_init_loadsize = imximage_ivt_offset; |
538 | if (unlikely(cmd_ver_first != 1)) | 538 | if (unlikely(cmd_ver_first != 1)) |
539 | cmd_ver_first = 0; | 539 | cmd_ver_first = 0; |
540 | break; | 540 | break; |
541 | case CMD_BOOT_OFFSET: | 541 | case CMD_BOOT_OFFSET: |
542 | imximage_ivt_offset = get_cfg_value(token, name, lineno); | 542 | imximage_ivt_offset = get_cfg_value(token, name, lineno); |
543 | if (unlikely(cmd_ver_first != 1)) | 543 | if (unlikely(cmd_ver_first != 1)) |
544 | cmd_ver_first = 0; | 544 | cmd_ver_first = 0; |
545 | break; | 545 | break; |
546 | case CMD_DATA: | 546 | case CMD_DATA: |
547 | value = get_cfg_value(token, name, lineno); | 547 | value = get_cfg_value(token, name, lineno); |
548 | (*set_dcd_val)(imxhdr, name, lineno, fld, value, dcd_len); | 548 | (*set_dcd_val)(imxhdr, name, lineno, fld, value, dcd_len); |
549 | if (unlikely(cmd_ver_first != 1)) | 549 | if (unlikely(cmd_ver_first != 1)) |
550 | cmd_ver_first = 0; | 550 | cmd_ver_first = 0; |
551 | break; | 551 | break; |
552 | case CMD_CSF: | 552 | case CMD_CSF: |
553 | if (imximage_version != 2) { | 553 | if (imximage_version != 2) { |
554 | fprintf(stderr, | 554 | fprintf(stderr, |
555 | "Error: %s[%d] - CSF only supported for VERSION 2(%s)\n", | 555 | "Error: %s[%d] - CSF only supported for VERSION 2(%s)\n", |
556 | name, lineno, token); | 556 | name, lineno, token); |
557 | exit(EXIT_FAILURE); | 557 | exit(EXIT_FAILURE); |
558 | } | 558 | } |
559 | imximage_csf_size = get_cfg_value(token, name, lineno); | 559 | imximage_csf_size = get_cfg_value(token, name, lineno); |
560 | if (unlikely(cmd_ver_first != 1)) | 560 | if (unlikely(cmd_ver_first != 1)) |
561 | cmd_ver_first = 0; | 561 | cmd_ver_first = 0; |
562 | break; | 562 | break; |
563 | #ifdef CONFIG_USE_PLUGIN | 563 | #ifdef CONFIG_USE_PLUGIN |
564 | case CMD_PLUGIN: | 564 | case CMD_PLUGIN: |
565 | copy_plugin_code(imxhdr, token); | 565 | copy_plugin_code(imxhdr, token); |
566 | break; | 566 | break; |
567 | #endif | 567 | #endif |
568 | } | 568 | } |
569 | } | 569 | } |
570 | 570 | ||
571 | static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd, | 571 | static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd, |
572 | char *token, char *name, int lineno, int fld, int *dcd_len) | 572 | char *token, char *name, int lineno, int fld, int *dcd_len) |
573 | { | 573 | { |
574 | int value; | 574 | int value; |
575 | 575 | ||
576 | switch (fld) { | 576 | switch (fld) { |
577 | case CFG_COMMAND: | 577 | case CFG_COMMAND: |
578 | *cmd = get_table_entry_id(imximage_cmds, | 578 | *cmd = get_table_entry_id(imximage_cmds, |
579 | "imximage commands", token); | 579 | "imximage commands", token); |
580 | if (*cmd < 0) { | 580 | if (*cmd < 0) { |
581 | fprintf(stderr, "Error: %s[%d] - Invalid command" | 581 | fprintf(stderr, "Error: %s[%d] - Invalid command" |
582 | "(%s)\n", name, lineno, token); | 582 | "(%s)\n", name, lineno, token); |
583 | exit(EXIT_FAILURE); | 583 | exit(EXIT_FAILURE); |
584 | } | 584 | } |
585 | break; | 585 | break; |
586 | case CFG_REG_SIZE: | 586 | case CFG_REG_SIZE: |
587 | parse_cfg_cmd(imxhdr, *cmd, token, name, lineno, fld, *dcd_len); | 587 | parse_cfg_cmd(imxhdr, *cmd, token, name, lineno, fld, *dcd_len); |
588 | break; | 588 | break; |
589 | case CFG_REG_ADDRESS: | 589 | case CFG_REG_ADDRESS: |
590 | case CFG_REG_VALUE: | 590 | case CFG_REG_VALUE: |
591 | switch (*cmd) { | 591 | switch (*cmd) { |
592 | case CMD_DATA: | 592 | case CMD_DATA: |
593 | value = get_cfg_value(token, name, lineno); | 593 | value = get_cfg_value(token, name, lineno); |
594 | (*set_dcd_val)(imxhdr, name, lineno, fld, value, | 594 | (*set_dcd_val)(imxhdr, name, lineno, fld, value, |
595 | *dcd_len); | 595 | *dcd_len); |
596 | 596 | ||
597 | if (fld == CFG_REG_VALUE) { | 597 | if (fld == CFG_REG_VALUE) { |
598 | (*dcd_len)++; | 598 | (*dcd_len)++; |
599 | if (*dcd_len > max_dcd_entries) { | 599 | if (*dcd_len > max_dcd_entries) { |
600 | fprintf(stderr, "Error: %s[%d] -" | 600 | fprintf(stderr, "Error: %s[%d] -" |
601 | "DCD table exceeds maximum\ | 601 | "DCD table exceeds maximum\ |
602 | size(%d)\n", | 602 | size(%d)\n", |
603 | name, lineno, max_dcd_entries); | 603 | name, lineno, max_dcd_entries); |
604 | exit(EXIT_FAILURE); | 604 | exit(EXIT_FAILURE); |
605 | } | 605 | } |
606 | } | 606 | } |
607 | break; | 607 | break; |
608 | #ifdef CONFIG_USE_PLUGIN | 608 | #ifdef CONFIG_USE_PLUGIN |
609 | case CMD_PLUGIN: | 609 | case CMD_PLUGIN: |
610 | value = get_cfg_value(token, name, lineno); | 610 | value = get_cfg_value(token, name, lineno); |
611 | imximage_iram_free_start = value; | 611 | imximage_iram_free_start = value; |
612 | break; | 612 | break; |
613 | #endif | 613 | #endif |
614 | default: | 614 | default: |
615 | return; | 615 | return; |
616 | } | 616 | } |
617 | break; | 617 | break; |
618 | default: | 618 | default: |
619 | break; | 619 | break; |
620 | } | 620 | } |
621 | } | 621 | } |
622 | static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name) | 622 | static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name) |
623 | { | 623 | { |
624 | FILE *fd = NULL; | 624 | FILE *fd = NULL; |
625 | char *line = NULL; | 625 | char *line = NULL; |
626 | char *token, *saveptr1, *saveptr2; | 626 | char *token, *saveptr1, *saveptr2; |
627 | int lineno = 0; | 627 | int lineno = 0; |
628 | int fld; | 628 | int fld; |
629 | size_t len; | 629 | size_t len; |
630 | int dcd_len = 0; | 630 | int dcd_len = 0; |
631 | int32_t cmd; | 631 | int32_t cmd; |
632 | 632 | ||
633 | fd = fopen(name, "r"); | 633 | fd = fopen(name, "r"); |
634 | if (fd == 0) { | 634 | if (fd == 0) { |
635 | fprintf(stderr, "Error: %s - Can't open DCD file\n", name); | 635 | fprintf(stderr, "Error: %s - Can't open DCD file\n", name); |
636 | exit(EXIT_FAILURE); | 636 | exit(EXIT_FAILURE); |
637 | } | 637 | } |
638 | 638 | ||
639 | /* | 639 | /* |
640 | * Very simple parsing, line starting with # are comments | 640 | * Very simple parsing, line starting with # are comments |
641 | * and are dropped | 641 | * and are dropped |
642 | */ | 642 | */ |
643 | while ((getline(&line, &len, fd)) > 0) { | 643 | while ((getline(&line, &len, fd)) > 0) { |
644 | lineno++; | 644 | lineno++; |
645 | 645 | ||
646 | token = strtok_r(line, "\r\n", &saveptr1); | 646 | token = strtok_r(line, "\r\n", &saveptr1); |
647 | if (token == NULL) | 647 | if (token == NULL) |
648 | continue; | 648 | continue; |
649 | 649 | ||
650 | /* Check inside the single line */ | 650 | /* Check inside the single line */ |
651 | for (fld = CFG_COMMAND, cmd = CMD_INVALID, | 651 | for (fld = CFG_COMMAND, cmd = CMD_INVALID, |
652 | line = token; ; line = NULL, fld++) { | 652 | line = token; ; line = NULL, fld++) { |
653 | token = strtok_r(line, " \t", &saveptr2); | 653 | token = strtok_r(line, " \t", &saveptr2); |
654 | if (token == NULL) | 654 | if (token == NULL) |
655 | break; | 655 | break; |
656 | 656 | ||
657 | /* Drop all text starting with '#' as comments */ | 657 | /* Drop all text starting with '#' as comments */ |
658 | if (token[0] == '#') | 658 | if (token[0] == '#') |
659 | break; | 659 | break; |
660 | 660 | ||
661 | parse_cfg_fld(imxhdr, &cmd, token, name, | 661 | parse_cfg_fld(imxhdr, &cmd, token, name, |
662 | lineno, fld, &dcd_len); | 662 | lineno, fld, &dcd_len); |
663 | } | 663 | } |
664 | 664 | ||
665 | } | 665 | } |
666 | 666 | ||
667 | (*set_dcd_rst)(imxhdr, dcd_len, name, lineno); | 667 | (*set_dcd_rst)(imxhdr, dcd_len, name, lineno); |
668 | fclose(fd); | 668 | fclose(fd); |
669 | 669 | ||
670 | /* Exit if there is no BOOT_FROM field specifying the flash_offset */ | 670 | /* Exit if there is no BOOT_FROM field specifying the flash_offset */ |
671 | if (imximage_ivt_offset == FLASH_OFFSET_UNDEFINED) { | 671 | if (imximage_ivt_offset == FLASH_OFFSET_UNDEFINED) { |
672 | fprintf(stderr, "Error: No BOOT_FROM tag in %s\n", name); | 672 | fprintf(stderr, "Error: No BOOT_FROM tag in %s\n", name); |
673 | exit(EXIT_FAILURE); | 673 | exit(EXIT_FAILURE); |
674 | } | 674 | } |
675 | return dcd_len; | 675 | return dcd_len; |
676 | } | 676 | } |
677 | 677 | ||
678 | 678 | ||
679 | static int imximage_check_image_types(uint8_t type) | 679 | static int imximage_check_image_types(uint8_t type) |
680 | { | 680 | { |
681 | if (type == IH_TYPE_IMXIMAGE) | 681 | if (type == IH_TYPE_IMXIMAGE) |
682 | return EXIT_SUCCESS; | 682 | return EXIT_SUCCESS; |
683 | else | 683 | else |
684 | return EXIT_FAILURE; | 684 | return EXIT_FAILURE; |
685 | } | 685 | } |
686 | 686 | ||
687 | static int imximage_verify_header(unsigned char *ptr, int image_size, | 687 | static int imximage_verify_header(unsigned char *ptr, int image_size, |
688 | struct image_tool_params *params) | 688 | struct image_tool_params *params) |
689 | { | 689 | { |
690 | struct imx_header *imx_hdr = (struct imx_header *) ptr; | 690 | struct imx_header *imx_hdr = (struct imx_header *) ptr; |
691 | 691 | ||
692 | if (detect_imximage_version(imx_hdr) == IMXIMAGE_VER_INVALID) | 692 | if (detect_imximage_version(imx_hdr) == IMXIMAGE_VER_INVALID) |
693 | return -FDT_ERR_BADSTRUCTURE; | 693 | return -FDT_ERR_BADSTRUCTURE; |
694 | 694 | ||
695 | return 0; | 695 | return 0; |
696 | } | 696 | } |
697 | 697 | ||
698 | static void imximage_print_header(const void *ptr) | 698 | static void imximage_print_header(const void *ptr) |
699 | { | 699 | { |
700 | struct imx_header *imx_hdr = (struct imx_header *) ptr; | 700 | struct imx_header *imx_hdr = (struct imx_header *) ptr; |
701 | uint32_t version = detect_imximage_version(imx_hdr); | 701 | uint32_t version = detect_imximage_version(imx_hdr); |
702 | 702 | ||
703 | switch (version) { | 703 | switch (version) { |
704 | case IMXIMAGE_V1: | 704 | case IMXIMAGE_V1: |
705 | print_hdr_v1(imx_hdr); | 705 | print_hdr_v1(imx_hdr); |
706 | break; | 706 | break; |
707 | case IMXIMAGE_V2: | 707 | case IMXIMAGE_V2: |
708 | print_hdr_v2(imx_hdr); | 708 | print_hdr_v2(imx_hdr); |
709 | break; | 709 | break; |
710 | default: | 710 | default: |
711 | err_imximage_version(version); | 711 | err_imximage_version(version); |
712 | break; | 712 | break; |
713 | } | 713 | } |
714 | } | 714 | } |
715 | 715 | ||
716 | static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd, | 716 | static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd, |
717 | struct image_tool_params *params) | 717 | struct image_tool_params *params) |
718 | { | 718 | { |
719 | struct imx_header *imxhdr = (struct imx_header *)ptr; | 719 | struct imx_header *imxhdr = (struct imx_header *)ptr; |
720 | uint32_t dcd_len; | 720 | uint32_t dcd_len; |
721 | 721 | ||
722 | /* | 722 | /* |
723 | * In order to not change the old imx cfg file | 723 | * In order to not change the old imx cfg file |
724 | * by adding VERSION command into it, here need | 724 | * by adding VERSION command into it, here need |
725 | * set up function ptr group to V1 by default. | 725 | * set up function ptr group to V1 by default. |
726 | */ | 726 | */ |
727 | imximage_version = IMXIMAGE_V1; | 727 | imximage_version = IMXIMAGE_V1; |
728 | /* Be able to detect if the cfg file has no BOOT_FROM tag */ | 728 | /* Be able to detect if the cfg file has no BOOT_FROM tag */ |
729 | imximage_ivt_offset = FLASH_OFFSET_UNDEFINED; | 729 | imximage_ivt_offset = FLASH_OFFSET_UNDEFINED; |
730 | imximage_csf_size = 0; | 730 | imximage_csf_size = 0; |
731 | set_hdr_func(); | 731 | set_hdr_func(); |
732 | 732 | ||
733 | /* Parse dcd configuration file */ | 733 | /* Parse dcd configuration file */ |
734 | dcd_len = parse_cfg_file(imxhdr, params->imagename); | 734 | dcd_len = parse_cfg_file(imxhdr, params->imagename); |
735 | 735 | ||
736 | if (imximage_version == IMXIMAGE_V2) { | 736 | if (imximage_version == IMXIMAGE_V2) { |
737 | if (imximage_init_loadsize < imximage_ivt_offset + | 737 | if (imximage_init_loadsize < imximage_ivt_offset + |
738 | sizeof(imx_header_v2_t)) | 738 | sizeof(imx_header_v2_t)) |
739 | imximage_init_loadsize = imximage_ivt_offset + | 739 | imximage_init_loadsize = imximage_ivt_offset + |
740 | sizeof(imx_header_v2_t); | 740 | sizeof(imx_header_v2_t); |
741 | } | 741 | } |
742 | 742 | ||
743 | /* Set the imx header */ | 743 | /* Set the imx header */ |
744 | (*set_imx_hdr)(imxhdr, dcd_len, params->ep, imximage_ivt_offset); | 744 | (*set_imx_hdr)(imxhdr, dcd_len, params->ep, imximage_ivt_offset); |
745 | 745 | ||
746 | /* | 746 | /* |
747 | * ROM bug alert | 747 | * ROM bug alert |
748 | * | 748 | * |
749 | * MX53 only loads 512 byte multiples in case of SD boot. | 749 | * MX53 only loads 512 byte multiples in case of SD boot. |
750 | * MX53 only loads NAND page multiples in case of NAND boot and | 750 | * MX53 only loads NAND page multiples in case of NAND boot and |
751 | * supports up to 4096 byte large pages, thus align to 4096. | 751 | * supports up to 4096 byte large pages, thus align to 4096. |
752 | * | 752 | * |
753 | * The remaining fraction of a block bytes would not be loaded! | 753 | * The remaining fraction of a block bytes would not be loaded! |
754 | */ | 754 | */ |
755 | *header_size_ptr = ROUND(sbuf->st_size, 4096); | 755 | *header_size_ptr = ROUND((sbuf->st_size + imximage_ivt_offset), 4096); |
756 | 756 | ||
757 | if (csf_ptr && imximage_csf_size) { | 757 | if (csf_ptr && imximage_csf_size) { |
758 | *csf_ptr = params->ep - imximage_init_loadsize + | 758 | *csf_ptr = params->ep - imximage_init_loadsize + |
759 | *header_size_ptr; | 759 | *header_size_ptr; |
760 | *header_size_ptr += imximage_csf_size; | 760 | *header_size_ptr += imximage_csf_size; |
761 | } | 761 | } |
762 | } | 762 | } |
763 | 763 | ||
764 | int imximage_check_params(struct image_tool_params *params) | 764 | int imximage_check_params(struct image_tool_params *params) |
765 | { | 765 | { |
766 | if (!params) | 766 | if (!params) |
767 | return CFG_INVALID; | 767 | return CFG_INVALID; |
768 | if (!strlen(params->imagename)) { | 768 | if (!strlen(params->imagename)) { |
769 | fprintf(stderr, "Error: %s - Configuration file not specified, " | 769 | fprintf(stderr, "Error: %s - Configuration file not specified, " |
770 | "it is needed for imximage generation\n", | 770 | "it is needed for imximage generation\n", |
771 | params->cmdname); | 771 | params->cmdname); |
772 | return CFG_INVALID; | 772 | return CFG_INVALID; |
773 | } | 773 | } |
774 | /* | 774 | /* |
775 | * Check parameters: | 775 | * Check parameters: |
776 | * XIP is not allowed and verify that incompatible | 776 | * XIP is not allowed and verify that incompatible |
777 | * parameters are not sent at the same time | 777 | * parameters are not sent at the same time |
778 | * For example, if list is required a data image must not be provided | 778 | * For example, if list is required a data image must not be provided |
779 | */ | 779 | */ |
780 | return (params->dflag && (params->fflag || params->lflag)) || | 780 | return (params->dflag && (params->fflag || params->lflag)) || |
781 | (params->fflag && (params->dflag || params->lflag)) || | 781 | (params->fflag && (params->dflag || params->lflag)) || |
782 | (params->lflag && (params->dflag || params->fflag)) || | 782 | (params->lflag && (params->dflag || params->fflag)) || |
783 | (params->xflag) || !(strlen(params->imagename)); | 783 | (params->xflag) || !(strlen(params->imagename)); |
784 | } | 784 | } |
785 | 785 | ||
786 | static int imximage_generate(struct image_tool_params *params, | 786 | static int imximage_generate(struct image_tool_params *params, |
787 | struct image_type_params *tparams) | 787 | struct image_type_params *tparams) |
788 | { | 788 | { |
789 | struct imx_header *imxhdr; | 789 | struct imx_header *imxhdr; |
790 | size_t alloc_len; | 790 | size_t alloc_len; |
791 | struct stat sbuf; | 791 | struct stat sbuf; |
792 | char *datafile = params->datafile; | 792 | char *datafile = params->datafile; |
793 | uint32_t pad_len; | 793 | uint32_t pad_len; |
794 | 794 | ||
795 | memset(&imximage_header, 0, sizeof(imximage_header)); | 795 | memset(&imximage_header, 0, sizeof(imximage_header)); |
796 | 796 | ||
797 | /* | 797 | /* |
798 | * In order to not change the old imx cfg file | 798 | * In order to not change the old imx cfg file |
799 | * by adding VERSION command into it, here need | 799 | * by adding VERSION command into it, here need |
800 | * set up function ptr group to V1 by default. | 800 | * set up function ptr group to V1 by default. |
801 | */ | 801 | */ |
802 | imximage_version = IMXIMAGE_V1; | 802 | imximage_version = IMXIMAGE_V1; |
803 | /* Be able to detect if the cfg file has no BOOT_FROM tag */ | 803 | /* Be able to detect if the cfg file has no BOOT_FROM tag */ |
804 | imximage_ivt_offset = FLASH_OFFSET_UNDEFINED; | 804 | imximage_ivt_offset = FLASH_OFFSET_UNDEFINED; |
805 | imximage_csf_size = 0; | 805 | imximage_csf_size = 0; |
806 | set_hdr_func(); | 806 | set_hdr_func(); |
807 | 807 | ||
808 | /* Parse dcd configuration file */ | 808 | /* Parse dcd configuration file */ |
809 | parse_cfg_file(&imximage_header, params->imagename); | 809 | parse_cfg_file(&imximage_header, params->imagename); |
810 | 810 | ||
811 | /* TODO: check i.MX image V1 handling, for now use 'old' style */ | 811 | /* TODO: check i.MX image V1 handling, for now use 'old' style */ |
812 | if (imximage_version == IMXIMAGE_V1) { | 812 | if (imximage_version == IMXIMAGE_V1) { |
813 | alloc_len = 4096; | 813 | alloc_len = 4096; |
814 | } else { | 814 | } else { |
815 | if (imximage_init_loadsize < imximage_ivt_offset + | 815 | if (imximage_init_loadsize < imximage_ivt_offset + |
816 | sizeof(imx_header_v2_t)) | 816 | sizeof(imx_header_v2_t)) |
817 | imximage_init_loadsize = imximage_ivt_offset + | 817 | imximage_init_loadsize = imximage_ivt_offset + |
818 | sizeof(imx_header_v2_t); | 818 | sizeof(imx_header_v2_t); |
819 | alloc_len = imximage_init_loadsize - imximage_ivt_offset; | 819 | alloc_len = imximage_init_loadsize - imximage_ivt_offset; |
820 | } | 820 | } |
821 | 821 | ||
822 | if (alloc_len < sizeof(struct imx_header)) { | 822 | if (alloc_len < sizeof(struct imx_header)) { |
823 | fprintf(stderr, "%s: header error\n", | 823 | fprintf(stderr, "%s: header error\n", |
824 | params->cmdname); | 824 | params->cmdname); |
825 | exit(EXIT_FAILURE); | 825 | exit(EXIT_FAILURE); |
826 | } | 826 | } |
827 | 827 | ||
828 | imxhdr = malloc(alloc_len); | 828 | imxhdr = malloc(alloc_len); |
829 | 829 | ||
830 | if (!imxhdr) { | 830 | if (!imxhdr) { |
831 | fprintf(stderr, "%s: malloc return failure: %s\n", | 831 | fprintf(stderr, "%s: malloc return failure: %s\n", |
832 | params->cmdname, strerror(errno)); | 832 | params->cmdname, strerror(errno)); |
833 | exit(EXIT_FAILURE); | 833 | exit(EXIT_FAILURE); |
834 | } | 834 | } |
835 | 835 | ||
836 | memset(imxhdr, 0, alloc_len); | 836 | memset(imxhdr, 0, alloc_len); |
837 | 837 | ||
838 | tparams->header_size = alloc_len; | 838 | tparams->header_size = alloc_len; |
839 | tparams->hdr = imxhdr; | 839 | tparams->hdr = imxhdr; |
840 | 840 | ||
841 | /* determine data image file length */ | 841 | /* determine data image file length */ |
842 | 842 | ||
843 | if (stat(datafile, &sbuf) < 0) { | 843 | if (stat(datafile, &sbuf) < 0) { |
844 | fprintf(stderr, "%s: Can't stat %s: %s\n", | 844 | fprintf(stderr, "%s: Can't stat %s: %s\n", |
845 | params->cmdname, datafile, strerror(errno)); | 845 | params->cmdname, datafile, strerror(errno)); |
846 | exit(EXIT_FAILURE); | 846 | exit(EXIT_FAILURE); |
847 | } | 847 | } |
848 | 848 | ||
849 | pad_len = ROUND(sbuf.st_size, 4096) - sbuf.st_size; | 849 | pad_len = ROUND(sbuf.st_size, 4096) - sbuf.st_size; |
850 | 850 | ||
851 | /* TODO: check i.MX image V1 handling, for now use 'old' style */ | 851 | /* TODO: check i.MX image V1 handling, for now use 'old' style */ |
852 | if (imximage_version == IMXIMAGE_V1) | 852 | if (imximage_version == IMXIMAGE_V1) |
853 | return 0; | 853 | return 0; |
854 | else | 854 | else |
855 | return pad_len; | 855 | return pad_len; |
856 | } | 856 | } |
857 | 857 | ||
858 | 858 | ||
859 | /* | 859 | /* |
860 | * imximage parameters | 860 | * imximage parameters |
861 | */ | 861 | */ |
862 | static struct image_type_params imximage_params = { | 862 | static struct image_type_params imximage_params = { |
863 | .name = "Freescale i.MX Boot Image support", | 863 | .name = "Freescale i.MX Boot Image support", |
864 | .header_size = 0, | 864 | .header_size = 0, |
865 | .hdr = NULL, | 865 | .hdr = NULL, |
866 | .check_image_type = imximage_check_image_types, | 866 | .check_image_type = imximage_check_image_types, |
867 | .verify_header = imximage_verify_header, | 867 | .verify_header = imximage_verify_header, |
868 | .print_header = imximage_print_header, | 868 | .print_header = imximage_print_header, |
869 | .set_header = imximage_set_header, | 869 | .set_header = imximage_set_header, |
870 | .check_params = imximage_check_params, | 870 | .check_params = imximage_check_params, |
871 | .vrec_header = imximage_generate, | 871 | .vrec_header = imximage_generate, |
872 | }; | 872 | }; |
873 | 873 | ||
874 | void init_imx_image_type(void) | 874 | void init_imx_image_type(void) |
875 | { | 875 | { |
876 | register_image_type(&imximage_params); | 876 | register_image_type(&imximage_params); |
877 | } | 877 | } |
878 | 878 |