Index: apps/Makefile
===================================================================
RCS file: /cvsroot/rockbox/apps/Makefile,v
retrieving revision 1.111
diff -u -3 -p -r1.111 Makefile
--- apps/Makefile	27 Oct 2006 21:47:46 -0000	1.111
+++ apps/Makefile	7 Dec 2006 07:27:07 -0000
@@ -190,6 +190,9 @@ $(BUILDDIR)/rombox.ucl: $(OBJDIR)/rombox
 	  echo "fake" > $@; \
 	fi
 
+$(BUILDDIR)/rombox.iriver: $(OBJDIR)/rombox.bin
+	$(call PRINTS,Build ROM file)$(MKFIRMWARE) $< $@
+    
 include $(TOOLSDIR)/make.inc
 
 $(OBJDIR)/lang.o: lang/$(LANGUAGE).lang
Index: apps/plugin.c
===================================================================
RCS file: /cvsroot/rockbox/apps/plugin.c,v
retrieving revision 1.203
diff -u -3 -p -r1.203 plugin.c
--- apps/plugin.c	6 Dec 2006 08:34:54 -0000	1.203
+++ apps/plugin.c	7 Dec 2006 07:27:07 -0000
@@ -484,6 +484,13 @@ static const struct plugin_api rockbox_a
     sound_default,
     pcm_record_more,
 #endif
+
+#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)
Index: apps/plugin.h
===================================================================
RCS file: /cvsroot/rockbox/apps/plugin.h,v
retrieving revision 1.207
diff -u -3 -p -r1.207 plugin.h
--- apps/plugin.h	6 Dec 2006 08:34:55 -0000	1.207
+++ apps/plugin.h	7 Dec 2006 07:27:07 -0000
@@ -600,6 +600,13 @@ struct plugin_api {
     int (*sound_default)(int setting);
     void (*pcm_record_more)(void *start, size_t size);
 #endif
+    
+#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 */
Index: apps/main.c
===================================================================
RCS file: /cvsroot/rockbox/apps/main.c,v
retrieving revision 1.198
diff -u -3 -p -r1.198 main.c
--- apps/main.c	6 Dec 2006 12:11:56 -0000	1.198
+++ apps/main.c	7 Dec 2006 07:27:07 -0000
@@ -292,6 +292,8 @@ void init(void)
     cpu_boost(true);
 #endif
     
+    backlight_init();
+
     buffer_init();
 
     settings_reset();
@@ -333,8 +335,6 @@ void init(void)
     m5636_init();
 #endif
 
-    backlight_init();
-
     button_init();
 
     powermgmt_init();
Index: apps/plugins/iriver_flash.c
===================================================================
RCS file: /cvsroot/rockbox/apps/plugins/iriver_flash.c,v
retrieving revision 1.6
diff -u -3 -p -r1.6 iriver_flash.c
--- apps/plugins/iriver_flash.c	16 Oct 2006 08:34:48 -0000	1.6
+++ apps/plugins/iriver_flash.c	7 Dec 2006 07:27:07 -0000
@@ -59,6 +59,10 @@ static struct plugin_api* rb; /* here is
 #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 *filen
     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. */
+    { 63696, 0x7bf1c4f9 }, /* 7-pre2, improved failsafe functions */
     { 0,     0 }
 };
 
@@ -378,15 +368,28 @@ bool detect_valid_bootloader(const unsig
     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,11 +412,32 @@ 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;
+        
+        rc = cfi_erase_sector(FB + (i + pos)/2);
+        rb->snprintf(buf, sizeof(buf), "Erase: 0x%03x  (%d)", (i+pos)/SEC_SIZE, rc);
         rb->lcd_puts(0, 3, buf);
         rb->lcd_update();
     }
@@ -429,7 +453,7 @@ int flash_rockbox(const char *filename)
     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]);
@@ -445,7 +469,7 @@ int flash_rockbox(const char *filename)
     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 +480,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 +768,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"))
