rendered paste bodyIndex: bootloader/e200.c
===================================================================
RCS file: /cvsroot/rockbox/bootloader/e200.c,v
retrieving revision 1.5
diff -u -r1.5 e200.c
--- bootloader/e200.c 16 Oct 2006 17:21:30 -0000 1.5
+++ bootloader/e200.c 5 Dec 2006 01:27:21 -0000
@@ -5,9 +5,12 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
- * $Id: e200.c,v 1.5 2006-10-16 17:21:30 dan_a Exp $
+ * $Id: h10.c,v 1.4 2006-08-28 08:11:32 barrywardell Exp $
*
- * Copyright (C) 2006 Daniel Stenberg
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * Based on Rockbox iriver bootloader by Linus Nielsen Feltzing
+ * and the ipodlinux bootloader by Daniel Palffy and Bernard Leach
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
@@ -32,63 +35,202 @@
#include "font.h"
#include "adc.h"
#include "backlight.h"
+#include "button.h"
#include "panic.h"
#include "power.h"
#include "file.h"
-static inline void blink(void)
+/* Size of the buffer to store the loaded Rockbox/Sansa image */
+#define MAX_LOADSIZE (10*1024*1024)
+
+/* A buffer to load the iriver firmware or Rockbox into */
+unsigned char loadbuffer[MAX_LOADSIZE];
+
+char version[] = APPSVERSION;
+
+#define DRAM_START 0x10000000
+
+int line=0;
+
+/* Load original Sandisk firmware. This function expects a file called
+ "/.rockbox/OF.bin" on the player. It should be decrypted
+ and have the header stripped using mi4code. It reads the file in to a memory
+ buffer called buf. The rest of the loading is done in main() and crt0.S
+*/
+int load_sandisk(unsigned char* buf)
{
- volatile unsigned int* ptr;
+ int fd;
+ int rc;
+ int len;
+
+ fd = open("/.rockbox/OF.bin", O_RDONLY);
+
+ len = filesize(fd);
+
+ if (len > MAX_LOADSIZE)
+ return -6;
+
+ rc = read(fd, buf, len);
+ if(rc < len)
+ return -4;
+
+ close(fd);
+ return len;
+}
+
+/* Load Rockbox firmware (rockbox.e200) */
+int load_rockbox(unsigned char* buf)
+{
+ int fd;
+ int rc;
+ int len;
+ unsigned long chksum;
+ char model[5];
+ unsigned long sum;
int i;
- ptr = (volatile unsigned int*)0x70000020;
+ char str[80];
- *ptr &= ~(1 << 13);
- for(i = 0; i < 0xfffff; i++)
+ fd = open("/.rockbox/" BOOTFILE, O_RDONLY);
+ if(fd < 0)
{
+ fd = open("/" BOOTFILE, O_RDONLY);
+ if(fd < 0)
+ return -1;
}
- *ptr |= (1 << 13);
- for(i = 0; i < 0xfffff; i++)
- {
+
+ len = filesize(fd) - 8;
+
+ snprintf(str, sizeof(str), "Length: %x", len);
+ lcd_puts(0, line++ ,str);
+ lcd_update();
+
+ if (len > MAX_LOADSIZE)
+ return -6;
+
+ lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET);
+
+ rc = read(fd, &chksum, 4);
+ chksum=betoh32(chksum); /* Rockbox checksums are big-endian */
+ if(rc < 4)
+ return -2;
+
+ snprintf(str, sizeof(str), "Checksum: %x", chksum);
+ lcd_puts(0, line++ ,str);
+ lcd_update();
+
+ rc = read(fd, model, 4);
+ if(rc < 4)
+ return -3;
+
+ model[4] = 0;
+
+ snprintf(str, sizeof(str), "Model name: %s", model);
+ lcd_puts(0, line++ ,str);
+ lcd_update();
+
+ lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);
+
+ rc = read(fd, buf, len);
+ if(rc < len)
+ return -4;
+
+ close(fd);
+
+ sum = MODEL_NUMBER;
+
+ for(i = 0;i < len;i++) {
+ sum += buf[i];
}
+
+ snprintf(str, sizeof(str), "Sum: %x", sum);
+ lcd_puts(0, line++ ,str);
+ lcd_update();
+
+ if(sum != chksum)
+ return -5;
+
+ return len;
}
-static inline void slow_blink(void)
+void* main(void)
{
- volatile unsigned int* ptr;
+ char buf[256];
int i;
- ptr = (volatile unsigned int*)0x70000020;
+ int rc;
+ unsigned short* identify_info;
+ struct partinfo* pinfo;
- *ptr &= ~(1 << 13);
- for(i = 0; i < (0xfffff); i++)
- {
- }
- for(i = 0; i < (0xfffff); i++)
- {
- }
- for(i = 0; i < (0xfffff); i++)
- {
- }
+ system_init();
+ kernel_init();
+ lcd_init();
+ font_init();
- *ptr |= (1 << 13);
- for(i = 0; i < (0xfffff); i++)
+ line=0;
+
+ lcd_setfont(FONT_SYSFIXED);
+
+ lcd_puts(0, line++, "Rockbox boot loader");
+ snprintf(buf, sizeof(buf), "Version: 20%s", version);
+ lcd_puts(0, line++, buf);
+ snprintf(buf, sizeof(buf), "Sandisk Sansa E200");
+ lcd_puts(0, line++, buf);
+ lcd_update();
+
+ i=ata_init();
+ if (i==0) {
+ identify_info=ata_get_identify();
+ /* Show model */
+ for (i=0; i < 20; i++) {
+ ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
+ }
+ buf[40]=0;
+ for (i=39; i && buf[i]==' '; i--) {
+ buf[i]=0;
+ }
+ lcd_puts(0, line++, buf);
+ lcd_update();
+ } else {
+ snprintf(buf, sizeof(buf), "ATA: %d", i);
+ lcd_puts(0, line++, buf);
+ lcd_update();
+ }
+
+ disk_init();
+ rc = disk_mount_all();
+ if (rc<=0)
{
+ lcd_puts(0, line++, "No partition found");
+ lcd_update();
}
- for(i = 0; i < (0xfffff); i++)
+
+ pinfo = disk_partinfo(0);
+ snprintf(buf, sizeof(buf), "Partition 0: 0x%02x %ld MB",
+ pinfo->type, pinfo->size / 2048);
+ lcd_puts(0, line++, buf);
+ lcd_update();
+
+ i=button_read_device();
+ if(i==BUTTON_LEFT)
{
+ lcd_puts(0, line, "Loading Sandisk firmware...");
+ lcd_update();
+ rc=load_sandisk(loadbuffer);
+ /* Sandisk firmware doesn't like having the cache enabled */
+ } else {
+ lcd_puts(0, line, "Loading Rockbox...");
+ lcd_update();
+ rc=load_rockbox(loadbuffer);
}
- for(i = 0; i < (0xfffff); i++)
- {
+
+ if (rc < 0) {
+ snprintf(buf, sizeof(buf), "Rockbox error: %d",rc);
+ lcd_puts(0, line++, buf);
+ lcd_update();
+ while(1) {}
}
-}
-static inline unsigned long get_pc(void)
-{
- unsigned long pc;
- asm volatile (
- "mov %0, pc\n"
- : "=r"(pc)
- );
- return pc;
+ memcpy((void*)DRAM_START,loadbuffer,rc);
+ return (void*)DRAM_START;
}
/* These functions are present in the firmware library, but we reimplement
@@ -100,62 +242,7 @@
int dbg_ports(void)
{
- unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
- unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
- unsigned int gpio_i, gpio_j, gpio_k, gpio_l;
-
- char buf[128];
- int line;
-
- lcd_setmargins(0, 0);
- lcd_clear_display();
- lcd_setfont(FONT_SYSFIXED);
-
- while(1)
- {
- gpio_a = GPIOA_INPUT_VAL;
- gpio_b = GPIOB_INPUT_VAL;
- gpio_c = GPIOC_INPUT_VAL;
-
- gpio_g = GPIOG_INPUT_VAL;
- gpio_h = GPIOH_INPUT_VAL;
- gpio_i = GPIOI_INPUT_VAL;
-
- line = 0;
- snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_G: %02x", gpio_a, gpio_g);
- lcd_puts(0, line++, buf);
- snprintf(buf, sizeof(buf), "GPIO_B: %02x GPIO_H: %02x", gpio_b, gpio_h);
- lcd_puts(0, line++, buf);
- snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_I: %02x", gpio_c, gpio_i);
- lcd_puts(0, line++, buf);
- line++;
-
- gpio_d = GPIOD_INPUT_VAL;
- gpio_e = GPIOE_INPUT_VAL;
- gpio_f = GPIOF_INPUT_VAL;
-
- gpio_j = GPIOJ_INPUT_VAL;
- gpio_k = GPIOK_INPUT_VAL;
- gpio_l = GPIOL_INPUT_VAL;
-
- snprintf(buf, sizeof(buf), "GPIO_D: %02x GPIO_J: %02x", gpio_d, gpio_j);
- lcd_puts(0, line++, buf);
- snprintf(buf, sizeof(buf), "GPIO_E: %02x GPIO_K: %02x", gpio_e, gpio_k);
- lcd_puts(0, line++, buf);
- snprintf(buf, sizeof(buf), "GPIO_F: %02x GPIO_L: %02x", gpio_f, gpio_l);
- lcd_puts(0, line++, buf);
- line++;
- snprintf(buf, sizeof(buf), "ADC_1: %02x", adc_read(ADC_0));
- lcd_puts(0, line++, buf);
- snprintf(buf, sizeof(buf), "ADC_2: %02x", adc_read(ADC_1));
- lcd_puts(0, line++, buf);
- snprintf(buf, sizeof(buf), "ADC_3: %02x", adc_read(ADC_2));
- lcd_puts(0, line++, buf);
- snprintf(buf, sizeof(buf), "ADC_4: %02x", adc_read(ADC_3));
- lcd_puts(0, line++, buf);
- lcd_update();
- }
- return 0;
+ return 0;
}
void mpeg_stop(void)
@@ -173,18 +260,3 @@
void sys_poweroff(void)
{
}
-
-void system_reboot(void)
-{
-
-}
-
-void main(void)
-{
- kernel_init();
- adc_init();
- lcd_init_device();
-
- dbg_ports();
-}
-
Index: firmware/export/config-e200.h
===================================================================
RCS file: /cvsroot/rockbox/firmware/export/config-e200.h,v
retrieving revision 1.4
diff -u -r1.4 config-e200.h
--- firmware/export/config-e200.h 22 Nov 2006 00:49:15 -0000 1.4
+++ firmware/export/config-e200.h 5 Dec 2006 01:27:24 -0000
@@ -4,7 +4,7 @@
#define TARGET_TREE /* this target is using the target tree system */
/* For Rolo and boot loader */
-#define MODEL_NUMBER 12
+#define MODEL_NUMBER 16
/* define this if you have recording possibility */
/*#define HAVE_RECORDING 1*/ /* TODO: add support for this */
Index: firmware/target/arm/crt0-pp.S
===================================================================
RCS file: /cvsroot/rockbox/firmware/target/arm/crt0-pp.S,v
retrieving revision 1.2
diff -u -r1.2 crt0-pp.S
--- firmware/target/arm/crt0-pp.S 22 Nov 2006 00:49:16 -0000 1.2
+++ firmware/target/arm/crt0-pp.S 5 Dec 2006 01:27:24 -0000
@@ -5,7 +5,7 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
- * $Id: crt0-pp.S,v 1.2 2006-11-22 00:49:16 dan_a Exp $
+ * $Id: crt0-pp.S,v 1.2 2006/11/22 00:49:16 dan_a Exp $
*
* Copyright (C) 2002 by Linus Nielsen Feltzing
*
@@ -52,17 +52,36 @@
msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ */
-#ifndef BOOTLOADER
b pad_skip
-#if defined(SANSA_E200)
-/* mi4tool writes junk between 0xe0 and 0xeb. Avoid this. */
-.space 60*4 /* (more than enough) space for exception vectors */
-#else
-.space 50*4
-#endif
+.space 60*4 /* For bootloader builds on targets with mi4 firmware, scramble
+ writes data to 0xe0-0xeb, so jump past that. For normal builds
+ this provides more than enough space for exception vectors */
pad_skip:
+
+#ifdef BOOTLOADER
+/* 1 - Copy the bootloader to IRAM */
+ /* get the high part of our execute address */
+ and r4, pc, #0xff000000
+
+ /* Copy bootloader to safe area - 0x40000000 */
+ mov r5, #0x40000000
+ ldr r6, = _dataend
+ sub r0, r6, r5 /* length of loader */
+ add r8, r4, r0 /* r8 points to start of loader */
+1:
+ cmp r5, r6
+ ldrcc r2, [r4], #4
+ strcc r2, [r5], #4
+ bcc 1b
+
+/* 2 - Jump both CPU and COP there */
+ ldr pc, =start_loc /* jump to the relocated start_loc: */
+
+start_loc:
+
+#else /* BOOTLOADER */
#ifdef SANSA_E200
/* On the Sansa, copying the vectors fails if the cache is initialised */
ldr r1, =CACHE_CTRL
@@ -106,24 +125,63 @@
L_post_remap: .word remap_end
remap_end:
- /* After doing the remapping, send the COP to sleep.
- On wakeup it will go to cop_init */
+#endif
+
+ /* Send the COP to sleep. On wakeup it will go to cop_init */
ldr r0, =PROC_ID
ldr r0, [r0]
and r0, r0, #0xff
cmp r0, #0x55
- beq 1f
+ beq cpu
/* put us (co-processor) to sleep */
ldr r4, =COP_CTRL
mov r3, #SLEEP
str r3, [r4]
+ ldr pc, =cop_wake_start
- ldr pc, =cop_init
+cop_wake_start:
+ /* COP: Invalidate cache */
+ ldr r0, =0xf000f044
+ ldr r1, [r0]
+ orr r1, r1, #0x6
+ str r1, [r0]
+ ldr r0, =0x6000c000
1:
+ ldr r1, [r0]
+ tst r1, #0x8000
+ bne 1b
+
+#ifdef BOOTLOADER
+ ldr r0, =startup_loc
+ ldr pc, [r0]
+#else
+ /* Setup stack for COP */
+ ldr sp, =cop_stackend
+ mov r3, sp
+ ldr r2, =cop_stackbegin
+ ldr r4, =0xdeadbeef
+2:
+ cmp r3, r2
+ strhi r4, [r2], #4
+ bhi 2b
-#ifndef DEBUG
+ ldr sp, =cop_stackend
+
+ /* Run cop_main() in apps/main.c */
+ bl cop_main
+#endif
+
+cpu:
+ /* Wait for COP to be sleeping */
+ ldr r4, =COP_STATUS
+1:
+ ldr r3, [r4]
+ ands r3, r3, #SLEEPING
+ beq 1b
+
+#ifndef BOOTLOADER
/* Copy exception handler code to address 0 */
ldr r2, =_vectorsstart
ldr r3, =_vectorsend
@@ -133,24 +191,18 @@
ldrhi r5, [r4], #4
strhi r5, [r2], #4
bhi 1b
-#else
- ldr r1, =vectors
- ldr r0, =irq_handler
- str r0, [r1, #24]
- ldr r0, =fiq_handler
- str r0, [r1, #28]
#endif
-#ifndef STUB
- /* Zero out IBSS */
- ldr r2, =_iedata
- ldr r3, =_iend
+ /* Initialise bss section to zero */
+ ldr r2, =_edata
+ ldr r3, =_end
mov r4, #0
1:
cmp r3, r2
strhi r4, [r2], #4
bhi 1b
-
+
+#ifndef BOOTLOADER
/* Copy the IRAM */
ldr r2, =_iramcopy
ldr r3, =_iramstart
@@ -160,18 +212,8 @@
ldrhi r5, [r2], #4
strhi r5, [r3], #4
bhi 1b
-#endif /* !STUB */
-#endif /* !BOOTLOADER */
+#endif
- /* Initialise bss section to zero */
- ldr r2, =_edata
- ldr r3, =_end
- mov r4, #0
-1:
- cmp r3, r2
- strhi r4, [r2], #4
- bhi 1b
-
/* Set up some stack and munge it with 0xdeadbeef */
ldr sp, =stackend
mov r3, sp
@@ -183,76 +225,31 @@
bhi 1b
#ifdef BOOTLOADER
- /* TODO: the high part of the address is probably dependent on CONFIG_CPU.
- Since we tend to use ifdefs for each chipset target
- anyway, we might as well just hardcode it here.
- */
-
- /* get the high part of our execute address */
- ldr r0, =0xff000000
- and r8, pc, r0 @ r8 is used later
-
- /* Find out which processor we are */
- mov r0, #PROC_ID
- ldr r0, [r0]
- and r0, r0, #0xff
- cmp r0, #0x55
- beq 1f
-
- /* put us (co-processor) to sleep */
- ldr r4, =COP_CTRL
- mov r3, #SLEEP
- str r3, [r4]
- ldr pc, =cop_wake_start
-
-cop_wake_start:
- /* jump the COP to startup */
- ldr r0, =startup_loc
- ldr pc, [r0]
-
-1:
-
- /* get the high part of our execute address */
- ldr r2, =0xffffff00
- and r4, pc, r2
-
- /* Copy bootloader to safe area - 0x40000000 */
- mov r5, #0x40000000
- ldr r6, = _dataend
- sub r0, r6, r5 /* length of loader */
- add r0, r4, r0 /* r0 points to start of loader */
-1:
- cmp r5, r6
- ldrcc r2, [r4], #4
- strcc r2, [r5], #4
- bcc 1b
-
- ldr pc, =start_loc /* jump to the relocated start_loc: */
-
-start_loc:
+ mov r0, r8 /* r8 holds the start of the loader - copy this to r0 */
/* execute the loader - this will load an image to 0x10000000 */
bl main
- /* Wake up the coprocessor before executing the firmware */
-
- /* save the startup address for the COP */
ldr r1, =startup_loc
str r0, [r1]
- /* make sure COP is sleeping */
- ldr r4, =COP_STATUS
+ /* Flush cache */
+ ldr r3, =0xf000f044
+ ldr r4, [r3]
+ orr r4, r4, #0x2
+ str r4, [r3]
+
+ ldr r3, =0x6000c000
1:
- ldr r3, [r4]
- ands r3, r3, #SLEEPING
- beq 1b
+ ldr r4, [r3]
+ tst r4, #0x8000
+ bne 1b
- /* wake up COP */
+ /* Wake up the coprocessor before executing the firmware */
ldr r4, =COP_CTRL
mov r3, #WAKE
str r3, [r4]
- /* jump to start location */
mov pc, r0
startup_loc:
@@ -265,7 +262,7 @@
.space 400
#else /* BOOTLOADER */
-
+
/* Set up stack for IRQ mode */
msr cpsr_c, #0xd2
ldr sp, =irq_stack
@@ -288,19 +285,6 @@
ldr sp, =stackend
bl main
/* main() should never return */
-
-cop_init:
- ldr sp, =cop_stackend
- mov r3, sp
- ldr r2, =cop_stackbegin
- ldr r4, =0xdeadbeef
-2:
- cmp r3, r2
- strhi r4, [r2], #4
- bhi 2b
-
- ldr sp, =cop_stackend
- bl cop_main
/* Exception handlers. Will be copied to address 0 after memory remapping */
.section .vectors,"aw"
@@ -385,5 +369,4 @@
/* 256 words of FIQ stack */
.space 256*4
fiq_stack:
-
-#endif /* BOOTLOADER */
+#endif /* BOOTLOADER */
Index: tools/configure
===================================================================
RCS file: /cvsroot/rockbox/tools/configure,v
retrieving revision 1.245
diff -u -r1.245 configure
--- tools/configure 27 Nov 2006 02:15:39 -0000 1.245
+++ tools/configure 5 Dec 2006 01:27:27 -0000
@@ -1115,10 +1115,10 @@
target="-DSANSA_E200"
memory=32 # supposedly
arm7tdmicc
- tool="$rootdir/tools/scramble -mi4v3"
+ tool="$rootdir/tools/scramble -add=e200"
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
- output="PP5022.mi4"
+ output="rockbox.e200"
appextra="recorder:gui"
archosrom=""
flash=""
Index: tools/scramble.c
===================================================================
RCS file: /cvsroot/rockbox/tools/scramble.c,v
retrieving revision 1.35
diff -u -r1.35 scramble.c
--- tools/scramble.c 31 Aug 2006 19:19:35 -0000 1.35
+++ tools/scramble.c 5 Dec 2006 01:27:28 -0000
@@ -89,7 +89,7 @@
"\t-mi4v3 PortalPlayer .mi4 format (revision 010301)\n"
"\t-add=X Rockbox generic \"add-up\" checksum format\n"
"\t (X values: h100, h120, h140, h300, ipco, nano, ipvd\n"
- "\t ip3g, ip4g, mini, x5, h10, h10_5gb)\n"
+ "\t ip3g, ip4g, mini, x5, h10, h10_5gb, tpj2, e200)\n"
"\nNo option results in Archos standard player/recorder format.\n");
exit(1);
@@ -207,6 +207,8 @@
modelnum = 14;
else if(!strcmp(&argv[1][5], "tpj2"))
modelnum = 15;
+ else if(!strcmp(&argv[1][5], "e200"))
+ modelnum = 16;
else {
fprintf(stderr, "unsupported model: %s\n", &argv[1][5]);
return 2;