summaryrefslogtreecommitdiff
path: root/utils/rk27utils/rkwtool
diff options
context:
space:
mode:
Diffstat (limited to 'utils/rk27utils/rkwtool')
-rw-r--r--utils/rk27utils/rkwtool/Makefile7
-rw-r--r--utils/rk27utils/rkwtool/main.c129
-rw-r--r--utils/rk27utils/rkwtool/rkw.c538
-rw-r--r--utils/rk27utils/rkwtool/rkw.h123
4 files changed, 797 insertions, 0 deletions
diff --git a/utils/rk27utils/rkwtool/Makefile b/utils/rk27utils/rkwtool/Makefile
new file mode 100644
index 0000000000..239733cb87
--- /dev/null
+++ b/utils/rk27utils/rkwtool/Makefile
@@ -0,0 +1,7 @@
1all: rkwtool
2
3rkwtool: rkw.c main.c
4 gcc -g -std=c99 -o $@ -W -Wall $^
5
6clean:
7 rm -fr rkwtool
diff --git a/utils/rk27utils/rkwtool/main.c b/utils/rk27utils/rkwtool/main.c
new file mode 100644
index 0000000000..dacfd9ffab
--- /dev/null
+++ b/utils/rk27utils/rkwtool/main.c
@@ -0,0 +1,129 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2014 by Marcin Bukat
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <getopt.h>
22#include <stdbool.h>
23#include <stddef.h>
24#include <stdio.h>
25#include "rkw.h"
26
27#define VERSION "v0.1"
28
29static void banner(void)
30{
31 printf("RKWtool " VERSION " (C) Marcin Bukat 2014\n");
32 printf("This is free software; see the source for copying conditions. There is NO\n");
33 printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
34}
35
36static void usage(char *name)
37{
38 banner();
39
40 printf("Usage: %s [-i] [-b] [-e] [-a] [-o prefix] file.rkw\n", name);
41 printf("-i\t\tprint info about RKW file\n");
42 printf("-b\t\textract nand bootloader images (s1.bin and s2.bin)\n");
43 printf("-e\t\textract firmware files stored in RKST section\n");
44 printf("-o prefix\twhen extracting firmware files put it there\n");
45 printf("-a\t\textract additional file(s) (usually Rock27Boot.bin)\n");
46 printf("-A\t\textract all data\n");
47 printf("file.rkw\tRKW file to be processed\n");
48}
49
50int main(int argc, char **argv)
51{
52 int opt;
53 struct rkw_info_t *rkw_info = NULL;
54 char *prefix = NULL;
55 bool info = false;
56 bool extract = false;
57 bool bootloader = false;
58 bool addfile = false;
59
60 while ((opt = getopt(argc, argv, "iebo:aA")) != -1)
61 {
62 switch (opt)
63 {
64 case 'i':
65 info = true;
66 break;
67
68 case 'e':
69 extract = true;
70 break;
71
72 case 'b':
73 bootloader = true;
74 break;
75
76 case 'o':
77 prefix = optarg;
78 break;
79
80 case 'a':
81 addfile = true;
82 break;
83
84 case 'A':
85 extract = true;
86 bootloader = true;
87 addfile = true;
88 break;
89
90 default:
91 usage(argv[0]);
92 break;
93 }
94 }
95
96 if ((argc - optind) != 1 ||
97 (!info && !extract && ! bootloader && !addfile))
98 {
99 usage(argv[0]);
100 return -1;
101 }
102
103 banner();
104
105 rkw_info = rkw_slurp(argv[optind]);
106
107 if (rkw_info)
108 {
109 if (info)
110 {
111 rkrs_list_named_items(rkw_info);
112 rkst_list_named_items(rkw_info);
113 }
114
115 if (extract)
116 unpack_rkst(rkw_info, prefix);
117
118 if (bootloader)
119 unpack_bootloader(rkw_info, prefix);
120
121 if (addfile)
122 unpack_addfile(rkw_info, prefix);
123
124 rkw_free(rkw_info);
125 return 0;
126 }
127
128 return -1;
129}
diff --git a/utils/rk27utils/rkwtool/rkw.c b/utils/rk27utils/rkwtool/rkw.c
new file mode 100644
index 0000000000..eacef87b8e
--- /dev/null
+++ b/utils/rk27utils/rkwtool/rkw.c
@@ -0,0 +1,538 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2014 by Marcin Bukat
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <stdio.h>
22#include <stdint.h>
23#include <stdbool.h>
24#include <stdlib.h>
25#include <string.h>
26#include <errno.h>
27#include <sys/stat.h>
28#include <sys/types.h>
29
30#include "rkw.h"
31
32const char *section_name[] = {
33 "RKLD",
34 "RKRS",
35 "RKST"
36};
37
38const uint32_t section_magic[] = {
39 RKLD_MAGIC,
40 RKRS_MAGIC,
41 RKST_MAGIC
42};
43
44const char *rkrs_action_name[] = {
45 [act_null] = "null",
46 [act_mkdir] = "mkdir",
47 [act_fcopy] = "fcopy",
48 [act_fsoper] = "fsoper",
49 [act_format] = "format",
50 [act_loader] = "loader",
51 [act_dispbmp] = "dispbmp",
52 [act_dispstr] = "dispstr",
53 [act_setfont] = "setfont",
54 [act_delay] = "delay",
55 [act_system] = "system",
56 [act_readme] = "readme",
57 [act_copyright] = "copyright",
58 [act_select] = "select",
59 [act_restart] = "restart",
60 [act_regkey] = "regkey",
61 [act_version] = "version",
62 [act_freplace] = "freplace",
63 [act_fpreplace] = "fpreplace",
64 [act_fsdel] = "fsdel",
65 [act_space] = "space",
66 [act_addfile] = "addfile",
67 [act_setmem] = "setmem",
68 [act_getmem] = "getmem"
69};
70
71/* scrambling/descrambling reverse engineered by AleMaxx */
72static void encode_page(uint8_t *inpg, uint8_t *outpg, const int size)
73{
74
75uint8_t key[] = {
76 0x7C, 0x4E, 0x03, 0x04,
77 0x55, 0x05, 0x09, 0x07,
78 0x2D, 0x2C, 0x7B, 0x38,
79 0x17, 0x0D, 0x17, 0x11
80};
81 int i, i3, x, val, idx;
82
83 uint8_t key1[0x100];
84 uint8_t key2[0x100];
85
86 for (i=0; i<0x100; i++) {
87 key1[i] = i;
88 key2[i] = key[i&0xf];
89 }
90
91 i3 = 0;
92 for (i=0; i<0x100; i++) {
93 x = key1[i];
94 i3 = key1[i] + i3;
95 i3 += key2[i];
96 i3 &= 0xff;
97 key1[i] = key1[i3];
98 key1[i3] = x;
99 }
100
101 idx = 0;
102 for (i=0; i<size; i++) {
103 x = key1[(i+1) & 0xff];
104 val = x;
105 idx = (x + idx) & 0xff;
106 key1[(i+1) & 0xff] = key1[idx];
107 key1[idx] = (x & 0xff);
108 val = (key1[(i+1)&0xff] + x) & 0xff;
109 val = key1[val];
110 outpg[i] = val ^ inpg[i];
111 }
112}
113
114/* take path as stored in RKST and convert it to unix path
115 * with optional prefix
116 */
117static char *unixpath(char *path, char *prefix)
118{
119 char *parsed, *ptr;
120 size_t size = 0;
121
122 if (NULL == path)
123 return NULL;
124
125 size = strlen(path) + 1;
126
127 /* full windows path i.e C:\something */
128 if (strlen(path) > 2 && ':' == path[1])
129 path += 3;
130
131 if (prefix)
132 {
133 /* account for '/' after prefix */
134 size += strlen(prefix) + 1;
135 }
136
137 /* allocate buffer */
138 parsed = malloc(size);
139 ptr = parsed;
140
141 /* malloc failed */
142 if (NULL == ptr)
143 return NULL;
144
145 /* copy prefix */
146 if (prefix)
147 {
148 strcpy(ptr, prefix);
149 ptr += strlen(prefix);
150 *ptr++ = '/';
151 }
152
153 do
154 {
155 if (*path == '\\')
156 *ptr = '/';
157 else
158 *ptr = *path;
159
160 ptr++;
161 } while ('\0' != *(path++));
162
163 return parsed;
164}
165
166/* returns pointer to the rkrs header in rkw file */
167static char *find_section(struct rkw_info_t *rkw_info, enum section_type_t type)
168{
169 char *ptr;
170 struct section_header_t *h;
171
172 switch(type)
173 {
174 case ST_RKRS:
175 case ST_RKST:
176 for (ptr=(char *)rkw_info->rkw; ptr<(char *)rkw_info->rkw+rkw_info->size; ptr++)
177 {
178 h = (struct section_header_t *)ptr;
179 if (h->magic == section_magic[type] &&
180 h->size == sizeof(struct section_header_t) &&
181 h->number_of_named_entries != 0)
182 {
183 fprintf(stderr, "[info]: %s found at 0x%0x\n",
184 section_name[type], (int)(ptr - rkw_info->rkw));
185
186 return ptr;
187 }
188 }
189 break;
190
191 default:
192 fprintf(stderr, "[error]: Not supported section type %d\n", type);
193 return NULL;
194 }
195 return NULL;
196}
197
198/* load rkw file into memory and setup pointers to various sections */
199struct rkw_info_t *rkw_slurp(char *filename)
200{
201 FILE *fp;
202 struct rkw_info_t *rkw_info;
203
204 rkw_info = (struct rkw_info_t *)malloc(sizeof(struct rkw_info_t));
205
206 if (NULL == rkw_info)
207 {
208 fprintf(stderr, "[error]: Can't allocate %ld bytes of memory\n",
209 sizeof(struct rkw_info_t));
210
211 return NULL;
212 }
213
214 fp = fopen(filename, "rb");
215
216 if (NULL == fp)
217 {
218 fprintf(stderr, "[error]: Can't open %s\n", filename);
219 free(rkw_info);
220 return NULL;
221 }
222
223 fseek(fp, 0, SEEK_END);
224 rkw_info->size = ftell(fp);
225 fseek(fp, 0, SEEK_SET);
226
227 rkw_info->rkw = (char *)malloc(rkw_info->size);
228
229 if (NULL == rkw_info->rkw)
230 {
231 fprintf(stderr, "[error]: Can't allocate %ld bytes of memory\n",
232 rkw_info->size);
233
234 free(rkw_info);
235 fclose(fp);
236 return NULL;
237 }
238
239 if (fread(rkw_info->rkw, rkw_info->size, 1, fp) != 1)
240 {
241 fprintf(stderr, "[error]: Can't read %s\n", filename);
242 free(rkw_info);
243 fclose(fp);
244 return NULL;
245 }
246
247 rkw_info->rkrs_info.header = find_section(rkw_info, ST_RKRS);
248 rkw_info->rkrs_info.items = rkw_info->rkrs_info.header +
249 ((struct section_header_t *)
250 (rkw_info->rkrs_info.header))->offset_of_named_entries;
251
252 rkw_info->rkst_info.header = find_section(rkw_info, ST_RKST);
253 rkw_info->rkst_info.items = rkw_info->rkst_info.header +
254 ((struct section_header_t *)
255 (rkw_info->rkst_info.header))->offset_of_named_entries;
256
257 fclose(fp);
258 return rkw_info;
259}
260
261void rkw_free(struct rkw_info_t *rkw_info)
262{
263 free(rkw_info->rkw);
264 free(rkw_info);
265}
266
267static void rkrs_named_item_info(struct rkrs_named_t *item)
268{
269 fprintf(stderr, "[info]: size=0x%0x (%d)\n", item->size, item->size);
270 fprintf(stderr, "[info]: type=0x%0x (%d) %s\n", item->type, item->type, rkrs_action_name[item->type]);
271 fprintf(stderr, "[info]: data_offset=0x%0x (%d)\n", item->data_offset, item->data_offset);
272 fprintf(stderr, "[info]: data_size=0x%0x (%d)\n", item->data_size, item->data_size);
273 fprintf(stderr, "[info]: param[0]=0x%0x (%d)\n", item->param[0], item->param[0]);
274 fprintf(stderr, "[info]: param[1]=0x%0x (%d)\n", item->param[1], item->param[1]);
275 fprintf(stderr, "[info]: param[2]=0x%0x (%d)\n", item->param[2], item->param[2]);
276 fprintf(stderr, "[info]: param[3]=0x%0x (%d)\n", item->param[3], item->param[3]);
277}
278
279static void rkst_named_item_info(struct rkst_named_t *item)
280{
281 fprintf(stderr, "[info]: size=0x%0x (%d)\n", item->size, item->size);
282 fprintf(stderr, "[info]: action=0x%0x (%d) %s\n", item->action, item->action, rkrs_action_name[item->action]);
283 fprintf(stderr, "[info]: data_offset=0x%0x (%d)\n", item->data_offset, item->data_offset);
284 fprintf(stderr, "[info]: data_size=0x%0x (%d)\n", item->data_size, item->data_size);
285 fprintf(stderr, "[info]: name=\"%s\"\n", &item->name);
286}
287
288static struct rkrs_named_t *find_item(struct rkw_info_t *rkw_info, enum rkst_action_t type, bool search_start)
289{
290 static struct rkrs_named_t *item;
291
292 if (search_start)
293 {
294 item = (struct rkrs_named_t *)rkw_info->rkrs_info.items;
295 }
296 else
297 {
298 if (item)
299 item++;
300 else
301 return NULL;
302 }
303
304 while (item->size > 0)
305 {
306 if (item->type == type)
307 {
308 fprintf(stderr, "[info]: Item type=%d found at 0x%x\n", type,
309 (int)((char *)item - rkw_info->rkw));
310 return item;
311 }
312 item++;
313 }
314
315 return NULL;
316}
317
318void rkrs_list_named_items(struct rkw_info_t *rkw_info)
319{
320 struct rkrs_named_t *item = (struct rkrs_named_t *)rkw_info->rkrs_info.items;
321 struct section_header_t *rkrs_header = (struct section_header_t *)(rkw_info->rkrs_info.header);
322 int i;
323
324 for (i=0; i<rkrs_header->number_of_named_entries; i++)
325 {
326 fprintf(stderr, "[info]: rkrs named entry %d\n", i);
327 rkrs_named_item_info(item++);
328 fprintf(stderr, "\n");
329 }
330}
331
332void rkst_list_named_items(struct rkw_info_t *rkw_info)
333{
334 struct rkst_named_t *item = (struct rkst_named_t *)rkw_info->rkst_info.items;
335 struct section_header_t *rkst_header = (struct section_header_t *)(rkw_info->rkst_info.header);
336 int i;
337
338 for (i=0; i<rkst_header->number_of_named_entries; i++)
339 {
340 fprintf(stderr, "[info]: rkst named entry %d\n", i);
341 rkst_named_item_info(item);
342 item = (struct rkst_named_t *)((char *)item + item->size);
343 fprintf(stderr, "\n");
344 }
345}
346
347void unpack_bootloader(struct rkw_info_t *rkw_info, char *prefix)
348{
349 FILE *fp;
350 char *ptr;
351 size_t size;
352 int len;
353 char *buf;
354 struct rkrs_named_t *item = find_item(rkw_info, act_loader, true);
355
356 if (NULL == item)
357 {
358 fprintf(stderr, "[error]: Can't find nand bootloader\n");
359 return;
360 }
361
362 ptr = (char *)(rkw_info->rkrs_info.header) + item->data_offset;
363 size = item->param[0];
364 buf = malloc(size);
365
366 if (NULL == buf)
367 {
368 fprintf(stderr, "[error]: Can't allocate %ld bytes of memory\n",
369 size);
370 return;
371 }
372
373 /* make a copy for decryption */
374 memcpy(buf, ptr, size);
375 encode_page((uint8_t *)buf, (uint8_t *)buf, size);
376 fp = fopen(unixpath("s1.bin", prefix), "w");
377
378 if (NULL == fp)
379 {
380 fprintf(stderr, "[error]: Can't open s1.bin for writing\n");
381 free(buf);
382 return;
383 }
384
385 if (fwrite(buf, size, 1, fp) != 1)
386 {
387 fprintf(stderr, "[error]: Can't write s1.bin file\n");
388 free(buf);
389 fclose(fp);
390 return;
391 }
392
393 fclose(fp);
394
395 ptr = (char *)(rkw_info->rkrs_info.header) + item->param[1];
396 size = item->param[2];
397 len = size;
398 buf = realloc(buf, size);
399
400 if (NULL == buf)
401 {
402 fprintf(stderr, "[error]: Can't allocate %ld bytes of memory\n",
403 size);
404
405 free(buf);
406 return;
407 }
408
409 memcpy(buf, ptr, size);
410 ptr = buf;
411
412 while (len >= 0x200)
413 {
414 encode_page((uint8_t *)ptr, (uint8_t *)ptr, 0x200);
415 ptr += 0x200;
416 len -= 0x200;
417 }
418 encode_page((uint8_t *)ptr, (uint8_t *)ptr, len);
419
420 fp = fopen(unixpath("s2.bin", prefix), "w");
421
422 if (NULL == fp)
423 {
424 fprintf(stderr, "[error]: Can't open s2.bin for writing\n");
425 free(buf);
426 return;
427 }
428
429 if (fwrite(buf, size, 1, fp) != 1)
430 {
431 fprintf(stderr, "[error]: Can't write s2.bin file\n");
432 free(buf);
433 fclose(fp);
434 return;
435 }
436
437 fclose(fp);
438 free(buf);
439 fprintf(stderr, "[info]: Extracted bootloader version: %x.%x\n",
440 (item->param[3] >> 8) & 0xff, item->param[3] & 0xff);
441}
442
443void unpack_addfile(struct rkw_info_t *rkw_info, char *prefix)
444{
445 FILE *fp;
446 char *name;
447 int name_len;
448
449 struct rkrs_named_t *item = find_item(rkw_info, act_addfile, true);
450
451 do
452 {
453 name = unixpath(rkw_info->rkrs_info.header + item->data_offset, prefix);
454 name_len = item->param[0];
455
456 fprintf(stderr, "[info]: unpacking addfile %s\n", name);
457
458 fp = fopen(name, "w");
459
460 if (NULL == fp)
461 {
462 fprintf(stderr, "[error]: Can't open %s for writing\n", name);
463 return;
464 }
465
466 if (fwrite(rkw_info->rkrs_info.header + item->data_offset + name_len,
467 item->data_size - name_len, 1, fp) != 1)
468 {
469 fprintf(stderr, "[error]: Can't write %s file\n", name);
470 fclose(fp);
471 return;
472 }
473
474 fclose(fp);
475 } while (NULL != (item = find_item(rkw_info, act_addfile, false)));
476}
477
478/* unpack content of RKST section
479 * this mimics what is done when processing 'fsoper' field of RKRS
480 */
481void unpack_rkst(struct rkw_info_t *rkw_info, char *prefix)
482{
483 FILE *fp;
484 struct rkst_named_t *item = (struct rkst_named_t *)rkw_info->rkst_info.items;
485 struct section_header_t *rkst_header = (struct section_header_t *)(rkw_info->rkst_info.header);
486 char *name;
487 int i;
488
489 if (prefix)
490 {
491 if (0 != mkdir(prefix, 0755))
492 {
493 fprintf(stderr, "[error]: Can't create %s directory (%s)\n",
494 prefix, strerror(errno));
495 return;
496 }
497 }
498
499 fprintf(stderr, "[info]: Unpacking content of RKST section\n");
500
501 for (i=0; i<rkst_header->number_of_named_entries; i++)
502 {
503 name = unixpath((char *)&(item->name), prefix);
504
505 switch (item->action)
506 {
507 case act_mkdir:
508 if (0 != mkdir(name, 0755))
509 {
510 fprintf(stderr, "[error]: Can't create %s directory (%s)\n",
511 name, strerror(errno));
512 return;
513 }
514 fprintf(stderr, "[info]: mkdir %s\n", name);
515 break;
516
517 case act_fcopy:
518 fp = fopen(name, "w");
519 if (NULL == fp)
520 {
521 fprintf(stderr, "[error]: Can't open %s for writing (%s)\n",
522 name, strerror(errno));
523 return;
524 }
525
526 fwrite((char *)rkst_header + item->data_offset, item->data_size, 1, fp);
527 fprintf(stderr, "[info]: unpack %s\n", name);
528 fclose(fp);
529 break;
530
531 default:
532 break;
533 }
534
535 if (name) free(name);
536 item = (struct rkst_named_t *)((char *)item + item->size);
537 }
538}
diff --git a/utils/rk27utils/rkwtool/rkw.h b/utils/rk27utils/rkwtool/rkw.h
new file mode 100644
index 0000000000..eba673c974
--- /dev/null
+++ b/utils/rk27utils/rkwtool/rkw.h
@@ -0,0 +1,123 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2014 by Marcin Bukat
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <stdint.h>
22
23#define RKLD_MAGIC 0x4C44524B
24#define RKRS_MAGIC 0x53524B52
25#define RKST_MAGIC 0X53544B52
26
27enum section_type_t {
28 ST_RKLD,
29 ST_RKRS,
30 ST_RKST
31};
32
33enum rkst_action_t {
34 act_null = 0,
35 act_mkdir = 1,
36 act_fcopy = 2,
37 act_fsoper = 3,
38 act_format = 4,
39 act_loader = 5,
40
41 act_dispbmp = 10,
42 act_dispstr = 11,
43 act_setfont = 12,
44
45 act_delay = 20,
46
47 act_system = 100,
48 act_uilogo = 100,
49 act_readme = 101,
50 act_copyright = 102,
51 act_select = 103,
52 act_restart = 104,
53
54 act_regkey = 120,
55 act_version = 121,
56
57 act_freplace = 130,
58 act_fpreplace = 131,
59 act_fsdel = 132,
60
61 act_space = 200,
62
63 act_addfile = 300,
64
65 act_setmem = 1000,
66 act_getmem = 1001,
67};
68
69struct section_header_t {
70 uint32_t size;
71 uint32_t magic;
72 uint32_t property;
73 uint32_t timestamp;
74 uint32_t allign;
75 uint32_t file_size;
76 uint16_t size_of_name_dir;
77 uint16_t size_of_id_dir;
78 uint16_t number_of_named_entries;
79 uint16_t number_of_id_entries;
80 uint32_t offset_of_named_entries;
81 uint32_t offset_of_id_entries;
82} __attribute__((__packed__));
83
84struct rkrs_named_t {
85 uint32_t size;
86 uint32_t type;
87 uint32_t data_offset;
88 uint32_t data_size;
89 uint32_t param[4];
90} __attribute__((__packed__));
91
92struct rkst_named_t {
93 uint32_t size;
94 uint32_t action;
95 uint32_t data_offset;
96 uint32_t data_size;
97 uint8_t name;
98};
99
100struct section_info_t {
101 char *header;
102 char *items;
103};
104
105struct rkw_info_t {
106 char *rkw;
107 long size;
108 struct section_info_t rkrs_info;
109 struct section_info_t rkst_info;
110};
111
112/* general functions */
113struct rkw_info_t *rkw_slurp(char *filename);
114void rkw_free(struct rkw_info_t *rkw_info);
115
116/* info functions */
117void rkrs_list_named_items(struct rkw_info_t *rkw_info);
118void rkst_list_named_items(struct rkw_info_t *rkw_info);
119
120/* extract functions */
121void unpack_bootloader(struct rkw_info_t *rkw_info, char *prefix);
122void unpack_rkst(struct rkw_info_t *rkw_info, char *prefix);
123void unpack_addfile(struct rkw_info_t *rkw_info, char *prefix);