Index: bootloader/main.c
===================================================================
RCS file: /cvsroot/rockbox/bootloader/main.c,v
retrieving revision 1.40
diff -u -3 -p -r1.40 main.c
--- bootloader/main.c	6 Dec 2006 10:36:20 -0000	1.40
+++ bootloader/main.c	7 Dec 2006 07:27:07 -0000
@@ -25,6 +25,7 @@
 #include "cpu.h"
 #include "system.h"
 #include "lcd.h"
+#include "lcd-remote.h"
 #include "kernel.h"
 #include "thread.h"
 #include "ata.h"
@@ -46,7 +47,12 @@
 
 #define DRAM_START 0x31000000
 
+static bool recovery_mode = false;
+
 int line = 0;
+#ifdef HAVE_REMOTE_LCD
+int remote_line = 0;
+#endif
 
 int usb_screen(void)
 {
@@ -57,6 +63,16 @@ char version[] = APPSVERSION;
 
 char printfbuf[256];
 
+void reset_screen(void)
+{
+    lcd_clear_display();
+    line = 0;
+#ifdef HAVE_REMOTE_LCD
+    lcd_remote_clear_display();
+    remote_line = 0;
+#endif
+}
+
 void printf(const char *format, ...)
 {
     int len;
@@ -72,6 +88,12 @@ void printf(const char *format, ...)
     lcd_update();
     if(line >= 16)
         line = 0;
+#ifdef HAVE_REMOTE_LCD
+    lcd_remote_puts(0, remote_line++, ptr);
+    lcd_remote_update();
+    if(remote_line >= 8)
+        remote_line = 0;
+#endif
 }
 
 void start_iriver_fw(void)
@@ -108,7 +130,6 @@ int load_firmware(void)
     len = filesize(fd) - 8;
 
     printf("Length: %x", len);
-    lcd_update();
 
     lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET);
 
@@ -117,7 +138,6 @@ int load_firmware(void)
         return -2;
 
     printf("Checksum: %x", chksum);
-    lcd_update();
 
     rc = read(fd, model, 4);
     if(rc < 4)
@@ -143,7 +163,6 @@ int load_firmware(void)
     }
 
     printf("Sum: %x", sum);
-    lcd_update();
 
     if(sum != chksum)
         return -5;
@@ -151,35 +170,266 @@ int load_firmware(void)
     return 0;
 }
 
-int load_flashed_rockbox(void)
+void start_firmware(void)
+{
+    asm(" move.w #0x2700,%sr");
+    /* Reset the cookie for the crt0 crash check */
+    asm(" move.l #0,%d0");
+    asm(" move.l %d0,0x10017ffc");
+    asm(" move.l %0,%%d0" :: "i"(DRAM_START));
+    asm(" movec.l %d0,%vbr");
+    asm(" move.l %0,%%sp" :: "m"(*(int *)DRAM_START));
+    asm(" move.l %0,%%a0" :: "m"(*(int *)(DRAM_START+4)));
+    asm(" jmp (%a0)");
+}
+
+#ifdef IRIVER_H100_SERIES
+void start_flashed_romimage(void)
+{
+    uint8_t *src = (uint8_t *)FLASH_ROMIMAGE_ENTRY;
+    int *reset_vector;
+    
+    if (!detect_flashed_romimage())
+        return ;
+        
+    reset_vector = (int *)(&src[sizeof(struct flash_header)+4]);
+
+    /*
+    printf("sp=0x%08x", reset_vector[0]);
+    printf("a0=0x%08x", reset_vector[1]);
+    sleep(HZ*10);
+     */
+    // set_irq_level(HIGHEST_IRQ_LEVEL);
+    // TMR0 = 0; /* Stop the kernel timer. */
+    
+    asm(" move.w #0x2700,%sr");
+    /* Reset the cookie for the crt0 crash check */
+    asm(" move.l #0,%d0");
+    asm(" move.l %d0,0x10017ffc");
+    
+    asm(" move.l %0,%%d0" :: "i"(DRAM_START));
+    asm(" movec.l %d0,%vbr");
+    asm(" move.l %0,%%sp" :: "m"(reset_vector[0]));
+    asm(" move.l %0,%%a0" :: "m"(reset_vector[1]));
+    asm(" jmp (%a0)");
+    
+    /* Failure */
+    power_off();
+}
+
+void start_flashed_ramimage(void)
 {
     struct flash_header hdr;
     unsigned char *buf = (unsigned char *)DRAM_START;
-    uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT;
+    uint8_t *src = (uint8_t *)FLASH_RAMIMAGE_ENTRY;
 
+    if (!detect_flashed_ramimage())
+         return;
+    
+    /* Load firmware from flash */
     cpu_boost(true);
     memcpy(&hdr, src, sizeof(struct flash_header));
     src += sizeof(struct flash_header);
     memcpy(buf, src, hdr.length);
     cpu_boost(false);
+    
+    start_firmware();
 
-    return 0;
+    /* Failure */
+    power_off();
 }
