2b9e944021
Also support the e200 with this code. Apparently it's also possible to get the e200 in a state where .fmt files don't help. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30413 a1c6a512-1295-4272-9138-f99709370657
250 lines
6.7 KiB
C
250 lines
6.7 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id: main-e200r-installer.c 15599 2007-11-12 18:49:53Z amiconn $
|
|
*
|
|
* Copyright (C) 2011 by Frank Gevaerts
|
|
*
|
|
* All files in this archive are subject to the GNU General Public License.
|
|
* See the file COPYING in the source tree root for full license agreement.
|
|
*
|
|
* 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 "common.h"
|
|
#include "cpu.h"
|
|
#include "file.h"
|
|
#include "system.h"
|
|
#include "kernel.h"
|
|
#include "lcd.h"
|
|
#include "font.h"
|
|
#include "storage.h"
|
|
#include "button.h"
|
|
#include "disk.h"
|
|
#include "crc32-mi4.h"
|
|
#include <string.h>
|
|
#include "i2c.h"
|
|
#include "backlight-target.h"
|
|
#include "power.h"
|
|
|
|
unsigned char zero[1024*64];
|
|
unsigned char nonzero[1024*64];
|
|
unsigned char scratch[1024*64];
|
|
struct storage_info info;
|
|
|
|
int format_partition(int start, int size);
|
|
|
|
#define SPT 63
|
|
#define HPC 255
|
|
|
|
int c(int lba)
|
|
{
|
|
return lba/(SPT * HPC);
|
|
}
|
|
int h(int lba)
|
|
{
|
|
return (lba/SPT)%HPC;
|
|
}
|
|
int s(int lba)
|
|
{
|
|
return (lba%SPT) + 1;
|
|
}
|
|
|
|
int write_mbr(int datastart,int datasize, int firmwarestart, int firmwaresize)
|
|
{
|
|
unsigned char mbr[512];
|
|
memset(mbr,0,512);
|
|
mbr[446]=0x80; /* flags */
|
|
mbr[447]=h(datastart); /* chs1[0] (h) */
|
|
mbr[448]=s(datastart); /* chs1[1] (s) */
|
|
mbr[449]=c(datastart); /* chs1[2] (c) */
|
|
mbr[450]=0x0b; /* type */
|
|
mbr[451]=h(datastart+datasize-1); /* chs2[0] (h) */
|
|
mbr[452]=s(datastart+datasize-1); /* chs2[1] (s) */
|
|
mbr[453]=c(datastart+datasize-1); /* chs2[2] (c) */
|
|
mbr[454]=(datastart&0x000000ff); /* lba[0] */
|
|
mbr[455]=(datastart&0x0000ff00) >>8; /* lba[1] */
|
|
mbr[456]=(datastart&0x00ff0000) >>16; /* lba[2] */
|
|
mbr[457]=(datastart&0xff000000) >>24; /* lba[3] */
|
|
mbr[458]=(datasize&0x000000ff); /* size[0] */
|
|
mbr[459]=(datasize&0x0000ff00) >>8; /* size[1] */
|
|
mbr[460]=(datasize&0x00ff0000) >>16; /* size[2] */
|
|
mbr[461]=(datasize&0xff000000) >>24; /* size[3] */
|
|
|
|
mbr[462]=0; /* flags */
|
|
mbr[463]=h(firmwarestart); /* chs1[0] (h) */
|
|
mbr[464]=s(firmwarestart); /* chs1[1] (s) */
|
|
mbr[465]=c(firmwarestart); /* chs1[2] (c) */
|
|
mbr[466]=0x84; /* type */
|
|
mbr[467]=h(firmwarestart+firmwaresize-1); /* chs2[0] (h) */
|
|
mbr[468]=s(firmwarestart+firmwaresize-1); /* chs2[1] (s) */
|
|
mbr[469]=c(firmwarestart+firmwaresize-1); /* chs2[2] (c) */
|
|
mbr[470]=(firmwarestart&0x000000ffu); /* lba[0] */
|
|
mbr[471]=(firmwarestart&0x0000ff00u) >>8; /* lba[1] */
|
|
mbr[472]=(firmwarestart&0x00ff0000u) >>16; /* lba[2] */
|
|
mbr[473]=(firmwarestart&0xff000000u) >>24; /* lba[3] */
|
|
mbr[474]=(firmwaresize&0x000000ffu); /* size[0] */
|
|
mbr[475]=(firmwaresize&0x0000ff00u) >>8; /* size[1] */
|
|
mbr[476]=(firmwaresize&0x00ff0000u) >>16; /* size[2] */
|
|
mbr[477]=(firmwaresize&0xff000000u) >>24; /* size[3] */
|
|
|
|
mbr[510]=0x55;
|
|
mbr[511]=0xaa;
|
|
|
|
int res = storage_write_sectors(0,1,mbr);
|
|
if(res != 0)
|
|
{
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* Hack. We "steal" line from common.c to reset the line number
|
|
* so we can overwrite the previous line for nicer progress info
|
|
*/
|
|
extern int line;
|
|
int wipe(int size, int verify)
|
|
{
|
|
int i;
|
|
int res;
|
|
int sectors = sizeof(nonzero)/512;
|
|
for(i=0;i<size;i+=sectors)
|
|
{
|
|
if(verify)
|
|
{
|
|
res = storage_write_sectors(i,sectors,nonzero);
|
|
if(res != 0)
|
|
{
|
|
printf("write error (1) on sector %d (of %d)!",i,size);
|
|
return -1;
|
|
}
|
|
res = storage_read_sectors(i,sectors,scratch);
|
|
if(res != 0)
|
|
{
|
|
printf("read error (1) on sector %d (of %d)!",i,size);
|
|
return -1;
|
|
}
|
|
res = memcmp(nonzero, scratch, sizeof(nonzero));
|
|
if(res != 0)
|
|
{
|
|
printf("compare error (1) on sector %d (of %d)!",i,size);
|
|
return -1;
|
|
}
|
|
}
|
|
res = storage_write_sectors(i,sectors,zero);
|
|
if(res != 0)
|
|
{
|
|
printf("write error (2) on sector %d (of %d)!",i,size);
|
|
return -1;
|
|
}
|
|
if(verify)
|
|
{
|
|
res = storage_read_sectors(i,sectors,scratch);
|
|
if(res != 0)
|
|
{
|
|
printf("read error (2) on sector %d (of %d)!",i,size);
|
|
return -1;
|
|
}
|
|
res = memcmp(zero, scratch, sizeof(nonzero));
|
|
if(res != 0)
|
|
{
|
|
printf("compare error (2) on sector %d (of %d)!",i,size);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if(i%2048 == 0)
|
|
{
|
|
printf("%d of %d MB done",i/2048, size/2048);
|
|
/* Hack to overwrite the previous line */
|
|
line--;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void* main(void)
|
|
{
|
|
int i;
|
|
int btn;
|
|
|
|
chksum_crc32gentab ();
|
|
|
|
system_init();
|
|
kernel_init();
|
|
lcd_init();
|
|
font_init();
|
|
button_init();
|
|
i2c_init();
|
|
_backlight_on();
|
|
|
|
lcd_set_foreground(LCD_WHITE);
|
|
lcd_set_background(LCD_BLACK);
|
|
lcd_clear_display();
|
|
|
|
btn = button_read_device();
|
|
verbose = true;
|
|
|
|
lcd_setfont(FONT_SYSFIXED);
|
|
|
|
printf("Sansa initialiser");
|
|
printf("");
|
|
|
|
|
|
i=storage_init();
|
|
disk_init(IF_MD(0));
|
|
|
|
storage_get_info(0,&info);
|
|
int size = info.num_sectors;
|
|
memset(zero,0,sizeof(zero));
|
|
memset(nonzero,0xff,sizeof(nonzero));
|
|
printf("Zeroing flash");
|
|
int res;
|
|
|
|
res = wipe(size, 0);
|
|
if(res != 0)
|
|
{
|
|
printf("error wiping flash");
|
|
}
|
|
|
|
int firmwaresize = 0xa000;
|
|
int firmwarestart = size - firmwaresize;
|
|
int datastart = 600;
|
|
int datasize = firmwarestart - datastart;
|
|
|
|
res = write_mbr(datastart,datasize,firmwarestart,firmwaresize);
|
|
if(res != 0)
|
|
{
|
|
printf("error writing mbr");
|
|
}
|
|
res = format_partition(datastart, datasize);
|
|
if(res != 0)
|
|
{
|
|
printf("error formatting");
|
|
}
|
|
|
|
printf("Wipe done.");
|
|
if (button_hold())
|
|
printf("Release Hold and");
|
|
printf("press any key to");
|
|
printf("shutdown.");
|
|
|
|
printf("Remember to use");
|
|
printf("manufacturing");
|
|
printf("mode to recover");
|
|
printf("further");
|
|
|
|
while(button_read_device() == BUTTON_NONE);
|
|
|
|
power_off();
|
|
|
|
return NULL;
|
|
}
|