summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2009-10-11 01:37:12 +0000
committerDave Chapman <dave@dchapman.com>2009-10-11 01:37:12 +0000
commitb04a7a86e1d903a37091486764d0dfe09372d663 (patch)
tree35c74cc921eb641858269c30c2add4e436d97ec8
parenta27f2b8683204e337b142124979592ee1cd0d6f9 (diff)
downloadrockbox-b04a7a86e1d903a37091486764d0dfe09372d663.tar.gz
rockbox-b04a7a86e1d903a37091486764d0dfe09372d663.zip
Make the Nano2G bootloader actually function as a bootloader. The resulting bootloader-ipodnano2g.ipod file needs to be encrypted on a target using the crypt_firmware plugin to create bootloader-ipodnano2g.ipodx, which can then be written to the firmware partition using the ipodpatcher patch at FS#10609. Dual-booting doesn't work yet - only Rockbox can be run.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23084 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--bootloader/SOURCES7
-rw-r--r--bootloader/ipodnano2g.c137
-rw-r--r--firmware/target/arm/s5l8700/boot.lds12
-rw-r--r--firmware/target/arm/s5l8700/crt0.S21
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/ftl-target.h5
-rwxr-xr-xtools/configure3
6 files changed, 141 insertions, 44 deletions
diff --git a/bootloader/SOURCES b/bootloader/SOURCES
index f297f18fba..a512064ffd 100644
--- a/bootloader/SOURCES
+++ b/bootloader/SOURCES
@@ -1,6 +1,8 @@
common.c
-#if defined(IPOD_ARCH)
+#if defined(IPOD_NANO2G)
+ipodnano2g.c
+#elif defined(IPOD_ARCH)
ipod.c
#elif defined(GIGABEAT_F)
gigabeat.c
@@ -55,7 +57,4 @@ show_logo.c
#elif defined(LYRE_PROTO1)
lyre_proto1.c
show_logo.c
-#elif defined(IPOD_NANO2G)
-ipodnano2g.c
-show_logo.c
#endif
diff --git a/bootloader/ipodnano2g.c b/bootloader/ipodnano2g.c
index f6bfe148ac..f05829eb6d 100644
--- a/bootloader/ipodnano2g.c
+++ b/bootloader/ipodnano2g.c
@@ -45,56 +45,127 @@
#include "file.h"
#include "common.h"
-char version[] = APPSVERSION;
+/* Safety measure - maximum allowed firmware image size.
+ The largest known current (October 2009) firmware is about 6.2MB so
+ we set this to 8MB.
+*/
+#define MAX_LOADSIZE (8*1024*1024)
+
+/* The buffer to load the firmware into */
+unsigned char *loadbuffer = (unsigned char *)0x08000000;
-/* Show the Rockbox logo - in show_logo.c */
-extern int show_logo(void);
+/* Bootloader version */
+char version[] = APPSVERSION;
extern int line;
+void fatal_error(void)
+{
+ extern int line;
+ bool holdstatus=false;
+
+ /* System font is 6 pixels wide */
+ printf("Hold MENU+SELECT to");
+ printf("reboot then SELECT+PLAY");
+ printf("for disk mode");
+ lcd_update();
+
+ while (1) {
+ if (button_hold() != holdstatus) {
+ if (button_hold()) {
+ holdstatus=true;
+ lcd_puts(0, line, "Hold switch on!");
+ } else {
+ holdstatus=false;
+ lcd_puts(0, line, " ");
+ }
+ lcd_update();
+ }
+ }
+}
+
void main(void)
{
int i;
+ int btn;
+ int rc;
+ bool button_was_held;
+
+ /* Check the button hold status as soon as possible - to
+ give the user maximum chance to turn it on in order to
+ reset the settings in rockbox. */
+ button_was_held = button_hold();
system_init();
- i2c_init();
kernel_init();
+ i2c_init();
+
enable_irq();
+ backlight_init(); /* Turns on the backlight */
+
lcd_init();
+ font_init();
+
+ lcd_set_foreground(LCD_WHITE);
+ lcd_set_background(LCD_BLACK);
+ lcd_clear_display();
+
+// button_init();
+
+ btn=0; /* TODO */
- _backlight_init();
-
- lcd_puts_scroll(0,0,"+++ this is a very very long line to test scrolling. ---");
- verbose = 0;
- i = 0;
- while (!button_hold()) {
- 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);
-
- lcd_update();
+ /* Enable bootloader messages */
+ if (btn==BUTTON_RIGHT)
+ verbose = true;
+
+ lcd_setfont(FONT_SYSFIXED);
+
+ printf("Rockbox boot loader");
+ printf("Version: %s", version);
+
+ i = storage_init();
+
+ if (i != 0) {
+ printf("ATA error: %d", i);
+ fatal_error();
}
- disable_irq();
+ disk_init();
+ rc = disk_mount_all();
+ if (rc<=0)
+ {
+ printf("No partition found");
+ fatal_error();
+ }
+
+ if (button_was_held || (btn==BUTTON_MENU)) {
+ /* If either the hold switch was on, or the Menu button was held, then
+ try the Apple firmware */
- /* Branch back to iBugger entry point */
- asm volatile("ldr pc, =0x08640568");
+ printf("Loading original firmware...");
+
+ /* TODO */
+ fatal_error();
+ } else {
+ printf("Loading Rockbox...");
+ rc=load_firmware(loadbuffer, BOOTFILE, MAX_LOADSIZE);
+
+ if (rc != EOK) {
+ printf("Error!");
+ printf("Can't load " BOOTFILE ": ");
+ printf(strerror(rc));
+ fatal_error();
+ }
+
+ printf("Rockbox loaded.");
+ }
+
+ /* If we get here, we have a new firmware image at 0x08000000, run it */
+
+ disable_irq();
- /* We never reach here */
- while(1);
+ /* Branch to start of DRAM */
+ asm volatile("ldr pc, =0x08000000");
}
diff --git a/firmware/target/arm/s5l8700/boot.lds b/firmware/target/arm/s5l8700/boot.lds
index 2dea0ee4ea..637a3a29c1 100644
--- a/firmware/target/arm/s5l8700/boot.lds
+++ b/firmware/target/arm/s5l8700/boot.lds
@@ -9,14 +9,14 @@ OUTPUT_FORMAT(elf32-bigarm)
OUTPUT_ARCH(arm)
STARTUP(target/arm/s5l8700/crt0.o)
-/* DRAMORIG is in fact 0x08000000 but remapped to 0x0 */
#define DRAMORIG 0x08000000
#define DRAMSIZE (MEMORYSIZE * 0x100000)
-#define IRAMORIG 0x22000000
#if CONFIG_CPU==S5L8701
+#define IRAMORIG 0x0
#define IRAMSIZE 176K
#else
+#define IRAMORIG 0x22000000
#define IRAMSIZE 256K
#endif
@@ -91,7 +91,11 @@ SECTIONS
_fiqstackend = .;
} > IRAM
- .bss : {
+ /* The bss section is too large for IRAM - we just move it 12MB into the
+ DRAM */
+
+ . = DRAMORIG;
+ .bss . + (12*1024*1024): {
_edata = .;
*(.bss*);
*(.ibss);
@@ -99,5 +103,5 @@ SECTIONS
*(COMMON);
. = ALIGN(0x4);
_end = .;
- } > IRAM
+ } > DRAM
}
diff --git a/firmware/target/arm/s5l8700/crt0.S b/firmware/target/arm/s5l8700/crt0.S
index 4a89f3da39..aa2923cb29 100644
--- a/firmware/target/arm/s5l8700/crt0.S
+++ b/firmware/target/arm/s5l8700/crt0.S
@@ -27,7 +27,11 @@
.global _newstart
/* Exception vectors */
start:
+#if CONFIG_CPU==S5L8701 && defined(BOOTLOADER)
+ b newstart2
+#else
b _newstart
+#endif
ldr pc, =undef_instr_handler
ldr pc, =software_int_handler
ldr pc, =prefetch_abort_handler
@@ -88,7 +92,22 @@ newstart2:
orr r2, r2, #1
bic r2, r2, #0x10000
str r2, [r1] // remap iram to address 0x0
-#endif
+
+#ifdef BOOTLOADER
+ /* Relocate ourself to IRAM - we have been loaded to DRAM */
+ mov r0, #0x08000000 /* source (DRAM) */
+ mov r1, #0x00000000 /* dest (IRAM) */
+ ldr r2, =_dataend
+1:
+ cmp r2, r1
+ ldrhi r3, [r0], #4
+ strhi r3, [r1], #4
+ bhi 1b
+
+ ldr pc, =start_loc /* jump to the relocated start_loc: */
+start_loc:
+#endif /* BOOTLOADER */
+#endif /* CONFIG_CPU==S5L8701 */
ldr r1, =0x3c500000 // CLKCON
ldr r0, =0x00800080
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/ftl-target.h b/firmware/target/arm/s5l8700/ipodnano2g/ftl-target.h
index f214964551..0c36db9799 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/ftl-target.h
+++ b/firmware/target/arm/s5l8700/ipodnano2g/ftl-target.h
@@ -25,6 +25,11 @@
#include "config.h"
#include "inttypes.h"
+#ifdef BOOTLOADER
+/* Bootloaders don't need write access */
+#define FTL_READONLY
+#endif
+
uint32_t ftl_init(void);
uint32_t ftl_read(uint32_t sector, uint32_t count, void* buffer);
uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer);
diff --git a/tools/configure b/tools/configure
index acbfba42e0..790be27cc5 100755
--- a/tools/configure
+++ b/tools/configure
@@ -1441,8 +1441,7 @@ fi
appextra="recorder:gui"
plugins="yes"
swcodec="yes"
- boottool="cp"
- bootoutput="bootloader-$modelname.bin"
+ bootoutput="bootloader-$modelname.ipod"
# toolset is the tools within the tools directory that we build for
# this particular target.
toolset=$ipodbitmaptools