summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Riebeling <Dominik.Riebeling@gmail.com>2009-09-19 21:29:08 +0000
committerDominik Riebeling <Dominik.Riebeling@gmail.com>2009-09-19 21:29:08 +0000
commitdad3f299936c08e8689a5db242a687fc2638002d (patch)
tree09a596137673bc1710f2a9134c05a3f921403866
parentd0b048e82d4dbb41302201f7b4b9c96d499312d9 (diff)
downloadrockbox-dad3f299936c08e8689a5db242a687fc2638002d.tar.gz
rockbox-dad3f299936c08e8689a5db242a687fc2638002d.zip
Split out file access from mknkboot handling.
- make main dualboot creation function work on buffers instead of files. This is to be used in beastpatcher and simplifies error handling a bit. - prepare for building with beastpatcher. - export dualboot creation function. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22740 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--tools/mknkboot.c186
-rw-r--r--tools/mknkboot.h49
2 files changed, 151 insertions, 84 deletions
diff --git a/tools/mknkboot.c b/tools/mknkboot.c
index 87372500e5..f17d1e9070 100644
--- a/tools/mknkboot.c
+++ b/tools/mknkboot.c
@@ -45,6 +45,8 @@
45#include <unistd.h> 45#include <unistd.h>
46#include <inttypes.h> 46#include <inttypes.h>
47 47
48#include "mknkboot.h"
49
48/* New entry point for nk.bin - where our dualboot code is inserted */ 50/* New entry point for nk.bin - where our dualboot code is inserted */
49#define NK_ENTRY_POINT 0x88200000 51#define NK_ENTRY_POINT 0x88200000
50 52
@@ -113,6 +115,7 @@ static uint32_t dualboot[] =
113 BL_ENTRY_POINT /* RB bootloader load address/entry point */ 115 BL_ENTRY_POINT /* RB bootloader load address/entry point */
114}; 116};
115 117
118
116static void put_uint32le(uint32_t x, unsigned char* p) 119static void put_uint32le(uint32_t x, unsigned char* p)
117{ 120{
118 p[0] = x & 0xff; 121 p[0] = x & 0xff;
@@ -121,13 +124,6 @@ static void put_uint32le(uint32_t x, unsigned char* p)
121 p[3] = (x >> 24) & 0xff; 124 p[3] = (x >> 24) & 0xff;
122} 125}
123 126
124static void usage(void)
125{
126 printf("Usage: mknkboot <firmware file> <boot file> <output file>\n");
127
128 exit(1);
129}
130
131static off_t filesize(int fd) { 127static off_t filesize(int fd) {
132 struct stat buf; 128 struct stat buf;
133 129
@@ -140,100 +136,62 @@ static off_t filesize(int fd) {
140} 136}
141 137
142 138
143int mknkboot(const char* infile, const char* bootfile, const char* outfile) 139int mknkboot(const struct filebuf *indata, const struct filebuf *bootdata,
140 struct filebuf *outdata)
144{ 141{
145 int fdin, fdboot = -1, fdout = -1; 142 int i;
146 int i,n;
147 int inlength,bootlength,newlength;
148 unsigned char* buf = NULL;
149 unsigned char* boot; 143 unsigned char* boot;
150 unsigned char* boot2; 144 unsigned char* boot2;
151 unsigned char* disable; 145 unsigned char* disable;
152 uint32_t sum; 146 uint32_t sum;
153 int result = 0;
154
155 fdin = open(infile, O_RDONLY|O_BINARY);
156 if (fdin < 0)
157 {
158 perror(infile);
159 result = 1;
160 goto quit;
161 }
162
163 fdboot = open(bootfile, O_RDONLY|O_BINARY);
164 if (fdboot < 0)
165 {
166 perror(bootfile);
167 close(fdin);
168 result = 2;
169 goto quit;
170 }
171
172 inlength = filesize(fdin);
173 bootlength = filesize(fdboot);
174 147
175 /* Create buffer for original nk.bin, plus our bootloader (with 12 148 /* Create buffer for original nk.bin, plus our bootloader (with 12
176 byte header), plus the 16-byte "disable record", plus our dual-boot code */ 149 byte header), plus the 16-byte "disable record", plus our dual-boot code */
150 outdata->len = indata->len + (bootdata->len + 12) + 16 + (12 + 28);
151 outdata->buf = malloc(outdata->len);
177 152
178 newlength = inlength + (bootlength + 12) + 16 + (12 + 28); 153 if (outdata->buf==NULL)
179 buf = malloc(newlength);
180
181 if (buf==NULL)
182 { 154 {
183 printf("[ERR] Could not allocate memory, aborting\n"); 155 printf("[ERR] Could not allocate memory, aborting\n");
184 result = 3; 156 return -1;
185 goto quit;
186 } 157 }
187 158
188 /****** STEP 1 - Read original nk.bin into buffer */ 159 /****** STEP 1 - Read original nk.bin into buffer */
189 160 memcpy(outdata->buf, indata->buf, indata->len);
190 n = read(fdin, buf, inlength);
191 if (n != inlength)
192 {
193 printf("[ERR] Could not read from %s\n",infile);
194 result = 4;
195 goto quit;
196 }
197 161
198 /****** STEP 2 - Move EOF record to the new EOF */ 162 /****** STEP 2 - Move EOF record to the new EOF */
199 memcpy(buf + newlength - 12, buf + inlength - 12, 12); 163 memcpy(outdata->buf + outdata->len - 12, outdata->buf + indata->len - 12, 12);
200 164
201 /* Overwrite default entry point with NK_ENTRY_POINT */ 165 /* Overwrite default entry point with NK_ENTRY_POINT */
202 put_uint32le(NK_ENTRY_POINT, buf + newlength - 8); 166 put_uint32le(NK_ENTRY_POINT, outdata->buf + outdata->len - 8);
203 167
204 /****** STEP 3 - Create a record to disable the firmware signature 168 /****** STEP 3 - Create a record to disable the firmware signature
205 check in EBoot */ 169 check in EBoot */
206 disable = buf + inlength - 12; 170 disable = outdata->buf + indata->len - 12;
207 171
208 put_uint32le(DISABLE_ADDR, disable); 172 put_uint32le(DISABLE_ADDR, disable);
209 put_uint32le(4, disable + 4); 173 put_uint32le(4, disable + 4);
210 put_uint32le(DISABLE_SUM, disable + 8); 174 put_uint32le(DISABLE_SUM, disable + 8);
211 put_uint32le(DISABLE_INSN, disable + 12); 175 put_uint32le(DISABLE_INSN, disable + 12);
212 176
213 /****** STEP 4 - Read the bootloader binary */ 177 /****** STEP 4 - Append the bootloader binary */
214 boot = disable + 16; 178 boot = disable + 16;
215 n = read(fdboot, boot + 12, bootlength); 179 memcpy(boot + 12, bootdata->buf, bootdata->len);
216 if (n != bootlength)
217 {
218 printf("[ERR] Could not read from %s\n",bootfile);
219 result = 5;
220 goto quit;
221 }
222 180
223 /****** STEP 5 - Create header for bootloader record */ 181 /****** STEP 5 - Create header for bootloader record */
224 182
225 /* Calculate checksum */ 183 /* Calculate checksum */
226 sum = 0; 184 sum = 0;
227 for (i = 0; i < bootlength; i++) { 185 for (i = 0; i < bootdata->len; i++) {
228 sum += boot[12 + i]; 186 sum += boot[12 + i];
229 } 187 }
230 188
231 put_uint32le(BL_ENTRY_POINT, boot); /* Our entry point */ 189 put_uint32le(BL_ENTRY_POINT, boot); /* Our entry point */
232 put_uint32le(bootlength, boot + 4); 190 put_uint32le(bootdata->len, boot + 4);
233 put_uint32le(sum, boot + 8); 191 put_uint32le(sum, boot + 8);
234 192
235 /****** STEP 6 - Insert our dual-boot code */ 193 /****** STEP 6 - Insert our dual-boot code */
236 boot2 = boot + bootlength + 12; 194 boot2 = boot + bootdata->len + 12;
237 195
238 /* Copy dual-boot code in an endian-safe way */ 196 /* Copy dual-boot code in an endian-safe way */
239 for (i = 0; i < (signed int)sizeof(dualboot) / 4; i++) { 197 for (i = 0; i < (signed int)sizeof(dualboot) / 4; i++) {
@@ -250,47 +208,107 @@ int mknkboot(const char* infile, const char* bootfile, const char* outfile)
250 put_uint32le(sizeof(dualboot), boot2 + 4); 208 put_uint32le(sizeof(dualboot), boot2 + 4);
251 put_uint32le(sum, boot2 + 8); 209 put_uint32le(sum, boot2 + 8);
252 210
253 /****** STEP 7 - Now write the output file */ 211 return 0;
212}
213
214#if !defined(BEASTPATCHER)
215static void usage(void)
216{
217 printf("Usage: mknkboot <firmware file> <boot file> <output file>\n");
218
219 exit(1);
220}
221
222
223int main(int argc, char* argv[])
224{
225 char *infile, *bootfile, *outfile;
226 int fdin = -1, fdboot = -1, fdout = -1;
227 int n;
228 struct filebuf indata = {0, NULL}, bootdata = {0, NULL}, outdata = {0, NULL};
229 int result = 0;
230
231 if(argc < 4) {
232 usage();
233 }
234
235 infile = argv[1];
236 bootfile = argv[2];
237 outfile = argv[3];
238
239 fdin = open(infile, O_RDONLY|O_BINARY);
240 if (fdin < 0)
241 {
242 perror(infile);
243 result = 2;
244 goto quit;
245 }
246
247 fdboot = open(bootfile, O_RDONLY|O_BINARY);
248 if (fdboot < 0)
249 {
250 perror(bootfile);
251 close(fdin);
252 result = 3;
253 goto quit;
254 }
255
256 indata.len = filesize(fdin);
257 bootdata.len = filesize(fdboot);
258 indata.buf = (unsigned char*)malloc(indata.len);
259 bootdata.buf = (unsigned char*)malloc(bootdata.len);
260 if(indata.buf == NULL || bootdata.buf == NULL)
261 {
262 printf("[ERR] Could not allocate memory, aborting\n");
263 result = 4;
264 goto quit;
265 }
266 n = read(fdin, indata.buf, indata.len);
267 if (n != indata.len)
268 {
269 printf("[ERR] Could not read from %s\n",infile);
270 result = 5;
271 goto quit;
272 }
273 n = read(fdboot, bootdata.buf, bootdata.len);
274 if (n != bootdata.len)
275 {
276 printf("[ERR] Could not read from %s\n",bootfile);
277 result = 6;
278 goto quit;
279 }
254 280
281 result = mknkboot(&indata, &bootdata, &outdata);
282 if(result != 0)
283 {
284 goto quit;
285 }
255 fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644); 286 fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
256 if (fdout < 0) 287 if (fdout < 0)
257 { 288 {
258 perror(outfile); 289 perror(outfile);
259 result = 6; 290 result = 7;
260 goto quit; 291 goto quit;
261 } 292 }
262 293
263 n = write(fdout, buf, newlength); 294 n = write(fdout, outdata.buf, outdata.len);
264 if (n != newlength) 295 if (n != outdata.len)
265 { 296 {
266 printf("[ERR] Could not write output file %s\n",outfile); 297 printf("[ERR] Could not write output file %s\n",outfile);
267 result = 7; 298 result = 8;
268 goto quit; 299 goto quit;
269 } 300 }
270 301
271quit: 302quit:
272 if(buf != NULL) 303 free(bootdata.buf);
273 free(buf); 304 free(indata.buf);
305 free(outdata.buf);
274 close(fdin); 306 close(fdin);
275 close(fdboot); 307 close(fdboot);
276 close(fdout); 308 close(fdout);
277
278 return result;
279}
280 309
281 310 return result;
282int main(int argc, char* argv[])
283{
284 char *infile, *bootfile, *outfile;
285 if(argc < 4) {
286 usage();
287 }
288
289 infile = argv[1];
290 bootfile = argv[2];
291 outfile = argv[3];
292
293 return mknkboot(infile, bootfile, outfile);
294 311
295} 312}
313#endif
296 314
diff --git a/tools/mknkboot.h b/tools/mknkboot.h
new file mode 100644
index 0000000000..0373421a17
--- /dev/null
+++ b/tools/mknkboot.h
@@ -0,0 +1,49 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Dave Chapman
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are
14 * met:
15 *
16 * * Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * * Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials provided
22 * with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 ****************************************************************************/
37
38#ifndef MKNKBOOT_H
39#define MKNKBOOT_H
40
41struct filebuf {
42 off_t len;
43 unsigned char* buf;
44};
45
46int mknkboot(const struct filebuf *indata, const struct filebuf *bootdata,
47 struct filebuf *outdata);
48#endif
49