diff options
author | Dave Chapman <dave@dchapman.com> | 2007-11-11 12:08:06 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2007-11-11 12:08:06 +0000 |
commit | fe16efdd0c54ca63f8a380341edcda758c4573f7 (patch) | |
tree | 1ef21819abcc0ba3e3e94c9e02a073c2a6b76231 /tools | |
parent | b9f62e991d5380d780e8462622d9fb863e903684 (diff) | |
download | rockbox-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
Diffstat (limited to 'tools')
-rw-r--r-- | tools/Makefile | 5 | ||||
-rwxr-xr-x | tools/configure | 2 | ||||
-rw-r--r-- | tools/mknkboot.c | 210 |
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 | ||
12 | CLEANALL := scramble descramble iriver sh2d bmp2rb rdf2binary convbdf \ | 12 | CLEANALL := 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 | ||
16 | all: | 16 | all: |
17 | @echo "Run make in your build directory!" | 17 | @echo "Run make in your build directory!" |
@@ -41,6 +41,9 @@ mkboot: mkboot.c | |||
41 | mktccboot: mktccboot.c telechips.o | 41 | mktccboot: mktccboot.c telechips.o |
42 | $(SILENT)$(CC) -g $+ -o $@ | 42 | $(SILENT)$(CC) -g $+ -o $@ |
43 | 43 | ||
44 | mknkboot: mknkboot.c | ||
45 | $(SILENT)$(CC) -g $+ -o $@ | ||
46 | |||
44 | lngdump: lngdump.c | 47 | lngdump: 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 | |||
32 | Description of nk.bin from | ||
33 | |||
34 | http://www.xs4all.nl/~itsme/projects/xda/wince-flashfile-formats.html | ||
35 | |||
36 | these files contain most information, several non-contigouos blocks | ||
37 | may 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 | |||
53 | NOTE: The Gigabeat-S nk.bin contains 171 records, plus the EOF record. | ||
54 | |||
55 | mknkboot.c appends two images: | ||
56 | |||
57 | 1) A "Disable" image which overwrites a word in the EBoot image | ||
58 | 2) 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 | |||
73 | static 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 | |||
81 | static void usage(void) | ||
82 | { | ||
83 | printf("Usage: mknkboot <firmware file> <boot file> <output file>\n"); | ||
84 | |||
85 | exit(1); | ||
86 | } | ||
87 | |||
88 | static 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 | |||
100 | int 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 | } | ||