1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
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 */
60 for (i
= 0; i
< length
; i
++)
68 int mkmpioboot(const char* infile
, const char* bootfile
, const char* outfile
, int origin
)
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");
85 i
= fread(image
, 1, OF_FIRMWARE_LEN
, f
);
86 if(i
< OF_FIRMWARE_LEN
) {
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!");
104 /* Now, read the boot loader into the image */
105 f
= fopen(bootfile
, "rb");
112 /* get bootloader size
115 fseek(f
, 0, SEEK_END
);
118 /* Now check if the place we want to put
119 * our bootloader is free
123 if (image
[origin
+i
] != 0)
125 perror("Place for bootloader in OF file not empty");
130 fseek(f
, 0, SEEK_SET
);
132 /* get bootloader checksum from the header*/
133 fread(header_checksum
,1,4,f
);
136 fseek(f
, 8, SEEK_SET
);
138 i
= fread(image
+ origin
, 1, len
, f
);
147 /* calculate checksum and compare with data
150 file_checksum
= checksum(image
+ origin
, len
);
152 if ( file_checksum
!= get_uint32be(header_checksum
) )
154 printf("Bootloader checksum error\n");
158 f
= fopen(outfile
, "wb");
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
) {
183 printf("Wrote 0x%x bytes in %s\n", OF_FIRMWARE_LEN
, outfile
);