summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2007-11-11 12:08:06 +0000
committerDave Chapman <dave@dchapman.com>2007-11-11 12:08:06 +0000
commitfe16efdd0c54ca63f8a380341edcda758c4573f7 (patch)
tree1ef21819abcc0ba3e3e94c9e02a073c2a6b76231
parentb9f62e991d5380d780e8462622d9fb863e903684 (diff)
downloadrockbox-fe16efdd0c54ca63f8a380341edcda758c4573f7.tar.gz
rockbox-fe16efdd0c54ca63f8a380341edcda758c4573f7.zip
Initial version of mknkboot - a utility to replace "merge0.cpp" to insert a Rockbox bootloader into a Gigabeat-S nk.bin firmware update image. This was rewritten from scratch, but has been tested to produce output files identical to merge0.cpp.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15570 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--tools/Makefile5
-rwxr-xr-xtools/configure2
-rw-r--r--tools/mknkboot.c210
3 files changed, 215 insertions, 2 deletions
diff --git a/tools/Makefile b/tools/Makefile
index f45c5df036..4b72b4c638 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -11,7 +11,7 @@ LDFLAGS := -g
11 11
12CLEANALL := scramble descramble iriver sh2d bmp2rb rdf2binary convbdf \ 12CLEANALL := scramble descramble iriver sh2d bmp2rb rdf2binary convbdf \
13 generate_rocklatin mkboot ipod_fw codepages uclpack mi4 gigabeat database \ 13 generate_rocklatin mkboot ipod_fw codepages uclpack mi4 gigabeat database \
14 lngdump telechips gigabeats mktccboot 14 lngdump telechips gigabeats mktccboot mknkboot
15 15
16all: 16all:
17 @echo "Run make in your build directory!" 17 @echo "Run make in your build directory!"
@@ -41,6 +41,9 @@ mkboot: mkboot.c
41mktccboot: mktccboot.c telechips.o 41mktccboot: mktccboot.c telechips.o
42 $(SILENT)$(CC) -g $+ -o $@ 42 $(SILENT)$(CC) -g $+ -o $@
43 43
44mknkboot: mknkboot.c
45 $(SILENT)$(CC) -g $+ -o $@
46
44lngdump: lngdump.c 47lngdump: lngdump.c
45 $(SILENT)$(CC) -g $+ -o $@ 48 $(SILENT)$(CC) -g $+ -o $@
46 49
diff --git a/tools/configure b/tools/configure
index f8150e8356..e3a69945e3 100755
--- a/tools/configure
+++ b/tools/configure
@@ -1283,7 +1283,7 @@ EOF
1283 flash="" 1283 flash=""
1284 plugins="" 1284 plugins=""
1285 swcodec="yes" 1285 swcodec="yes"
1286 toolset=$gigabeatbitmaptools 1286 toolset="$gigabeatbitmaptools mknkboot"
1287 boottool="$rootdir/tools/scramble -gigabeats" 1287 boottool="$rootdir/tools/scramble -gigabeats"
1288 bootoutput="nk.bin" 1288 bootoutput="nk.bin"
1289 # architecture, manufacturer and model for the target-tree build 1289 # architecture, manufacturer and model for the target-tree build
diff --git a/tools/mknkboot.c b/tools/mknkboot.c
new file mode 100644
index 0000000000..c5e89f6834
--- /dev/null
+++ b/tools/mknkboot.c
@@ -0,0 +1,210 @@
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 * All files in this archive are subject to the GNU General Public License.
15 * See the file COPYING in the source tree root for full license agreement.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <fcntl.h>
27#include <unistd.h>
28#include <inttypes.h>
29
30/*
31
32Description of nk.bin from
33
34http://www.xs4all.nl/~itsme/projects/xda/wince-flashfile-formats.html
35
36these files contain most information, several non-contigouos blocks
37may be present and an entrypoint in the code.
38
39 1. a 7 character signature "B000FF\n" ( that is with 3 zeroes, and
40 ending in a linefeed )
41 2. DWORD for image start
42 3. DWORD for image length
43 4. followd by several records of this format:
44 1. DWORD with address where this block is to be flashed to
45 2. DWORD with the length of this block
46 3. DWORD with the 32 bit checksum of this block, in perl:
47 unpack("%32C*", $data);
48 4. followed by <length> bytes of data
49 5. the last record has address ZERO, in the length the entrypoint
50 into the rom, and ZERO as checksum.
51
52
53NOTE: The Gigabeat-S nk.bin contains 171 records, plus the EOF record.
54
55mknkboot.c appends two images:
56
571) A "Disable" image which overwrites a word in the EBoot image
582) Our bootloader image, which has the same load address as nk.exe
59
60*/
61
62/* win32 compatibility */
63
64#ifndef O_BINARY
65#define O_BINARY 0
66#endif
67
68
69#define DISABLE_ADDR 0x88065A10 /* in EBoot */
70#define DISABLE_INSN 0xe3a00001
71#define DISABLE_SUM (0xe3+0xa0+0x00+0x01)
72
73static void put_uint32le(uint32_t x, unsigned char* p)
74{
75 p[0] = x & 0xff;
76 p[1] = (x >> 8) & 0xff;
77 p[2] = (x >> 16) & 0xff;
78 p[3] = (x >> 24) & 0xff;
79}
80
81static void usage(void)
82{
83 printf("Usage: mknkboot <firmware file> <boot file> <output file>\n");
84
85 exit(1);
86}
87
88static off_t filesize(int fd) {
89 struct stat buf;
90
91 if (fstat(fd,&buf) < 0) {
92 perror("[ERR] Checking filesize of input file");
93 return -1;
94 } else {
95 return(buf.st_size);
96 }
97}
98
99
100int main(int argc, char *argv[])
101{
102 char *infile, *bootfile, *outfile;
103 int fdin, fdboot,fdout;
104 int i,n;
105 int inlength,bootlength,newlength;
106 unsigned char* buf;
107 unsigned char* boot;
108 unsigned char* disable;
109 uint32_t sum;
110
111 if(argc < 3) {
112 usage();
113 }
114
115 infile = argv[1];
116 bootfile = argv[2];
117 outfile = argv[3];
118
119 fdin = open(infile, O_RDONLY|O_BINARY);
120 if (fdin < 0)
121 {
122 perror(infile);
123 }
124
125 fdboot = open(bootfile, O_RDONLY|O_BINARY);
126 if (fdboot < 0)
127 {
128 perror(bootfile);
129 }
130
131 inlength = filesize(fdin);
132
133 bootlength = filesize(fdboot);
134
135 /* Create buffer for original nk.bin, plus our bootloader (with 12
136 byte header), plus the 16-byte "disable record" */
137
138 newlength = inlength + (bootlength + 12) + 16;
139 buf = malloc(newlength);
140
141 if (buf==NULL)
142 {
143 printf("[ERR] Could not allocate memory, aborting\n");
144 return 1;
145 }
146
147 /****** STEP 1 - Read original nk.bin into buffer */
148
149 n = read(fdin, buf, inlength);
150 if (n != inlength)
151 {
152 printf("[ERR] Could not read from %s\n",infile);
153 return 2;
154 }
155
156 /****** STEP 2 - Move EOF record to the new EOF */
157 memcpy(buf + newlength - 12, buf + inlength - 12, 12);
158
159
160 /****** STEP 3 - Create a record to disable the firmware signature
161 check in EBoot */
162 disable = buf + inlength - 12;
163
164 put_uint32le(DISABLE_ADDR, disable);
165 put_uint32le(4, disable + 4);
166 put_uint32le(DISABLE_SUM, disable + 8);
167 put_uint32le(DISABLE_INSN, disable + 12);
168
169 /****** STEP 4 - Read the bootloader binary */
170 boot = disable + 16;
171 n = read(fdboot, boot + 12, bootlength);
172 if (n != bootlength)
173 {
174 printf("[ERR] Could not read from %s\n",bootfile);
175 return 3;
176 }
177
178 /****** STEP 5 - Create header for bootloader record */
179
180 /* Calculate simple checksum */
181 sum = 0;
182 for (i = 0; i < bootlength; i++) {
183 sum += boot[12 + i];
184 }
185
186 put_uint32le(0x88201000, boot); /* nk.exe start address */
187 put_uint32le(bootlength, boot + 4);
188 put_uint32le(sum, boot + 8);
189
190 /****** STEP 6 - Now write the output file */
191
192 fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
193 if (fdout < 0)
194 {
195 perror(outfile);
196 }
197
198 n = write(fdout, buf, newlength);
199 if (n != newlength)
200 {
201 printf("[ERR] Could not write output file %s\n",outfile);
202 return 3;
203 }
204
205 close(fdin);
206 close(fdboot);
207 close(fdout);
208
209 return 0;
210}