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
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 @@
     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 @@
     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 @@
     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 @@
         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 @@
     printf("Result: %d", i);
     lcd_update();
 
+#ifdef HAVE_EEPROM
+    if (firmware_settings.initialized)
+        eeprom_settings_store();
+#endif
+    
     if(i == 0)
         start_firmware();