+#endif /* IRIVER_H100_SERIES */
 
-
-void start_firmware(void)
+void shutdown(void)
 {
-    asm(" move.w #0x2700,%sr");
+    printf("Shutting down...");
+#ifdef HAVE_EEPROM_SETTINGS
+    /* Reset the rockbox crash check. */
+    firmware_settings.bl_version = 0;
+    eeprom_settings_store();
+#endif
+    
+    sleep(HZ*2);
+    
+    /* Backlight OFF */
+#ifdef HAVE_REMOTE_LCD
+# ifdef IRIVER_H300_SERIES
+    or_l(0x00000002, &GPIO1_OUT);
+# else
+    or_l(0x00000800, &GPIO_OUT);
+# endif
+#endif
+    
     /* Reset the cookie for the crt0 crash check */
     asm(" move.l #0,%d0");
     asm(" move.l %d0,0x10017ffc");
-    asm(" move.l %0,%%d0" :: "i"(DRAM_START));
-    asm(" movec.l %d0,%vbr");
-    asm(" move.l %0,%%sp" :: "m"(*(int *)DRAM_START));
-    asm(" move.l %0,%%a0" :: "m"(*(int *)(DRAM_START+4)));
-    asm(" jmp (%a0)");
+    power_off();
+}
+
+#ifdef HAVE_EEPROM_SETTINGS
+void initialize_eeprom(void)
+{
+    if (detect_original_firmware())
+        return ;
+    
+    if (!eeprom_settings_init())
+    {
+        recovery_mode = true;
+        return ;
+    }
+    
+    /* If bootloader version has not been reset, disk might
+     * not be intact. */
+    if (firmware_settings.bl_version || !firmware_settings.disk_clean)
+    {
+        firmware_settings.disk_clean = false;
+        recovery_mode = true;
+    }
+    
+    firmware_settings.bl_version = EEPROM_SETTINGS_BL_MINVER;
+    eeprom_settings_store();
 }
 
