summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2008-10-02 12:37:47 +0000
committerDave Chapman <dave@dchapman.com>2008-10-02 12:37:47 +0000
commitc2933cd46e7a84df24acf488249f62f9ec090759 (patch)
tree34a0850ee83e61b890fcd74856f79ada9c2187b9
parentd1d8b4ca555b47f190a075efb83f66738477b485 (diff)
downloadrockbox-c2933cd46e7a84df24acf488249f62f9ec090759.tar.gz
rockbox-c2933cd46e7a84df24acf488249f62f9ec090759.zip
Remove the dependency on sufficient free space in the padding at the end of the firmware block by storing the ucl unpack function in the main firmware block, immediately before the compressed firmware image. Also simplify the memcpy function in test.S. This has been tested successfully on a Clip.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18682 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--utils/AMS/hacking/mkamsboot.c88
-rw-r--r--utils/AMS/hacking/test.S21
2 files changed, 52 insertions, 57 deletions
diff --git a/utils/AMS/hacking/mkamsboot.c b/utils/AMS/hacking/mkamsboot.c
index 47738ebdde..52ead58b69 100644
--- a/utils/AMS/hacking/mkamsboot.c
+++ b/utils/AMS/hacking/mkamsboot.c
@@ -26,34 +26,41 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
26 26
27Insert a Rockbox bootloader into an AMS original firmware file. 27Insert a Rockbox bootloader into an AMS original firmware file.
28 28
29We replace the main firmware block (bytes 0x400..padded_firmware_size+0x400) 29We replace the main firmware block (bytes 0x400..0x400+firmware_size)
30with the following: 30as follows:
31 31
32Bytes 0..(firmware_size-ucl_size) - Our bootloader code 32
33Bytes (firmware_size-ucl_size)..firmware_size - UCL compressed OF image 33 --------------------- 0x0
34Bytes firmware_size..padded_firmware_size - UCL decompress function 34| |
35 35| Rockbox bootloader |
36mkamsboot writes the following values at offsets into our bootloader code: 36| |
37 37|---------------------|
380x20 - Entry point (plus 1 - for thumb mode) of the ucl_unpack function 38| EMPTY SPACE |
390x24 - Location of the UCL compressed version of the original firmware block 39|---------------------|
40 40| ucl unpack function |
41mkamsboot then corrects the length (to include the UCL decompress 41|---------------------|
42function) and checksum in the main firmware headers (both copies), 42| |
43creating a new legal firmware file which can be installed on the 43| compressed OF image |
44device. 44| |
45| |
46 ---------------------
47
48This entire block fits into the space previously occupied by the main
49firmware block, and gives about 40KB of space to store the Rockbox
50bootloader. This could be increased if we also UCL compress the
51Rockbox bootloader.
52
53mkamsboot then corrects the checksums and writes a new legal firmware
54file which can be installed on the device.
45 55
46Our bootloader first checks for the "dual-boot" keypress, and then either: 56Our bootloader first checks for the "dual-boot" keypress, and then either:
47 57
48a) Branches to the ucl_unpack function, which will then branch to 0x0 after 58a) Copies the ucl unpack function and compressed OF image to an unused
49 decompressing the OF. 59 part of RAM and then branches to the ucl_unpack function, which
60 will then branch to 0x0 after decompressing the OF to that location.
50 61
51b) Continues running with our test code 62b) Continues running with our test code
52 63
53This method uses no RAM outside the padded area of the original
54firmware block - the UCL compression can happen in-place when the
55compressed image is stored at the end of the destination buffer.
56
57*/ 64*/
58 65
59 66
@@ -142,6 +149,7 @@ int main(int argc, char* argv[])
142 uint32_t firmware_paddedsize; 149 uint32_t firmware_paddedsize;
143 uint32_t bootloader_size; 150 uint32_t bootloader_size;
144 uint32_t ucl_size; 151 uint32_t ucl_size;
152 uint32_t ucl_paddedsize;
145 uint32_t uclunpack_size; 153 uint32_t uclunpack_size;
146 uint32_t sum,filesum; 154 uint32_t sum,filesum;
147 uint32_t i; 155 uint32_t i;
@@ -204,6 +212,7 @@ int main(int argc, char* argv[])
204 return 1; 212 return 1;
205 } 213 }
206 ucl_size = get_uint32be(&uclheader[22]) + 8; 214 ucl_size = get_uint32be(&uclheader[22]) + 8;
215 ucl_paddedsize = (ucl_size + 3) & ~0x3;
207 216
208 if (ucl_size + 26 > (unsigned)filesize(fducl)) { 217 if (ucl_size + 26 > (unsigned)filesize(fducl)) {
209 fprintf(stderr, "[ERR] Size mismatch in UCL file\n"); 218 fprintf(stderr, "[ERR] Size mismatch in UCL file\n");
@@ -246,26 +255,15 @@ int main(int argc, char* argv[])
246 fprintf(stderr,"Original firmware size - %d bytes\n",firmware_size); 255 fprintf(stderr,"Original firmware size - %d bytes\n",firmware_size);
247 fprintf(stderr,"Padded firmware size - %d bytes\n",firmware_paddedsize); 256 fprintf(stderr,"Padded firmware size - %d bytes\n",firmware_paddedsize);
248 fprintf(stderr,"Bootloader size - %d bytes\n",bootloader_size); 257 fprintf(stderr,"Bootloader size - %d bytes\n",bootloader_size);
249 fprintf(stderr,"UCL image size - %d bytes\n",ucl_size); 258 fprintf(stderr,"UCL image size - %d bytes (%d bytes padded)\n",ucl_size,ucl_paddedsize);
250 fprintf(stderr,"UCL unpack function size - %d bytes\n",uclunpack_size); 259 fprintf(stderr,"UCL unpack function size - %d bytes\n",uclunpack_size);
251 fprintf(stderr,"Original total size of firmware - %d bytes\n",(int)len); 260 fprintf(stderr,"Original total size of firmware - %d bytes\n",(int)len);
252 261
253 /* Check we have room for our bootloader - in the future, we could UCL 262 /* Check we have room for our bootloader - in the future, we could UCL
254 pack this image as well if we need to. */ 263 pack this image as well if we need to. */
255 if (bootloader_size > (firmware_size - ucl_size)) { 264 if (bootloader_size > (firmware_size - ucl_paddedsize - uclunpack_size)) {
256 fprintf(stderr,"[ERR] Bootloader too large (%d bytes, %d available)\n", 265 fprintf(stderr,"[ERR] Bootloader too large (%d bytes, %d available)\n",
257 bootloader_size, firmware_size - ucl_size); 266 bootloader_size, firmware_size - ucl_paddedsize - uclunpack_size);
258 return 1;
259 }
260
261 /* Check we have enough room for the UCL unpack function. This
262 needs to be outside the firmware block, so if we wanted to
263 support every firmware version, we could store this function in
264 the main firmware block, and then copy it to an unused part of
265 RAM. */
266 if (uclunpack_size > (firmware_paddedsize - firmware_size)) {
267 fprintf(stderr,"[ERR] UCL unpack function too large (%d bytes, %d available)\n",
268 uclunpack_size, firmware_paddedsize - firmware_size);
269 return 1; 267 return 1;
270 } 268 }
271 269
@@ -283,7 +281,7 @@ int main(int argc, char* argv[])
283 281
284 /* Locate the compressed image of the original firmware block at the end 282 /* Locate the compressed image of the original firmware block at the end
285 of the firmware block */ 283 of the firmware block */
286 n = read(fducl, buf + 0x400 + firmware_size - ucl_size, ucl_size); 284 n = read(fducl, buf + 0x400 + firmware_size - ucl_paddedsize, ucl_size);
287 285
288 if (n != ucl_size) { 286 if (n != ucl_size) {
289 fprintf(stderr,"[ERR] Could not load ucl file\n"); 287 fprintf(stderr,"[ERR] Could not load ucl file\n");
@@ -292,8 +290,8 @@ int main(int argc, char* argv[])
292 close(fducl); 290 close(fducl);
293 291
294 292
295 /* Locate our UCL unpack function in the padding after the firmware block */ 293 /* Locate our UCL unpack function before copy of the compressed firmware */
296 n = read(fduclunpack, buf + 0x400 + firmware_size, uclunpack_size); 294 n = read(fduclunpack, buf + 0x400 + firmware_size - ucl_paddedsize - uclunpack_size, uclunpack_size);
297 295
298 if (n != uclunpack_size) { 296 if (n != uclunpack_size) {
299 fprintf(stderr,"[ERR] Could not load uclunpack file\n"); 297 fprintf(stderr,"[ERR] Could not load uclunpack file\n");
@@ -301,20 +299,18 @@ int main(int argc, char* argv[])
301 } 299 }
302 close(fduclunpack); 300 close(fduclunpack);
303 301
304 put_uint32le(&buf[0x420], firmware_size + 1); /* UCL unpack entry point */ 302 put_uint32le(&buf[0x420], 0x40000 - ucl_paddedsize - uclunpack_size + 1); /* UCL unpack entry point */
305 put_uint32le(&buf[0x424], firmware_size - ucl_size); /* Location of OF */ 303 put_uint32le(&buf[0x424], 0x40000 - ucl_paddedsize); /* Location of OF */
306 put_uint32le(&buf[0x428], ucl_size); /* Size of UCL image */ 304 put_uint32le(&buf[0x428], ucl_size); /* Size of UCL image */
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 307
308 /* Update checksum */ 308 /* Update checksum */
309 sum = calc_checksum(buf + 0x400,firmware_size + uclunpack_size); 309 sum = calc_checksum(buf + 0x400,firmware_size);
310 310
311 put_uint32le(&buf[0x04], sum); 311 put_uint32le(&buf[0x04], sum);
312 put_uint32le(&buf[0x204], sum); 312 put_uint32le(&buf[0x204], sum);
313 313
314 /* Update firmware size */
315 put_uint32le(&buf[0x0c], firmware_size + uclunpack_size);
316 put_uint32le(&buf[0x20c], firmware_size + uclunpack_size);
317
318 /* Update the whole-file checksum */ 314 /* Update the whole-file checksum */
319 filesum = 0; 315 filesum = 0;
320 for (i=0;i < (unsigned)len - 4; i+=4) 316 for (i=0;i < (unsigned)len - 4; i+=4)
diff --git a/utils/AMS/hacking/test.S b/utils/AMS/hacking/test.S
index 79d23deb6a..a4757b44ce 100644
--- a/utils/AMS/hacking/test.S
+++ b/utils/AMS/hacking/test.S
@@ -16,10 +16,11 @@
16.word 0 16.word 0
17 17
18/* These values are filled in by mkamsboot - don't move them from offset 0x20 */ 18/* These values are filled in by mkamsboot - don't move them from offset 0x20 */
19ucl_unpack: .word 0 /* Entry point (plus 1 - for thumb) of ucl_unpack */ 19ucl_unpack: .word 0 /* Entry point (plus 1 - for thumb) of ucl_unpack after copy*/
20ucl_start: .word 0 /* Start of the ucl-compressed OF image */ 20ucl_start: .word 0 /* Start of the ucl-compressed OF image after copy */
21ucl_size: .word 0 /* Length in bytes of the compressed OF image */ 21ucl_size: .word 0 /* Length in bytes of the compressed OF image */
22 22copy_start: .word 0 /* Start of the copy of the ucl_unpack function */
23copy_size: .word 0 /* uclunpack_size + ucl_paddedsize */
23 24
24start: 25start:
25 /* A delay loop - just to prove we're running */ 26 /* A delay loop - just to prove we're running */
@@ -29,25 +30,23 @@ loop: subs r1, r1, #1
29 30
30 /* First copy the compressed firmware to unused RAM */ 31 /* First copy the compressed firmware to unused RAM */
31 32
32 ldr r0, ucl_start /* Source */ 33 ldr r0, copy_start /* Source */
33 ldr r1, ucl_size /* Source length */ 34 ldr r1, copy_size /* Source length */
34 35
35 mov r2, #0x40000 /* Destination end */ 36 mov r2, #0x40000 /* Destination end */
36 sub r2, r2, r1 37 sub r2, r2, r1
37 38
38memcpy: 39memcpy:
39 ldrb r3, [r0] 40 ldrb r3, [r0], #1
40 strb r3, [r2] 41 strb r3, [r2], #1
41 adds r0, r0, #1
42 adds r2, r2, #1
43 cmp r2, #0x40000 /* Stop when we reached dest_end */ 42 cmp r2, #0x40000 /* Stop when we reached dest_end */
44 bne memcpy 43 bne memcpy
45 44
46 sub r0, r2, r1 /* Point to the compressed firmware */
47
48 /* Call the ucl decompress function, which will branch to 0x0 */ 45 /* Call the ucl decompress function, which will branch to 0x0 */
49 /* on completion */ 46 /* on completion */
50 47
48 ldr r0, ucl_start /* Address of compressed image */
49 ldr r1, ucl_size /* Compressed size */
51 mov r2, #0 /* Destination */ 50 mov r2, #0 /* Destination */
52 51
53 ldr r3, ucl_unpack 52 ldr r3, ucl_unpack