summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2012-06-07 14:49:14 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2012-06-07 14:49:14 +0200
commitc4911de1a086db288561f2875b5108bf79b2e23d (patch)
tree2af1449f21676914e270dc87bc9348619cb8bd7c
parent71f3255a0e73b6999580a8743c05731f7742bc14 (diff)
downloadrockbox-c4911de1a086db288561f2875b5108bf79b2e23d.tar.gz
rockbox-c4911de1a086db288561f2875b5108bf79b2e23d.zip
Initial commit from rknano utils. This is very preliminary work.
Change-Id: Iddc4b39a4611f12b9eefc3a96d7eeb7229777ebb
-rw-r--r--utils/rknanoutils/rkboottool/Makefile20
-rw-r--r--utils/rknanoutils/rkboottool/misc.c46
-rw-r--r--utils/rknanoutils/rkboottool/misc.h40
-rw-r--r--utils/rknanoutils/rkboottool/rkboottool.c290
4 files changed, 396 insertions, 0 deletions
diff --git a/utils/rknanoutils/rkboottool/Makefile b/utils/rknanoutils/rkboottool/Makefile
new file mode 100644
index 0000000000..5bfc40416e
--- /dev/null
+++ b/utils/rknanoutils/rkboottool/Makefile
@@ -0,0 +1,20 @@
1DEFINES=
2CC=gcc
3LD=gcc
4CFLAGS=-g -std=c99 -W -Wall $(DEFINES)
5LDFLAGS=
6BINS=rkboottool
7
8all: $(BINS)
9
10%.o: %.c
11 $(CC) $(CFLAGS) -c -o $@ $<
12
13rkboottool: rkboottool.o misc.o
14 $(LD) -o $@ $^ $(LDFLAGS)
15
16clean:
17 rm -fr *.o
18
19veryclean:
20 rm -rf $(BINS)
diff --git a/utils/rknanoutils/rkboottool/misc.c b/utils/rknanoutils/rkboottool/misc.c
new file mode 100644
index 0000000000..b8644b3bf8
--- /dev/null
+++ b/utils/rknanoutils/rkboottool/misc.c
@@ -0,0 +1,46 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
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 <stdlib.h>
22#include <stdio.h>
23#include <time.h>
24#include <ctype.h>
25#include "misc.h"
26
27char OFF[] = { 0x1b, 0x5b, 0x31, 0x3b, '0', '0', 0x6d, '\0' };
28
29char GREY[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '0', 0x6d, '\0' };
30char RED[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '1', 0x6d, '\0' };
31char GREEN[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '2', 0x6d, '\0' };
32char YELLOW[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '3', 0x6d, '\0' };
33char BLUE[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '4', 0x6d, '\0' };
34
35static bool g_color_enable = true;
36
37void enable_color(bool enable)
38{
39 g_color_enable = enable;
40}
41
42void color(color_t c)
43{
44 if(g_color_enable)
45 printf("%s", (char *)c);
46}
diff --git a/utils/rknanoutils/rkboottool/misc.h b/utils/rknanoutils/rkboottool/misc.h
new file mode 100644
index 0000000000..c4975c068c
--- /dev/null
+++ b/utils/rknanoutils/rkboottool/misc.h
@@ -0,0 +1,40 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __MISC_H__
22#define __MISC_H__
23
24#include <stdbool.h>
25
26#define _STR(a) #a
27#define STR(a) _STR(a)
28
29#define bug(...) do { fprintf(stderr,"["__FILE__":"STR(__LINE__)"]ERROR: "__VA_ARGS__); exit(1); } while(0)
30#define bugp(...) do { fprintf(stderr, __VA_ARGS__); perror(" "); exit(1); } while(0)
31
32#define ROUND_UP(val, round) ((((val) + (round) - 1) / (round)) * (round))
33
34typedef char color_t[];
35
36extern color_t OFF, GREY, RED, GREEN, YELLOW, BLUE;
37void color(color_t c);
38void enable_color(bool enable);
39
40#endif /* __MISC_H__ */
diff --git a/utils/rknanoutils/rkboottool/rkboottool.c b/utils/rknanoutils/rkboottool/rkboottool.c
new file mode 100644
index 0000000000..e41224065d
--- /dev/null
+++ b/utils/rknanoutils/rkboottool/rkboottool.c
@@ -0,0 +1,290 @@
1#include <stdio.h>
2#include <stdint.h>
3#include <stdbool.h>
4#include <stdlib.h>
5#include <string.h>
6#include "misc.h"
7
8#define cprintf(col, ...) do {printf("%s", col); printf(__VA_ARGS__); }while(0)
9
10typedef uint8_t packed_bcd_uint8_t;
11typedef uint16_t packed_bcd_uint16_t;
12
13struct rknano_date_t
14{
15 packed_bcd_uint16_t year;
16 packed_bcd_uint8_t mday;
17 packed_bcd_uint8_t month;
18};
19
20struct rknano_version_t
21{
22 packed_bcd_uint16_t major;
23 packed_bcd_uint16_t minor;
24 packed_bcd_uint16_t rev;
25};
26
27struct rknano_image_t
28{
29 uint16_t width;
30 uint16_t height;
31 uint8_t data[0];
32};
33
34struct rknano_blob_t
35{
36 uint32_t offset;
37 uint32_t size;
38};
39
40#define VENDOR_NAME_SIZE 32
41#define MODEL_NAME_SIZE 32
42#define MAX_NR_STAGES 4
43#define MAX_NR_FONTS 10
44#define MAX_NR_GBK 5
45#define MAX_NR_STRTBL 10
46#define MAX_NR_IMAGERES 10
47#define MAX_NR_UNK 10
48#define MAGIC_RKNANOFW "RKnanoFW"
49#define MAGIC_RKNANOFW_SIZE 8
50
51struct rknano_header_t
52{
53 struct rknano_date_t date;
54 struct rknano_version_t version;
55 uint8_t unk6[6];
56 char vendor[VENDOR_NAME_SIZE];
57 char model[MODEL_NAME_SIZE];
58 uint32_t nr_stages;
59 struct rknano_blob_t stage[MAX_NR_STAGES];
60 uint32_t nr_fonts;
61 struct rknano_blob_t font[MAX_NR_FONTS];
62 uint32_t nr_gbk;
63 struct rknano_blob_t gbk[MAX_NR_GBK];
64 uint32_t nr_strtbl;
65 struct rknano_blob_t strtbl[MAX_NR_STRTBL];
66 uint32_t nr_imageres;
67 struct rknano_blob_t imageres[MAX_NR_IMAGERES];
68 uint32_t nr_unk;
69 struct rknano_blob_t unk[MAX_NR_UNK];
70 uint32_t pad;
71 uint32_t size;
72 char magic[MAGIC_RKNANOFW_SIZE];
73};
74
75char *prefix = NULL;
76
77static void encode_page(uint8_t *inpg, uint8_t *outpg, const int size)
78{
79
80uint8_t key[] = {
81 0x7C, 0x4E, 0x03, 0x04,
82 0x55, 0x05, 0x09, 0x07,
83 0x2D, 0x2C, 0x7B, 0x38,
84 0x17, 0x0D, 0x17, 0x11
85};
86 int i, i3, x, val, idx;
87
88 uint8_t key1[0x100];
89 uint8_t key2[0x100];
90
91 for (i=0; i<0x100; i++) {
92 key1[i] = i;
93 key2[i] = key[i&0xf];
94 }
95
96 i3 = 0;
97 for (i=0; i<0x100; i++) {
98 x = key1[i];
99 i3 = key1[i] + i3;
100 i3 += key2[i];
101 i3 &= 0xff;
102 key1[i] = key1[i3];
103 key1[i3] = x;
104 }
105
106 idx = 0;
107 for (i=0; i<size; i++) {
108 x = key1[(i+1) & 0xff];
109 val = x;
110 idx = (x + idx) & 0xff;
111 key1[(i+1) & 0xff] = key1[idx];
112 key1[idx] = (x & 0xff);
113 val = (key1[(i+1)&0xff] + x) & 0xff;
114 val = key1[val];
115 outpg[i] = val ^ inpg[i];
116 }
117}
118
119static uint16_t crc(uint8_t *buf, int size)
120{
121 uint16_t result = 65535;
122 for(; size; buf++, size--)
123 {
124 for(int bit = 128; bit; bit >>= 1)
125 {
126 if(result & 0x80)
127 result = (2 * result) ^ 0x1021;
128 else
129 result *= 2;
130 if(*buf & bit)
131 result ^= 0x1021;
132 }
133 }
134 return result;
135}
136
137static void save_blob(const struct rknano_blob_t *b, void *buf, uint32_t size,
138 char *name, int suffix, bool descramble)
139{
140 if(prefix == NULL || b->size == 0 || b->offset + b->size > size)
141 return;
142 char *path = malloc(strlen(prefix) + strlen(name) + 32);
143 sprintf(path, "%s%s%d.bin", prefix, name, suffix);
144 FILE *f = fopen(path, "wb");
145 uint8_t *ptr = buf + b->offset;
146 if(descramble)
147 {
148 ptr = malloc(b->size);
149 encode_page(buf + b->offset, ptr, b->size);
150 }
151
152 if(f)
153 {
154 fwrite(ptr, b->size, 1, f);
155 fclose(f);
156 }
157
158 if(descramble)
159 free(ptr);
160}
161
162static void print_blob_interval(const struct rknano_blob_t *b)
163{
164 cprintf(YELLOW, "%#x -> %#x", b->offset, b->offset + b->size);
165}
166
167static int do_image(int argc, char **argv, uint8_t *buf, unsigned long size)
168{
169 (void) argc;
170 (void) argv;
171
172 if(size < sizeof(struct rknano_header_t))
173 return 1;
174 struct rknano_header_t *hdr = (void *)buf;
175 if(size < hdr->size)
176 return 1;
177
178 cprintf(BLUE, "Header\n");
179 cprintf(GREEN, " Date: ");
180 cprintf(YELLOW, "%x/%x/%x\n", hdr->date.mday, hdr->date.month, hdr->date.year);
181 cprintf(GREEN, " Version: ");
182 cprintf(YELLOW, "%x.%x.%x\n", hdr->version.major, hdr->version.minor, hdr->version.rev);
183 cprintf(GREEN, " Vendor: ");
184 cprintf(YELLOW, "%s\n", hdr->vendor);
185 cprintf(GREEN, " Model: ");
186 cprintf(YELLOW, "%s\n", hdr->model);
187 cprintf(GREEN, " Pad: ");
188 for(int i = 0; i < 6; i++)
189 cprintf(YELLOW, " %02x", hdr->unk6[i]);
190 cprintf(YELLOW, "\n");
191 cprintf(BLUE, "Stages\n");
192 for(unsigned i = 0; i < hdr->nr_stages; i++)
193 {
194 cprintf(GREEN, " %i: ", i);
195 print_blob_interval(&hdr->stage[i]);
196 cprintf(OFF, "\n");
197 save_blob(&hdr->stage[i], buf, size, "stage", i, false);
198 }
199 cprintf(BLUE, "Fonts\n");
200 for(unsigned i = 0; i < hdr->nr_fonts; i++)
201 {
202 cprintf(GREEN, " %i: ", i);
203 print_blob_interval(&hdr->font[i]);
204 cprintf(OFF, "\n");
205 save_blob(&hdr->font[i], buf, size, "font", i, false);
206 }
207 cprintf(BLUE, "GBK\n");
208 for(unsigned i = 0; i < hdr->nr_gbk; i++)
209 {
210 cprintf(GREEN, " %i: ", i);
211 print_blob_interval(&hdr->gbk[i]);
212 cprintf(OFF, "\n");
213 save_blob(&hdr->gbk[i], buf, size, "gbk", i, false);
214 }
215 cprintf(BLUE, "String Tables\n");
216 for(unsigned i = 0; i < hdr->nr_strtbl; i++)
217 {
218 cprintf(GREEN, " %i: ", i);
219 print_blob_interval(&hdr->strtbl[i]);
220 cprintf(OFF, "\n");
221 save_blob(&hdr->strtbl[i], buf, size, "strtbl", i, false);
222 }
223 cprintf(BLUE, "Image Resources\n");
224 for(unsigned i = 0; i < hdr->nr_imageres; i++)
225 {
226 cprintf(GREEN, " %i: ", i);
227 print_blob_interval(&hdr->imageres[i]);
228 cprintf(OFF, "\n");
229 save_blob(&hdr->imageres[i], buf, size, "imgres", i, false);
230 }
231 cprintf(BLUE, "Unknown\n");
232 for(unsigned i = 0; i < hdr->nr_unk; i++)
233 {
234 cprintf(GREEN, " %i: ", i);
235 print_blob_interval(&hdr->unk[i]);
236 cprintf(OFF, "\n");
237 save_blob(&hdr->unk[i], buf, size, "unk", i, false);
238 }
239 cprintf(BLUE, "Other\n");
240 cprintf(GREEN, " Size: ");
241 cprintf(YELLOW, "%#x\n", hdr->size);
242 cprintf(GREEN, " Magic: ");
243 cprintf(YELLOW, "%." STR(MAGIC_RKNANOFW_SIZE) "s ", hdr->magic);
244 if(strncmp(hdr->magic, MAGIC_RKNANOFW, MAGIC_RKNANOFW_SIZE) == 0)
245 cprintf(RED, "OK\n");
246 else
247 cprintf(RED, "Mismatch\n");
248
249 return 0;
250}
251
252static void usage(void)
253{
254 printf("Usage: rkboottool [options] rknanoboot.bin out_prefix\n");
255 exit(1);
256}
257
258int main(int argc, char **argv)
259{
260 if(argc < 3)
261 usage();
262 prefix = argv[argc - 1];
263 FILE *fin = fopen(argv[argc - 2], "r");
264 if(fin == NULL)
265 {
266 perror("Cannot open boot file");
267 return 1;
268 }
269 fseek(fin, 0, SEEK_END);
270 long size = ftell(fin);
271 fseek(fin, 0, SEEK_SET);
272
273 void *buf = malloc(size);
274 if(buf == NULL)
275 {
276 perror("Cannot allocate memory");
277 return 1;
278 }
279
280 if(fread(buf, size, 1, fin) != 1)
281 {
282 perror("Cannot read file");
283 return 1;
284 }
285
286 fclose(fin);
287
288 return do_image(argc - 1, argv, buf, size);
289}
290