+void try_flashboot(void)
+{
+    if (!firmware_settings.initialized)
+        return ;
+    
+   switch (firmware_settings.bootmethod)
+    {
+        case BOOT_DISK:
+            return;
+        
+        case BOOT_ROM:
+            start_flashed_romimage();
+            recovery_mode = true;
+            break;
+        
+        case BOOT_RAM:
+            start_flashed_ramimage();
+            recovery_mode = true;
+            break;
+        
+        default:
+            recovery_mode = true;
+            return;
+    }
+}
+
+static const char *options[] = { 
+    "Boot from disk",
+    "Boot RAM image",
+    "Boot ROM image",
+    "Shutdown" 
+};
+
+#define FAILSAFE_OPTIONS 4
+void failsafe_menu(void)
+{
+    int timeout = 15;
+    int option = 3;
+    int button;
+    int defopt = -1;
+    char buf[32];
+    int i;
+    
+    reset_screen();
+    printf("Rockbox Failsafe Menu");
+    printf("=========================");
+    line += FAILSAFE_OPTIONS;
+    printf("");
+    printf("  [NAVI] to confirm.");
+    printf("  [REC] to set as default.");
+    printf("");
+
+    if (firmware_settings.initialized)
+    {
+        defopt = firmware_settings.bootmethod;
+        if (defopt < 0 || defopt >= FAILSAFE_OPTIONS)
+            defopt = option;
+    }
+    
+    while (timeout > 0)
+    {
+        /* Draw the menu. */
+        line = 2;
+        for (i = 0; i < FAILSAFE_OPTIONS; i++)
+        {
+            char *def = "[DEF]";
+            char *arrow = "->";
+            
+            if (i != defopt)
+                def = "";
+            if (i != option)
+                arrow = "  ";
+            
+            printf("%s %s %s", arrow, options[i], def);
+        }
+        
+        snprintf(buf, sizeof(buf), "Time left: %ds", timeout);
+        lcd_puts(0, 10, buf);
+        lcd_update();
+        button = button_get_w_tmo(HZ);
+
+        if (button == BUTTON_NONE)
+        {
+            timeout--;
+            continue ;
+        }
+
+        timeout = 15;
+        switch (button)
+        {
+            case BUTTON_UP:
+                if (option > 0)
+                    option--;
+                break ;
+                
+            case BUTTON_DOWN:
+                if (option < FAILSAFE_OPTIONS-1)
+                    option++;
+                break ;
+
+            case BUTTON_SELECT:
+                timeout = 0;
+                break ;
+            
+            case BUTTON_REC:
+                if (firmware_settings.initialized)
+                {
+                    firmware_settings.bootmethod = option;
+                    eeprom_settings_store();
+                    defopt = option;
+                }
+                break ;
+        }
+    }
+    
+    lcd_puts(0, 10, "Executing command...");
+    lcd_update();
+    sleep(HZ);
+    reset_screen();
+
+    switch (option)
+    {
+        case BOOT_DISK:
+            return ;
+        
+        case BOOT_RAM:
+            start_flashed_ramimage();
+            printf("Image not found");
+            break;
+        
+        case BOOT_ROM:
+            start_flashed_romimage();
+            printf("Image not found");
+            break;
+    }
+    
+    shutdown();
+}
+#endif
+
 void main(void)
 {
     int i;
@@ -187,6 +437,7 @@ void main(void)
     bool rc_on_button = false;
     bool on_button = false;
     bool rec_button = false;
+    bool hold_status = false;
     int data;
     int adc_battery, battery_voltage, batt_int, batt_frac;
 
@@ -205,6 +456,9 @@ void main(void)
 
     set_irq_level(0);
     lcd_init();
+#ifdef HAVE_REMOTE_LCD
+    lcd_remote_init();
+#endif
     backlight_init();
     font_init();
     adc_init();
@@ -212,7 +466,6 @@ void main(void)
 
     printf("Rockbox boot loader");
     printf("Version %s", version);
-    lcd_update();
 
     adc_battery = adc_read(ADC_BATTERY);
 
@@ -221,7 +474,6 @@ void main(void)
     batt_frac = battery_voltage % 100;
 
     printf("Batt: %d.%02dV", batt_int, batt_frac);
-    lcd_update();
 
     rc = ata_init();
     if(rc)
@@ -242,10 +494,8 @@ void main(void)
     }
 
     printf("Loading firmware");
-    lcd_update();
     i = load_firmware();
     printf("Result: %d", i);
-    lcd_update();
 
     if(i == 0)
         start_firmware();
@@ -277,11 +527,6 @@ void main(void)
     if(!(on_button || rc_on_button || usb_detect()))
         power_off();
 
