summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2008-10-01 09:15:44 +0000
committerDave Chapman <dave@dchapman.com>2008-10-01 09:15:44 +0000
commit757f5112e25efbfa71a2d289436a1b285ca46663 (patch)
tree04ab1f66bf8e6d7e8e49a4c0d7180e1250de90a1
parentfe72d579969b9b5365fb5f430cd8eb265d2f4d44 (diff)
downloadrockbox-757f5112e25efbfa71a2d289436a1b285ca46663.tar.gz
rockbox-757f5112e25efbfa71a2d289436a1b285ca46663.zip
Untested (i.e. will almost certainly brick your device if you attempt to use it) first attempt at making mkamsboot store the original firmware as a UCL compressed image. If it works, then this means we have about 40KB (depending on target and OF version) for our bootloader code. I repeat: This is UNTESTED and needs reviewing fully before attempting to install on a device.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18675 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--utils/AMS/hacking/Makefile35
-rw-r--r--utils/AMS/hacking/extract_fw.c129
-rw-r--r--utils/AMS/hacking/mkamsboot.c195
-rw-r--r--utils/AMS/hacking/nrv2e_d8.S9
-rw-r--r--utils/AMS/hacking/test.S31
5 files changed, 304 insertions, 95 deletions
diff --git a/utils/AMS/hacking/Makefile b/utils/AMS/hacking/Makefile
index 7a10c20ae4..8f48d611c8 100644
--- a/utils/AMS/hacking/Makefile
+++ b/utils/AMS/hacking/Makefile
@@ -1,4 +1,3 @@
1
2# Change INFILE to point to your original firmware file 1# Change INFILE to point to your original firmware file
3INFILE=$(HOME)/FW/AMS/CLIP/m300a-1.1.17A.bin 2INFILE=$(HOME)/FW/AMS/CLIP/m300a-1.1.17A.bin
4 3
@@ -6,6 +5,8 @@ INFILE=$(HOME)/FW/AMS/CLIP/m300a-1.1.17A.bin
6# (e.g.) m300a.bin 5# (e.g.) m300a.bin
7OUTFILE=patched.bin 6OUTFILE=patched.bin
8 7
8# The uclpack command
9UCLPACK=../../../tools/uclpack
9 10
10all: amsinfo $(OUTFILE) 11all: amsinfo $(OUTFILE)
11 12
@@ -15,6 +16,9 @@ amsinfo: amsinfo.c
15mkamsboot: mkamsboot.c 16mkamsboot: mkamsboot.c
16 gcc -o mkamsboot -W -Wall mkamsboot.c 17 gcc -o mkamsboot -W -Wall mkamsboot.c
17 18
19extract_fw: extract_fw.c
20 gcc -o extract_fw -W -Wall extract_fw.c
21
18# Rules for our test ARM application - assemble, link, then extract 22# Rules for our test ARM application - assemble, link, then extract
19# the binary code 23# the binary code
20 24
@@ -22,13 +26,34 @@ test.o: test.S
22 arm-elf-as -o test.o test.S 26 arm-elf-as -o test.o test.S
23 27
24test.elf: test.o 28test.elf: test.o
25 arm-elf-ld -e 0 -o test.elf test.o 29 arm-elf-ld -e 0 -Ttext=0 -o test.elf test.o
26 30
27test.bin: test.elf 31test.bin: test.elf
28 arm-elf-objcopy -O binary test.elf test.bin 32 arm-elf-objcopy -O binary test.elf test.bin
29 33
30$(OUTFILE): mkamsboot test.bin $(INFILE) 34# Rules for the ucl unpack function - this is inserted in the padding at
31 ./mkamsboot $(INFILE) test.bin $(OUTFILE) 35# the end of the original firmware block
36nrv2e_d8.o: nrv2e_d8.S
37 arm-elf-gcc -DPURE_THUMB -c -o nrv2e_d8.o nrv2e_d8.S
38
39# NOTE: this function has no absolute references, so the link address (-e)
40# is irrelevant. We just link at address 0.
41nrv2e_d8.elf: nrv2e_d8.o
42 arm-elf-ld -e 0 -Ttext=0 -o nrv2e_d8.elf nrv2e_d8.o
43
44nrv2e_d8.bin: nrv2e_d8.elf
45 arm-elf-objcopy -O binary nrv2e_d8.elf nrv2e_d8.bin
46
47firmware_block.ucl: firmware_block.bin
48 $(UCLPACK) --best --2e firmware_block.bin firmware_block.ucl
49
50firmware_block.bin: $(INFILE) extract_fw
51 ./extract_fw $(INFILE) firmware_block.bin
52
53$(OUTFILE): mkamsboot firmware_block.ucl test.bin nrv2e_d8.bin $(INFILE)
54 ./mkamsboot $(INFILE) firmware_block.ucl test.bin nrv2e_d8.bin $(OUTFILE)
32 55
33clean: 56clean:
34 rm -fr amsinfo mkamsboot test.bin test.o test.elf $(OUTFILE) *~ 57 rm -fr amsinfo mkamsboot test.o test.elf test.bin extract_fw \
58 nrv2e_d8.o nrv2e_d8.elf nrv2e_d8.bin firmware_block.bin \
59 firmware_block.ucl $(OUTFILE) *~
diff --git a/utils/AMS/hacking/extract_fw.c b/utils/AMS/hacking/extract_fw.c
new file mode 100644
index 0000000000..e91d1f8de1
--- /dev/null
+++ b/utils/AMS/hacking/extract_fw.c
@@ -0,0 +1,129 @@
1/*
2
3extract_fw.c - extract the main firmware image from a Sansa V2 (AMS) firmware
4 file
5
6Copyright (C) Dave Chapman 2008
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
21
22*/
23
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <stdint.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <fcntl.h>
31#include <unistd.h>
32#include <string.h>
33
34
35/* Win32 compatibility */
36#ifndef O_BINARY
37#define O_BINARY 0
38#endif
39
40
41static off_t filesize(int fd) {
42 struct stat buf;
43
44 if (fstat(fd,&buf) < 0) {
45 perror("[ERR] Checking filesize of input file");
46 return -1;
47 } else {
48 return(buf.st_size);
49 }
50}
51
52static uint32_t get_uint32le(unsigned char* p)
53{
54 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
55}
56
57void usage(void)
58{
59 printf("Usage: extract_fw <firmware file> <output file>\n");
60
61 exit(1);
62}
63
64int main(int argc, char* argv[])
65{
66 char *infile, *outfile;
67 int fdin, fdout;
68 off_t len;
69 uint32_t n;
70 unsigned char* buf;
71 uint32_t firmware_size;
72
73 if(argc != 3) {
74 usage();
75 }
76
77 infile = argv[1];
78 outfile = argv[2];
79
80 /* Open the firmware file */
81 fdin = open(infile,O_RDONLY|O_BINARY);
82
83 if (fdin < 0) {
84 fprintf(stderr,"[ERR] Could not open %s for reading\n",infile);
85 return 1;
86 }
87
88 if ((len = filesize(fdin)) < 0)
89 return 1;
90
91 /* We will need no more memory than the total size plus the bootloader size
92 padded to a boundary */
93 if ((buf = malloc(len)) == NULL) {
94 fprintf(stderr,"[ERR] Could not allocate buffer for input file (%d bytes)\n",(int)len);
95 return 1;
96 }
97
98 n = read(fdin, buf, len);
99
100 if (n != (uint32_t)len) {
101 fprintf(stderr,"[ERR] Could not read firmware file\n");
102 return 1;
103 }
104
105 close(fdin);
106
107 /* Get the firmware size */
108 firmware_size = get_uint32le(&buf[0x0c]);
109
110 fdout = open(outfile, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666);
111
112 if (fdout < 0) {
113 fprintf(stderr,"[ERR] Could not open %s for writing\n",outfile);
114 return 1;
115 }
116
117 n = write(fdout, buf + 0x400, firmware_size);
118
119 if (n != (uint32_t)firmware_size) {
120 fprintf(stderr,"[ERR] Could not write firmware block\n");
121 return 1;
122 }
123
124 /* Clean up */
125 close(fdout);
126 free(buf);
127
128 return 0;
129}
diff --git a/utils/AMS/hacking/mkamsboot.c b/utils/AMS/hacking/mkamsboot.c
index 30ca66e43b..ea434bc893 100644
--- a/utils/AMS/hacking/mkamsboot.c
+++ b/utils/AMS/hacking/mkamsboot.c
@@ -26,26 +26,33 @@ 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
29The first instruction in an AMS firmware file is always of the form: 29We replace the main firmware block (bytes 0x400..padded_firmware_size+0x400)
30with the following:
30 31
31 ldr pc, [pc, #xxx] 32Bytes 0..(firmware_size-ucl_size) - Our bootloader code
33Bytes (firmware_size-ucl_size)..firmware_size - UCL compressed OF image
34Bytes firmware_size..padded_firmware_size - UCL decompress function
32 35
33where [pc, #xxx] contains the entry point of the firmware - e.g. 0x00000138 36mkamsboot writes the following values at offsets into our bootloader code:
34 37
35mkamsboot appends the Rockbox bootloader to the end of the original 380x20 - Entry point (plus 1 - for thumb mode) of the ucl_unpack function
36firmware block in the firmware file and shifts the remaining contents of the firmware file to make space for it. 390x24 - Location of the UCL compressed version of the original firmware block
37 40
38It also replaces the contents of [pc, #xxx] with the entry point of 41mkamsboot then corrects the length (to include the UCL decompress
39our bootloader - i.e. the length of the original firmware block plus 4 42function) and checksum in the main firmware headers (both copies),
40bytes. 43creating a new legal firmware file which can be installed on the
44device.
41 45
42It then stores the original entry point from [pc, #xxx] in the first 46Our bootloader first checks for the "dual-boot" keypress, and then either:
43four bytes of the Rockbox bootloader image, which is used by the
44bootloader to dual-boot.
45 47
46Finally, mkamsboot corrects the length and checksum in the main 48a) Branches to the ucl_unpack function, which will then branch to 0x0 after
47firmware headers (both copies), creating a new legal firmware file 49 decompressing the OF.
48which can be installed on the device. 50
51b) Continues running with our test code
52
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.
49 56
50*/ 57*/
51 58
@@ -106,35 +113,35 @@ static int calc_checksum(unsigned char* buf, uint32_t n)
106 113
107void usage(void) 114void usage(void)
108{ 115{
109 printf("Usage: mkamsboot <firmware file> <boot file> <output file>\n"); 116 printf("Usage: mkamsboot <firmware file> <ucl image> <boot file> <ucl unpack file> <output file>\n");
110 117
111 exit(1); 118 exit(1);
112} 119}
113 120
114int main(int argc, char* argv[]) 121int main(int argc, char* argv[])
115{ 122{
116 char *infile, *bootfile, *outfile; 123 char *infile, *uclfile, *bootfile, *uclunpackfile, *outfile;
117 int fdin, fdboot,fdout; 124 int fdin, fducl, fdboot, fduclunpack, fdout;
118 off_t len; 125 off_t len;
119 uint32_t n; 126 uint32_t n;
120 unsigned char* buf; 127 unsigned char* buf;
121 uint32_t ldr;
122 uint32_t origoffset;
123 uint32_t firmware_size; 128 uint32_t firmware_size;
124 uint32_t firmware_paddedsize; 129 uint32_t firmware_paddedsize;
125 uint32_t bootloader_size; 130 uint32_t bootloader_size;
126 uint32_t new_paddedsize; 131 uint32_t ucl_size;
132 uint32_t uclunpack_size;
127 uint32_t sum,filesum; 133 uint32_t sum,filesum;
128 uint32_t new_length;
129 uint32_t i; 134 uint32_t i;
130 135
131 if(argc != 4) { 136 if(argc != 6) {
132 usage(); 137 usage();
133 } 138 }
134 139
135 infile = argv[1]; 140 infile = argv[1];
136 bootfile = argv[2]; 141 uclfile = argv[2];
137 outfile = argv[3]; 142 bootfile = argv[3];
143 uclunpackfile = argv[4];
144 outfile = argv[5];
138 145
139 /* Open the bootloader file */ 146 /* Open the bootloader file */
140 fdboot = open(bootfile, O_RDONLY|O_BINARY); 147 fdboot = open(bootfile, O_RDONLY|O_BINARY);
@@ -147,6 +154,28 @@ int main(int argc, char* argv[])
147 bootloader_size = filesize(fdboot); 154 bootloader_size = filesize(fdboot);
148 155
149 156
157 /* Open the UCL-compressed image of the firmware block */
158 fduclunpack = open(uclunpackfile, O_RDONLY|O_BINARY);
159 if (fduclunpack < 0)
160 {
161 fprintf(stderr,"[ERR] Could not open %s for reading\n",uclunpackfile);
162 return 1;
163 }
164
165 uclunpack_size = filesize(fduclunpack);
166
167
168 /* Open the UCL-compressed image of the firmware block */
169 fducl = open(uclfile, O_RDONLY|O_BINARY);
170 if (fducl < 0)
171 {
172 fprintf(stderr,"[ERR] Could not open %s for reading\n",uclfile);
173 return 1;
174 }
175
176 ucl_size = filesize(fducl);
177
178
150 /* Open the firmware file */ 179 /* Open the firmware file */
151 fdin = open(infile,O_RDONLY|O_BINARY); 180 fdin = open(infile,O_RDONLY|O_BINARY);
152 181
@@ -158,9 +187,8 @@ int main(int argc, char* argv[])
158 if ((len = filesize(fdin)) < 0) 187 if ((len = filesize(fdin)) < 0)
159 return 1; 188 return 1;
160 189
161 /* We will need no more memory than the total size plus the bootloader size 190 /* Allocate memory for the OF image - we don't change the size */
162 padded to a boundary */ 191 if ((buf = malloc(len)) == NULL) {
163 if ((buf = malloc(len + PAD_TO_BOUNDARY(bootloader_size))) == NULL) {
164 fprintf(stderr,"[ERR] Could not allocate buffer for input file (%d bytes)\n",(int)len); 192 fprintf(stderr,"[ERR] Could not allocate buffer for input file (%d bytes)\n",(int)len);
165 return 1; 193 return 1;
166 } 194 }
@@ -181,91 +209,83 @@ int main(int argc, char* argv[])
181 209
182 firmware_paddedsize = PAD_TO_BOUNDARY(firmware_size); 210 firmware_paddedsize = PAD_TO_BOUNDARY(firmware_size);
183 211
184 /* Total new size */ 212 fprintf(stderr,"Original firmware size - %d bytes\n",firmware_size);
185 new_paddedsize = PAD_TO_BOUNDARY(firmware_size + bootloader_size); 213 fprintf(stderr,"Padded firmware size - %d bytes\n",firmware_paddedsize);
186 214 fprintf(stderr,"Bootloader size - %d bytes\n",bootloader_size);
187 /* Total new size of firmware file */ 215 fprintf(stderr,"UCL image size - %d bytes\n",ucl_size);
188 new_length = len + (new_paddedsize - firmware_paddedsize); 216 fprintf(stderr,"UCL unpack function size - %d bytes\n",uclunpack_size);
217 fprintf(stderr,"Original total size of firmware - %d bytes\n",(int)len);
218
219 /* Check we have room for our bootloader - in the future, we could UCL
220 pack this image as well if we need to. */
221 if (bootloader_size > (firmware_size - ucl_size)) {
222 fprintf(stderr,"[ERR] Bootloader too large (%d bytes, %d available)\n",
223 bootloader_size, firmware_size - ucl_size);
224 return 1;
225 }
189 226
190 fprintf(stderr,"Original firmware size - 0x%08x\n",firmware_size); 227 /* Check we have enough room for the UCL unpack function. This
191 fprintf(stderr,"Padded firmware size - 0x%08x\n",firmware_paddedsize); 228 needs to be outside the firmware block, so if we wanted to
192 fprintf(stderr,"Bootloader size - 0x%08x\n",bootloader_size); 229 support every firmware version, we could store this function in
193 fprintf(stderr,"New padded size - 0x%08x\n",new_paddedsize); 230 the main firmware block, and then copy it to an unused part of
194 fprintf(stderr,"Original total size of firmware - 0x%08x\n",(int)len); 231 RAM. */
195 fprintf(stderr,"New total size of firmware - 0x%08x\n",new_length); 232 if (uclunpack_size > (firmware_paddedsize - firmware_size)) {
233 fprintf(stderr,"[ERR] UCL unpack function too large (%d bytes, %d available)\n",
234 uclunpack_size, firmware_paddedsize - firmware_size);
235 return 1;
236 }
196 237
197 if (firmware_paddedsize != new_paddedsize) { 238 /* Zero the original firmware area - not needed, but helps debugging */
198 /* We don't know how to safely increase the firmware size, so abort */ 239 memset(buf + 0x400, 0, firmware_size);
199 240
200 fprintf(stderr, 241 /* Locate our bootloader code at the start of the firmware block */
201 "[ERR] Bootloader too large (%d bytes - %d bytes available), aborting.\n", 242 n = read(fdboot, buf + 0x400, bootloader_size);
202 bootloader_size, firmware_paddedsize - firmware_size);
203 243
244 if (n != bootloader_size) {
245 fprintf(stderr,"[ERR] Could not load bootloader file\n");
204 return 1; 246 return 1;
205 } 247 }
248 close(fdboot);
206 249
207 ldr = get_uint32le(&buf[0x400]); 250 /* Locate the compressed image of the original firmware block at the end
251 of the firmware block */
252 n = read(fducl, buf + 0x400 + firmware_size - ucl_size, ucl_size);
208 253
209 if ((ldr & 0xfffff000) != 0xe59ff000) { 254 if (n != ucl_size) {
210 fprintf(stderr,"[ERR] Firmware file doesn't start with an \"ldr pc, [pc, #xx]\" instruction.\n"); 255 fprintf(stderr,"[ERR] Could not load ucl file\n");
211 return 1; 256 return 1;
212 } 257 }
213 origoffset = (ldr&0xfff) + 8; 258 close(fducl);
214
215 printf("original firmware entry point: 0x%08x\n",get_uint32le(buf + 0x400 + origoffset));
216 printf("New entry point: 0x%08x\n", firmware_size + 4);
217
218#if 0
219 /* Replace the "Product: Express" string with "Rockbox" */
220 i = 0x400 + firmware_size - 7;
221 while ((i > 0x400) && (memcmp(&buf[i],"Express",7)!=0))
222 i--;
223 259
224 i = (i + 3) & ~0x3;
225
226 if (i >= 0x400) {
227 printf("Replacing \"Express\" string at offset 0x%08x\n",i);
228 memcpy(&buf[i],"Rockbox",7);
229 } else {
230 printf("Could not find \"Express\" string to replace\n");
231 }
232#endif
233 260
234 n = read(fdboot, buf + 0x400 + firmware_size, bootloader_size); 261 /* Locate our UCL unpack function in the padding after the firmware block */
262 n = read(fduclunpack, buf + 0x400 + firmware_size, uclunpack_size);
235 263
236 if (n != bootloader_size) { 264 if (n != uclunpack_size) {
237 fprintf(stderr,"[ERR] Could not bootloader file\n"); 265 fprintf(stderr,"[ERR] Could not load uclunpack file\n");
238 return 1; 266 return 1;
239 } 267 }
240 close(fdboot); 268 close(fduclunpack);
241 269
242 /* Replace first word of the bootloader with the original entry point */ 270 put_uint32le(&buf[0x420], firmware_size + 1); /* UCL unpack entry point */
243 put_uint32le(buf + 0x400 + firmware_size, get_uint32le(buf + 0x400 + origoffset)); 271 put_uint32le(&buf[0x424], firmware_size - ucl_size); /* Location of OF */
244
245#if 1
246 put_uint32le(buf + 0x400 + origoffset, firmware_size + 4);
247#endif
248 272
249 /* Update checksum */ 273 /* Update checksum */
250 sum = calc_checksum(buf + 0x400,firmware_size + bootloader_size); 274 sum = calc_checksum(buf + 0x400,firmware_size + uclunpack_size);
251 275
252 put_uint32le(&buf[0x04], sum); 276 put_uint32le(&buf[0x04], sum);
253 put_uint32le(&buf[0x204], sum); 277 put_uint32le(&buf[0x204], sum);
254 278
255 /* Update firmware block count */
256 put_uint32le(&buf[0x08], new_paddedsize / 0x200);
257 put_uint32le(&buf[0x208], new_paddedsize / 0x200);
258
259 /* Update firmware size */ 279 /* Update firmware size */
260 put_uint32le(&buf[0x0c], firmware_size + bootloader_size); 280 put_uint32le(&buf[0x0c], firmware_size + uclunpack_size);
261 put_uint32le(&buf[0x20c], firmware_size + bootloader_size); 281 put_uint32le(&buf[0x20c], firmware_size + uclunpack_size);
262 282
263 /* Update the whole-file checksum */ 283 /* Update the whole-file checksum */
264 filesum = 0; 284 filesum = 0;
265 for (i=0;i < new_length - 4; i+=4) 285 for (i=0;i < (unsigned)len - 4; i+=4)
266 filesum += get_uint32le(&buf[i]); 286 filesum += get_uint32le(&buf[i]);
267 287
268 put_uint32le(buf + new_length - 4, filesum); 288 put_uint32le(buf + len - 4, filesum);
269 289
270 290
271 /* Write the new firmware */ 291 /* Write the new firmware */
@@ -276,7 +296,12 @@ int main(int argc, char* argv[])
276 return 1; 296 return 1;
277 } 297 }
278 298
279 write(fdout, buf, new_length); 299 n = write(fdout, buf, len);
300
301 if (n != (unsigned)len) {
302 fprintf(stderr,"[ERR] Could not write firmware file\n");
303 return 1;
304 }
280 305
281 close(fdout); 306 close(fdout);
282 307
diff --git a/utils/AMS/hacking/nrv2e_d8.S b/utils/AMS/hacking/nrv2e_d8.S
index 88df64a58f..89cb76dead 100644
--- a/utils/AMS/hacking/nrv2e_d8.S
+++ b/utils/AMS/hacking/nrv2e_d8.S
@@ -77,13 +77,15 @@ ucl_nrv2e_decompress_8: .globl ucl_nrv2e_decompress_8 @ ARM mode
77 For SAFE mode: at call, *plen_dst must be allowed length of output buffer. 77 For SAFE mode: at call, *plen_dst must be allowed length of output buffer.
78*/ 78*/
79 adr r12,1+.thumb_nrv2e_d8; bx r12 @ enter THUMB mode 79 adr r12,1+.thumb_nrv2e_d8; bx r12 @ enter THUMB mode
80#endif
80 .code 16 @ THUMB mode 81 .code 16 @ THUMB mode
81 .thumb_func 82 .thumb_func
82#endif
83 83
84.thumb_nrv2e_d8: 84.thumb_nrv2e_d8:
85#if 0
85 push {r2,r3, r4,r5,r6,r7, lr} 86 push {r2,r3, r4,r5,r6,r7, lr}
86#define sp_DST0 0 /* stack offset of original dst */ 87#define sp_DST0 0 /* stack offset of original dst */
88#endif
87 add srclim,len,src @ srclim= eof_src; 89 add srclim,len,src @ srclim= eof_src;
88#if 1==SAFE /*{*/ 90#if 1==SAFE /*{*/
89 ldr tmp,[r3] @ len_dst 91 ldr tmp,[r3] @ len_dst
@@ -103,12 +105,17 @@ bad_src_n2e: # return value will be 1
103 add src,#1 105 add src,#1
104#endif /*}*/ 106#endif /*}*/
105eof_n2e: 107eof_n2e:
108#if 0
106 pop {r3,r4} @ r3= orig_dst; r4= plen_dst 109 pop {r3,r4} @ r3= orig_dst; r4= plen_dst
107 sub src,srclim @ 0 if actual src length equals expected length 110 sub src,srclim @ 0 if actual src length equals expected length
108 sub dst,r3 @ actual dst length 111 sub dst,r3 @ actual dst length
109 str dst,[r4] 112 str dst,[r4]
110 pop {r4,r5,r6,r7 /*,pc*/} 113 pop {r4,r5,r6,r7 /*,pc*/}
111 pop {r1}; bx r1 @ "pop {,pc}" fails return to ARM mode on ARMv4T 114 pop {r1}; bx r1 @ "pop {,pc}" fails return to ARM mode on ARMv4T
115#else
116 mov r0, #0
117 bx r0 /* Branch to 0x0, switch to ARM mode */
118#endif
112 119
113get1_n2e: @ In: Carry set [from adding 0x80000000 (1<<31) to itself] 120get1_n2e: @ In: Carry set [from adding 0x80000000 (1<<31) to itself]
114 ldrb bits,[src] @ zero-extend next byte 121 ldrb bits,[src] @ zero-extend next byte
diff --git a/utils/AMS/hacking/test.S b/utils/AMS/hacking/test.S
index 52f54bdaf6..d4bb2143bb 100644
--- a/utils/AMS/hacking/test.S
+++ b/utils/AMS/hacking/test.S
@@ -1,11 +1,34 @@
1/* int ucl_nrv2e_decompress_8(const unsigned char *src, unsigned char *dst,
2 unsigned long *dst_len) */
1 3
2/* This value is filled in by mkamsboot */ 4.text
3originalentry: .word 0 5.global ucl_nrv2e_decompress_8
4 6
7
8/* Vectors */
9 ldr pc, =start
10.word 0
11.word 0
12.word 0
13.word 0
14.word 0
15.word 0
16.word 0
17
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 */
20ucl_start: .word 0 /* Start of the ucl-compressed OF image */
21
22
23start:
5 /* A delay loop - just to prove we're running */ 24 /* A delay loop - just to prove we're running */
6 mov r1, #0x500000 /* Approximately 5 seconds */ 25 mov r1, #0x500000 /* Approximately 5 seconds */
7loop: subs r1, r1, #1 26loop: subs r1, r1, #1
8 bne loop 27 bne loop
9 28
10 /* Now branch back to the original firmware's entry point */ 29 /* Call the ucl decompress function, which will branch to 0x0
11 ldr pc, originalentry 30 on completion */
31 ldr r0, ucl_start /* Source */
32 mov r1, #0 /* Destination */
33 ldr r2, ucl_unpack
34 bx r2