diff options
Diffstat (limited to 'rbutil/mkamsboot/mkamsboot.c')
-rw-r--r-- | rbutil/mkamsboot/mkamsboot.c | 429 |
1 files changed, 283 insertions, 146 deletions
diff --git a/rbutil/mkamsboot/mkamsboot.c b/rbutil/mkamsboot/mkamsboot.c index 52ead58b69..e617b1204a 100644 --- a/rbutil/mkamsboot/mkamsboot.c +++ b/rbutil/mkamsboot/mkamsboot.c | |||
@@ -30,36 +30,46 @@ We replace the main firmware block (bytes 0x400..0x400+firmware_size) | |||
30 | as follows: | 30 | as follows: |
31 | 31 | ||
32 | 32 | ||
33 | --------------------- 0x0 | 33 | ---------------------- 0x0 |
34 | | | | 34 | | | |
35 | | Rockbox bootloader | | 35 | | Dual-boot code | |
36 | | | | 36 | | | |
37 | |---------------------| | 37 | |----------------------| |
38 | | EMPTY SPACE | | 38 | | EMPTY SPACE | |
39 | |---------------------| | 39 | |----------------------| |
40 | | ucl unpack function | | 40 | | | |
41 | |---------------------| | 41 | | compressed RB image | |
42 | | | | 42 | | | |
43 | | compressed OF image | | 43 | |----------------------| |
44 | | | | 44 | | | |
45 | | | | 45 | | compressed OF image | |
46 | --------------------- | 46 | | | |
47 | |----------------------| | ||
48 | | UCL unpack function | | ||
49 | ---------------------- | ||
47 | 50 | ||
48 | This entire block fits into the space previously occupied by the main | 51 | This entire block fits into the space previously occupied by the main |
49 | firmware block, and gives about 40KB of space to store the Rockbox | 52 | firmware block - the space saved by compressing the OF image is used |
50 | bootloader. This could be increased if we also UCL compress the | 53 | to store the compressed version of the Rockbox bootloader. The OF |
51 | Rockbox bootloader. | 54 | image is typically about 120KB, which allows us to store a Rockbox |
55 | bootloader with an uncompressed size of about 60KB-70KB. | ||
52 | 56 | ||
53 | mkamsboot then corrects the checksums and writes a new legal firmware | 57 | mkamsboot then corrects the checksums and writes a new legal firmware |
54 | file which can be installed on the device. | 58 | file which can be installed on the device. |
55 | 59 | ||
56 | Our bootloader first checks for the "dual-boot" keypress, and then either: | 60 | When the Sansa device boots, this firmware block is loaded to RAM at |
61 | address 0x0 and executed. | ||
57 | 62 | ||
58 | a) Copies the ucl unpack function and compressed OF image to an unused | 63 | Firstly, the dual-boot code will copy the UCL unpack function to the |
59 | part of RAM and then branches to the ucl_unpack function, which | 64 | end of RAM. |
60 | will then branch to 0x0 after decompressing the OF to that location. | 65 | |
66 | Then, depending on the detection of the dual-boot keypress, either the | ||
67 | OF image or the Rockbox image is copied to the end of RAM (just before | ||
68 | the ucl unpack function) and uncompress it to the start of RAM. | ||
69 | |||
70 | Finally, the ucl unpack function branches to address 0x0, passing | ||
71 | execution to the uncompressed firmware. | ||
61 | 72 | ||
62 | b) Continues running with our test code | ||
63 | 73 | ||
64 | */ | 74 | */ |
65 | 75 | ||
@@ -73,14 +83,62 @@ b) Continues running with our test code | |||
73 | #include <unistd.h> | 83 | #include <unistd.h> |
74 | #include <string.h> | 84 | #include <string.h> |
75 | 85 | ||
86 | #include <ucl/ucl.h> | ||
87 | |||
88 | /* Headers for ARM code binaries */ | ||
89 | #include "uclimg.h" | ||
90 | #include "bootimg_clip.h" | ||
91 | #include "bootimg_e200v2.h" | ||
76 | 92 | ||
77 | /* Win32 compatibility */ | 93 | /* Win32 compatibility */ |
78 | #ifndef O_BINARY | 94 | #ifndef O_BINARY |
79 | #define O_BINARY 0 | 95 | #define O_BINARY 0 |
80 | #endif | 96 | #endif |
81 | 97 | ||
98 | #ifndef VERSION | ||
99 | #define VERSION "0.1" | ||
100 | #endif | ||
82 | 101 | ||
83 | #define PAD_TO_BOUNDARY(x) (((x) + 0x1ff) & ~0x1ff) | 102 | enum |
103 | { | ||
104 | MODEL_UNKNOWN = -1, | ||
105 | MODEL_FUZE = 0, | ||
106 | MODEL_CLIP, | ||
107 | MODEL_CLIPV2, | ||
108 | MODEL_E200, | ||
109 | MODEL_M200, | ||
110 | MODEL_C200 | ||
111 | }; | ||
112 | |||
113 | static const char* model_names[] = | ||
114 | { | ||
115 | "Fuze", | ||
116 | "Clip", | ||
117 | "Clip V2", | ||
118 | "E200", | ||
119 | "M200", | ||
120 | "C200" | ||
121 | }; | ||
122 | |||
123 | static const unsigned char* bootloaders[] = | ||
124 | { | ||
125 | NULL, | ||
126 | bootimg_clip, | ||
127 | NULL, | ||
128 | bootimg_e200v2, | ||
129 | NULL, | ||
130 | NULL | ||
131 | }; | ||
132 | |||
133 | static const int bootloader_sizes[] = | ||
134 | { | ||
135 | 0, | ||
136 | sizeof(bootimg_clip), | ||
137 | 0, | ||
138 | sizeof(bootimg_e200v2), | ||
139 | 0, | ||
140 | 0 | ||
141 | }; | ||
84 | 142 | ||
85 | 143 | ||
86 | /* This magic should appear at the start of any UCL file */ | 144 | /* This magic should appear at the start of any UCL file */ |
@@ -105,12 +163,6 @@ static uint32_t get_uint32le(unsigned char* p) | |||
105 | return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); | 163 | return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); |
106 | } | 164 | } |
107 | 165 | ||
108 | static uint32_t get_uint32be(unsigned char* p) | ||
109 | { | ||
110 | return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; | ||
111 | |||
112 | } | ||
113 | |||
114 | static void put_uint32le(unsigned char* p, uint32_t x) | 166 | static void put_uint32le(unsigned char* p, uint32_t x) |
115 | { | 167 | { |
116 | p[0] = x & 0xff; | 168 | p[0] = x & 0xff; |
@@ -130,186 +182,271 @@ static int calc_checksum(unsigned char* buf, uint32_t n) | |||
130 | return sum; | 182 | return sum; |
131 | } | 183 | } |
132 | 184 | ||
133 | void usage(void) | 185 | static int get_model(int model_id) |
134 | { | 186 | { |
135 | printf("Usage: mkamsboot <firmware file> <ucl image> <boot file> <ucl unpack file> <output file>\n"); | 187 | switch(model_id) |
188 | { | ||
189 | case 0x1e: | ||
190 | return MODEL_FUZE; | ||
191 | case 0x22: | ||
192 | return MODEL_CLIP; | ||
193 | case 0x23: | ||
194 | return MODEL_C200; | ||
195 | case 0x24: | ||
196 | return MODEL_E200; | ||
197 | case 0x25: | ||
198 | return MODEL_M200; | ||
199 | case 0x27: | ||
200 | return MODEL_CLIPV2; | ||
201 | } | ||
136 | 202 | ||
137 | exit(1); | 203 | return MODEL_UNKNOWN; |
138 | } | 204 | } |
139 | 205 | ||
140 | int main(int argc, char* argv[]) | 206 | |
207 | static unsigned char* uclpack(unsigned char* inbuf, int insize, int* outsize) | ||
141 | { | 208 | { |
142 | char *infile, *uclfile, *bootfile, *uclunpackfile, *outfile; | 209 | int maxsize; |
143 | int fdin, fducl, fdboot, fduclunpack, fdout; | 210 | unsigned char* outbuf; |
144 | off_t len; | 211 | int r; |
145 | unsigned char uclheader[26]; | ||
146 | uint32_t n; | ||
147 | unsigned char* buf; | ||
148 | uint32_t firmware_size; | ||
149 | uint32_t firmware_paddedsize; | ||
150 | uint32_t bootloader_size; | ||
151 | uint32_t ucl_size; | ||
152 | uint32_t ucl_paddedsize; | ||
153 | uint32_t uclunpack_size; | ||
154 | uint32_t sum,filesum; | ||
155 | uint32_t i; | ||
156 | 212 | ||
157 | if(argc != 6) { | 213 | /* The following formula comes from the UCL documentation */ |
158 | usage(); | 214 | maxsize = insize + (insize / 8) + 256; |
159 | } | ||
160 | 215 | ||
161 | infile = argv[1]; | 216 | /* Allocate some memory for the output buffer */ |
162 | uclfile = argv[2]; | 217 | outbuf = malloc(maxsize); |
163 | bootfile = argv[3]; | 218 | |
164 | uclunpackfile = argv[4]; | 219 | if (outbuf == NULL) { |
165 | outfile = argv[5]; | 220 | return NULL; |
166 | 221 | } | |
167 | /* Open the bootloader file */ | 222 | |
168 | fdboot = open(bootfile, O_RDONLY|O_BINARY); | 223 | r = ucl_nrv2e_99_compress( |
169 | if (fdboot < 0) | 224 | (const ucl_bytep) inbuf, |
225 | (ucl_uint) insize, | ||
226 | (ucl_bytep) outbuf, | ||
227 | (ucl_uintp) outsize, | ||
228 | 0, 10, NULL, NULL); | ||
229 | |||
230 | if (r != UCL_E_OK || *outsize > maxsize) | ||
170 | { | 231 | { |
171 | fprintf(stderr,"[ERR] Could not open %s for reading\n",bootfile); | 232 | /* this should NEVER happen, and implies memory corruption */ |
172 | return 1; | 233 | fprintf(stderr, "internal error - compression failed: %d\n", r); |
234 | free(outbuf); | ||
235 | return NULL; | ||
173 | } | 236 | } |
174 | 237 | ||
175 | bootloader_size = filesize(fdboot); | 238 | return outbuf; |
239 | } | ||
176 | 240 | ||
241 | static unsigned char* load_file(char* filename, off_t* bufsize) | ||
242 | { | ||
243 | int fd; | ||
244 | unsigned char* buf; | ||
245 | off_t n; | ||
177 | 246 | ||
178 | /* Open the UCL-compressed image of the firmware block */ | 247 | fd = open(filename, O_RDONLY|O_BINARY); |
179 | fduclunpack = open(uclunpackfile, O_RDONLY|O_BINARY); | 248 | if (fd < 0) |
180 | if (fduclunpack < 0) | ||
181 | { | 249 | { |
182 | fprintf(stderr,"[ERR] Could not open %s for reading\n",uclunpackfile); | 250 | fprintf(stderr,"[ERR] Could not open %s for reading\n",filename); |
183 | return 1; | 251 | return NULL; |
184 | } | 252 | } |
185 | 253 | ||
186 | uclunpack_size = filesize(fduclunpack); | 254 | *bufsize = filesize(fd); |
187 | 255 | ||
188 | 256 | buf = malloc(*bufsize); | |
189 | /* Open the UCL-compressed image of the firmware block */ | 257 | if (buf == NULL) { |
190 | fducl = open(uclfile, O_RDONLY|O_BINARY); | 258 | fprintf(stderr,"[ERR] Could not allocate memory for %s\n",filename); |
191 | if (fducl < 0) | 259 | return NULL; |
192 | { | ||
193 | fprintf(stderr,"[ERR] Could not open %s for reading\n",uclfile); | ||
194 | return 1; | ||
195 | } | 260 | } |
196 | 261 | ||
197 | /* Some UCL file sanity checks */ | 262 | n = read(fd, buf, *bufsize); |
198 | n = read(fducl, uclheader, sizeof(uclheader)); | ||
199 | 263 | ||
200 | if (n != sizeof(uclheader)) { | 264 | if (n != *bufsize) { |
201 | fprintf(stderr,"[ERR] Could not read header from UCL file\n"); | 265 | fprintf(stderr,"[ERR] Could not read file %s\n",filename); |
202 | return 1; | 266 | return NULL; |
203 | } | 267 | } |
204 | 268 | ||
205 | if (memcmp(uclmagic, uclheader, sizeof(uclmagic))!=0) { | 269 | return buf; |
206 | fprintf(stderr,"[ERR] Invalid UCL file\n"); | 270 | } |
271 | |||
272 | |||
273 | int main(int argc, char* argv[]) | ||
274 | { | ||
275 | char *infile, *bootfile, *outfile; | ||
276 | int fdout; | ||
277 | off_t len; | ||
278 | uint32_t n; | ||
279 | unsigned char* buf; | ||
280 | int firmware_size; | ||
281 | off_t bootloader_size; | ||
282 | uint32_t ucl_size; | ||
283 | uint32_t ucl_paddedsize; | ||
284 | uint32_t sum,filesum; | ||
285 | uint8_t model_id; | ||
286 | int model; | ||
287 | uint32_t i; | ||
288 | unsigned char* of_packed; | ||
289 | int of_packedsize; | ||
290 | unsigned char* rb_unpacked; | ||
291 | unsigned char* rb_packed; | ||
292 | int rb_packedsize; | ||
293 | int fw_version; | ||
294 | int totalsize; | ||
295 | unsigned char* p; | ||
296 | |||
297 | fprintf(stderr,"mkamsboot v" VERSION " - (C) Dave Chapman 2008\n"); | ||
298 | fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n"); | ||
299 | fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); | ||
300 | |||
301 | if(argc != 4) { | ||
302 | printf("Usage: mkamsboot <firmware file> <boot file> <output file>\n\n"); | ||
207 | return 1; | 303 | return 1; |
208 | } | 304 | } |
209 | 305 | ||
210 | if (uclheader[12] != 0x2e) { | 306 | infile = argv[1]; |
211 | fprintf(stderr,"[ERR] Unsupported UCL compression format (0x%02x) - only 0x2e supported.\n",uclheader[12]); | 307 | bootfile = argv[2]; |
308 | outfile = argv[3]; | ||
309 | |||
310 | /* Load bootloader file */ | ||
311 | rb_unpacked = load_file(bootfile, &bootloader_size); | ||
312 | if (rb_unpacked == NULL) { | ||
313 | fprintf(stderr,"[ERR] Could not load %s\n",bootfile); | ||
212 | return 1; | 314 | return 1; |
213 | } | 315 | } |
214 | ucl_size = get_uint32be(&uclheader[22]) + 8; | ||
215 | ucl_paddedsize = (ucl_size + 3) & ~0x3; | ||
216 | 316 | ||
217 | if (ucl_size + 26 > (unsigned)filesize(fducl)) { | 317 | /* Load original firmware file */ |
218 | fprintf(stderr, "[ERR] Size mismatch in UCL file\n"); | 318 | buf = load_file(infile, &len); |
319 | |||
320 | if (buf == NULL) { | ||
321 | fprintf(stderr,"[ERR] Could not load bootloader file\n"); | ||
219 | return 1; | 322 | return 1; |
220 | } | 323 | } |
221 | 324 | ||
222 | /* Open the firmware file */ | 325 | /* TODO: Do some more sanity checks on the OF image - e.g. checksum */ |
223 | fdin = open(infile,O_RDONLY|O_BINARY); | ||
224 | 326 | ||
225 | if (fdin < 0) { | 327 | if (get_uint32le(&buf[0x204])==0x0000f000) { |
226 | fprintf(stderr,"[ERR] Could not open %s for reading\n",infile); | 328 | fw_version = 2; |
227 | return 1; | 329 | model_id = buf[0x219]; |
330 | } else { | ||
331 | fw_version = 1; | ||
332 | model_id = buf[0x215]; | ||
228 | } | 333 | } |
229 | 334 | ||
230 | if ((len = filesize(fdin)) < 0) | 335 | model = get_model(model_id); |
231 | return 1; | ||
232 | 336 | ||
233 | /* Allocate memory for the OF image - we don't change the size */ | 337 | if (model == MODEL_UNKNOWN) { |
234 | if ((buf = malloc(len)) == NULL) { | 338 | fprintf(stderr,"[ERR] Unknown firmware - model id 0x%02x\n",model_id); |
235 | fprintf(stderr,"[ERR] Could not allocate buffer for input file (%d bytes)\n",(int)len); | ||
236 | return 1; | 339 | return 1; |
237 | } | 340 | } |
238 | 341 | ||
239 | n = read(fdin, buf, len); | 342 | if (bootloaders[model] == NULL) { |
240 | 343 | fprintf(stderr,"[ERR] Unsupported model - \"%s\"\n",model_names[model]); | |
241 | if (n != (uint32_t)len) { | 344 | free(buf); |
242 | fprintf(stderr,"[ERR] Could not read firmware file\n"); | 345 | free(rb_unpacked); |
243 | return 1; | 346 | return 1; |
244 | } | 347 | } |
245 | 348 | ||
246 | close(fdin); | 349 | printf("[INFO] Patching %s firmware\n",model_names[model]); |
247 | 350 | ||
248 | /* Get the firmware size */ | 351 | /* Get the firmware size */ |
249 | firmware_size = get_uint32le(&buf[0x0c]); | 352 | firmware_size = get_uint32le(&buf[0x0c]); |
250 | 353 | ||
251 | /* Round size up to next multiple of 0x200 */ | 354 | /* Compress the original firmware image */ |
355 | of_packed = uclpack(buf + 0x400, firmware_size, &of_packedsize); | ||
356 | if (of_packed == NULL) { | ||
357 | fprintf(stderr,"[ERR] Could not compress original firmware\n"); | ||
358 | free(buf); | ||
359 | free(rb_unpacked); | ||
360 | return 1; | ||
361 | } | ||
362 | |||
363 | rb_packed = uclpack(rb_unpacked, bootloader_size, &rb_packedsize); | ||
364 | if (rb_packed == NULL) { | ||
365 | fprintf(stderr,"[ERR] Could not compress %s\n",bootfile); | ||
366 | free(buf); | ||
367 | free(rb_unpacked); | ||
368 | free(of_packed); | ||
369 | return 1; | ||
370 | } | ||
252 | 371 | ||
253 | firmware_paddedsize = PAD_TO_BOUNDARY(firmware_size); | 372 | /* We are finished with the unpacked version of the bootloader */ |
373 | free(rb_unpacked); | ||
254 | 374 | ||
255 | fprintf(stderr,"Original firmware size - %d bytes\n",firmware_size); | 375 | fprintf(stderr,"[INFO] Original firmware size: %d bytes\n",firmware_size); |
256 | fprintf(stderr,"Padded firmware size - %d bytes\n",firmware_paddedsize); | 376 | fprintf(stderr,"[INFO] Packed OF size: %d bytes\n",of_packedsize); |
257 | fprintf(stderr,"Bootloader size - %d bytes\n",bootloader_size); | 377 | fprintf(stderr,"[INFO] Bootloader size: %d bytes\n",(int)bootloader_size); |
258 | fprintf(stderr,"UCL image size - %d bytes (%d bytes padded)\n",ucl_size,ucl_paddedsize); | 378 | fprintf(stderr,"[INFO] Packed bootloader size: %d bytes\n",rb_packedsize); |
259 | fprintf(stderr,"UCL unpack function size - %d bytes\n",uclunpack_size); | 379 | fprintf(stderr,"[INFO] Dual-boot function size: %d bytes\n",bootloader_sizes[model]); |
260 | fprintf(stderr,"Original total size of firmware - %d bytes\n",(int)len); | 380 | fprintf(stderr,"[INFO] UCL unpack function size: %d bytes\n",sizeof(uclimg)); |
261 | 381 | ||
262 | /* Check we have room for our bootloader - in the future, we could UCL | 382 | totalsize = bootloader_sizes[model] + sizeof(uclimg) + of_packedsize + |
263 | pack this image as well if we need to. */ | 383 | rb_packedsize; |
264 | if (bootloader_size > (firmware_size - ucl_paddedsize - uclunpack_size)) { | 384 | |
265 | fprintf(stderr,"[ERR] Bootloader too large (%d bytes, %d available)\n", | 385 | fprintf(stderr,"[INFO] Total size of new image: %d bytes\n",totalsize); |
266 | bootloader_size, firmware_size - ucl_paddedsize - uclunpack_size); | 386 | |
387 | if (totalsize > firmware_size) { | ||
388 | fprintf(stderr,"[ERR] No room to insert bootloader, aborting\n"); | ||
389 | free(buf); | ||
390 | free(rb_unpacked); | ||
391 | free(of_packed); | ||
267 | return 1; | 392 | return 1; |
268 | } | 393 | } |
269 | 394 | ||
270 | /* Zero the original firmware area - not needed, but helps debugging */ | 395 | /* Zero the original firmware area - not needed, but helps debugging */ |
271 | memset(buf + 0x400, 0, firmware_size); | 396 | memset(buf + 0x400, 0, firmware_size); |
272 | 397 | ||
273 | /* Locate our bootloader code at the start of the firmware block */ | ||
274 | n = read(fdboot, buf + 0x400, bootloader_size); | ||
275 | 398 | ||
276 | if (n != bootloader_size) { | 399 | /* Insert dual-boot bootloader at offset 0 */ |
277 | fprintf(stderr,"[ERR] Could not load bootloader file\n"); | 400 | memcpy(buf + 0x400, bootloaders[model], bootloader_sizes[model]); |
278 | return 1; | ||
279 | } | ||
280 | close(fdboot); | ||
281 | 401 | ||
282 | /* Locate the compressed image of the original firmware block at the end | 402 | /* We are filling the firmware buffer backwards from the end */ |
283 | of the firmware block */ | 403 | p = buf + 0x400 + firmware_size; |
284 | n = read(fducl, buf + 0x400 + firmware_size - ucl_paddedsize, ucl_size); | ||
285 | 404 | ||
286 | if (n != ucl_size) { | 405 | /* 1 - UCL unpack function */ |
287 | fprintf(stderr,"[ERR] Could not load ucl file\n"); | 406 | p -= sizeof(uclimg); |
288 | return 1; | 407 | memcpy(p, uclimg, sizeof(uclimg)); |
289 | } | ||
290 | close(fducl); | ||
291 | 408 | ||
409 | /* 2 - Compressed copy of original firmware */ | ||
410 | p -= of_packedsize; | ||
411 | memcpy(p, of_packed, of_packedsize); | ||
292 | 412 | ||
293 | /* Locate our UCL unpack function before copy of the compressed firmware */ | 413 | /* 3 - Compressed copy of Rockbox bootloader */ |
294 | n = read(fduclunpack, buf + 0x400 + firmware_size - ucl_paddedsize - uclunpack_size, uclunpack_size); | 414 | p -= rb_packedsize; |
415 | memcpy(p, rb_packed, rb_packedsize); | ||
295 | 416 | ||
296 | if (n != uclunpack_size) { | 417 | /* Write the locations of the various images to the variables at the |
297 | fprintf(stderr,"[ERR] Could not load uclunpack file\n"); | 418 | start of the dualboot image - we save the location of the last byte |
298 | return 1; | 419 | in each image, along with the size in bytes */ |
299 | } | 420 | |
300 | close(fduclunpack); | 421 | /* UCL unpack function */ |
422 | put_uint32le(&buf[0x420], firmware_size); | ||
423 | put_uint32le(&buf[0x424], sizeof(uclimg)); | ||
424 | |||
425 | /* Compressed original firmware image */ | ||
426 | put_uint32le(&buf[0x428], firmware_size - sizeof(uclimg)); | ||
427 | put_uint32le(&buf[0x42c], of_packedsize); | ||
301 | 428 | ||
302 | put_uint32le(&buf[0x420], 0x40000 - ucl_paddedsize - uclunpack_size + 1); /* UCL unpack entry point */ | 429 | /* Compressed Rockbox image */ |
303 | put_uint32le(&buf[0x424], 0x40000 - ucl_paddedsize); /* Location of OF */ | 430 | put_uint32le(&buf[0x430], firmware_size - sizeof(uclimg) - of_packedsize); |
304 | put_uint32le(&buf[0x428], ucl_size); /* Size of UCL image */ | 431 | put_uint32le(&buf[0x434], rb_packedsize); |
305 | put_uint32le(&buf[0x42c], firmware_size - uclunpack_size - ucl_paddedsize); /* Start of data to copy */ | ||
306 | put_uint32le(&buf[0x430], uclunpack_size + ucl_paddedsize); /* Size of data to copy */ | ||
307 | 432 | ||
308 | /* Update checksum */ | 433 | |
434 | /* Update the firmware block checksum */ | ||
309 | sum = calc_checksum(buf + 0x400,firmware_size); | 435 | sum = calc_checksum(buf + 0x400,firmware_size); |
310 | 436 | ||
311 | put_uint32le(&buf[0x04], sum); | 437 | if (fw_version == 1) { |
312 | put_uint32le(&buf[0x204], sum); | 438 | put_uint32le(&buf[0x04], sum); |
439 | put_uint32le(&buf[0x204], sum); | ||
440 | } else { | ||
441 | /* TODO: Verify that this is correct for the v2 firmware */ | ||
442 | |||
443 | put_uint32le(&buf[0x08], sum); | ||
444 | put_uint32le(&buf[0x208], sum); | ||
445 | |||
446 | /* Update the header checksums */ | ||
447 | put_uint32le(&buf[0x1fc], calc_checksum(buf, 0x1fc)); | ||
448 | put_uint32le(&buf[0x3fc], calc_checksum(buf + 0x200, 0x1fc)); | ||
449 | } | ||
313 | 450 | ||
314 | /* Update the whole-file checksum */ | 451 | /* Update the whole-file checksum */ |
315 | filesum = 0; | 452 | filesum = 0; |