summaryrefslogtreecommitdiff
path: root/rbutil/mkmpioboot
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil/mkmpioboot')
-rw-r--r--rbutil/mkmpioboot/Makefile94
-rw-r--r--rbutil/mkmpioboot/main.c49
-rw-r--r--rbutil/mkmpioboot/mkmpioboot.c188
-rw-r--r--rbutil/mkmpioboot/mkmpioboot.h37
4 files changed, 368 insertions, 0 deletions
diff --git a/rbutil/mkmpioboot/Makefile b/rbutil/mkmpioboot/Makefile
new file mode 100644
index 0000000000..f50392793e
--- /dev/null
+++ b/rbutil/mkmpioboot/Makefile
@@ -0,0 +1,94 @@
1
2#change for releases
3ifndef APPVERSION
4APPVERSION=`../../tools/version.sh ../../`
5endif
6
7# We use the UCL code available in the Rockbox tools/ directory
8CFLAGS=-I../../tools/ucl/include -Wall -DVERSION=\"$(APPVERSION)\"
9
10ifndef V
11SILENT = @
12endif
13
14ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
15OUTPUT=mkmpioboot.exe
16CFLAGS+=-mno-cygwin
17else
18ifeq ($(findstring MINGW,$(shell uname)),MINGW)
19OUTPUT=mkmpioboot.exe
20else
21ifeq ($(findstring mingw,$(CC)),mingw)
22OUTPUT=mkmpioboot.exe
23else
24OUTPUT=mkmpioboot
25endif
26endif
27endif
28
29ifdef RBARCH
30CFLAGS += -arch $(RBARCH)
31OBJDIR = $(RBARCH)/
32endif
33
34
35all: $(OUTPUT)
36
37# inputs
38LIBSOURCES := mkmpioboot.c
39SOURCES := $(LIBSOURCES) main.c
40OBJS := $(patsubst %.c,%.o,$(addprefix $(OBJDIR),$(SOURCES)))
41LIBOBJS := $(patsubst %.c,%.o,$(addprefix $(OBJDIR),$(LIBSOURCES)))
42EXTRADEPS := $(LIBUCL)
43
44# explicit dependencies
45$(OBJDIR)mkmpioboot.o: mkmpioboot.c mkmpioboot.h
46$(OBJDIR)main.o: main.c
47
48$(OBJDIR)%.o: %.c
49 @echo CC $< $
50 $(SILENT)mkdir -p $(dir $@)
51 $(SILENT)$(CC) $(CFLAGS) -c -o $@ $<
52
53libmkamsboot$(RBARCH).a: $(LIBOBJS)
54 @echo AR $@
55 $(SILENT)$(AR) ruc $(TARGET_DIR)$@ $^
56
57# building the standalone executable
58$(OUTPUT): $(OBJS) $(EXTRADEPS)
59 @echo LD $@
60 $(SILENT)$(CC) $(CFLAGS) -o $(OUTPUT) $(OBJS) $(EXTRADEPS)
61
62# some trickery to build ppc and i386 from a single call
63ifeq ($(RBARCH),)
64$(TARGET_DIR)libmkmpiobooti386.a:
65 make RBARCH=i386 TARGET_DIR=$(TARGET_DIR) libmkmpiobooti386.a
66
67$(TARGET_DIR)libmkmpiobootppc.a:
68 make RBARCH=ppc TARGET_DIR=$(TARGET_DIR) libmkmpiobootppc.a
69endif
70
71libmkmpioboot-universal: $(TARGET_DIR)libmkmpiobooti386.a $(TARGET_DIR)libmkmpiobootppc.a
72 @echo lipo $(TARGET_DIR)libmkmpioboot.a
73 $(SILENT) rm -f $(TARGET_DIR)libmkmpioboot.a
74 $(SILENT)lipo -create $(TARGET_DIR)libmkmpiobootppc.a $(TARGET_DIR)libmkmpiobooti386.a -output $(TARGET_DIR)libmkmpioboot.a
75
76clean:
77 rm -f $(OBJS) $(OUTPUT) libmkmpioboot.o $(TARGET_DIR)libmkmpioboot*.a mkmpioboot.dmg
78 rm -rf mkmpioboot-* i386 ppc $(OBJDIR)
79
80mkmpioboot-i386:
81 $(MAKE) RBARCH=i386
82 mv mkmpioboot mkmpioboot-i386
83
84mkmpioboot-ppc:
85 $(MAKE) RBARCH=ppc
86 mv mkmpioboot mkmpioboot-ppc
87
88mkmpioboot-mac: mkmpioboot-i386 mkmpioboot-ppc
89 $(SILENT)lipo -create mkmpioboot-ppc mkmpioboot-i386 -output mkmpioboot-mac
90
91mkmpioboot.dmg: mkmpioboot-mac
92 mkdir -p mkmpioboot-dmg
93 cp -p mkmpioboot-mac mkmpioboot-dmg
94 hdiutil create -srcfolder mkmpioboot-dmg mkmpioboot.dmg
diff --git a/rbutil/mkmpioboot/main.c b/rbutil/mkmpioboot/main.c
new file mode 100644
index 0000000000..38e6d25288
--- /dev/null
+++ b/rbutil/mkmpioboot/main.c
@@ -0,0 +1,49 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2010 by Marcin Bukat
11 *
12 * code taken mostly from mkboot.c
13 * Copyright (C) 2005 by Linus Nielsen Feltzing
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include <stdio.h>
26#include <stdlib.h>
27#include "mkmpioboot.h"
28
29static void usage(void)
30{
31 printf("usage: mkmpioboot <firmware file> <boot file> <output file>\n");
32 exit(1);
33}
34
35int main(int argc, char *argv[])
36{
37 char *infile, *bootfile, *outfile;
38 int origin = 0xe0000; /* MPIO HD200 bootloader address */
39
40 if(argc < 3) {
41 usage();
42 }
43
44 infile = argv[1];
45 bootfile = argv[2];
46 outfile = argv[3];
47
48 return mkmpioboot(infile, bootfile, outfile, origin);
49}
diff --git a/rbutil/mkmpioboot/mkmpioboot.c b/rbutil/mkmpioboot/mkmpioboot.c
new file mode 100644
index 0000000000..6d52e53f09
--- /dev/null
+++ b/rbutil/mkmpioboot/mkmpioboot.c
@@ -0,0 +1,188 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2010 by Marcin Bukat
11 *
12 * code taken mostly from mkboot.c
13 * Copyright (C) 2005 by Linus Nielsen Feltzing
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include "mkmpioboot.h"
28
29#define OF_FIRMWARE_LEN 0x100000 /* size of HD200_UPG.SYS file */
30#define MPIO_STRING_OFFSET 0xfffe0
31
32/* We support only 1.30.05 version of OF for now */
33static char *mpio_string = "HD200 HDD Audio Ver113005";
34
35/* MPIO HD200 firmware is plain binary image
36 * 4 bytes of initial SP (loaded on reset)
37 * 4 bytes of initial PC (loaded on reset)
38 * binary image with entry point 0x00000008
39 *
40 * We put our bootloader code at 0x000e0000
41 * and patch reset vector to jump directly
42 * into our code on reset
43 */
44
45static unsigned char image[OF_FIRMWARE_LEN];
46
47static unsigned int get_uint32be(unsigned char* p)
48{
49 return ((p[0] << 24) | (p[1] << 16) | (p[2]<<8) | p[3]);
50}
51
52static long checksum(unsigned char* buf, unsigned long length)
53{
54 unsigned long chksum = 69; /* MPIO HD200 model number */
55 unsigned long i;
56
57 if(buf == NULL)
58 return -1;
59
60 for (i = 0; i < length; i++)
61 {
62 chksum += *buf++;
63 }
64
65return chksum;
66}
67
68int mkmpioboot(const char* infile, const char* bootfile, const char* outfile, int origin)
69{
70 FILE *f;
71 int i;
72 int len;
73 unsigned long file_checksum;
74 unsigned char header_checksum[4];
75
76 memset(image, 0xff, sizeof(image));
77
78 /* First, read the mpio original firmware into the image */
79 f = fopen(infile, "rb");
80 if(!f) {
81 perror(infile);
82 return -1;
83 }
84
85 i = fread(image, 1, OF_FIRMWARE_LEN, f);
86 if(i < OF_FIRMWARE_LEN) {
87 perror(infile);
88 fclose(f);
89 return -2;
90 }
91
92 fclose(f);
93
94 /* Now check if we have OF file loaded based on presence
95 * of the version string in firmware
96 */
97
98 if (strcmp((char*)(image + MPIO_STRING_OFFSET),mpio_string) != 0)
99 {
100 perror("Loaded firmware file does not look like MPIO OF file!");
101 return -3;
102 }
103
104 /* Now, read the boot loader into the image */
105 f = fopen(bootfile, "rb");
106 if(!f) {
107 perror(bootfile);
108 fclose(f);
109 return -4;
110 }
111
112 /* get bootloader size
113 * excluding header
114 */
115 fseek(f, 0, SEEK_END);
116 len = ftell(f) - 8;
117
118 /* Now check if the place we want to put
119 * our bootloader is free
120 */
121 for(i=0;i<len;i++)
122 {
123 if (image[origin+i] != 0)
124 {
125 perror("Place for bootloader in OF file not empty");
126 return -5;
127 }
128 }
129
130 fseek(f, 0, SEEK_SET);
131
132 /* get bootloader checksum from the header*/
133 fread(header_checksum,1,4,f);
134
135 /* omit header */
136 fseek(f, 8, SEEK_SET);
137
138 i = fread(image + origin, 1, len, f);
139 if(i < len) {
140 perror(bootfile);
141 fclose(f);
142 return -6;
143 }
144
145 fclose(f);
146
147 /* calculate checksum and compare with data
148 * from header
149 */
150 file_checksum = checksum(image + origin, len);
151
152 if ( file_checksum != get_uint32be(header_checksum) )
153 {
154 printf("Bootloader checksum error\n");
155 return -7;
156 }
157
158 f = fopen(outfile, "wb");
159 if(!f) {
160 perror(outfile);
161 return -8;
162 }
163
164 /* Patch the stack pointer address */
165 image[0] = image[origin + 0];
166 image[1] = image[origin + 1];
167 image[2] = image[origin + 2];
168 image[3] = image[origin + 3];
169
170 /* Patch the reset vector to start the boot loader */
171 image[4] = image[origin + 4];
172 image[5] = image[origin + 5];
173 image[6] = image[origin + 6];
174 image[7] = image[origin + 7];
175
176 i = fwrite(image, 1, OF_FIRMWARE_LEN, f);
177 if(i < OF_FIRMWARE_LEN) {
178 perror(outfile);
179 fclose(f);
180 return -9;
181 }
182
183 printf("Wrote 0x%x bytes in %s\n", OF_FIRMWARE_LEN, outfile);
184
185 fclose(f);
186
187 return 0;
188}
diff --git a/rbutil/mkmpioboot/mkmpioboot.h b/rbutil/mkmpioboot/mkmpioboot.h
new file mode 100644
index 0000000000..794f9df765
--- /dev/null
+++ b/rbutil/mkmpioboot/mkmpioboot.h
@@ -0,0 +1,37 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2010 by Marcin Bukat
11 * code based mainly on mkboot.h
12 * Copyright (C) 2008 by Dominik Riebeling
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#ifndef MKMPIOBOOT_H
25#define MKMPIOBOOT_H
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31int mkmpioboot(const char* infile, const char* bootfile, const char* outfile, int origin);
32
33#ifdef __cplusplus
34}
35#endif
36#endif
37