-    /* Backlight ON */
-    or_l(0x00020000, &GPIO1_ENABLE);
-    or_l(0x00020000, &GPIO1_FUNCTION);
-    and_l(~0x00020000, &GPIO1_OUT);
-
     /* Remote backlight ON */
 #ifdef HAVE_REMOTE_LCD
 #ifdef IRIVER_H300_SERIES
@@ -294,15 +539,12 @@ void main(void)
 #endif
 #endif
 
-    /* Power on the hard drive early, to speed up the loading.
-       Some H300 don't like this, so we only do it for the H100 */
-#ifndef IRIVER_H300_SERIES
-    if(!((on_button && button_hold()) ||
-         (rc_on_button && remote_button_hold()))) {
-        ide_power_enable(true);
+    if (((on_button && button_hold()) ||
+         (rc_on_button && remote_button_hold())))
+    {
+        hold_status = true;
     }
-#endif
-
+    
     system_init();
     kernel_init();
 
@@ -313,14 +555,33 @@ void main(void)
     coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
 #endif
 #endif
+    set_irq_level(0);
 
+#ifdef HAVE_EEPROM_SETTINGS
+    initialize_eeprom();
+#endif
+    
+    /* Power on the hard drive early, to speed up the loading.
+       Some H300 don't like this, so we only do it for the H100 */
+#ifndef IRIVER_H300_SERIES
+    if (!hold_status && !recovery_mode)
+    {
+        ide_power_enable(true);
+    }
+    
+    if (!hold_status && !usb_detect() && !recovery_mode)
+        try_flashboot();
+#endif
+
+    backlight_init();
 #ifdef HAVE_UDA1380
     audiohw_reset();
 #endif
 
-    backlight_init();
-    set_irq_level(0);
     lcd_init();
+#ifdef HAVE_REMOTE_LCD
+    lcd_remote_init();
+#endif
     font_init();
     adc_init();
     button_init();
@@ -329,7 +590,6 @@ void main(void)
 
     printf("Rockbox boot loader");
     printf("Version %s", version);
-    lcd_update();
 
     sleep(HZ/50); /* Allow the button driver to check the buttons */
     rec_button = ((button_status() & BUTTON_REC) == BUTTON_REC)
@@ -337,83 +597,24 @@ void main(void)
 
     /* Don't start if the Hold button is active on the device you
        are starting with */
-    if (!usb_detect() && ((on_button && button_hold()) ||
-                          (rc_on_button && remote_button_hold())))
+    if (!usb_detect() && (hold_status || recovery_mode))
     {
-        printf("HOLD switch on, power off...");
-        lcd_update();
-        sleep(HZ*2);
-
-        /* Backlight OFF */
-#ifdef HAVE_REMOTE_LCD
-#ifdef IRIVER_H300_SERIES
-        or_l(0x00000002, &GPIO1_OUT);
-#else
-        or_l(0x00000800, &GPIO_OUT);
-#endif
-#endif
-        /* Reset the cookie for the crt0 crash check */
-        asm(" move.l #0,%d0");
-        asm(" move.l %d0,0x10017ffc");
-        power_off();
-    }
-
-#ifdef HAVE_EEPROM_SETTINGS
-    firmware_settings.initialized = false;
-#endif
-    if (detect_flashed_rockbox())
-    {
-        bool load_from_flash;
-
-        load_from_flash = !rec_button;
-#ifdef HAVE_EEPROM_SETTINGS
-        if (eeprom_settings_init())
+        if (detect_original_firmware())
         {
-            /* 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;
+            printf("Hold switch on");
+            shutdown();
         }
+        
+#ifdef IRIVER_H100_SERIES
+        failsafe_menu();
 #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_SETTINGS
-                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();
     }
-    else
+
+    /* Holding REC while starting runs the original firmware */
+    if (detect_original_firmware() && rec_button)
     {
-        /* Holding REC while starting runs the original firmware */
-        if (rec_button)
-        {
-            printf("Starting original firmware...");
-            lcd_update();
-            start_iriver_fw();
-        }
+        printf("Starting original firmware...");
+        start_iriver_fw();
     }
 
     usb_init();
@@ -425,11 +626,9 @@ void main(void)
     batt_frac = battery_voltage % 100;
 
     printf("Batt: %d.%02dV", batt_int, batt_frac);
-    lcd_update();
 
     if(battery_voltage <= 300) {
         printf("WARNING! BATTERY LOW!!");
-        lcd_update();
         sleep(HZ*2);
     }
 
@@ -440,7 +639,6 @@ void main(void)
         printf("ATA error: %d", rc);
         printf("Insert USB cable and press");
         printf("a button");
-        lcd_update();
         while(!(button_get(true) & BUTTON_REL));
     }
 
@@ -494,30 +692,21 @@ void main(void)
     {
         lcd_clear_display();
         printf("No partition found");
-        lcd_update();
         while(button_get(true) != SYS_USB_CONNECTED) {};
     }
 
     printf("Loading firmware");
-    lcd_update();
     i = load_firmware();
     printf("Result: %d", i);
-    lcd_update();
-
-#ifdef HAVE_EEPROM_SETTINGS
-    if (firmware_settings.initialized)
-        eeprom_settings_store();
-#endif
 
     if (i == 0)
         start_firmware();
 
-    if (detect_flashed_rockbox())
+    if (!detect_original_firmware())
     {
         printf("No firmware found on disk");
         printf("Powering off...");
-        lcd_update();
-        ata_sleep();
+        ata_sleepnow();
         sleep(HZ*4);
         power_off();
     }
Index: firmware/eeprom_settings.c
===================================================================
RCS file: /cvsroot/rockbox/firmware/eeprom_settings.c,v
retrieving revision 1.4
diff -u -3 -p -r1.4 eeprom_settings.c
--- firmware/eeprom_settings.c	11 Aug 2006 10:13:16 -0000	1.4
+++ firmware/eeprom_settings.c	7 Dec 2006 07:27:07 -0000
@@ -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;
Index: firmware/rom.lds
===================================================================
RCS file: /cvsroot/rockbox/firmware/rom.lds,v
retrieving revision 1.13
diff -u -3 -p -r1.13 rom.lds
--- firmware/rom.lds	31 Aug 2006 19:45:05 -0000	1.13
+++ firmware/rom.lds	7 Dec 2006 07:27:07 -0000
@@ -1,38 +1,47 @@
 #include "config.h"
 
 ENTRY(start)
+
 #ifdef CPU_COLDFIRE
 OUTPUT_FORMAT(elf32-m68k)
-#else
-OUTPUT_FORMAT(elf32-sh)
-#endif
-#ifdef CPU_COLDFIRE
 INPUT(target/coldfire/crt0.o)
 #elif defined(CPU_PP)
+OUTPUT_FORMAT(elf32-littlearm)
 INPUT(target/arm/crt0-pp.o)
 #elif defined(CPU_ARM)
+OUTPUT_FORMAT(elf32-littlearm)
 INPUT(target/arm/crt0.o)
 #elif CONFIG_CPU == SH7034
+OUTPUT_FORMAT(elf32-sh)
 INPUT(target/sh/crt0.o)
 #else
+OUTPUT_FORMAT(elf32-sh)
 INPUT(crt0.o)
 #endif
 
 
 #if MEMORYSIZE >= 32
-#define PLUGINSIZE 0xC0000
+#define PLUGINSIZE PLUGIN_BUFFER_SIZE
 #else
 #define PLUGINSIZE 0x8000
 #endif
 
-#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE
+#define CODECSIZE CODEC_SIZE
 
-#ifdef IRIVER_H100
-#define DRAMORIG 0x31000000
+#ifdef DEBUG
+#define STUBOFFSET 0x10000
+#else
+#define STUBOFFSET 0
+#endif
+
+#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - STUBOFFSET - CODECSIZE
+
+#ifdef IRIVER_H100_SERIES
+#define DRAMORIG 0x31000000 + STUBOFFSET
 #define IRAMORIG 0x10000000
-#define IRAMSIZE 0x18000
-#define FLASHORIG 0x001f0000
-#define FLASHSIZE 2M
+#define IRAMSIZE 0xc000
+#define FLASHORIG 0x00100028
+#define FLASHSIZE 0x000eff80
 #else
 #define DRAMORIG 0x09000000
 #define IRAMORIG 0x0f000000
@@ -41,7 +50,11 @@ INPUT(crt0.o)
 #define FLASHSIZE 256K - ROM_START
 #endif
 
-#define ENDADDR  (DRAMORIG + DRAMSIZE)
+/* End of the audio buffer, where the codec buffer starts */
+#define ENDAUDIOADDR  (DRAMORIG + DRAMSIZE)
+
+/* Where the codec buffer ends, and the plugin buffer starts */
+#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
 
 MEMORY
 {
@@ -74,10 +87,15 @@ SECTIONS
         . = ALIGN(0x200);
         *(.data)
         . = ALIGN(0x4);
-        _dataend = .;         
+        _dataend = .;        
         . = ALIGN(0x10);  /* Maintain proper alignment for .text section */
     } > DRAM
     
+    /DISCARD/ : 
+    {
+        *(.eh_frame)
+    }
+
     /* TRICK ALERT! Newer versions of the linker don't allow output sections
        to overlap even if one of them is empty, so advance the location pointer
        "by hand" */
@@ -105,7 +123,7 @@ SECTIONS
         *(.idata)
         _iramend = .;
     } > IRAM
-  
+
     .ibss (NOLOAD) :
     {
         _iedata = .;
@@ -122,29 +140,42 @@ SECTIONS
        . += 0x2000;
        _stackend = .;
        stackend = .;
-    } > DRAM
+    } > IRAM
 
