summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2011-11-06 19:44:03 +0000
committerAmaury Pouly <pamaury@rockbox.org>2011-11-06 19:44:03 +0000
commit303c486f4f7d557c35e7b6543fa9827fb94846b9 (patch)
tree3c735d8255359f1d3c4525185300035c4f029efc
parentcd832bd0f5d19b066dc859df9355243de9a95424 (diff)
downloadrockbox-303c486f4f7d557c35e7b6543fa9827fb94846b9.tar.gz
rockbox-303c486f4f7d557c35e7b6543fa9827fb94846b9.zip
Introduce mkimxboot to build bootloader images for the i.MX (only the fuze+ currently). Still not integrated in rbutil
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30920 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--rbutil/mkimxboot/Makefile112
-rw-r--r--rbutil/mkimxboot/dualboot.c9
-rw-r--r--rbutil/mkimxboot/dualboot.h3
-rw-r--r--rbutil/mkimxboot/dualboot/Makefile33
-rw-r--r--rbutil/mkimxboot/dualboot/bin2c.c140
-rw-r--r--rbutil/mkimxboot/dualboot/dualboot.S39
-rw-r--r--rbutil/mkimxboot/dualboot/dualboot.lds16
-rw-r--r--rbutil/mkimxboot/main.c132
-rw-r--r--rbutil/mkimxboot/md5.c246
-rw-r--r--rbutil/mkimxboot/md5.h25
-rw-r--r--rbutil/mkimxboot/mkimxboot.c409
-rw-r--r--rbutil/mkimxboot/mkimxboot.h55
12 files changed, 1219 insertions, 0 deletions
diff --git a/rbutil/mkimxboot/Makefile b/rbutil/mkimxboot/Makefile
new file mode 100644
index 0000000000..08cd887fce
--- /dev/null
+++ b/rbutil/mkimxboot/Makefile
@@ -0,0 +1,112 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7
8#change for releases
9ifndef APPVERSION
10APPVERSION=$(shell ../../tools/version.sh ../../)
11endif
12TARGET_DIR ?= $(shell pwd)/
13# We use the SB code available in the Rockbox utils/sbtools directory
14IMXTOOLS_DIR=../../utils/imxtools/
15CFLAGS=-I$(IMXTOOLS_DIR) -Wall -DVERSION=\"$(APPVERSION)\"
16
17ifndef V
18SILENT = @
19endif
20
21ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
22OUTPUT=mkimxboot.exe
23CFLAGS+=-mno-cygwin
24else
25ifeq ($(findstring MINGW,$(shell uname)),MINGW)
26OUTPUT=mkimxboot.exe
27else
28ifeq ($(findstring mingw,$(CC)),mingw)
29OUTPUT=mkimxboot.exe
30else
31OUTPUT=mkimxboot
32endif
33endif
34endif
35
36ifdef RBARCH
37CFLAGS += -arch $(RBARCH)
38OBJDIR = $(TARGET_DIR)build/$(RBARCH)/
39else
40OBJDIR = $(TARGET_DIR)build/
41endif
42
43CFLAGS += -std=c99
44
45all: $(OUTPUT)
46
47# inputs
48LIBIMXSOURCES=misc.c sb.c crypto.c crc.c aes128.c sha1.c
49LIBSOURCES := dualboot.c mkimxboot.c md5.c $(LIBIMXSOURCES)
50SOURCES := $(LIBSOURCES) main.c
51OBJS := $(patsubst %.c,%.o,$(addprefix $(OBJDIR),$(SOURCES)))
52LIBOBJS := $(patsubst %.c,%.o,$(addprefix $(OBJDIR),$(LIBSOURCES)))
53EXTRADEPS :=
54
55# explicit dependencies on dualboot.{c,h} and mkimxboot.h
56$(OBJDIR)mkimxboot.o: dualboot.h dualboot.c mkimxboot.c mkimxboot.h
57$(OBJDIR)main.o: dualboot.h dualboot.c main.c mkimxboot.h
58
59$(OBJDIR)%.o: %.c
60 @echo CC $<
61 $(SILENT)mkdir -p $(dir $@)
62 $(SILENT)$(CC) $(CFLAGS) -c -o $@ $<
63
64$(OBJDIR)%.o: $(IMXTOOLS_DIR)%.c
65 @echo CC $<
66 $(SILENT)mkdir -p $(dir $@)
67 $(SILENT)$(CC) $(CFLAGS) -c -o $@ $<
68
69libmkimxboot$(RBARCH).a: $(TARGET_DIR)libmkimxboot$(RBARCH).a
70
71$(TARGET_DIR)libmkimxboot$(RBARCH).a: $(LIBOBJS)
72 @echo AR $(notdir $@)
73 $(SILENT)$(AR) rucs $@ $^
74
75# building the standalone executable
76$(OUTPUT): $(OBJS) $(EXTRADEPS)
77 @echo LD $@
78 $(SILENT)$(CC) $(CFLAGS) -o $(OUTPUT) $(OBJS) $(EXTRADEPS)
79
80# some trickery to build ppc and i386 from a single call
81ifeq ($(RBARCH),)
82$(TARGET_DIR)libmkimxbooti386.a:
83 make RBARCH=i386 TARGET_DIR=$(TARGET_DIR) libmkimxbooti386.a
84
85$(TARGET_DIR)libmkimxbootppc.a:
86 make RBARCH=ppc TARGET_DIR=$(TARGET_DIR) libmkimxbootppc.a
87endif
88
89libmkimxboot-universal: $(TARGET_DIR)libmkimxbooti386.a $(TARGET_DIR)libmkimxbootppc.a
90 @echo lipo $(TARGET_DIR)libmkimxboot.a
91 $(SILENT) rm -f $(TARGET_DIR)libmkimxboot.a
92 $(SILENT)lipo -create $(TARGET_DIR)libmkimxbootppc.a $(TARGET_DIR)libmkimxbooti386.a -output $(TARGET_DIR)libmkimxboot.a
93
94clean:
95 rm -f $(OBJS) $(OUTPUT) libmkimxboot.o $(TARGET_DIR)libmkimxboot*.a mkimxboot.dmg
96 rm -rf mkimxboot-* i386 ppc $(OBJDIR)
97
98mkimxboot-i386:
99 $(MAKE) RBARCH=i386
100 mv mkimxboot mkimxboot-i386
101
102mkimxboot-ppc:
103 $(MAKE) RBARCH=ppc
104 mv mkimxboot mkimxboot-ppc
105
106mkimxboot-mac: mkimxboot-i386 mkimxboot-ppc
107 $(SILENT)lipo -create mkimxboot-ppc mkimxboot-i386 -output mkimxboot-mac
108
109mkimxboot.dmg: mkimxboot-mac
110 mkdir -p mkimxboot-dmg
111 cp -p mkimxboot-mac mkimxboot-dmg
112 hdiutil create -srcfolder mkimxboot-dmg mkimxboot.dmg
diff --git a/rbutil/mkimxboot/dualboot.c b/rbutil/mkimxboot/dualboot.c
new file mode 100644
index 0000000000..95bee11cf8
--- /dev/null
+++ b/rbutil/mkimxboot/dualboot.c
@@ -0,0 +1,9 @@
1/* Generated by bin2c */
2
3#include "dualboot.h"
4
5unsigned char dualboot_fuzeplus[36] = {
6 0x18, 0x20, 0x9f, 0xe5, 0x00, 0x20, 0x92, 0xe5, 0x01, 0x01, 0x12, 0xe3, 0x00, 0x00, 0xa0, 0x03,
7 0x1e, 0xff, 0x2f, 0x01, 0x00, 0x00, 0x81, 0xe5, 0x01, 0x00, 0xa0, 0xe3, 0x1e, 0xff, 0x2f, 0xe1,
8 0x10, 0x86, 0x01, 0x80
9};
diff --git a/rbutil/mkimxboot/dualboot.h b/rbutil/mkimxboot/dualboot.h
new file mode 100644
index 0000000000..e14f3582a8
--- /dev/null
+++ b/rbutil/mkimxboot/dualboot.h
@@ -0,0 +1,3 @@
1/* Generated by bin2c */
2
3extern unsigned char dualboot_fuzeplus[36];
diff --git a/rbutil/mkimxboot/dualboot/Makefile b/rbutil/mkimxboot/dualboot/Makefile
new file mode 100644
index 0000000000..fa5f341b6d
--- /dev/null
+++ b/rbutil/mkimxboot/dualboot/Makefile
@@ -0,0 +1,33 @@
1CC=gcc
2CROSS_PREFIX=arm-elf-eabi
3# Edit the following variables (plus copy/paste another set of rules) when
4# adding a new target. mkimxboot.c also needs to be edited to refer to these
5# new images.
6
7BOOTOBJS = dualboot_fuzeplus.o
8BOOTBINS = dualboot_fuzeplus.arm-bin
9
10all: ../dualboot.h ../dualboot.c
11
12# Dualboot bootloaders
13
14dualboot_fuzeplus.o: dualboot.S
15 $(CROSS_PREFIX)-$(CC) -mcpu=arm926ej-s -DSANSA_FUZEPLUS -c -o dualboot_fuzeplus.o dualboot.S
16
17# Rules for the ARM code embedded in mkamsboot - assemble, link, then extract
18# the binary code and finally convert to .h for building in mkamsboot
19
20%.arm-elf: %.o
21 $(CROSS_PREFIX)-ld -Tdualboot.lds -o $@ $<
22
23%.arm-bin: %.arm-elf
24 $(CROSS_PREFIX)-objcopy -O binary $< $@
25
26../dualboot.c ../dualboot.h: $(BOOTBINS) bin2c
27 ./bin2c ../dualboot $(BOOTBINS)
28
29bin2c: bin2c.c
30 $(CC) -o bin2c bin2c.c
31
32clean:
33 rm -f *~ bin2c $(BOOTBINS) $(BOOTOBJS)
diff --git a/rbutil/mkimxboot/dualboot/bin2c.c b/rbutil/mkimxboot/dualboot/bin2c.c
new file mode 100644
index 0000000000..b02af88a4d
--- /dev/null
+++ b/rbutil/mkimxboot/dualboot/bin2c.c
@@ -0,0 +1,140 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Dave Chapman
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
22#include <stdio.h>
23#include <string.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <unistd.h>
27#include <fcntl.h>
28#include <stdlib.h>
29#include <libgen.h>
30
31#ifndef O_BINARY
32#define O_BINARY 0
33#endif
34
35static off_t filesize(int fd)
36{
37 struct stat buf;
38
39 fstat(fd,&buf);
40 return buf.st_size;
41}
42
43static void write_cfile(const unsigned char* buf, off_t len, FILE* fp, const char *name)
44{
45 int i;
46
47 fprintf(fp,"unsigned char %s[%ld] = {",name,len);
48
49 for (i=0;i<len;i++) {
50 if ((i % 16) == 0) {
51 fprintf(fp,"\n ");
52 }
53 if (i == (len-1)) {
54 fprintf(fp,"0x%02x",buf[i]);
55 } else if ((i % 16) == 15) {
56 fprintf(fp,"0x%02x,",buf[i]);
57 } else {
58 fprintf(fp,"0x%02x, ",buf[i]);
59 }
60 }
61 fprintf(fp,"\n};\n");
62}
63
64int main (int argc, char* argv[])
65{
66 char* cname;
67 int i;
68 FILE *cfile, *hfile;
69 char cfilename[256], hfilename[256];
70
71 if (argc < 3) {
72 fprintf(stderr,"Usage: bin2c cname file1 [file2 [file3 ...]]\n");
73 return 1;
74 }
75
76 cname=argv[1];
77
78 snprintf(cfilename,256,"%s.c",cname);
79 cfile = fopen(cfilename,"w+");
80 if (cfile == NULL) {
81 fprintf(stderr,"Couldn't open %s\n",cfilename);
82 return 2;
83 }
84
85 snprintf(hfilename,256,"%s.h",cname);
86 hfile = fopen(hfilename,"w+");
87 if (hfile == NULL) {
88 fprintf(stderr,"Couldn't open %s\n",hfilename);
89 fclose(cfile);
90 return 3;
91 }
92
93 fprintf(cfile,"/* Generated by bin2c */\n\n");
94 fprintf(cfile,"#include \"%s\"\n\n", basename(hfilename));
95 fprintf(hfile,"/* Generated by bin2c */\n\n");
96
97 for(i=0; i < argc - 2; i++) {
98 unsigned char* buf;
99 off_t len;
100 off_t orig_len;
101 char *ext;
102 char *array = argv[2+i];
103
104 int fd = open(array,O_RDONLY|O_BINARY);
105 if (fd < 0) {
106 fprintf(stderr,"Can not open %s\n",argv[2+i]);
107 fclose(cfile);
108 fclose(hfile);
109 return 4;
110 }
111
112 orig_len = filesize(fd);
113 /* pad to 32bit */
114 len = (orig_len + 3) & ~3;
115
116 buf = malloc(len);
117 if (read(fd,buf,orig_len) < orig_len) {
118 fprintf(stderr,"Short read, aborting\n");
119 return 5;
120 }
121
122 /* pad to 32bit with zeros */
123 if (len > orig_len)
124 memset(buf+orig_len, 0, len-orig_len);
125
126 /* remove file extension */
127 ext = strchr (array, '.');
128 if (ext != NULL)
129 *ext = '\0';
130 write_cfile (buf, len, cfile, array);
131 fprintf(hfile,"extern unsigned char %s[%ld];\n",array,len);
132
133 close(fd);
134 }
135
136 fclose(cfile);
137 fclose(hfile);
138
139 return 0;
140}
diff --git a/rbutil/mkimxboot/dualboot/dualboot.S b/rbutil/mkimxboot/dualboot/dualboot.S
new file mode 100644
index 0000000000..8302829a81
--- /dev/null
+++ b/rbutil/mkimxboot/dualboot/dualboot.S
@@ -0,0 +1,39 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by 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
22.text
23.global start
24@ int start(uint32_t arg, uint32_t *result_id)
25start:
26#if defined(SANSA_FUZEPLUS)
27 /* If volume down key is hold, return so that the OF can boot */
28 ldr r2, =0x80018610 @ HW_PINCTRL_DIN1
29 ldr r2, [r2]
30 tst r2, #0x40000000 @ bit 30, active low
31 moveq r0, #0 @ return 0, continue boot
32 bxeq lr
33 /* otherwise jump to section given as argument */
34 str r0, [r1]
35 mov r0, #1
36 bx lr
37#else
38#error No target defined !
39#endif
diff --git a/rbutil/mkimxboot/dualboot/dualboot.lds b/rbutil/mkimxboot/dualboot/dualboot.lds
new file mode 100644
index 0000000000..caaff1a41d
--- /dev/null
+++ b/rbutil/mkimxboot/dualboot/dualboot.lds
@@ -0,0 +1,16 @@
1ENTRY(start)
2OUTPUT_FORMAT(elf32-littlearm)
3OUTPUT_ARCH(arm)
4
5MEMORY
6{
7 OCRAM : ORIGIN = 0, LENGTH = 0x8000
8}
9
10SECTIONS
11{
12 .text 0 :
13 {
14 *(.text*)
15 } > OCRAM
16}
diff --git a/rbutil/mkimxboot/main.c b/rbutil/mkimxboot/main.c
new file mode 100644
index 0000000000..ec2a42380d
--- /dev/null
+++ b/rbutil/mkimxboot/main.c
@@ -0,0 +1,132 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by 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
22#include <getopt.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include "mkimxboot.h"
26
27static void usage(void)
28{
29 printf("Usage: elftosb [options | file]...\n");
30 printf("Options:\n");
31 printf(" -?/--help\tDisplay this message\n");
32 printf(" -o <file>\tSet output file\n");
33 printf(" -i <file>\tSet input file\n");
34 printf(" -b <file>\tSet boot file\n");
35 printf(" -d/--debug\tEnable debug output\n");
36 printf(" -t <type>\tSet type (dualboot, singleboot, recovery)\n");
37 printf("By default a dualboot image is built\n");
38 exit(1);
39}
40
41int main(int argc, char *argv[])
42{
43 char *infile = NULL;
44 char *outfile = NULL;
45 char *bootfile = NULL;
46 enum imx_output_type_t type = IMX_DUALBOOT;
47 bool debug = false;
48
49 if(argc == 1)
50 usage();
51
52 while(1)
53 {
54 static struct option long_options[] =
55 {
56 {"help", no_argument, 0, '?'},
57 {"in-file", no_argument, 0, 'i'},
58 {"out-file", required_argument, 0, 'o'},
59 {"boot-file", required_argument, 0, 'b'},
60 {"debug", no_argument, 0, 'd'},
61 {"type", required_argument, 0, 't'},
62 {0, 0, 0, 0}
63 };
64
65 int c = getopt_long(argc, argv, "?di:o:b:t:", long_options, NULL);
66 if(c == -1)
67 break;
68 switch(c)
69 {
70 case 'd':
71 debug = true;
72 break;
73 case '?':
74 usage();
75 break;
76 case 'o':
77 outfile = optarg;
78 break;
79 case 'i':
80 infile = optarg;
81 break;
82 case 'b':
83 {
84 bootfile = optarg;
85 break;
86 }
87 case 't':
88 if(strcmp(optarg, "dualboot") == 0)
89 type = IMX_DUALBOOT;
90 else if(strcmp(optarg, "singleboot") == 0)
91 type = IMX_SINGLEBOOT;
92 else if(strcmp(optarg, "recovery") == 0)
93 type = IMX_RECOVERY;
94 else
95 {
96 printf("Invalid boot type '%s'\n", optarg);
97 return 1;
98 }
99 break;
100 default:
101 abort();
102 }
103 }
104
105 if(!infile)
106 {
107 printf("You must specify an input file\n");
108 return 1;
109 }
110 if(!outfile)
111 {
112 printf("You must specify an output file\n");
113 return 1;
114 }
115 if(!bootfile)
116 {
117 printf("You must specify an boot file\n");
118 return 1;
119 }
120 if(optind != argc)
121 {
122 printf("Extra arguments on command line\n");
123 return 1;
124 }
125
126 struct imx_option_t opt;
127 opt.debug = debug;
128 opt.output = type;
129 enum imx_error_t err = mkimxboot(infile, bootfile, outfile, opt);
130 printf("Result: %d\n", err);
131 return 0;
132}
diff --git a/rbutil/mkimxboot/md5.c b/rbutil/mkimxboot/md5.c
new file mode 100644
index 0000000000..530d8df15a
--- /dev/null
+++ b/rbutil/mkimxboot/md5.c
@@ -0,0 +1,246 @@
1/*
2 * RFC 1321 compliant MD5 implementation
3 *
4 * Copyright (C) 2001-2003 Christophe Devine
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <string.h>
22
23#include "md5.h"
24
25#define GET_UINT32(n,b,i) \
26{ \
27 (n) = ( (uint32) (b)[(i) ] ) \
28 | ( (uint32) (b)[(i) + 1] << 8 ) \
29 | ( (uint32) (b)[(i) + 2] << 16 ) \
30 | ( (uint32) (b)[(i) + 3] << 24 ); \
31}
32
33#define PUT_UINT32(n,b,i) \
34{ \
35 (b)[(i) ] = (uint8) ( (n) ); \
36 (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \
37 (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \
38 (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \
39}
40
41void md5_starts( md5_context *ctx )
42{
43 ctx->total[0] = 0;
44 ctx->total[1] = 0;
45
46 ctx->state[0] = 0x67452301;
47 ctx->state[1] = 0xEFCDAB89;
48 ctx->state[2] = 0x98BADCFE;
49 ctx->state[3] = 0x10325476;
50}
51
52void md5_process( md5_context *ctx, uint8 data[64] )
53{
54 uint32 X[16], A, B, C, D;
55
56 GET_UINT32( X[0], data, 0 );
57 GET_UINT32( X[1], data, 4 );
58 GET_UINT32( X[2], data, 8 );
59 GET_UINT32( X[3], data, 12 );
60 GET_UINT32( X[4], data, 16 );
61 GET_UINT32( X[5], data, 20 );
62 GET_UINT32( X[6], data, 24 );
63 GET_UINT32( X[7], data, 28 );
64 GET_UINT32( X[8], data, 32 );
65 GET_UINT32( X[9], data, 36 );
66 GET_UINT32( X[10], data, 40 );
67 GET_UINT32( X[11], data, 44 );
68 GET_UINT32( X[12], data, 48 );
69 GET_UINT32( X[13], data, 52 );
70 GET_UINT32( X[14], data, 56 );
71 GET_UINT32( X[15], data, 60 );
72
73#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
74
75#define P(a,b,c,d,k,s,t) \
76{ \
77 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
78}
79
80 A = ctx->state[0];
81 B = ctx->state[1];
82 C = ctx->state[2];
83 D = ctx->state[3];
84
85#define F(x,y,z) (z ^ (x & (y ^ z)))
86
87 P( A, B, C, D, 0, 7, 0xD76AA478 );
88 P( D, A, B, C, 1, 12, 0xE8C7B756 );
89 P( C, D, A, B, 2, 17, 0x242070DB );
90 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
91 P( A, B, C, D, 4, 7, 0xF57C0FAF );
92 P( D, A, B, C, 5, 12, 0x4787C62A );
93 P( C, D, A, B, 6, 17, 0xA8304613 );
94 P( B, C, D, A, 7, 22, 0xFD469501 );
95 P( A, B, C, D, 8, 7, 0x698098D8 );
96 P( D, A, B, C, 9, 12, 0x8B44F7AF );
97 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
98 P( B, C, D, A, 11, 22, 0x895CD7BE );
99 P( A, B, C, D, 12, 7, 0x6B901122 );
100 P( D, A, B, C, 13, 12, 0xFD987193 );
101 P( C, D, A, B, 14, 17, 0xA679438E );
102 P( B, C, D, A, 15, 22, 0x49B40821 );
103
104#undef F
105
106#define F(x,y,z) (y ^ (z & (x ^ y)))
107
108 P( A, B, C, D, 1, 5, 0xF61E2562 );
109 P( D, A, B, C, 6, 9, 0xC040B340 );
110 P( C, D, A, B, 11, 14, 0x265E5A51 );
111 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
112 P( A, B, C, D, 5, 5, 0xD62F105D );
113 P( D, A, B, C, 10, 9, 0x02441453 );
114 P( C, D, A, B, 15, 14, 0xD8A1E681 );
115 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
116 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
117 P( D, A, B, C, 14, 9, 0xC33707D6 );
118 P( C, D, A, B, 3, 14, 0xF4D50D87 );
119 P( B, C, D, A, 8, 20, 0x455A14ED );
120 P( A, B, C, D, 13, 5, 0xA9E3E905 );
121 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
122 P( C, D, A, B, 7, 14, 0x676F02D9 );
123 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
124
125#undef F
126
127#define F(x,y,z) (x ^ y ^ z)
128
129 P( A, B, C, D, 5, 4, 0xFFFA3942 );
130 P( D, A, B, C, 8, 11, 0x8771F681 );
131 P( C, D, A, B, 11, 16, 0x6D9D6122 );
132 P( B, C, D, A, 14, 23, 0xFDE5380C );
133 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
134 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
135 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
136 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
137 P( A, B, C, D, 13, 4, 0x289B7EC6 );
138 P( D, A, B, C, 0, 11, 0xEAA127FA );
139 P( C, D, A, B, 3, 16, 0xD4EF3085 );
140 P( B, C, D, A, 6, 23, 0x04881D05 );
141 P( A, B, C, D, 9, 4, 0xD9D4D039 );
142 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
143 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
144 P( B, C, D, A, 2, 23, 0xC4AC5665 );
145
146#undef F
147
148#define F(x,y,z) (y ^ (x | ~z))
149
150 P( A, B, C, D, 0, 6, 0xF4292244 );
151 P( D, A, B, C, 7, 10, 0x432AFF97 );
152 P( C, D, A, B, 14, 15, 0xAB9423A7 );
153 P( B, C, D, A, 5, 21, 0xFC93A039 );
154 P( A, B, C, D, 12, 6, 0x655B59C3 );
155 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
156 P( C, D, A, B, 10, 15, 0xFFEFF47D );
157 P( B, C, D, A, 1, 21, 0x85845DD1 );
158 P( A, B, C, D, 8, 6, 0x6FA87E4F );
159 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
160 P( C, D, A, B, 6, 15, 0xA3014314 );
161 P( B, C, D, A, 13, 21, 0x4E0811A1 );
162 P( A, B, C, D, 4, 6, 0xF7537E82 );
163 P( D, A, B, C, 11, 10, 0xBD3AF235 );
164 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
165 P( B, C, D, A, 9, 21, 0xEB86D391 );
166
167#undef F
168
169 ctx->state[0] += A;
170 ctx->state[1] += B;
171 ctx->state[2] += C;
172 ctx->state[3] += D;
173}
174
175void md5_update( md5_context *ctx, uint8 *input, uint32 length )
176{
177 uint32 left, fill;
178
179 if( ! length ) return;
180
181 left = ctx->total[0] & 0x3F;
182 fill = 64 - left;
183
184 ctx->total[0] += length;
185 ctx->total[0] &= 0xFFFFFFFF;
186
187 if( ctx->total[0] < length )
188 ctx->total[1]++;
189
190 if( left && length >= fill )
191 {
192 memcpy( (void *) (ctx->buffer + left),
193 (void *) input, fill );
194 md5_process( ctx, ctx->buffer );
195 length -= fill;
196 input += fill;
197 left = 0;
198 }
199
200 while( length >= 64 )
201 {
202 md5_process( ctx, input );
203 length -= 64;
204 input += 64;
205 }
206
207 if( length )
208 {
209 memcpy( (void *) (ctx->buffer + left),
210 (void *) input, length );
211 }
212}
213
214static uint8 md5_padding[64] =
215{
216 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
218 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
219 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
220};
221
222void md5_finish( md5_context *ctx, uint8 digest[16] )
223{
224 uint32 last, padn;
225 uint32 high, low;
226 uint8 msglen[8];
227
228 high = ( ctx->total[0] >> 29 )
229 | ( ctx->total[1] << 3 );
230 low = ( ctx->total[0] << 3 );
231
232 PUT_UINT32( low, msglen, 0 );
233 PUT_UINT32( high, msglen, 4 );
234
235 last = ctx->total[0] & 0x3F;
236 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
237
238 md5_update( ctx, md5_padding, padn );
239 md5_update( ctx, msglen, 8 );
240
241 PUT_UINT32( ctx->state[0], digest, 0 );
242 PUT_UINT32( ctx->state[1], digest, 4 );
243 PUT_UINT32( ctx->state[2], digest, 8 );
244 PUT_UINT32( ctx->state[3], digest, 12 );
245}
246
diff --git a/rbutil/mkimxboot/md5.h b/rbutil/mkimxboot/md5.h
new file mode 100644
index 0000000000..71fa395548
--- /dev/null
+++ b/rbutil/mkimxboot/md5.h
@@ -0,0 +1,25 @@
1#ifndef _MD5_H
2#define _MD5_H
3
4#ifndef uint8
5#define uint8 unsigned char
6#endif
7
8#ifndef uint32
9#define uint32 unsigned long int
10#endif
11
12typedef struct
13{
14 uint32 total[2];
15 uint32 state[4];
16 uint8 buffer[64];
17}
18md5_context;
19
20void md5_starts( md5_context *ctx );
21void md5_update( md5_context *ctx, uint8 *input, uint32 length );
22void md5_finish( md5_context *ctx, uint8 digest[16] );
23
24#endif /* md5.h */
25
diff --git a/rbutil/mkimxboot/mkimxboot.c b/rbutil/mkimxboot/mkimxboot.c
new file mode 100644
index 0000000000..f1a874b3f5
--- /dev/null
+++ b/rbutil/mkimxboot/mkimxboot.c
@@ -0,0 +1,409 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by 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 <stdio.h>
22#include <stdlib.h>
23#include <stdarg.h>
24#include "mkimxboot.h"
25#include "sb.h"
26#include "dualboot.h"
27#include "md5.h"
28
29/* Supported models */
30enum imx_model_t
31{
32 MODEL_UNKNOWN = -1,
33 MODEL_FUZEPLUS = 0,
34 /* new models go here */
35
36 NUM_MODELS
37};
38
39struct imx_md5sum_t
40{
41 int model;
42 char *md5sum;
43};
44
45struct imx_model_desc_t
46{
47 /* Descriptive name of this model */
48 const char *model_name;
49 /* Dualboot code for this model */
50 const unsigned char *dualboot;
51 /* Size of dualboot functions for this model */
52 int dualboot_size;
53 /* Model name used in the Rockbox header in ".sansa" files - these match the
54 -add parameter to the "scramble" tool */
55 const char *rb_model_name;
56 /* Model number used to initialise the checksum in the Rockbox header in
57 ".sansa" files - these are the same as MODEL_NUMBER in config-target.h */
58 const int rb_model_num;
59 /* Number of keys needed to decrypt/encrypt */
60 int nr_keys;
61 /* Array of keys */
62 struct crypto_key_t *keys;
63 /* Dualboot load address */
64 uint32_t dualboot_addr;
65 /* Bootloader load address */
66 uint32_t bootloader_addr;
67};
68
69static const struct imx_md5sum_t imx_sums[] =
70{
71 { MODEL_FUZEPLUS, "c3e27620a877dc6b200b97dcb3e0ecc7" }, /* Version 2.38.6 */
72};
73
74static struct crypto_key_t zero_key =
75{
76 .method = CRYPTO_KEY,
77 .u.key = {0}
78};
79
80static const struct imx_model_desc_t imx_models[] =
81{
82 [MODEL_FUZEPLUS] = { "Fuze+", dualboot_fuzeplus, sizeof(dualboot_fuzeplus), "fuz+", 72,
83 1, &zero_key },
84};
85
86#define NR_IMX_SUMS (sizeof(imx_sums) / sizeof(imx_sums[0]))
87#define NR_IMX_MODELS (sizeof(imx_models) / sizeof(imx_models[0]))
88
89#define MAGIC_ROCK 0x726f636b /* 'rock' */
90#define MAGIC_RECOVERY 0xfee1dead
91#define MAGIC_NORMAL 0xcafebabe
92
93static enum imx_error_t patch_std_zero_host_play(int jump_before, int model,
94 enum imx_output_type_t type, struct sb_file_t *sb_file, void *boot, size_t boot_sz)
95{
96 /* We assume the file has three boot sections: ____, host, play and one
97 * resource section rsrc.
98 *
99 * Dual Boot:
100 * ----------
101 * We patch the file by inserting the dualboot code before the <jump_before>th
102 * call in the ____ section. We give it as argument the section name 'rock'
103 * and add a section called 'rock' after rsrc which contains the bootloader.
104 *
105 * Single Boot & Recovery:
106 * -----------------------
107 * We patch the file by inserting the bootloader code after the <jump_before>th
108 * call in the ____ section and get rid of everything else. In recovery mode,
109 * we give 0xfee1dead as argument */
110
111 /* Do not override real key and IV */
112 sb_file->override_crypto_iv = false;
113 sb_file->override_real_key = false;
114
115 /* first locate the good instruction */
116 struct sb_section_t *sec = &sb_file->sections[0];
117 int jump_idx = 0;
118 while(jump_idx < sec->nr_insts && jump_before > 0)
119 if(sec->insts[jump_idx++].inst == SB_INST_CALL)
120 jump_before--;
121 if(jump_idx == sec->nr_insts)
122 {
123 printf("[ERR] Cannot locate call in section ____\n");
124 return IMX_DONT_KNOW_HOW_TO_PATCH;
125 }
126
127 if(type == IMX_DUALBOOT)
128 {
129 /* create a new instruction array with a hole for two instructions */
130 struct sb_inst_t *new_insts = xmalloc(sizeof(struct sb_inst_t) * (sec->nr_insts + 2));
131 memcpy(new_insts, sec->insts, sizeof(struct sb_inst_t) * jump_idx);
132 memcpy(new_insts + jump_idx + 2, sec->insts + jump_idx,
133 sizeof(struct sb_inst_t) * (sec->nr_insts - jump_idx));
134 /* first instruction is be a load */
135 struct sb_inst_t *load = &new_insts[jump_idx];
136 memset(load, 0, sizeof(struct sb_inst_t));
137 load->inst = SB_INST_LOAD;
138 load->size = imx_models[model].dualboot_size;
139 load->addr = imx_models[model].dualboot_addr;
140 /* duplicate memory because it will be free'd */
141 load->data = memdup(imx_models[model].dualboot, imx_models[model].dualboot_size);
142 /* second instruction is a call */
143 struct sb_inst_t *call = &new_insts[jump_idx + 1];
144 memset(call, 0, sizeof(struct sb_inst_t));
145 call->inst = SB_INST_CALL;
146 call->addr = imx_models[model].dualboot_addr;
147 call->argument = MAGIC_ROCK;
148 /* free old instruction array */
149 free(sec->insts);
150 sec->insts = new_insts;
151 sec->nr_insts += 2;
152
153 /* create a new section */
154 struct sb_section_t rock_sec;
155 memset(&rock_sec, 0, sizeof(rock_sec));
156 /* section has two instructions: load and call */
157 rock_sec.identifier = MAGIC_ROCK;
158 rock_sec.alignment = BLOCK_SIZE;
159 rock_sec.nr_insts = 2;
160 rock_sec.insts = xmalloc(2 * sizeof(struct sb_inst_t));
161 memset(rock_sec.insts, 0, 2 * sizeof(struct sb_inst_t));
162 rock_sec.insts[0].inst = SB_INST_LOAD;
163 rock_sec.insts[0].size = boot_sz;
164 rock_sec.insts[0].data = memdup(boot, boot_sz);
165 rock_sec.insts[0].addr = imx_models[model].bootloader_addr;
166 rock_sec.insts[1].inst = SB_INST_CALL;
167 rock_sec.insts[1].addr = imx_models[model].bootloader_addr;
168 rock_sec.insts[1].argument = MAGIC_NORMAL;
169
170 sb_file->sections = augment_array(sb_file->sections,
171 sizeof(struct sb_section_t), sb_file->nr_sections,
172 &rock_sec, 1);
173 sb_file->nr_sections++;
174
175 return IMX_SUCCESS;
176 }
177 else if(type == IMX_SINGLEBOOT || type == IMX_RECOVERY)
178 {
179 bool recovery = type == IMX_RECOVERY;
180 /* remove everything after the call and add two instructions: load and call */
181 struct sb_inst_t *new_insts = xmalloc(sizeof(struct sb_inst_t) * (jump_idx + 2));
182 memcpy(new_insts, sec->insts, sizeof(struct sb_inst_t) * jump_idx);
183 for(int i = jump_idx; i < sec->nr_insts; i++)
184 sb_free_instruction(sec->insts[i]);
185 memset(new_insts + jump_idx, 0, 2 * sizeof(struct sb_inst_t));
186 new_insts[jump_idx + 0].inst = SB_INST_LOAD;
187 new_insts[jump_idx + 0].size = boot_sz;
188 new_insts[jump_idx + 0].data = memdup(boot, boot_sz);
189 new_insts[jump_idx + 0].addr = imx_models[model].bootloader_addr;
190 new_insts[jump_idx + 1].inst = SB_INST_CALL;
191 new_insts[jump_idx + 1].addr = imx_models[model].bootloader_addr;
192 new_insts[jump_idx + 1].argument = recovery ? MAGIC_RECOVERY : MAGIC_NORMAL;
193
194 free(sec->insts);
195 sec->insts = new_insts;
196 sec->nr_insts = jump_idx + 2;
197 /* remove all other sections */
198 for(int i = 1; i < sb_file->nr_sections; i++)
199 sb_free_section(sb_file->sections[i]);
200 struct sb_section_t *new_sec = xmalloc(sizeof(struct sb_section_t));
201 memcpy(new_sec, &sb_file->sections[0], sizeof(struct sb_section_t));
202 free(sb_file->sections);
203 sb_file->sections = new_sec;
204 sb_file->nr_sections = 1;
205
206 return IMX_SUCCESS;
207 }
208 else
209 {
210 printf("[ERR] Bad output type !\n");
211 return IMX_DONT_KNOW_HOW_TO_PATCH;
212 }
213}
214
215static enum imx_error_t patch_firmware(int model, enum imx_output_type_t type,
216 struct sb_file_t *sb_file, void *boot, size_t boot_sz)
217{
218 switch(model)
219 {
220 case MODEL_FUZEPLUS:
221 /* The Fuze+ uses the standard ____, host, play sections, patch after third
222 * call in ____ section */
223 return patch_std_zero_host_play(3, model, type, sb_file, boot, boot_sz);
224 default:
225 return IMX_DONT_KNOW_HOW_TO_PATCH;
226 }
227}
228
229static void imx_printf(void *user, bool error, color_t c, const char *fmt, ...)
230{
231 (void) user;
232 (void) c;
233 va_list args;
234 va_start(args, fmt);
235 /*
236 if(error)
237 printf("[ERR] ");
238 else
239 printf("[INFO] ");
240 */
241 vprintf(fmt, args);
242 va_end(args);
243}
244
245static uint32_t get_uint32be(unsigned char *p)
246{
247 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
248}
249
250enum imx_error_t mkimxboot(const char *infile, const char *bootfile,
251 const char *outfile, struct imx_option_t opt)
252{
253 /* Dump tables */
254 do
255 {
256 printf("[INFO] mkimxboot models:\n");
257 for(int i = 0; i < NR_IMX_MODELS; i++)
258 {
259 printf("[INFO] %s: idx=%d rb_model=%s rb_num=%d\n",
260 imx_models[i].model_name, i, imx_models[i].rb_model_name,
261 imx_models[i].rb_model_num);
262 }
263 printf("[INFO] mkimxboot mapping:\n");
264 for(int i = 0; i < NR_IMX_SUMS; i++)
265 {
266 printf("[INFO] md5sum=%s -> idx=%d\n", imx_sums[i].md5sum,
267 imx_sums[i].model);
268 }
269 }while(0);
270 /* compute MD5 sum of the file */
271 uint8_t file_md5sum[16];
272 do
273 {
274 FILE *f = fopen(infile, "rb");
275 if(f == NULL)
276 {
277 printf("[ERR] Cannot open input file\n");
278 return IMX_OPEN_ERROR;
279 }
280 fseek(f, 0, SEEK_END);
281 size_t sz = ftell(f);
282 fseek(f, 0, SEEK_SET);
283 void *buf = xmalloc(sz);
284 if(fread(buf, sz, 1, f) != 1)
285 {
286 fclose(f);
287 free(buf);
288 printf("[ERR] Cannot read file\n");
289 return IMX_READ_ERROR;
290 }
291 fclose(f);
292 md5_context ctx;
293 md5_starts(&ctx);
294 md5_update(&ctx, buf, sz);
295 md5_finish(&ctx, file_md5sum);
296 free(buf);
297 }while(0);
298 printf("[INFO] MD5 sum of the file: ");
299 print_hex(file_md5sum, 16, true);
300 /* find model */
301 int model;
302 do
303 {
304 int i = 0;
305 while(i < NR_IMX_SUMS)
306 {
307 uint8_t md5[20];
308 if(strlen(imx_sums[i].md5sum) != 32)
309 {
310 printf("[INFO] Invalid MD5 sum in imx_sums\n");
311 return IMX_ERROR;
312 }
313 for(int j = 0; j < 16; j++)
314 {
315 byte a, b;
316 if(convxdigit(imx_sums[i].md5sum[2 * j], &a) || convxdigit(imx_sums[i].md5sum[2 * j + 1], &b))
317 return false;
318 md5[j] = (a << 4) | b;
319 }
320 if(memcmp(file_md5sum, md5, 16) == 0)
321 break;
322 i++;
323 }
324 if(i == NR_IMX_SUMS)
325 {
326 printf("[ERR] MD5 sum doesn't match any known file\n");
327 return IMX_NO_MATCH;
328 }
329 model = imx_sums[i].model;
330 }while(0);
331 printf("[INFO] File is for model %d (%s)\n", model, imx_models[model].model_name);
332 /* load rockbox file */
333 uint8_t *boot;
334 size_t boot_size;
335 do
336 {
337 FILE *f = fopen(bootfile, "rb");
338 if(f == NULL)
339 {
340 printf("[ERR] Cannot open boot file\n");
341 return IMX_OPEN_ERROR;
342 }
343 fseek(f, 0, SEEK_END);
344 boot_size = ftell(f);
345 fseek(f, 0, SEEK_SET);
346 boot = xmalloc(boot_size);
347 if(fread(boot, boot_size, 1, f) != 1)
348 {
349 free(boot);
350 fclose(f);
351 printf("[ERR] Cannot read boot file\n");
352 return IMX_READ_ERROR;
353 }
354 fclose(f);
355 }while(0);
356 /* Check boot file */
357 do
358 {
359 if(boot_size < 8)
360 {
361 printf("[ERR] Bootloader file is too small to be valid\n");
362 free(boot);
363 return IMX_BOOT_INVALID;
364 }
365 /* check model name */
366 uint8_t *name = boot + 4;
367 if(memcmp(name, imx_models[model].rb_model_name, 4) != 0)
368 {
369 printf("[ERR] Bootloader model doesn't match found model for input file\n");
370 free(boot);
371 return IMX_BOOT_MISMATCH;
372 }
373 /* check checksum */
374 uint32_t sum = imx_models[model].rb_model_num;
375 for(int i = 8; i < boot_size; i++)
376 sum += boot[i];
377 if(sum != get_uint32be(boot))
378 {
379 printf("[ERR] Bootloader checksum mismatch\n");
380 free(boot);
381 return IMX_BOOT_CHECKSUM_ERROR;
382 }
383 }while(0);
384 /* load OF file */
385 struct sb_file_t *sb_file;
386 do
387 {
388 enum sb_error_t err;
389 g_debug = opt.debug;
390 clear_keys();
391 add_keys(imx_models[model].keys, imx_models[model].nr_keys);
392 sb_file = sb_read_file(infile, false, NULL, &imx_printf, &err);
393 if(sb_file == NULL)
394 {
395 clear_keys();
396 free(boot);
397 return IMX_FIRST_SB_ERROR + err;
398 }
399 }while(0);
400 /* produce file */
401 enum imx_error_t ret = patch_firmware(model, opt.output, sb_file, boot + 8, boot_size - 8);
402 if(ret == IMX_SUCCESS)
403 ret = sb_write_file(sb_file, outfile);
404
405 clear_keys();
406 free(boot);
407 sb_free(sb_file);
408 return ret;
409}
diff --git a/rbutil/mkimxboot/mkimxboot.h b/rbutil/mkimxboot/mkimxboot.h
new file mode 100644
index 0000000000..97642c5d84
--- /dev/null
+++ b/rbutil/mkimxboot/mkimxboot.h
@@ -0,0 +1,55 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by 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
22#include <stdbool.h>
23#include <stdint.h>
24#include <sys/types.h>
25#include "sb.h"
26
27enum imx_error_t
28{
29 IMX_SUCCESS = 0,
30 IMX_ERROR = -1,
31 IMX_OPEN_ERROR = -2,
32 IMX_READ_ERROR = -3,
33 IMX_NO_MATCH = -4,
34 IMX_BOOT_INVALID = -5,
35 IMX_BOOT_MISMATCH = -6,
36 IMX_BOOT_CHECKSUM_ERROR = -7,
37 IMX_DONT_KNOW_HOW_TO_PATCH = -8,
38 IMX_FIRST_SB_ERROR = -9,
39};
40
41enum imx_output_type_t
42{
43 IMX_DUALBOOT = 0,
44 IMX_RECOVERY = 1,
45 IMX_SINGLEBOOT = 2,
46};
47
48struct imx_option_t
49{
50 bool debug;
51 enum imx_output_type_t output;
52};
53
54enum imx_error_t mkimxboot(const char *infile, const char *bootfile,
55 const char *outfile, struct imx_option_t opt);