diff options
author | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2009-10-27 21:15:21 +0000 |
---|---|---|
committer | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2009-10-27 21:15:21 +0000 |
commit | b82963bd9dd99c705625aceadb7118a428fc4ed2 (patch) | |
tree | 5cc54c84c908933bb79614c502a3a61f863a2650 /tools/mknkboot.c | |
parent | 806bc7947b0b03f3b2d11b38d17066d5e1e890d3 (diff) | |
download | rockbox-b82963bd9dd99c705625aceadb7118a428fc4ed2.tar.gz rockbox-b82963bd9dd99c705625aceadb7118a428fc4ed2.zip |
Move mknkboot.[ch] to beastpatcher folder.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23372 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'tools/mknkboot.c')
-rw-r--r-- | tools/mknkboot.c | 320 |
1 files changed, 0 insertions, 320 deletions
diff --git a/tools/mknkboot.c b/tools/mknkboot.c deleted file mode 100644 index 6ac26428bc..0000000000 --- a/tools/mknkboot.c +++ /dev/null | |||
@@ -1,320 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Dave Chapman | ||
11 | * | ||
12 | * Based on merge0.cpp by James Espinoza, but completely rewritten. | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions are | ||
16 | * met: | ||
17 | * | ||
18 | * * Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * | ||
21 | * * Redistributions in binary form must reproduce the above | ||
22 | * copyright notice, this list of conditions and the following | ||
23 | * disclaimer in the documentation and/or other materials provided | ||
24 | * with the distribution. | ||
25 | * | ||
26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
27 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
28 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
29 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
30 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
31 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
32 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
33 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
34 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
35 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
36 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
37 | * | ||
38 | ****************************************************************************/ | ||
39 | #include <stdio.h> | ||
40 | #include <stdlib.h> | ||
41 | #include <string.h> | ||
42 | #include <sys/types.h> | ||
43 | #include <sys/stat.h> | ||
44 | #include <fcntl.h> | ||
45 | #if defined(_MSC_VER) | ||
46 | #include "pstdint.h" | ||
47 | #else | ||
48 | #include <unistd.h> | ||
49 | #include <inttypes.h> | ||
50 | #endif | ||
51 | |||
52 | #include "mknkboot.h" | ||
53 | |||
54 | /* New entry point for nk.bin - where our dualboot code is inserted */ | ||
55 | #define NK_ENTRY_POINT 0x88200000 | ||
56 | |||
57 | /* Entry point (and load address) for the main Rockbox bootloader */ | ||
58 | #define BL_ENTRY_POINT 0x8a000000 | ||
59 | |||
60 | /* | ||
61 | |||
62 | Description of nk.bin from | ||
63 | |||
64 | http://www.xs4all.nl/~itsme/projects/xda/wince-flashfile-formats.html | ||
65 | |||
66 | these files contain most information, several non-contigouos blocks | ||
67 | may be present and an entrypoint in the code. | ||
68 | |||
69 | 1. a 7 character signature "B000FF\n" ( that is with 3 zeroes, and | ||
70 | ending in a linefeed ) | ||
71 | 2. DWORD for image start | ||
72 | 3. DWORD for image length | ||
73 | 4. followd by several records of this format: | ||
74 | 1. DWORD with address where this block is to be flashed to | ||
75 | 2. DWORD with the length of this block | ||
76 | 3. DWORD with the 32 bit checksum of this block, in perl: | ||
77 | unpack("%32C*", $data); | ||
78 | 4. followed by <length> bytes of data | ||
79 | 5. the last record has address ZERO, in the length the entrypoint | ||
80 | into the rom, and ZERO as checksum. | ||
81 | |||
82 | |||
83 | NOTE: The Gigabeat-S nk.bin contains 171 records, plus the EOF record. | ||
84 | |||
85 | mknkboot.c appends two images: | ||
86 | |||
87 | 1) A "Disable" image which overwrites a word in the EBoot image | ||
88 | 2) Our bootloader image, which has the same load address as nk.exe | ||
89 | |||
90 | */ | ||
91 | |||
92 | /* win32 compatibility */ | ||
93 | |||
94 | #ifndef O_BINARY | ||
95 | #define O_BINARY 0 | ||
96 | #endif | ||
97 | |||
98 | #define DISABLE_ADDR 0x88065A10 /* in EBoot */ | ||
99 | #define DISABLE_INSN 0xe3a00001 | ||
100 | #define DISABLE_SUM (0xe3+0xa0+0x00+0x01) | ||
101 | |||
102 | /* Code to dual-boot - this is inserted at NK_ENTRY_POINT */ | ||
103 | static uint32_t dualboot[] = | ||
104 | { | ||
105 | 0xe59f900c, /* ldr r9, [pc, #12] -> 0x53fa4000 */ | ||
106 | 0xe5999000, /* ldr r9, [r9] */ | ||
107 | 0xe3190010, /* tst r9, #16 ; 0x10 */ | ||
108 | #if 0 | ||
109 | /* Branch to Rockbox if hold is on */ | ||
110 | 0x159ff004, /* ldrne pc, [pc, #4] -> 0x89000000 */ | ||
111 | #else | ||
112 | /* Branch to Rockbox if hold is off */ | ||
113 | 0x059ff004, /* ldreq pc, [pc, #4] -> 0x89000000 */ | ||
114 | #endif | ||
115 | /* Branch to original firmware */ | ||
116 | 0xea0003fa, /* b 0x1000 */ | ||
117 | |||
118 | 0x53fa4000, /* GPIO3_DR */ | ||
119 | BL_ENTRY_POINT /* RB bootloader load address/entry point */ | ||
120 | }; | ||
121 | |||
122 | |||
123 | static void put_uint32le(uint32_t x, unsigned char* p) | ||
124 | { | ||
125 | p[0] = (unsigned char)(x & 0xff); | ||
126 | p[1] = (unsigned char)((x >> 8) & 0xff); | ||
127 | p[2] = (unsigned char)((x >> 16) & 0xff); | ||
128 | p[3] = (unsigned char)((x >> 24) & 0xff); | ||
129 | } | ||
130 | |||
131 | #if !defined(BEASTPATCHER) | ||
132 | static off_t filesize(int fd) { | ||
133 | struct stat buf; | ||
134 | |||
135 | if (fstat(fd,&buf) < 0) { | ||
136 | perror("[ERR] Checking filesize of input file"); | ||
137 | return -1; | ||
138 | } else { | ||
139 | return(buf.st_size); | ||
140 | } | ||
141 | } | ||
142 | #endif | ||
143 | |||
144 | |||
145 | int mknkboot(const struct filebuf *indata, const struct filebuf *bootdata, | ||
146 | struct filebuf *outdata) | ||
147 | { | ||
148 | int i; | ||
149 | unsigned char* boot; | ||
150 | unsigned char* boot2; | ||
151 | unsigned char* disable; | ||
152 | uint32_t sum; | ||
153 | |||
154 | /* Create buffer for original nk.bin, plus our bootloader (with 12 | ||
155 | byte header), plus the 16-byte "disable record", plus our dual-boot code */ | ||
156 | outdata->len = indata->len + (bootdata->len + 12) + 16 + (12 + 28); | ||
157 | outdata->buf = malloc(outdata->len); | ||
158 | |||
159 | if (outdata->buf==NULL) | ||
160 | { | ||
161 | printf("[ERR] Could not allocate memory, aborting\n"); | ||
162 | return -1; | ||
163 | } | ||
164 | |||
165 | /****** STEP 1 - Read original nk.bin into buffer */ | ||
166 | memcpy(outdata->buf, indata->buf, indata->len); | ||
167 | |||
168 | /****** STEP 2 - Move EOF record to the new EOF */ | ||
169 | memcpy(outdata->buf + outdata->len - 12, outdata->buf + indata->len - 12, 12); | ||
170 | |||
171 | /* Overwrite default entry point with NK_ENTRY_POINT */ | ||
172 | put_uint32le(NK_ENTRY_POINT, outdata->buf + outdata->len - 8); | ||
173 | |||
174 | /****** STEP 3 - Create a record to disable the firmware signature | ||
175 | check in EBoot */ | ||
176 | disable = outdata->buf + indata->len - 12; | ||
177 | |||
178 | put_uint32le(DISABLE_ADDR, disable); | ||
179 | put_uint32le(4, disable + 4); | ||
180 | put_uint32le(DISABLE_SUM, disable + 8); | ||
181 | put_uint32le(DISABLE_INSN, disable + 12); | ||
182 | |||
183 | /****** STEP 4 - Append the bootloader binary */ | ||
184 | boot = disable + 16; | ||
185 | memcpy(boot + 12, bootdata->buf, bootdata->len); | ||
186 | |||
187 | /****** STEP 5 - Create header for bootloader record */ | ||
188 | |||
189 | /* Calculate checksum */ | ||
190 | sum = 0; | ||
191 | for (i = 0; i < bootdata->len; i++) { | ||
192 | sum += boot[12 + i]; | ||
193 | } | ||
194 | |||
195 | put_uint32le(BL_ENTRY_POINT, boot); /* Our entry point */ | ||
196 | put_uint32le(bootdata->len, boot + 4); | ||
197 | put_uint32le(sum, boot + 8); | ||
198 | |||
199 | /****** STEP 6 - Insert our dual-boot code */ | ||
200 | boot2 = boot + bootdata->len + 12; | ||
201 | |||
202 | /* Copy dual-boot code in an endian-safe way */ | ||
203 | for (i = 0; i < (signed int)sizeof(dualboot) / 4; i++) { | ||
204 | put_uint32le(dualboot[i], boot2 + 12 + i*4); | ||
205 | } | ||
206 | |||
207 | /* Calculate checksum */ | ||
208 | sum = 0; | ||
209 | for (i = 0; i < (signed int)sizeof(dualboot); i++) { | ||
210 | sum += boot2[i+12]; | ||
211 | } | ||
212 | |||
213 | put_uint32le(NK_ENTRY_POINT, boot2); /* New entry point for our nk.bin */ | ||
214 | put_uint32le(sizeof(dualboot), boot2 + 4); | ||
215 | put_uint32le(sum, boot2 + 8); | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | #if !defined(BEASTPATCHER) | ||
221 | static void usage(void) | ||
222 | { | ||
223 | printf("Usage: mknkboot <firmware file> <boot file> <output file>\n"); | ||
224 | |||
225 | exit(1); | ||
226 | } | ||
227 | |||
228 | |||
229 | int main(int argc, char* argv[]) | ||
230 | { | ||
231 | char *infile, *bootfile, *outfile; | ||
232 | int fdin = -1, fdboot = -1, fdout = -1; | ||
233 | int n; | ||
234 | struct filebuf indata = {0, NULL}, bootdata = {0, NULL}, outdata = {0, NULL}; | ||
235 | int result = 0; | ||
236 | |||
237 | if(argc < 4) { | ||
238 | usage(); | ||
239 | } | ||
240 | |||
241 | infile = argv[1]; | ||
242 | bootfile = argv[2]; | ||
243 | outfile = argv[3]; | ||
244 | |||
245 | fdin = open(infile, O_RDONLY|O_BINARY); | ||
246 | if (fdin < 0) | ||
247 | { | ||
248 | perror(infile); | ||
249 | result = 2; | ||
250 | goto quit; | ||
251 | } | ||
252 | |||
253 | fdboot = open(bootfile, O_RDONLY|O_BINARY); | ||
254 | if (fdboot < 0) | ||
255 | { | ||
256 | perror(bootfile); | ||
257 | close(fdin); | ||
258 | result = 3; | ||
259 | goto quit; | ||
260 | } | ||
261 | |||
262 | indata.len = filesize(fdin); | ||
263 | bootdata.len = filesize(fdboot); | ||
264 | indata.buf = (unsigned char*)malloc(indata.len); | ||
265 | bootdata.buf = (unsigned char*)malloc(bootdata.len); | ||
266 | if(indata.buf == NULL || bootdata.buf == NULL) | ||
267 | { | ||
268 | printf("[ERR] Could not allocate memory, aborting\n"); | ||
269 | result = 4; | ||
270 | goto quit; | ||
271 | } | ||
272 | n = read(fdin, indata.buf, indata.len); | ||
273 | if (n != indata.len) | ||
274 | { | ||
275 | printf("[ERR] Could not read from %s\n",infile); | ||
276 | result = 5; | ||
277 | goto quit; | ||
278 | } | ||
279 | n = read(fdboot, bootdata.buf, bootdata.len); | ||
280 | if (n != bootdata.len) | ||
281 | { | ||
282 | printf("[ERR] Could not read from %s\n",bootfile); | ||
283 | result = 6; | ||
284 | goto quit; | ||
285 | } | ||
286 | |||
287 | result = mknkboot(&indata, &bootdata, &outdata); | ||
288 | if(result != 0) | ||
289 | { | ||
290 | goto quit; | ||
291 | } | ||
292 | fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644); | ||
293 | if (fdout < 0) | ||
294 | { | ||
295 | perror(outfile); | ||
296 | result = 7; | ||
297 | goto quit; | ||
298 | } | ||
299 | |||
300 | n = write(fdout, outdata.buf, outdata.len); | ||
301 | if (n != outdata.len) | ||
302 | { | ||
303 | printf("[ERR] Could not write output file %s\n",outfile); | ||
304 | result = 8; | ||
305 | goto quit; | ||
306 | } | ||
307 | |||
308 | quit: | ||
309 | free(bootdata.buf); | ||
310 | free(indata.buf); | ||
311 | free(outdata.buf); | ||
312 | close(fdin); | ||
313 | close(fdboot); | ||
314 | close(fdout); | ||
315 | |||
316 | return result; | ||
317 | |||
318 | } | ||
319 | #endif | ||
320 | |||