Index: bootloader/ipodnano2g.c
===================================================================
--- bootloader/ipodnano2g.c	(revision 22645)
+++ bootloader/ipodnano2g.c	(working copy)
@@ -69,32 +69,37 @@
     lcd_puts_scroll(0,0,"+++ this is a very very long line to test scrolling. ---");
     verbose = 0;
     i = 0;
+    char i2c1, i2c2;
     while (!button_hold()) {
+        sleep(HZ);
         line = 1;

-        printf("i=%d",i++);
-        printf("TBCNT:   %08x",TBCNT);
-        printf("GPIO  0: %08x",PDAT0);
-        printf("GPIO  1: %08x",PDAT1);
-        printf("GPIO  2: %08x",PDAT2);
-        printf("GPIO  3: %08x",PDAT3);
-        printf("GPIO  4: %08x",PDAT4);
-        printf("GPIO  5: %08x",PDAT5);
-        printf("GPIO  6: %08x",PDAT6);
-        printf("GPIO  7: %08x",PDAT7);
-        printf("GPIO 10: %08x",PDAT10);
-        printf("GPIO 11: %08x",PDAT11);
-        printf("GPIO 13: %08x",PDAT13);
-        printf("GPIO 14: %08x",PDAT14);
+        printf("TICK:    %08x",current_tick);

+        line = 3;
+        i2c1 = 0x05;
+        i2c_write(0xe6, 0x54, 1, &i2c1);
+        while ((i2c1 & 0x80) == 0) i2c_read(0xe6, 0x57, 1, &i2c1);
+        i2c_read(0xe6, 0x55, 1, &i2c2);
+        int voltage = 6 * ((i2c2 << 2) | (i2c1 & 3));
+        printf("BATTERY: %d.%3dV",voltage/1000,voltage%1000);
+        i2c1 = 0x25;
+        i2c_write(0xe6, 0x54, 1, &i2c1);
+        while ((i2c1 & 0x80) == 0) i2c_read(0xe6, 0x57, 1, &i2c1);
+        i2c_read(0xe6, 0x55, 1, &i2c2);
+        printf("CURRENT: %dmA",(i2c2 << 2) | (i2c1 & 3));
+
         lcd_update();
     }

-    disable_irq();
+#ifdef DEBUG
+    // iBugger: terminate
+    asm volatile("MSR CPSR_c, #0x13; SWI 7");
+#else
+    // reset it
+    asm volatile("MSR CPSR_c, #0xD3; MOV R5, #0x110000; ADD R5, R5, #0xFF; \
+                  ADD R6, R5, #0xA00; MOV R10, #0x3C800000; STR R6, [R10]; \
+                  MOV R6, #0xFF0; STR R6, [R10,#4]; STR R5, [R10]; hang: B hang");
+#endif

-    /* Branch back to iBugger entry point */
-    asm volatile("ldr pc, =0x08640568");
-
-    /* We never reach here */
-    while(1);
 }
Index: firmware/export/config-ipodnano2g.h
===================================================================
--- firmware/export/config-ipodnano2g.h	(revision 22645)
+++ firmware/export/config-ipodnano2g.h	(working copy)
@@ -137,7 +137,7 @@
 #define FLASH_SIZE 0x400000

 /* Define this to the CPU frequency */
-#define CPU_FREQ      11289600
+#define CPU_FREQ      200000000

 /* Define this if you have ATA power-off control */
 //#define HAVE_ATA_POWER_OFF
Index: firmware/target/arm/s5l8700/boot.lds
===================================================================
--- firmware/target/arm/s5l8700/boot.lds	(revision 22645)
+++ firmware/target/arm/s5l8700/boot.lds	(working copy)
@@ -38,11 +38,12 @@
 }

 #ifdef IPOD_NANO2G
-#define LOAD_AREA IRAM
+#define LOAD_AREA DRAM
 #else
 #define LOAD_AREA FLASH
 #endif

