From e1eb91b976621f03fe7082e5290f47d09f6d7b2e Mon Sep 17 00:00:00 2001 From: Miika Pekkarinen Date: Wed, 9 Aug 2006 12:04:13 +0000 Subject: 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 --- apps/main.c | 4 +- apps/plugins/iriver_flash.c | 14 +++--- apps/plugins/viewers.config | 1 + bootloader/main.c | 95 ++++++++++++++++++++++++++++++++++++--- firmware/drivers/eeprom_24cxx.c | 10 ++--- firmware/eeprom_settings.c | 10 +++-- firmware/export/config-h300.h | 4 ++ firmware/export/eeprom_settings.h | 1 - 8 files changed, 115 insertions(+), 24 deletions(-) diff --git a/apps/main.c b/apps/main.c index 907e1126cf..d590790a85 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 28734d197b..40c9a2979b 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 5e1c6283f8..cc05bbc47d 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 181dbeade3..0ef6d8944e 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -20,6 +20,8 @@ #include #include +#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 75521ce2db..03e5a3d620 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 e472f4df07..450eff9623 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 6d5fbabbdf..f3ba076334 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 a3515bd69e..367e7b24e9 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); -- cgit v1.2.3