/*************************************************************************** * __________ __ ___. * 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 #include #include #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