+#ifdef IPOD_NANO2G
 SECTIONS
 {
   .intvect : {
@@ -72,6 +73,65 @@
     *(.ncdata*);
     . = ALIGN(0x4);
     _dataend = . ;
+   } > DRAM AT> LOAD_AREA
+   _datacopy = LOADADDR(.data) ;
+
+  .stack :
+  {
+     *(.stack)
+     _stackbegin = .;
+     stackbegin = .;
+     . += 0x2000;
+     _stackend = .;
+     stackend = .;
+     _irqstackbegin = .;
+     . += 0x400;
+     _irqstackend = .;
+     _fiqstackbegin = .;
+     . += 0x400;
+     _fiqstackend = .;
+  } > DRAM
+
+  .bss : {
+     _edata = .;
+     *(.bss*);
+     *(.ibss);
+     *(.ncbss*);
+     *(COMMON);
+    . = ALIGN(0x4);
+     _end = .;
+   } > DRAM
+}
+#else
+SECTIONS
+{
+  .intvect : {
+    _intvectstart = . ;
+    *(.intvect)
+    _intvectend = _newstart ;  
+  } >IRAM AT> LOAD_AREA
+  _intvectcopy = LOADADDR(.intvect) ;
+
+  .text : {
+    *(.init.text)
+    *(.text*)
+    *(.glue_7*)
+  } > LOAD_AREA
+
+  .rodata : {
+    *(.rodata*)
+    . = ALIGN(0x4);
+  } > LOAD_AREA
+
+  .data : {
+    _datastart = . ;
+    *(.irodata)
+    *(.icode)
+    *(.idata)
+    *(.data*)
+    *(.ncdata*);
+    . = ALIGN(0x4);
+    _dataend = . ;
    } > IRAM AT> LOAD_AREA
    _datacopy = LOADADDR(.data) ;

@@ -101,3 +161,4 @@
      _end = .;
    } > IRAM
 }
+#endif
Index: firmware/target/arm/s5l8700/crt0.S
===================================================================
--- firmware/target/arm/s5l8700/crt0.S	(revision 22645)
+++ firmware/target/arm/s5l8700/crt0.S	(working copy)
@@ -35,6 +35,9 @@
     ldr pc, =reserved_handler
     ldr pc, =irq_handler
     ldr pc, =fiq_handler
+#ifdef IPOD_NANO2G
+    b _newstart
+#endif
 #if CONFIG_CPU==S5L8700
     .word 0x43554644 /* DFUC */
 #endif
@@ -56,19 +59,34 @@
     mov r0, #0xa5
     str r0, [r1]

+#if defined(IPOD_NANO2G) && defined(DEBUG)
+    mov r0, #0x00010000
+#else
+     mov r0, #0
+#endif
+     ldr r1, =0x39c00008
+     str r0, [r1] // mask all interrupts
+#if defined(IPOD_NANO2G) && defined(DEBUG)
     mov r0, #0
-    ldr r1, =0x39c00008
-    str r0, [r1] // mask all interrupts
+#endif
     ldr r1, =0x39c00020
     str r0, [r1] // mask all external interrupts
     mvn r0, #0
+    ldr r1, =0x39c0001c
+    str r0, [r1] // clear pending external interrupts
     mov r1, #0x39c00000
     str r0, [r1] // irq priority
     ldr r1, =0x39c00010
     str r0, [r1] // clear pending interrupts
-    ldr r1, =0x39c0001c
-    str r0, [r1] // clear pending external interrupts

+#if defined(IPOD_NANO2G) && !defined(DEBUG)
+	LDR	R1, =0x38200000 // Remap IRAM to address zero
+	LDR	R2, [R1]
+	ORR	R2, R2, #1
+	BIC	R2, R2, #0x10000
+	STR	R2, [R1]
+#endif
+
 //    ldr r1, =0x3cf00000
 //    ldr r0, [r1]
 //    mvn r2, #0x30