+#ifdef CPU_COLDFIRE
+    .bss ADDR(.data) + SIZEOF(.data) + SIZEOF(.iram):
+#else
     .bss :
+#endif
     {
        _edata = .;
-        *(.bss)
+        *(.bss*)
         *(COMMON)
+        . = ALIGN(0x4);
        _end = .;
     } > DRAM
 
-    .audiobuf :
+    .audiobuf ALIGN(4):
     {
-        . = ALIGN(0x4);
         _audiobuffer = .;
+        audiobuffer = .;
     } > DRAM
 
-    .audiobufend ENDADDR:
+    .audiobufend ENDAUDIOADDR:
     {
         _audiobufend = .;
+        audiobufend = .;
     } > DRAM
 
+    .codec ENDAUDIOADDR:
+    {
+        codecbuf = .;
+        _codecbuf = .;
+    }
+
     .plugin ENDADDR:
     {
         _pluginbuf = .;
+        pluginbuf = .;
     }
 }
Index: firmware/system.c
===================================================================
RCS file: /cvsroot/rockbox/firmware/system.c,v
retrieving revision 1.131
diff -u -3 -p -r1.131 system.c
--- firmware/system.c	5 Dec 2006 20:01:45 -0000	1.131
+++ firmware/system.c	7 Dec 2006 07:27:07 -0000
@@ -91,31 +91,44 @@ void system_init(void) {
 
 #endif
 
-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"
Index: firmware/backlight.c
===================================================================
RCS file: /cvsroot/rockbox/firmware/backlight.c,v
retrieving revision 1.112
diff -u -3 -p -r1.112 backlight.c
--- firmware/backlight.c	5 Dec 2006 20:21:11 -0000	1.112
+++ firmware/backlight.c	7 Dec 2006 07:27:07 -0000
@@ -152,8 +152,8 @@ static int fade_in_count = 1;
 static int fade_out_count = 4;
 
 static bool bl_timer_active = false;
-static int bl_dim_current = BL_PWM_COUNT;
-static int bl_dim_target  = BL_PWM_COUNT;
+static int bl_dim_current = 0;
+static int bl_dim_target  = 0;
 static int bl_pwm_counter = 0;
 static volatile int bl_cycle_counter = 0;
 static enum {DIM_STATE_START, DIM_STATE_MAIN} bl_dim_state = DIM_STATE_START;
Index: firmware/export/config-h120.h
===================================================================
RCS file: /cvsroot/rockbox/firmware/export/config-h120.h,v
retrieving revision 1.53
diff -u -3 -p -r1.53 config-h120.h
--- firmware/export/config-h120.h	21 Nov 2006 17:14:07 -0000	1.53
+++ firmware/export/config-h120.h	7 Dec 2006 07:27:07 -0000
@@ -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
Index: firmware/export/eeprom_settings.h
===================================================================
RCS file: /cvsroot/rockbox/firmware/export/eeprom_settings.h,v
retrieving revision 1.2
diff -u -3 -p -r1.2 eeprom_settings.h
--- firmware/export/eeprom_settings.h	9 Aug 2006 12:04:13 -0000	1.2
+++ firmware/export/eeprom_settings.h	7 Dec 2006 07:27:07 -0000
@@ -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 */
 };
