summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Hohensohn <hohensoh@rockbox.org>2003-10-26 21:23:04 +0000
committerJörg Hohensohn <hohensoh@rockbox.org>2003-10-26 21:23:04 +0000
commita63cf9b392f1d3cf241bfab0e6badd0acc3cf6a5 (patch)
treee3531598d0f0a09f226657c16f4ac68038291cbf
parentf11d07c61f4d30c0f47a1a3685e116670bab29ca (diff)
downloadrockbox-a63cf9b392f1d3cf241bfab0e6badd0acc3cf6a5.zip
rockbox-a63cf9b392f1d3cf241bfab0e6badd0acc3cf6a5.tar.gz
rockbox-a63cf9b392f1d3cf241bfab0e6badd0acc3cf6a5.tar.bz2
rockbox-a63cf9b392f1d3cf241bfab0e6badd0acc3cf6a5.tar.xz
the plugin is now prepared to flash the "V2" variant: boxes without boot ROM which start from flash mirrored to address zero
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3988 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/firmware_flash.c141
1 files changed, 106 insertions, 35 deletions
diff --git a/apps/plugins/firmware_flash.c b/apps/plugins/firmware_flash.c
index d24a174..2574cb9 100644
--- a/apps/plugins/firmware_flash.c
+++ b/apps/plugins/firmware_flash.c
@@ -39,13 +39,13 @@
#endif
#if defined(ARCHOS_PLAYER)
-#define FILENAME "/firmware_play.bin"
+#define FILE_TYPE "player"
#define KEEP VERSION_ADR /* keep the firmware version */
#elif defined(ARCHOS_RECORDER)
-#define FILENAME "/firmware_rec.bin"
+#define FILE_TYPE "rec"
#define KEEP MASK_ADR /* keep the mask value */
#elif defined(ARCHOS_FMRECORDER)
-#define FILENAME "/firmware_fm.bin"
+#define FILE_TYPE "fm"
#define KEEP MASK_ADR /* keep the mask value */
#else
#error ("No known platform given!")
@@ -63,6 +63,14 @@ typedef enum
eCrcErr,
} tCheckResult;
+/* result of the CheckBootROM() function */
+typedef enum
+{
+ eBootROM, /* the supported boot ROM */
+ eUnknown, /* unknown boot ROM */
+ eROMless, /* flash mapped to zero */
+} tCheckROM;
+
typedef struct
{
UINT8 manufacturer;
@@ -244,7 +252,7 @@ unsigned crc_32(unsigned char* buf, unsigned len, unsigned crc32)
/*********** Firmware File Functions ************/
-tCheckResult CheckFirmwareFile(char* filename, int chipsize)
+tCheckResult CheckFirmwareFile(char* filename, int chipsize, bool is_romless)
{
int i;
int fd;
@@ -296,20 +304,31 @@ tCheckResult CheckFirmwareFile(char* filename, int chipsize)
if (has_crc)
crc32 = crc_32(sector, SEC_SIZE, crc32); /* checksum */
- /* compare some bytes which have to be identical */
- if (*(UINT32*)sector != 0x41524348) /* "ARCH" */
- {
- rb->close(fd);
- return eBadContent;
+ if (is_romless)
+ { /* in this case, there is not much we can check */
+ if (*(UINT32*)sector != 0x00000200) /* reset vector */
+ {
+ rb->close(fd);
+ return eBadContent;
+ }
}
-
- for (i = 0x30; i<MASK_ADR-1; i++) /* leave one byte for me */
+ else
{
- if (sector[i] != FB[i])
+ /* compare some bytes which have to be identical */
+ if (*(UINT32*)sector != 0x41524348) /* "ARCH" */
{
rb->close(fd);
return eBadContent;
}
+
+ for (i = 0x30; i<MASK_ADR-1; i++) /* leave one byte for me */
+ {
+ if (sector[i] != FB[i])
+ {
+ rb->close(fd);
+ return eBadContent;
+ }
+ }
}
/* check if we can read the whole file, and do checksum */
@@ -431,6 +450,32 @@ unsigned VerifyFirmwareFile(char* filename)
return failures;
}
+/***************** Support Functions *****************/
+
+/* check if we have "normal" boot ROM or flash mirrored to zero */
+tCheckROM CheckBootROM(void)
+{
+ unsigned boot_crc;
+ unsigned* pFlash = (unsigned*)FB;
+ unsigned* pRom = (unsigned*)0x0;
+ unsigned i;
+
+ boot_crc = crc_32((unsigned char*)0x0, 64*1024, 0xFFFFFFFF);
+ if (boot_crc == 0x56DBA4EE) /* the known boot ROM */
+ return eBootROM;
+
+ /* check if ROM is a flash mirror */
+ for (i=0; i<256*1024/sizeof(unsigned); i++)
+ {
+ if (*pRom++ != *pFlash++)
+ { /* difference means no mirror */
+ return eUnknown;
+ }
+ }
+
+ return eROMless;
+}
+
/***************** User Interface Functions *****************/
@@ -484,24 +529,39 @@ void ShowFlashInfo(tFlashInfo* pInfo)
/* Kind of our main function, defines the application flow. */
-void DoUserDialog(void)
+void DoUserDialog(char* filename)
{
tFlashInfo FlashInfo;
char buf[32];
+ char default_filename[32];
int button;
int rc; /* generic return code */
int memleft;
- unsigned boot_crc;
+ tCheckROM result;
+ bool is_romless;
rb->lcd_setfont(FONT_SYSFIXED);
/* check boot ROM */
- boot_crc = crc_32((unsigned char*)0x0, 64*1024, 0xFFFFFFFF);
- if (boot_crc != 0x56DBA4EE) /* Version 1 */
+ result = CheckBootROM();
+ if (result == eUnknown)
{ /* no support for any other yet */
rb->splash(HZ*3, 0, true, "Wrong boot ROM");
return; /* exit */
}
+ is_romless = (result == eROMless);
+
+ /* compose filename if none given */
+ if (filename == NULL)
+ {
+ rb->snprintf(
+ default_filename,
+ sizeof(default_filename),
+ "/firmware_%s%s.bin",
+ FILE_TYPE,
+ is_romless ? "_norom" : "");
+ filename = default_filename;
+ }
/* "allocate" memory */
sector = rb->plugin_get_buffer(&memleft);
@@ -520,7 +580,7 @@ void DoUserDialog(void)
}
rb->lcd_puts(0, 3, "using file:");
- rb->lcd_puts(0, 4, FILENAME);
+ rb->lcd_puts_scroll(0, 4, filename);
rb->lcd_puts(0, 6, "[F1] to check file");
rb->lcd_puts(0, 7, "other key to exit");
rb->lcd_update();
@@ -535,7 +595,7 @@ void DoUserDialog(void)
rb->lcd_puts(0, 0, "checking...");
rb->lcd_update();
- rc = CheckFirmwareFile(FILENAME, FlashInfo.size);
+ rc = CheckFirmwareFile(filename, FlashInfo.size, is_romless);
rb->lcd_puts(0, 0, "checked:");
switch (rc)
{
@@ -545,7 +605,7 @@ void DoUserDialog(void)
case eFileNotFound:
rb->lcd_puts(0, 1, "File not found.");
rb->lcd_puts(0, 2, "Put this in root:");
- rb->lcd_puts(0, 4, FILENAME);
+ rb->lcd_puts_scroll(0, 4, filename);
break;
case eTooBig:
rb->lcd_puts(0, 1, "File too big,");
@@ -611,7 +671,7 @@ void DoUserDialog(void)
rb->lcd_puts(0, 0, "Programming...");
rb->lcd_update();
- rc = ProgramFirmwareFile(FILENAME, FlashInfo.size);
+ rc = ProgramFirmwareFile(filename, FlashInfo.size);
if (rc)
{ /* errors */
rb->lcd_clear_display();
@@ -627,7 +687,7 @@ void DoUserDialog(void)
rb->lcd_puts(0, 0, "Verifying...");
rb->lcd_update();
- rc = VerifyFirmwareFile(FILENAME);
+ rc = VerifyFirmwareFile(filename);
rb->lcd_clear_display();
if (rc == 0)
@@ -681,22 +741,37 @@ void ShowFlashInfo(tFlashInfo* pInfo)
}
-void DoUserDialog(void)
+void DoUserDialog(char* filename)
{
tFlashInfo FlashInfo;
char buf[32];
+ char default_filename[32];
int button;
int rc; /* generic return code */
int memleft;
- unsigned boot_crc;
+ tCheckROM result;
+ bool is_romless;
/* check boot ROM */
- boot_crc = crc_32((unsigned char*)0x0, 64*1024, 0xFFFFFFFF);
- if (boot_crc != 0x56DBA4EE) /* Version 1 */
+ result = CheckBootROM();
+ if (result == eUnknown)
{ /* no support for any other yet */
rb->splash(HZ*3, 0, true, "Wrong boot ROM");
return; /* exit */
}
+ is_romless = (result == eROMless);
+
+ /* compose filename if none given */
+ if (filename == NULL)
+ {
+ rb->snprintf(
+ default_filename,
+ sizeof(default_filename),
+ "/firmware_%s%s.bin",
+ FILE_TYPE,
+ is_romless ? "_norom" : "");
+ filename = default_filename;
+ }
/* "allocate" memory */
sector = rb->plugin_get_buffer(&memleft);
@@ -714,7 +789,7 @@ void DoUserDialog(void)
return; /* exit */
}
- rb->lcd_puts_scroll(0, 0, FILENAME);
+ rb->lcd_puts_scroll(0, 0, filename);
rb->lcd_puts_scroll(0, 1, "[Menu] to check");
button = WaitForButton();
@@ -726,7 +801,7 @@ void DoUserDialog(void)
rb->lcd_clear_display();
rb->lcd_puts(0, 0, "Checking...");
- rc = CheckFirmwareFile(FILENAME, FlashInfo.size);
+ rc = CheckFirmwareFile(filename, FlashInfo.size, is_romless);
rb->lcd_puts(0, 0, "Checked:");
switch (rc)
{
@@ -735,7 +810,7 @@ void DoUserDialog(void)
break;
case eFileNotFound:
rb->lcd_puts_scroll(0, 0, "File not found:");
- rb->lcd_puts_scroll(0, 1, FILENAME);
+ rb->lcd_puts_scroll(0, 1, filename);
break;
case eTooBig:
rb->lcd_puts_scroll(0, 0, "File too big,");
@@ -794,7 +869,7 @@ void DoUserDialog(void)
rb->lcd_clear_display();
rb->lcd_puts_scroll(0, 0, "Programming...");
- rc = ProgramFirmwareFile(FILENAME, FlashInfo.size);
+ rc = ProgramFirmwareFile(filename, FlashInfo.size);
if (rc)
{ /* errors */
@@ -808,7 +883,7 @@ void DoUserDialog(void)
rb->lcd_clear_display();
rb->lcd_puts_scroll(0, 0, "Verifying...");
- rc = VerifyFirmwareFile(FILENAME);
+ rc = VerifyFirmwareFile(filename);
rb->lcd_clear_display();
@@ -838,14 +913,10 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
matches the machine it is running on */
TEST_PLUGIN_API(api);
- /* if you don't use the parameter, you can do like
- this to avoid the compiler warning about it */
- (void)parameter;
-
rb = api; /* copy to global api pointer */
/* now go ahead and have fun! */
- DoUserDialog();
+ DoUserDialog((char*) parameter);
return PLUGIN_OK;
}