summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2007-01-12 18:34:00 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2007-01-12 18:34:00 +0000
commit0ea4d3197ed7e56f39c630741cb69152ac9e41de (patch)
treebc29ccef30da139df3e928fd3b8ff3801407b58c
parent12ef310466937551dbedb2165769d7832b11156c (diff)
downloadrockbox-0ea4d3197ed7e56f39c630741cb69152ac9e41de.zip
rockbox-0ea4d3197ed7e56f39c630741cb69152ac9e41de.tar.gz
rockbox-0ea4d3197ed7e56f39c630741cb69152ac9e41de.tar.bz2
rockbox-0ea4d3197ed7e56f39c630741cb69152ac9e41de.tar.xz
Prepare core support for the iriver bootloader supporting ROM images
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11991 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugin.c7
-rw-r--r--apps/plugin.h9
-rw-r--r--apps/plugins/iriver_flash.c93
-rw-r--r--firmware/eeprom_settings.c8
-rw-r--r--firmware/export/config-h120.h5
-rw-r--r--firmware/export/eeprom_settings.h13
-rw-r--r--firmware/export/system.h4
-rw-r--r--firmware/system.c35
-rw-r--r--firmware/target/coldfire/crt0.S58
9 files changed, 178 insertions, 54 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index c2b697f..250b4cc 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -487,6 +487,13 @@ static const struct plugin_api rockbox_api = {
pcm_record_more,
#endif
create_thread_on_core,
+
+#ifdef IRIVER_H100_SERIES
+ /* Routines for the iriver_flash -plugin. */
+ detect_original_firmware,
+ detect_flashed_ramimage,
+ detect_flashed_romimage,
+#endif
};
int plugin_load(const char* plugin, void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index 16781de..b2d894f 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -602,11 +602,18 @@ struct plugin_api {
int (*sound_default)(int setting);
void (*pcm_record_more)(void *start, size_t size);
#endif
-
+
struct thread_entry*(*create_thread_on_core)(
unsigned int core, void (*function)(void),
void* stack, int stack_size,
const char *name IF_PRIO(, int priority));
+
+#ifdef IRIVER_H100_SERIES
+ /* Routines for the iriver_flash -plugin. */
+ bool (*detect_original_firmware)(void);
+ bool (*detect_flashed_ramimage)(void);
+ bool (*detect_flashed_romimage)(void);
+#endif
};
/* plugin header */
diff --git a/apps/plugins/iriver_flash.c b/apps/plugins/iriver_flash.c
index 590622f..44bd9c7 100644
--- a/apps/plugins/iriver_flash.c
+++ b/apps/plugins/iriver_flash.c
@@ -59,6 +59,10 @@ static struct plugin_api* rb; /* here is a global api struct pointer */
#ifdef IRIVER_H100_SERIES
#define SEC_SIZE 4096
#define BOOTLOADER_ERASEGUARD (BOOTLOADER_ENTRYPOINT / SEC_SIZE)
+enum sections {
+ SECT_RAMIMAGE = 1,
+ SECT_ROMIMAGE = 2,
+};
static volatile uint16_t* FB = (uint16_t*)0x00000000; /* Flash base address */
#endif
@@ -338,23 +342,9 @@ int load_firmware_file(const char *filename, uint32_t *checksum)
return len;
}
-bool detect_flashed_rockbox(void)
-{
- struct flash_header hdr;
- uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT;
-
- rb->memcpy(&hdr, src, sizeof(struct flash_header));
-
- if (hdr.magic != FLASH_MAGIC)
- return false;
-
- return true;
-}
-
unsigned long valid_bootloaders[][2] = {
/* Size-8 CRC32 */
- { 62332, 0x77395351 }, /* Pre-release v7 */
- { 63340, 0xc41857b6 }, /* Pre-release v7, fixed crash unless firmware found. */
+ { 63844, 0x98c5027a }, /* 7-pre3, improved failsafe functions */
{ 0, 0 }
};
@@ -378,15 +368,28 @@ bool detect_valid_bootloader(const unsigned char *addr, int len)
return false;
}
-int flash_rockbox(const char *filename)
+static int get_section_address(int section)
+{
+ if (section == SECT_RAMIMAGE)
+ return FLASH_RAMIMAGE_ENTRY;
+ else if (section == SECT_ROMIMAGE)
+ return FLASH_ROMIMAGE_ENTRY;
+ else
+ return -1;
+}
+
+int flash_rockbox(const char *filename, int section)
{
struct flash_header hdr;
- char buf[32];
+ char buf[64];
int pos, i, len, rc;
unsigned long checksum, sum;
unsigned char *p8;
uint16_t *p16;
+ if (get_section_address(section) < 0)
+ return -1;
+
p8 = (char *)BOOTLOADER_ENTRYPOINT;
if (!detect_valid_bootloader(p8, 0))
{
@@ -394,7 +397,7 @@ int flash_rockbox(const char *filename)
return -1;
}
- if (detect_flashed_rockbox())
+ if (!rb->detect_original_firmware())
{
if (!confirm("Update Rockbox flash image?"))
return -2;
@@ -409,13 +412,36 @@ int flash_rockbox(const char *filename)
if (len <= 0)
return len * 10;
+ pos = get_section_address(section);
+
+ /* Check if image relocation seems to be sane. */
+ if (section == SECT_ROMIMAGE)
+ {
+ uint32_t *p32 = (uint32_t *)audiobuf;
+
+ if (pos+sizeof(struct flash_header) != *p32)
+ {
+ rb->snprintf(buf, sizeof(buf), "Incorrect relocation: 0x%08x/0x%08x",
+ *p32, pos+sizeof(struct flash_header));
+ rb->splash(HZ*10, true, buf);
+ return -1;
+ }
+
+ }
+
/* Erase the program flash. */
- for (i = 1; i < BOOTLOADER_ERASEGUARD && (i-1)*4096 < len + 32; i++)
+ for (i = 0; i + pos < BOOTLOADER_ENTRYPOINT && i < len + 32; i += SEC_SIZE)
{
- rc = cfi_erase_sector(FB + (SEC_SIZE/2) * i);
- rb->snprintf(buf, sizeof(buf), "Erase: 0x%03x (%d)", i, rc);
+ /* Additional safety check. */
+ if (i + pos < SEC_SIZE)
+ return -1;
+
+ rb->snprintf(buf, sizeof(buf), "Erasing... %d%%",
+ (i+SEC_SIZE)*100/len);
rb->lcd_puts(0, 3, buf);
rb->lcd_update();
+
+ rc = cfi_erase_sector(FB + (i + pos)/2);
}
/* Write the magic and size. */
@@ -425,11 +451,11 @@ int flash_rockbox(const char *filename)
// rb->strncpy(hdr.version, APPSVERSION, sizeof(hdr.version)-1);
p16 = (uint16_t *)&hdr;
- rb->snprintf(buf, sizeof(buf), "Programming");
+ rb->snprintf(buf, sizeof(buf), "Programming...");
rb->lcd_puts(0, 4, buf);
rb->lcd_update();
- pos = FLASH_ENTRYPOINT/2;
+ pos = get_section_address(section)/2;
for (i = 0; i < (long)sizeof(struct flash_header)/2; i++)
{
cfi_program_word(FB + pos, p16[i]);
@@ -438,14 +464,24 @@ int flash_rockbox(const char *filename)
p16 = (uint16_t *)audiobuf;
for (i = 0; i < len/2 && pos + i < (BOOTLOADER_ENTRYPOINT/2); i++)
+ {
+ if (i % SEC_SIZE == 0)
+ {
+ rb->snprintf(buf, sizeof(buf), "Programming... %d%%",
+ (i+1)*100/(len/2));
+ rb->lcd_puts(0, 4, buf);
+ rb->lcd_update();
+ }
+
cfi_program_word(FB + pos + i, p16[i]);
+ }
/* Verify */
rb->snprintf(buf, sizeof(buf), "Verifying");
rb->lcd_puts(0, 5, buf);
rb->lcd_update();
- p8 = (char *)FLASH_ENTRYPOINT;
+ p8 = (char *)get_section_address(section);
p8 += sizeof(struct flash_header);
sum = 0;
for (i = 0; i < len; i++)
@@ -456,7 +492,10 @@ int flash_rockbox(const char *filename)
rb->splash(HZ*3, true, "Verify failed!");
/* Erase the magic sector so bootloader does not try to load
* rockbox from flash and crash. */
- cfi_erase_sector(FB + SEC_SIZE/2);
+ if (section == SECT_RAMIMAGE)
+ cfi_erase_sector(FB + FLASH_RAMIMAGE_ENTRY/2);
+ else
+ cfi_erase_sector(FB + FLASH_ROMIMAGE_ENTRY/2);
return -5;
}
@@ -741,7 +780,9 @@ void DoUserDialog(char* filename)
audiobuf = rb->plugin_get_audio_buffer(&audiobuf_size);
if (rb->strcasestr(filename, "/rockbox.iriver"))
- flash_rockbox(filename);
+ flash_rockbox(filename, SECT_RAMIMAGE);
+ else if (rb->strcasestr(filename, "/rombox.iriver"))
+ flash_rockbox(filename, SECT_ROMIMAGE);
else if (rb->strcasestr(filename, "/bootloader.iriver"))
flash_bootloader(filename);
else if (rb->strcasestr(filename, "/ihp_120.bin"))
diff --git a/firmware/eeprom_settings.c b/firmware/eeprom_settings.c
index ad2c9c8..f3be2ec 100644
--- a/firmware/eeprom_settings.c
+++ b/firmware/eeprom_settings.c
@@ -36,7 +36,7 @@ static bool reset_config(void)
#else
firmware_settings.version = EEPROM_SETTINGS_VERSION;
firmware_settings.initialized = true;
- firmware_settings.boot_disk = false;
+ firmware_settings.bootmethod = BOOT_RECOVERY;
firmware_settings.bl_version = 0;
#endif
@@ -51,7 +51,7 @@ bool eeprom_settings_init(void)
eeprom_24cxx_init();
/* Check if player has been flashed. */
- if (!detect_flashed_rockbox())
+ if (detect_original_firmware())
{
memset(&firmware_settings, 0, sizeof(struct eeprom_settings));
firmware_settings.initialized = false;
@@ -61,7 +61,7 @@ bool eeprom_settings_init(void)
ret = eeprom_24cxx_read(0, &firmware_settings,
sizeof(struct eeprom_settings));
-
+
if (ret < 0)
{
memset(&firmware_settings, 0, sizeof(struct eeprom_settings));
@@ -101,7 +101,7 @@ bool eeprom_settings_store(void)
int ret;
uint32_t sum;
- if (!firmware_settings.initialized || !detect_flashed_rockbox())
+ if (!firmware_settings.initialized || detect_original_firmware())
{
logf("Rockbox in flash is required");
return false;
diff --git a/firmware/export/config-h120.h b/firmware/export/config-h120.h
index ee3d702..9bfb958 100644
--- a/firmware/export/config-h120.h
+++ b/firmware/export/config-h120.h
@@ -139,8 +139,9 @@
#define BOOTFILE "rockbox." BOOTFILE_EXT
#define BOOTLOADER_ENTRYPOINT 0x001F0000
-#define FLASH_ENTRYPOINT 0x00001000
-#define FLASH_MAGIC 0xfbfbfbf1
+#define FLASH_RAMIMAGE_ENTRY 0x00001000
+#define FLASH_ROMIMAGE_ENTRY 0x00100000
+#define FLASH_MAGIC 0xfbfbfbf2
/* Define this if there is an EEPROM chip */
#define HAVE_EEPROM
diff --git a/firmware/export/eeprom_settings.h b/firmware/export/eeprom_settings.h
index 367e7b2..aade86b 100644
--- a/firmware/export/eeprom_settings.h
+++ b/firmware/export/eeprom_settings.h
@@ -23,17 +23,26 @@
#include <stdbool.h>
#include "inttypes.h"
-#define EEPROM_SETTINGS_VERSION 0x24c01001
+#define EEPROM_SETTINGS_VERSION 0x24c01002
#define EEPROM_SETTINGS_BL_MINVER 7
+enum boot_methods {
+ BOOT_DISK = 0,
+ BOOT_RAM,
+ BOOT_ROM,
+ BOOT_RECOVERY,
+};
+
struct eeprom_settings
{
long version; /* Settings version number */
bool initialized; /* Is eeprom_settings ready to be used */
bool disk_clean; /* Is disk intact from last reboot */
- bool boot_disk; /* Load firmware from disk (default=FLASH) */
+ uint8_t bootmethod; /* The default boot method. */
uint8_t bl_version; /* Installed bootloader version */
+ long reserved; /* A few reserved bits for the future. */
+
/* This must be the last entry */
uint32_t checksum; /* Checksum of this structure */
};
diff --git a/firmware/export/system.h b/firmware/export/system.h
index 9492287..86bbefb 100644
--- a/firmware/export/system.h
+++ b/firmware/export/system.h
@@ -52,7 +52,9 @@ struct flash_header {
char version[32];
};
-bool detect_flashed_rockbox(void);
+bool detect_flashed_romimage(void);
+bool detect_flashed_ramimage(void);
+bool detect_original_firmware(void);
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
#define FREQ cpu_frequency
diff --git a/firmware/system.c b/firmware/system.c
index 4ab47fa..c9ce086 100644
--- a/firmware/system.c
+++ b/firmware/system.c
@@ -82,31 +82,44 @@ void cpu_idle_mode(bool on_off)
#endif /* HAVE_ADJUSTABLE_CPU_FREQ */
-bool detect_flashed_rockbox(void)
-{
#ifdef HAVE_FLASHED_ROCKBOX
- struct flash_header hdr;
- uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT;
-
+static bool detect_flash_header(uint8_t *addr)
+{
#ifndef BOOTLOADER
int oldmode = system_memory_guard(MEMGUARD_NONE);
#endif
-
- memcpy(&hdr, src, sizeof(struct flash_header));
-
+ struct flash_header hdr;
+ memcpy(&hdr, addr, sizeof(struct flash_header));
#ifndef BOOTLOADER
system_memory_guard(oldmode);
#endif
+ return hdr.magic == FLASH_MAGIC;
+}
+#endif
- if (hdr.magic != FLASH_MAGIC)
- return false;
+bool detect_flashed_romimage(void)
+{
+#ifdef HAVE_FLASHED_ROCKBOX
+ return detect_flash_header((uint8_t *)FLASH_ROMIMAGE_ENTRY);
+#else
+ return false;
+#endif /* HAVE_FLASHED_ROCKBOX */
+}
- return true;
+bool detect_flashed_ramimage(void)
+{
+#ifdef HAVE_FLASHED_ROCKBOX
+ return detect_flash_header((uint8_t *)FLASH_RAMIMAGE_ENTRY);
#else
return false;
#endif /* HAVE_FLASHED_ROCKBOX */
}
+bool detect_original_firmware(void)
+{
+ return !(detect_flashed_ramimage() || detect_flashed_romimage());
+}
+
#if CONFIG_CPU == SH7034
#include "led.h"
#include "system.h"
diff --git a/firmware/target/coldfire/crt0.S b/firmware/target/coldfire/crt0.S
index 7fc389c..c177cd4 100644
--- a/firmware/target/coldfire/crt0.S
+++ b/firmware/target/coldfire/crt0.S
@@ -89,28 +89,40 @@ start:
#endif
#ifdef BOOTLOADER
- /* Check if original firmware is still present */
+ /* Check if we have a Rockbox ROM image */
+ lea 0x00100000,%a2
+ move.l (%a2),%d0
+ move.l #FLASH_MAGIC,%d1
+ cmp.l %d0,%d1
+ beq.b .imagefound
+
+ /* Check for RAM image */
lea 0x00001000,%a2
move.l (%a2),%d0
- move.l #0xfbfbfbf1,%d1
+ move.l #FLASH_MAGIC,%d1
cmp.l %d0,%d1
- beq.b .ignorecookie
+ beq.b .imagefound
- /* The cookie is not reset. This must mean that the boot loader
- has crashed. Let's start the original firmware immediately. */
+ /* Not either ROM or RAM image was found, so original firmware
+ should be still present. */
+
+ /* Check if the cookie is present. */
lea 0x10017ffc,%a2
move.l (%a2),%d0
move.l #0xc0015a17,%d1
cmp.l %d0,%d1
bne.b .nocookie
- /* Clear the cookie again */
+
+ /* The cookie is not reset. This must mean that the boot loader
+ has crashed. Let's start the original firmware immediately. */
+ lea 0x10017ffc,%a2
clr.l (%a2)
jmp 8
.nocookie:
/* Set the cookie */
move.l %d1,(%a2)
-.ignorecookie:
+.imagefound:
/* Set up the DRAM controller. The refresh is based on the 11.2896MHz
clock (5.6448MHz bus frequency). We haven't yet started the PLL */
@@ -168,6 +180,38 @@ start:
move.l %d0,0x31000800 /* A12=1 means CASL=1 (a0 is not connected) */
/* DACR0[IMRS] gets deactivated by the SDRAM controller */
+
+ /* Check if we have a Rockbox ROM image. For RAM image only cookie is
+ not set at all. But we could support also RAM images loading. */
+ lea 0x00100000,%a2
+ move.l (%a2),%d0
+ move.l #FLASH_MAGIC,%d1
+ cmp.l %d0,%d1
+ bne.b .noromimage
+
+ /* Check again if the cookie is present. */
+ lea 0x10017ffc,%a2
+ move.l (%a2),%d0
+ move.l #0xc0015a17,%d1
+ cmp.l %d0,%d1
+ bne.b .nocookie2
+
+ /* We have found Rockbox in ROM!
+ Clear the cookie and load the ROM image */
+ lea 0x10017ffc,%a2
+ clr.l (%a2)
+ lea 0x00100028+4,%a2
+ move.l (%a2),%sp
+ lea 0x00100028+8,%a2
+ move.l (%a2),%d0
+ move.l %d0,%a2
+ jmp (%a2)
+
+.nocookie2:
+ /* Set the cookie */
+ move.l %d1,(%a2)
+.noromimage:
+
#endif /* BOOTLOADER */
/* Invalicate cache */