summaryrefslogtreecommitdiff
path: root/utils/rknanoutils/rkboottool/rkboottool.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/rknanoutils/rkboottool/rkboottool.c')
-rw-r--r--utils/rknanoutils/rkboottool/rkboottool.c290
1 files changed, 290 insertions, 0 deletions
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