@@ -82,9 +100,6 @@
 //    orr r0, r0, r2
 //    str r0, [r1] // switch backlight on

-#ifndef IPOD_NANO2G
-/* Currently disabled for the Nano2G as it doesn't appear to be
-   correct - e.g. audio doesn't work with this code enabled. */
     ldr r1, =0x3c500000 // CLKCON
     ldr r0, =0x00800080
     str r0, [r1]
@@ -126,7 +141,6 @@
     nop					        
     nop
     nop
-#endif
 	
 //    ldr r0, =0x10100000
 //    ldr r1, =0x38200034
@@ -190,7 +204,11 @@
     mcr 15, 0, r0, c6, c0, 1
     mov r0, #0x2f
     mcr 15, 0, r0, c6, c1, 1
-    ldr r0, =0x08000031
+#ifdef IPOD_NANO2G
+    ldr r0, =0x08000031 // FIXME: calculate that from MEMORYSIZE
+#else
+    ldr r0, =0x0800002f // FIXME: calculate that from MEMORYSIZE
+#endif
     mcr 15, 0, r0, c6, c2, 1
     ldr r0, =0x22000023
     mcr 15, 0, r0, c6, c3, 1
@@ -200,7 +218,11 @@
     mcr 15, 0, r0, c6, c0, 0
     mov r0, #0x2f
     mcr 15, 0, r0, c6, c1, 0
-    ldr r0, =0x08000031
+#ifdef IPOD_NANO2G
+    ldr r0, =0x08000031 // FIXME: calculate that from MEMORYSIZE
+#else
+    ldr r0, =0x0800002f // FIXME: calculate that from MEMORYSIZE
+#endif
     mcr 15, 0, r0, c6, c2, 0
     ldr r0, =0x22000023
     mcr 15, 0, r0, c6, c3, 0
@@ -232,8 +254,7 @@
     orr r0, r0, r1
     mcr 15, 0, r0, c1, c0, 0 // enable protection unit

-    
-#if CONFIG_CPU==S5L8700
+#if !defined(IPOD_NANO2G) || !defined(DEBUG)
     /* Copy interrupt vectors to iram */
     ldr     r2, =_intvectstart
     ldr     r3, =_intvectend
Index: firmware/target/arm/s5l8700/kernel-s5l8700.c
===================================================================
--- firmware/target/arm/s5l8700/kernel-s5l8700.c	(revision 22645)
+++ firmware/target/arm/s5l8700/kernel-s5l8700.c	(working copy)
@@ -54,6 +54,6 @@
     TBCMD = (1 << 0);   /* TB_EN */

     /* enable timer interrupt */
-    INTMSK |= (1 << 7);
+    INTMSK |= (1 << 5);
 }

Index: firmware/target/arm/s5l8700/system-s5l8700.c
===================================================================
--- firmware/target/arm/s5l8700/system-s5l8700.c	(revision 22645)
+++ firmware/target/arm/s5l8700/system-s5l8700.c	(working copy)
@@ -66,7 +66,7 @@

 static void (* const irqvector[])(void) =
 {
-    EXT0,EXT1,EXT2,EINT_VBUS,EINTG,INT_TIMERA,INT_WDT,INT_TIMERB,
+    EXT0,EXT1,EXT2,EINT_VBUS,EINTG,INT_TIMERB,INT_WDT,INT_TIMERA,
     INT_TIMERC,INT_TIMERD,INT_DMA,INT_ALARM_RTC,INT_PRI_RTC,RESERVED1,INT_UART,INT_USB_HOST,
     INT_USB_FUNC,INT_LCDC_0,INT_LCDC_1,INT_ECC,INT_CALM,INT_ATA,INT_UART0,INT_SPDIF_OUT,
     INT_SDCI,INT_LCD,INT_SPI,INT_IIC,RESERVED2,INT_MSTICK,INT_ADC_WAKEUP,INT_ADC