summaryrefslogtreecommitdiff
path: root/utils/rknanoutils
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 /utils/rknanoutils
parent71f3255a0e73b6999580a8743c05731f7742bc14 (diff)
Initial commit from rknano utils. This is very preliminary work.
Change-Id: Iddc4b39a4611f12b9eefc3a96d7eeb7229777ebb
Diffstat (limited to 'utils/rknanoutils')
-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 @@
+DEFINES=
+CC=gcc
+LD=gcc
+CFLAGS=-g -std=c99 -W -Wall $(DEFINES)
+LDFLAGS=
+BINS=rkboottool
+
+all: $(BINS)
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+rkboottool: rkboottool.o misc.o
+ $(LD) -o $@ $^ $(LDFLAGS)
+
+clean:
+ rm -fr *.o
+
+veryclean:
+ 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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <ctype.h>
+#include "misc.h"
+
+char OFF[] = { 0x1b, 0x5b, 0x31, 0x3b, '0', '0', 0x6d, '\0' };
+
+char GREY[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '0', 0x6d, '\0' };
+char RED[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '1', 0x6d, '\0' };
+char GREEN[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '2', 0x6d, '\0' };
+char YELLOW[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '3', 0x6d, '\0' };
+char BLUE[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '4', 0x6d, '\0' };
+
+static bool g_color_enable = true;
+
+void enable_color(bool enable)
+{
+ g_color_enable = enable;
+}
+
+void color(color_t c)
+{
+ if(g_color_enable)
+ printf("%s", (char *)c);
+}
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef __MISC_H__
+#define __MISC_H__
+
+#include <stdbool.h>
+
+#define _STR(a) #a
+#define STR(a) _STR(a)
+
+#define bug(...) do { fprintf(stderr,"["__FILE__":"STR(__LINE__)"]ERROR: "__VA_ARGS__); exit(1); } while(0)
+#define bugp(...) do { fprintf(stderr, __VA_ARGS__); perror(" "); exit(1); } while(0)
+
+#define ROUND_UP(val, round) ((((val) + (round) - 1) / (round)) * (round))
+
+typedef char color_t[];
+
+extern color_t OFF, GREY, RED, GREEN, YELLOW, BLUE;
+void color(color_t c);
+void enable_color(bool enable);
+
+#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 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include "misc.h"
+
+#define cprintf(col, ...) do {printf("%s", col); printf(__VA_ARGS__); }while(0)
+
+typedef uint8_t packed_bcd_uint8_t;
+typedef uint16_t packed_bcd_uint16_t;
+
+struct rknano_date_t
+{
+ packed_bcd_uint16_t year;
+ packed_bcd_uint8_t mday;
+ packed_bcd_uint8_t month;
+};
+
+struct rknano_version_t
+{
+ packed_bcd_uint16_t major;
+ packed_bcd_uint16_t minor;
+ packed_bcd_uint16_t rev;
+};
+
+struct rknano_image_t
+{
+ uint16_t width;
+ uint16_t height;
+ uint8_t data[0];
+};
+
+struct rknano_blob_t
+{
+ uint32_t offset;
+ uint32_t size;
+};
+
+#define VENDOR_NAME_SIZE 32
+#define MODEL_NAME_SIZE 32
+#define MAX_NR_STAGES 4
+#define MAX_NR_FONTS 10
+#define MAX_NR_GBK 5
+#define MAX_NR_STRTBL 10
+#define MAX_NR_IMAGERES 10
+#define MAX_NR_UNK 10
+#define MAGIC_RKNANOFW "RKnanoFW"
+#define MAGIC_RKNANOFW_SIZE 8
+
+struct rknano_header_t
+{
+ struct rknano_date_t date;
+ struct rknano_version_t version;
+ uint8_t unk6[6];
+ char vendor[VENDOR_NAME_SIZE];
+ char model[MODEL_NAME_SIZE];
+ uint32_t nr_stages;
+ struct rknano_blob_t stage[MAX_NR_STAGES];
+ uint32_t nr_fonts;
+ struct rknano_blob_t font[MAX_NR_FONTS];
+ uint32_t nr_gbk;
+ struct rknano_blob_t gbk[MAX_NR_GBK];
+ uint32_t nr_strtbl;
+ struct rknano_blob_t strtbl[MAX_NR_STRTBL];
+ uint32_t nr_imageres;
+ struct rknano_blob_t imageres[MAX_NR_IMAGERES];
+ uint32_t nr_unk;
+ struct rknano_blob_t unk[MAX_NR_UNK];
+ uint32_t pad;
+ uint32_t size;
+ char magic[MAGIC_RKNANOFW_SIZE];
+};
+
+char *prefix = NULL;
+
+static void encode_page(uint8_t *inpg, uint8_t *outpg, const int size)
+{
+
+uint8_t key[] = {
+ 0x7C, 0x4E, 0x03, 0x04,
+ 0x55, 0x05, 0x09, 0x07,
+ 0x2D, 0x2C, 0x7B, 0x38,
+ 0x17, 0x0D, 0x17, 0x11
+};
+ int i, i3, x, val, idx;
+
+ uint8_t key1[0x100];
+ uint8_t key2[0x100];
+
+ for (i=0; i<0x100; i++) {
+ key1[i] = i;
+ key2[i] = key[i&0xf];
+ }
+
+ i3 = 0;
+ for (i=0; i<0x100; i++) {
+ x = key1[i];
+ i3 = key1[i] + i3;
+ i3 += key2[i];
+ i3 &= 0xff;
+ key1[i] = key1[i3];
+ key1[i3] = x;
+ }
+
+ idx = 0;
+ for (i=0; i<size; i++) {
+ x = key1[(i+1) & 0xff];
+ val = x;
+ idx = (x + idx) & 0xff;
+ key1[(i+1) & 0xff] = key1[idx];
+ key1[idx] = (x & 0xff);
+ val = (key1[(i+1)&0xff] + x) & 0xff;
+ val = key1[val];
+ outpg[i] = val ^ inpg[i];
+ }
+}
+
+static uint16_t crc(uint8_t *buf, int size)
+{
+ uint16_t result = 65535;
+ for(; size; buf++, size--)
+ {
+ for(int bit = 128; bit; bit >>= 1)
+ {
+ if(result & 0x80)
+ result = (2 * result) ^ 0x1021;
+ else
+ result *= 2;
+ if(*buf & bit)
+ result ^= 0x1021;
+ }
+ }
+ return result;
+}
+
+static void save_blob(const struct rknano_blob_t *b, void *buf, uint32_t size,
+ char *name, int suffix, bool descramble)
+{
+ if(prefix == NULL || b->size == 0 || b->offset + b->size > size)
+ return;
+ char *path = malloc(strlen(prefix) + strlen(name) + 32);
+ sprintf(path, "%s%s%d.bin", prefix, name, suffix);
+ FILE *f = fopen(path, "wb");
+ uint8_t *ptr = buf + b->offset;
+ if(descramble)
+ {
+ ptr = malloc(b->size);
+ encode_page(buf + b->offset, ptr, b->size);
+ }
+
+ if(f)
+ {
+ fwrite(ptr, b->size, 1, f);
+ fclose(f);
+ }
+
+ if(descramble)
+ free(ptr);
+}
+
+static void print_blob_interval(const struct rknano_blob_t *b)
+{
+ cprintf(YELLOW, "%#x -> %#x", b->offset, b->offset + b->size);
+}
+
+static int do_image(int argc, char **argv, uint8_t *buf, unsigned long size)
+{
+ (void) argc;
+ (void) argv;
+
+ if(size < sizeof(struct rknano_header_t))
+ return 1;
+ struct rknano_header_t *hdr = (void *)buf;
+ if(size < hdr->size)
+ return 1;
+
+ cprintf(BLUE, "Header\n");
+ cprintf(GREEN, " Date: ");
+ cprintf(YELLOW, "%x/%x/%x\n", hdr->date.mday, hdr->date.month, hdr->date.year);
+ cprintf(GREEN, " Version: ");
+ cprintf(YELLOW, "%x.%x.%x\n", hdr->version.major, hdr->version.minor, hdr->version.rev);
+ cprintf(GREEN, " Vendor: ");
+ cprintf(YELLOW, "%s\n", hdr->vendor);
+ cprintf(GREEN, " Model: ");
+ cprintf(YELLOW, "%s\n", hdr->model);
+ cprintf(GREEN, " Pad: ");
+ for(int i = 0; i < 6; i++)
+ cprintf(YELLOW, " %02x", hdr->unk6[i]);
+ cprintf(YELLOW, "\n");
+ cprintf(BLUE, "Stages\n");
+ for(unsigned i = 0; i < hdr->nr_stages; i++)
+ {
+ cprintf(GREEN, " %i: ", i);
+ print_blob_interval(&hdr->stage[i]);
+ cprintf(OFF, "\n");
+ save_blob(&hdr->stage[i], buf, size, "stage", i, false);
+ }
+ cprintf(BLUE, "Fonts\n");
+ for(unsigned i = 0; i < hdr->nr_fonts; i++)
+ {
+ cprintf(GREEN, " %i: ", i);
+ print_blob_interval(&hdr->font[i]);
+ cprintf(OFF, "\n");
+ save_blob(&hdr->font[i], buf, size, "font", i, false);
+ }
+ cprintf(BLUE, "GBK\n");
+ for(unsigned i = 0; i < hdr->nr_gbk; i++)
+ {
+ cprintf(GREEN, " %i: ", i);
+ print_blob_interval(&hdr->gbk[i]);
+ cprintf(OFF, "\n");
+ save_blob(&hdr->gbk[i], buf, size, "gbk", i, false);
+ }
+ cprintf(BLUE, "String Tables\n");
+ for(unsigned i = 0; i < hdr->nr_strtbl; i++)
+ {
+ cprintf(GREEN, " %i: ", i);
+ print_blob_interval(&hdr->strtbl[i]);
+ cprintf(OFF, "\n");
+ save_blob(&hdr->strtbl[i], buf, size, "strtbl", i, false);
+ }
+ cprintf(BLUE, "Image Resources\n");
+ for(unsigned i = 0; i < hdr->nr_imageres; i++)
+ {
+ cprintf(GREEN, " %i: ", i);
+ print_blob_interval(&hdr->imageres[i]);
+ cprintf(OFF, "\n");
+ save_blob(&hdr->imageres[i], buf, size, "imgres", i, false);
+ }
+ cprintf(BLUE, "Unknown\n");
+ for(unsigned i = 0; i < hdr->nr_unk; i++)
+ {
+ cprintf(GREEN, " %i: ", i);
+ print_blob_interval(&hdr->unk[i]);
+ cprintf(OFF, "\n");
+ save_blob(&hdr->unk[i], buf, size, "unk", i, false);
+ }
+ cprintf(BLUE, "Other\n");
+ cprintf(GREEN, " Size: ");
+ cprintf(YELLOW, "%#x\n", hdr->size);
+ cprintf(GREEN, " Magic: ");
+ cprintf(YELLOW, "%." STR(MAGIC_RKNANOFW_SIZE) "s ", hdr->magic);
+ if(strncmp(hdr->magic, MAGIC_RKNANOFW, MAGIC_RKNANOFW_SIZE) == 0)
+ cprintf(RED, "OK\n");
+ else
+ cprintf(RED, "Mismatch\n");
+
+ return 0;
+}
+
+static void usage(void)
+{
+ printf("Usage: rkboottool [options] rknanoboot.bin out_prefix\n");
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ if(argc < 3)
+ usage();
+ prefix = argv[argc - 1];
+ FILE *fin = fopen(argv[argc - 2], "r");
+ if(fin == NULL)
+ {
+ perror("Cannot open boot file");
+ return 1;
+ }
+ fseek(fin, 0, SEEK_END);
+ long size = ftell(fin);
+ fseek(fin, 0, SEEK_SET);
+
+ void *buf = malloc(size);
+ if(buf == NULL)
+ {
+ perror("Cannot allocate memory");
+ return 1;
+ }
+
+ if(fread(buf, size, 1, fin) != 1)
+ {
+ perror("Cannot read file");
+ return 1;
+ }
+
+ fclose(fin);
+
+ return do_image(argc - 1, argv, buf, size);
+}
+