Use DBOP to check for left button on C200v2 like we are supposed to instead of right...
[kugel-rb.git] / rbutil / mkmpioboot / mkmpioboot.c
blob6d52e53f0966aa0132f020b9020520f57717fa0e
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
10 * Copyright (C) 2010 by Marcin Bukat
12 * code taken mostly from mkboot.c
13 * Copyright (C) 2005 by Linus Nielsen Feltzing
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.
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
23 ****************************************************************************/
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include "mkmpioboot.h"
29 #define OF_FIRMWARE_LEN 0x100000 /* size of HD200_UPG.SYS file */
30 #define MPIO_STRING_OFFSET 0xfffe0
32 /* We support only 1.30.05 version of OF for now */
33 static char *mpio_string = "HD200 HDD Audio Ver113005";
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
40 * We put our bootloader code at 0x000e0000
41 * and patch reset vector to jump directly
42 * into our code on reset
45 static unsigned char image[OF_FIRMWARE_LEN];
47 static unsigned int get_uint32be(unsigned char* p)
49 return ((p[0] << 24) | (p[1] << 16) | (p[2]<<8) | p[3]);
52 static long checksum(unsigned char* buf, unsigned long length)
54 unsigned long chksum = 69; /* MPIO HD200 model number */
55 unsigned long i;
57 if(buf == NULL)
58 return -1;
60 for (i = 0; i < length; i++)
62 chksum += *buf++;
65 return chksum;
68 int mkmpioboot(const char* infile, const char* bootfile, const char* outfile, int origin)
70 FILE *f;
71 int i;
72 int len;
73 unsigned long file_checksum;
74 unsigned char header_checksum[4];
76 memset(image, 0xff, sizeof(image));
78 /* First, read the mpio original firmware into the image */
79 f = fopen(infile, "rb");
80 if(!f) {
81 perror(infile);
82 return -1;
85 i = fread(image, 1, OF_FIRMWARE_LEN, f);
86 if(i < OF_FIRMWARE_LEN) {
87 perror(infile);
88 fclose(f);
89 return -2;
92 fclose(f);
94 /* Now check if we have OF file loaded based on presence
95 * of the version string in firmware
98 if (strcmp((char*)(image + MPIO_STRING_OFFSET),mpio_string) != 0)
100 perror("Loaded firmware file does not look like MPIO OF file!");
101 return -3;
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;
112 /* get bootloader size
113 * excluding header
115 fseek(f, 0, SEEK_END);
116 len = ftell(f) - 8;
118 /* Now check if the place we want to put
119 * our bootloader is free
121 for(i=0;i<len;i++)
123 if (image[origin+i] != 0)
125 perror("Place for bootloader in OF file not empty");
126 return -5;
130 fseek(f, 0, SEEK_SET);
132 /* get bootloader checksum from the header*/
133 fread(header_checksum,1,4,f);
135 /* omit header */
136 fseek(f, 8, SEEK_SET);
138 i = fread(image + origin, 1, len, f);
139 if(i < len) {
140 perror(bootfile);
141 fclose(f);
142 return -6;
145 fclose(f);
147 /* calculate checksum and compare with data
148 * from header
150 file_checksum = checksum(image + origin, len);
152 if ( file_checksum != get_uint32be(header_checksum) )
154 printf("Bootloader checksum error\n");
155 return -7;
158 f = fopen(outfile, "wb");
159 if(!f) {
160 perror(outfile);
161 return -8;
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];
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];
176 i = fwrite(image, 1, OF_FIRMWARE_LEN, f);
177 if(i < OF_FIRMWARE_LEN) {
178 perror(outfile);
179 fclose(f);
180 return -9;
183 printf("Wrote 0x%x bytes in %s\n", OF_FIRMWARE_LEN, outfile);
185 fclose(f);
187 return 0;