Index: firmware/export/system.h
===================================================================
RCS file: /cvsroot/rockbox/firmware/export/system.h,v
retrieving revision 1.65
diff -u -3 -p -r1.65 system.h
--- firmware/export/system.h	5 Dec 2006 20:01:48 -0000	1.65
+++ firmware/export/system.h	7 Dec 2006 07:27:07 -0000
@@ -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
Index: firmware/target/coldfire/crt0.S
===================================================================
RCS file: /cvsroot/rockbox/firmware/target/coldfire/crt0.S,v
retrieving revision 1.1
diff -u -3 -p -r1.1 crt0.S
--- firmware/target/coldfire/crt0.S	31 Aug 2006 19:45:05 -0000	1.1
+++ firmware/target/coldfire/crt0.S	7 Dec 2006 07:27:07 -0000
@@ -90,28 +90,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 */
@@ -169,6 +181,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 */
Index: tools/configure
===================================================================
RCS file: /cvsroot/rockbox/tools/configure,v
retrieving revision 1.245
diff -u -3 -p -r1.245 configure
--- tools/configure	27 Nov 2006 02:15:39 -0000	1.245
+++ tools/configure	7 Dec 2006 07:27:07 -0000
@@ -767,7 +767,7 @@ EOF
     output="rockbox.iriver"
     appextra="recorder:gui"
     archosrom=""
-    flash=""
+    flash="$pwd/rombox.iriver"
     plugins="yes"
     codecs="libmad liba52 libffmpegFLAC libTremor libwavpack dumb libmusepack libalac libfaad libm4a"
     # toolset is the tools within the tools directory that we build for
Index: firmware/target/coldfire/iriver/h100/backlight-h100.c
===================================================================
RCS file: /cvsroot/rockbox/firmware/target/coldfire/iriver/h100/backlight-h100.c,v
retrieving revision 1.2
diff -u -3 -p -r1.2 backlight-h100.c
--- firmware/target/coldfire/iriver/h100/backlight-h100.c	10 Nov 2006 18:47:41 -0000	1.2
+++ firmware/target/coldfire/iriver/h100/backlight-h100.c	7 Dec 2006 07:27:07 -0000
@@ -28,7 +28,6 @@ void __backlight_init(void)
 {
     or_l(0x00020000, &GPIO1_ENABLE);
     or_l(0x00020000, &GPIO1_FUNCTION);
-    and_l(~0x00020000, &GPIO1_OUT);  /* Start with the backlight ON */
 }
 
 void __backlight_on(void)
