diff options
| author | Miika Pekkarinen <miipekk@ihme.org> | 2006-08-09 12:04:13 +0000 |
|---|---|---|
| committer | Miika Pekkarinen <miipekk@ihme.org> | 2006-08-09 12:04:13 +0000 |
| commit | e1eb91b976621f03fe7082e5290f47d09f6d7b2e (patch) | |
| tree | eca734c2a193dc8f933b784a72969ccc3b9101ea | |
| parent | 0f87f8fd366b0869c001a7d4e8ca6b2e27065e7b (diff) | |
| download | rockbox-e1eb91b976621f03fe7082e5290f47d09f6d7b2e.zip rockbox-e1eb91b976621f03fe7082e5290f47d09f6d7b2e.tar.gz rockbox-e1eb91b976621f03fe7082e5290f47d09f6d7b2e.tar.bz2 rockbox-e1eb91b976621f03fe7082e5290f47d09f6d7b2e.tar.xz | |
Bootloader support to search firmware also from flash. Bootloader <->
Rockbox communication when Rockbox has been flashed.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10499 a1c6a512-1295-4272-9138-f99709370657
| -rw-r--r-- | apps/main.c | 4 | ||||
| -rw-r--r-- | apps/plugins/iriver_flash.c | 14 | ||||
| -rw-r--r-- | apps/plugins/viewers.config | 1 | ||||
| -rw-r--r-- | bootloader/main.c | 95 | ||||
| -rw-r--r-- | firmware/drivers/eeprom_24cxx.c | 10 | ||||
| -rw-r--r-- | firmware/eeprom_settings.c | 10 | ||||
| -rw-r--r-- | firmware/export/config-h300.h | 4 | ||||
| -rw-r--r-- | firmware/export/eeprom_settings.h | 1 |
8 files changed, 115 insertions, 24 deletions
diff --git a/apps/main.c b/apps/main.c index 907e112..d590790 100644 --- a/apps/main.c +++ b/apps/main.c @@ -120,7 +120,9 @@ int init_dircache(void) # ifdef HAVE_EEPROM if (firmware_settings.initialized && firmware_settings.disk_clean) { - if (dircache_load(DIRCACHE_FILE) == 0) + result = dircache_load(DIRCACHE_FILE); + remove(DIRCACHE_FILE); + if (result == 0) return 0; } # endif diff --git a/apps/plugins/iriver_flash.c b/apps/plugins/iriver_flash.c index 28734d1..40c9a29 100644 --- a/apps/plugins/iriver_flash.c +++ b/apps/plugins/iriver_flash.c @@ -381,12 +381,13 @@ void show_fatal_error(void) int flash_bootloader(const char *filename) { - // char buf[32]; + char buf[32]; int pos, i, len, rc; unsigned long checksum, sum, crc32; unsigned char *p8; uint16_t *p16; + (void)buf; len = load_firmware_file(filename, &checksum); if (len < 0) return len * 10; @@ -399,15 +400,16 @@ int flash_bootloader(const char *filename) /* Verify the crc32 checksum also. */ crc32 = crc_32(audiobuf, len, 0xffffffff); - // rb->snprintf(buf, sizeof buf, "crc32 = 0x%08x", crc32); - // rb->splash(HZ*10, true, buf); - - if (crc32 != 0x5361a679) +#if 0 + rb->snprintf(buf, sizeof buf, "crc32 = 0x%08x", crc32); + rb->splash(HZ*10, true, buf); +#else + if (crc32 != 0xa930906d) { rb->splash(HZ*3, true, "Untested bootloader"); return -2; } - +#endif rb->lcd_puts(0, 3, "Processing critical sections..."); rb->lcd_update(); diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config index 5e1c628..cc05bbc 100644 --- a/apps/plugins/viewers.config +++ b/apps/plugins/viewers.config @@ -22,3 +22,4 @@ wav,viewers/mp3_encoder, 00 00 00 00 00 00 wav,viewers/wavplay,60 7F 05 35 3F 00 bmp,rocks/rockpaint, 01 10 01 10 01 10 m2v,viewers/mpegplayer,5D 7F 5D 7F 5D 7F +iriver,viewers/iriver_flash,2A 7F 41 41 7F 2A diff --git a/bootloader/main.c b/bootloader/main.c index 181dbea..0ef6d89 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -20,6 +20,8 @@ #include <stdlib.h> #include <stdio.h> +#include "inttypes.h" +#include "string.h" #include "cpu.h" #include "system.h" #include "lcd.h" @@ -39,6 +41,7 @@ #include "power.h" #include "file.h" #include "uda1380.h" +#include "eeprom_settings.h" #include "pcf50606.h" @@ -151,6 +154,21 @@ int load_firmware(void) return 0; } +int load_flashed_rockbox(void) +{ + struct flash_header hdr; + unsigned char *buf = (unsigned char *)DRAM_START; + uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT; + + cpu_boost(true); + memcpy(&hdr, src, sizeof(struct flash_header)); + src += sizeof(struct flash_header); + memcpy(buf, src, hdr.length); + cpu_boost(false); + + return 0; +} + void start_firmware(void) { @@ -171,12 +189,14 @@ void main(void) int rc; bool rc_on_button = false; bool on_button = false; + bool rec_button = false; int data; int adc_battery, battery_voltage, batt_int, batt_frac; #ifdef IAUDIO_X5 (void)rc_on_button; (void)on_button; + (void)rec_button; (void)data; power_init(); @@ -311,13 +331,66 @@ void main(void) lcd_update(); sleep(HZ/50); /* Allow the button driver to check the buttons */ + rec_button = ((button_status() & BUTTON_REC) == BUTTON_REC) + || ((button_status() & BUTTON_RC_REC) == BUTTON_RC_REC); + - /* Holding REC while starting runs the original firmware */ - if(((button_status() & BUTTON_REC) == BUTTON_REC) || - ((button_status() & BUTTON_RC_REC) == BUTTON_RC_REC)) { - printf("Starting original firmware..."); +#ifdef HAVE_EEPROM + firmware_settings.initialized = false; +#endif + if (detect_flashed_rockbox()) + { + bool load_from_flash; + + load_from_flash = !rec_button; +#ifdef HAVE_EEPROM + if (eeprom_settings_init()) + { + /* If bootloader version has not been reset, disk might + * not be intact. */ + if (firmware_settings.bl_version) + firmware_settings.disk_clean = false; + + firmware_settings.bl_version = 7; + /* Invert the record button if we want to load from disk + * by default. */ + if (firmware_settings.boot_disk) + load_from_flash = rec_button; + } +#endif + + if (load_from_flash) + { + /* Load firmware from flash */ + i = load_flashed_rockbox(); + printf("Result: %d", i); + lcd_update(); + if (i == 0) + { +#ifdef HAVE_EEPROM + eeprom_settings_store(); +#endif + start_firmware(); + printf("Fatal: Corrupted firmware"); + printf("Hold down REC on next boot"); + lcd_update(); + sleep(HZ*2); + power_off(); + } + } + + printf("Loading from disk..."); lcd_update(); - start_iriver_fw(); + } + else + { + /* Holding REC while starting runs the original firmware */ + if (rec_button) + { + printf("Starting original firmware..."); + lcd_update(); + start_iriver_fw(); + } } /* Don't start if the Hold button is active on the device you @@ -384,6 +457,13 @@ void main(void) sleep(HZ); #endif +#ifdef HAVE_EEPROM + if (firmware_settings.initialized) + { + firmware_settings.disk_clean = false; + eeprom_settings_store(); + } +#endif ata_spin(); ata_enable(false); usb_enable(true); @@ -423,6 +503,11 @@ void main(void) printf("Result: %d", i); lcd_update(); +#ifdef HAVE_EEPROM + if (firmware_settings.initialized) + eeprom_settings_store(); +#endif + if(i == 0) start_firmware(); diff --git a/firmware/drivers/eeprom_24cxx.c b/firmware/drivers/eeprom_24cxx.c index 75521ce..03e5a3d 100644 --- a/firmware/drivers/eeprom_24cxx.c +++ b/firmware/drivers/eeprom_24cxx.c @@ -82,10 +82,6 @@ static void sw_i2c_start(void) static void sw_i2c_stop(void) { - // SCL_LO; - // DELAY; - // SDA_LO; - // DELAY; SCL_HI; DELAY; SDA_HI; @@ -294,7 +290,7 @@ int eeprom_24cxx_read_byte(unsigned int address, char *c) if (ret < 0) { /* keep between {} as logf is whitespace in normal builds */ - logf("EEPROM Fail: %d/%d", ret, address); + logf("EEPROM rFail: %d/%d", ret, address); } } while (ret < 0 && count--); @@ -325,7 +321,7 @@ int eeprom_24cxx_write_byte(unsigned int address, char c) if (ret < 0) { /* keep between {} as logf is whitespace in normal builds */ - logf("EEPROM Fail: %d/%d", ret, address); + logf("EEPROM wFail: %d/%d", ret, address); } } while (ret < 0 && count--) ; @@ -357,7 +353,7 @@ int eeprom_24cxx_read(unsigned char address, void *dest, int length) int eeprom_24cxx_write(unsigned char address, const void *src, int length) { const char *buf = (const char *)src; - int count = 10; + int count = 5; int i; bool ok; diff --git a/firmware/eeprom_settings.c b/firmware/eeprom_settings.c index e472f4d..450eff9 100644 --- a/firmware/eeprom_settings.c +++ b/firmware/eeprom_settings.c @@ -21,6 +21,7 @@ #include "eeprom_24cxx.h" #include "crc32.h" +#include "system.h" #include "string.h" #include "logf.h" @@ -64,16 +65,17 @@ bool eeprom_settings_init(void) sum = crc_32(&firmware_settings, sizeof(struct eeprom_settings)-4, 0xffffffff); - if (firmware_settings.checksum != sum) + logf("BL version: %d", firmware_settings.bl_version); + if (firmware_settings.version != EEPROM_SETTINGS_VERSION) { - logf("Checksum mismatch"); + logf("Version mismatch"); reset_config(); return true; } - if (firmware_settings.version != EEPROM_SETTINGS_VERSION) + if (firmware_settings.checksum != sum) { - logf("Version mismatch"); + logf("Checksum mismatch"); reset_config(); return true; } diff --git a/firmware/export/config-h300.h b/firmware/export/config-h300.h index 6d5fbab..f3ba076 100644 --- a/firmware/export/config-h300.h +++ b/firmware/export/config-h300.h @@ -124,6 +124,10 @@ #define BOOTFILE_EXT "iriver" #define BOOTFILE "rockbox." BOOTFILE_EXT +#define BOOTLOADER_ENTRYPOINT 0x001F0000 +#define FLASH_ENTRYPOINT 0x00001000 +#define FLASH_MAGIC 0xfbfbfbf1 + #define HAVE_BACKLIGHT_BRIGHTNESS /* define this if the unit can be powered or charged via USB */ diff --git a/firmware/export/eeprom_settings.h b/firmware/export/eeprom_settings.h index a3515bd..367e7b2 100644 --- a/firmware/export/eeprom_settings.h +++ b/firmware/export/eeprom_settings.h @@ -40,7 +40,6 @@ struct eeprom_settings extern struct eeprom_settings firmware_settings; -bool detect_flashed_rockbox(void); bool eeprom_settings_init(void); bool eeprom_settings_store(void); |