summaryrefslogtreecommitdiffstats
path: root/rbutil
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil')
-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 @@
+
+#change for releases
+ifndef APPVERSION
+APPVERSION=`../../tools/version.sh ../../`
+endif
+
+# We use the UCL code available in the Rockbox tools/ directory
+CFLAGS=-I../../tools/ucl/include -Wall -DVERSION=\"$(APPVERSION)\"
+
+ifndef V
+SILENT = @
+endif
+
+ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
+OUTPUT=mkmpioboot.exe
+CFLAGS+=-mno-cygwin
+else
+ifeq ($(findstring MINGW,$(shell uname)),MINGW)
+OUTPUT=mkmpioboot.exe
+else
+ifeq ($(findstring mingw,$(CC)),mingw)
+OUTPUT=mkmpioboot.exe
+else
+OUTPUT=mkmpioboot
+endif
+endif
+endif
+
+ifdef RBARCH
+CFLAGS += -arch $(RBARCH)
+OBJDIR = $(RBARCH)/
+endif
+
+
+all: $(OUTPUT)
+
+# inputs
+LIBSOURCES := mkmpioboot.c
+SOURCES := $(LIBSOURCES) main.c
+OBJS := $(patsubst %.c,%.o,$(addprefix $(OBJDIR),$(SOURCES)))
+LIBOBJS := $(patsubst %.c,%.o,$(addprefix $(OBJDIR),$(LIBSOURCES)))
+EXTRADEPS := $(LIBUCL)
+
+# explicit dependencies
+$(OBJDIR)mkmpioboot.o: mkmpioboot.c mkmpioboot.h
+$(OBJDIR)main.o: main.c
+
+$(OBJDIR)%.o: %.c
+ @echo CC $< $
+ $(SILENT)mkdir -p $(dir $@)
+ $(SILENT)$(CC) $(CFLAGS) -c -o $@ $<
+
+libmkamsboot$(RBARCH).a: $(LIBOBJS)
+ @echo AR $@
+ $(SILENT)$(AR) ruc $(TARGET_DIR)$@ $^
+
+# building the standalone executable
+$(OUTPUT): $(OBJS) $(EXTRADEPS)
+ @echo LD $@
+ $(SILENT)$(CC) $(CFLAGS) -o $(OUTPUT) $(OBJS) $(EXTRADEPS)
+
+# some trickery to build ppc and i386 from a single call
+ifeq ($(RBARCH),)
+$(TARGET_DIR)libmkmpiobooti386.a:
+ make RBARCH=i386 TARGET_DIR=$(TARGET_DIR) libmkmpiobooti386.a
+
+$(TARGET_DIR)libmkmpiobootppc.a:
+ make RBARCH=ppc TARGET_DIR=$(TARGET_DIR) libmkmpiobootppc.a
+endif
+
+libmkmpioboot-universal: $(TARGET_DIR)libmkmpiobooti386.a $(TARGET_DIR)libmkmpiobootppc.a
+ @echo lipo $(TARGET_DIR)libmkmpioboot.a
+ $(SILENT) rm -f $(TARGET_DIR)libmkmpioboot.a
+ $(SILENT)lipo -create $(TARGET_DIR)libmkmpiobootppc.a $(TARGET_DIR)libmkmpiobooti386.a -output $(TARGET_DIR)libmkmpioboot.a
+
+clean:
+ rm -f $(OBJS) $(OUTPUT) libmkmpioboot.o $(TARGET_DIR)libmkmpioboot*.a mkmpioboot.dmg
+ rm -rf mkmpioboot-* i386 ppc $(OBJDIR)
+
+mkmpioboot-i386:
+ $(MAKE) RBARCH=i386
+ mv mkmpioboot mkmpioboot-i386
+
+mkmpioboot-ppc:
+ $(MAKE) RBARCH=ppc
+ mv mkmpioboot mkmpioboot-ppc
+
+mkmpioboot-mac: mkmpioboot-i386 mkmpioboot-ppc
+ $(SILENT)lipo -create mkmpioboot-ppc mkmpioboot-i386 -output mkmpioboot-mac
+
+mkmpioboot.dmg: mkmpioboot-mac
+ mkdir -p mkmpioboot-dmg
+ cp -p mkmpioboot-mac mkmpioboot-dmg
+ 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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 by Marcin Bukat
+ *
+ * code taken mostly from mkboot.c
+ * Copyright (C) 2005 by Linus Nielsen Feltzing
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include "mkmpioboot.h"
+
+static void usage(void)
+{
+ printf("usage: mkmpioboot <firmware file> <boot file> <output file>\n");
+ exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+ char *infile, *bootfile, *outfile;
+ int origin = 0xe0000; /* MPIO HD200 bootloader address */
+
+ if(argc < 3) {
+ usage();
+ }
+
+ infile = argv[1];
+ bootfile = argv[2];
+ outfile = argv[3];
+
+ return mkmpioboot(infile, bootfile, outfile, origin);
+}
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 by Marcin Bukat
+ *
+ * code taken mostly from mkboot.c
+ * Copyright (C) 2005 by Linus Nielsen Feltzing
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mkmpioboot.h"
+
+#define OF_FIRMWARE_LEN 0x100000 /* size of HD200_UPG.SYS file */
+#define MPIO_STRING_OFFSET 0xfffe0
+
+/* We support only 1.30.05 version of OF for now */
+static char *mpio_string = "HD200 HDD Audio Ver113005";
+
+/* MPIO HD200 firmware is plain binary image
+ * 4 bytes of initial SP (loaded on reset)
+ * 4 bytes of initial PC (loaded on reset)
+ * binary image with entry point 0x00000008
+ *
+ * We put our bootloader code at 0x000e0000
+ * and patch reset vector to jump directly
+ * into our code on reset
+ */
+
+static unsigned char image[OF_FIRMWARE_LEN];
+
+static unsigned int get_uint32be(unsigned char* p)
+{
+ return ((p[0] << 24) | (p[1] << 16) | (p[2]<<8) | p[3]);
+}
+
+static long checksum(unsigned char* buf, unsigned long length)
+{
+ unsigned long chksum = 69; /* MPIO HD200 model number */
+ unsigned long i;
+
+ if(buf == NULL)
+ return -1;
+
+ for (i = 0; i < length; i++)
+ {
+ chksum += *buf++;
+ }
+
+return chksum;
+}
+
+int mkmpioboot(const char* infile, const char* bootfile, const char* outfile, int origin)
+{
+ FILE *f;
+ int i;
+ int len;
+ unsigned long file_checksum;
+ unsigned char header_checksum[4];
+
+ memset(image, 0xff, sizeof(image));
+
+ /* First, read the mpio original firmware into the image */
+ f = fopen(infile, "rb");
+ if(!f) {
+ perror(infile);
+ return -1;
+ }
+
+ i = fread(image, 1, OF_FIRMWARE_LEN, f);
+ if(i < OF_FIRMWARE_LEN) {
+ perror(infile);
+ fclose(f);
+ return -2;
+ }
+
+ fclose(f);
+
+ /* Now check if we have OF file loaded based on presence
+ * of the version string in firmware
+ */
+
+ if (strcmp((char*)(image + MPIO_STRING_OFFSET),mpio_string) != 0)
+ {
+ perror("Loaded firmware file does not look like MPIO OF file!");
+ return -3;
+ }
+
+ /* Now, read the boot loader into the image */
+ f = fopen(bootfile, "rb");
+ if(!f) {
+ perror(bootfile);
+ fclose(f);
+ return -4;
+ }
+
+ /* get bootloader size
+ * excluding header
+ */
+ fseek(f, 0, SEEK_END);
+ len = ftell(f) - 8;
+
+ /* Now check if the place we want to put
+ * our bootloader is free
+ */
+ for(i=0;i<len;i++)
+ {
+ if (image[origin+i] != 0)
+ {
+ perror("Place for bootloader in OF file not empty");
+ return -5;
+ }
+ }
+
+ fseek(f, 0, SEEK_SET);
+
+ /* get bootloader checksum from the header*/
+ fread(header_checksum,1,4,f);
+
+ /* omit header */
+ fseek(f, 8, SEEK_SET);
+
+ i = fread(image + origin, 1, len, f);
+ if(i < len) {
+ perror(bootfile);
+ fclose(f);
+ return -6;
+ }
+
+ fclose(f);
+
+ /* calculate checksum and compare with data
+ * from header
+ */
+ file_checksum = checksum(image + origin, len);
+
+ if ( file_checksum != get_uint32be(header_checksum) )
+ {
+ printf("Bootloader checksum error\n");
+ return -7;
+ }
+
+ f = fopen(outfile, "wb");
+ if(!f) {
+ perror(outfile);
+ return -8;
+ }
+
+ /* Patch the stack pointer address */
+ image[0] = image[origin + 0];
+ image[1] = image[origin + 1];
+ image[2] = image[origin + 2];
+ image[3] = image[origin + 3];
+
+ /* Patch the reset vector to start the boot loader */
+ image[4] = image[origin + 4];
+ image[5] = image[origin + 5];
+ image[6] = image[origin + 6];
+ image[7] = image[origin + 7];
+
+ i = fwrite(image, 1, OF_FIRMWARE_LEN, f);
+ if(i < OF_FIRMWARE_LEN) {
+ perror(outfile);
+ fclose(f);
+ return -9;
+ }
+
+ printf("Wrote 0x%x bytes in %s\n", OF_FIRMWARE_LEN, outfile);
+
+ fclose(f);
+
+ return 0;
+}
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 by Marcin Bukat
+ * code based mainly on mkboot.h
+ * Copyright (C) 2008 by Dominik Riebeling
+ *
+ * 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 MKMPIOBOOT_H
+#define MKMPIOBOOT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int mkmpioboot(const char* infile, const char* bootfile, const char* outfile, int origin);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+