summaryrefslogtreecommitdiffstats
path: root/bootloader
diff options
context:
space:
mode:
authorBarry Wardell <rockbox@barrywardell.net>2006-08-28 08:11:32 +0000
committerBarry Wardell <rockbox@barrywardell.net>2006-08-28 08:11:32 +0000
commit1920df36d8378cf75c5c7165af9ee295adae7235 (patch)
tree77fafab725ec30b210f63647acefdf9771b2b31e /bootloader
parent93083e15c6cb25bcd1b0e9b659316d8e22959123 (diff)
downloadrockbox-1920df36d8378cf75c5c7165af9ee295adae7235.tar.gz
rockbox-1920df36d8378cf75c5c7165af9ee295adae7235.tar.bz2
rockbox-1920df36d8378cf75c5c7165af9ee295adae7235.zip
Add Rockbox bootloader for H10
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10781 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'bootloader')
-rw-r--r--bootloader/h10.c313
1 files changed, 153 insertions, 160 deletions
diff --git a/bootloader/h10.c b/bootloader/h10.c
index 86d3c33a17..0cfd64a96e 100644
--- a/bootloader/h10.c
+++ b/bootloader/h10.c
@@ -43,33 +43,19 @@
/* Size of the buffer to store the loaded Rockbox/iriver image */
#define MAX_LOADSIZE (5*1024*1024)
-/* This is identical to the function used in the iPod bootloader */
-static void memmove16(void *dest, const void *src, unsigned count)
-{
- struct bufstr {
- unsigned _buf[4];
- } *d, *s;
-
- if (src >= dest) {
- count = (count + 15) >> 4;
- d = (struct bufstr *) dest;
- s = (struct bufstr *) src;
- while (count--)
- *d++ = *s++;
- } else {
- count = (count + 15) >> 4;
- d = (struct bufstr *)(dest + (count <<4));
- s = (struct bufstr *)(src + (count <<4));
- while (count--)
- *--d = *--s;
- }
-}
+/* 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 iriver firmware. This function expects a file called
- "H10_20GC.mi4" in the root directory of the player. It should be decrypted
+ "/System/Original.mi4" 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()
+ buffer called buf. The rest of the loading is done in main() and crt0.S
*/
int load_iriver(unsigned char* buf)
{
@@ -77,9 +63,13 @@ int load_iriver(unsigned char* buf)
int rc;
int len;
- fd = open("/H10_20GC.mi4", O_RDONLY);
+ fd = open("/System/Original.mi4", O_RDONLY);
len = filesize(fd);
+
+ if (len > MAX_LOADSIZE)
+ return -6;
+
rc = read(fd, buf, len);
if(rc < len)
return -4;
@@ -88,155 +78,158 @@ int load_iriver(unsigned char* buf)
return len;
}
-/* A buffer to load the iriver firmware or Rockbox into */
-unsigned char loadbuffer[MAX_LOADSIZE];
-
-void main(void)
+/* Load Rockbox firmware (rockbox.h10) */
+int load_rockbox(unsigned char* buf)
{
- /* Attempt to load original iriver firmware. Successfully starts loading the
- iriver firmware but then locks up once the "System Initialising" screen
- is displayed.
-
- The iriver firmware was decrypted and the header removed. It was then
- appended to the end of bootloader.bin and an mi4 file was created from
- the resulting file.
-
- The original firmware starts at 0xd800 in the file and is of length
- 0x47da00.
-
- The whole file (bootloader.bin + decrypted mi4) are loaded to memory by
- the original iriver bootloader on startup. This copies the mi4 part to
- the start of DRAM and passes execution to there.
-
- memmove16((void*)DRAMORIG, (void*)(DRAMORIG + 0xd800), 0x47da00);
- asm volatile(
- "mov r0, #" SC(DRAMORIG) "\n"
- "mov pc, r0 \n"
- );
- */
-
- /*int i;
+ int fd;
int rc;
- int btn;
- int fd;*/
- char buffer[24];
+ int len;
+ unsigned long chksum;
+ char model[5];
+ unsigned long sum;
+ int i;
+ char str[80];
- snprintf(buffer, 24, "Hello World");
- lcd_puts(0, 0, buffer);
- lcd_update();
+ fd = open("/.rockbox/" BOOTFILE, O_RDONLY);
+ if(fd < 0)
+ {
+ fd = open("/" BOOTFILE, O_RDONLY);
+ if(fd < 0)
+ return -1;
+ }
- /*i=ata_init();
- disk_init();
- rc = disk_mount_all();*/
+ len = filesize(fd) - 8;
- /* Load original iriver firmware. Uses load_iriver(buf) to load the
- decrypted mi4 file from disk to DRAM. This then copies that part of DRAM
- to the start of DRAM and passes
- execution to there.
-
- rc=load_iriver(loadbuffer);
- memcpy((void*)DRAMORIG,loadbuffer,rc);
- asm volatile(
- "mov r0, #" SC(DRAMORIG) "\n"
- "mov pc, r0 \n"
- );*/
+ 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);
- /* This assumes that /test.txt exists */
- /*fd=open("/test.txt",O_RDWR);*/
+ 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<100;i++){
- btn = button_read_device();
- switch(btn){
- case BUTTON_LEFT:
- snprintf(buffer, sizeof(buffer), "Left");
- write(fd,buffer,sizeof(buffer));
- break;
- case BUTTON_RIGHT:
- break;
- case BUTTON_REW:
- break;
- case BUTTON_FF:
- break;
- case BUTTON_PLAY:
- break;
- default:
- break;
- }
-
+ 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;
+}
+
+void* main(void)
+{
+ char buf[256];
+ int i;
+ int rc;
+ unsigned short* identify_info;
+ struct partinfo* pinfo;
+
+ system_init();
+ kernel_init();
+ lcd_init();
+ font_init();
+
+ 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), "iriver H10");
+ 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();
+ }
+
+ 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 iriver firmware...");
+ lcd_update();
+ rc=load_iriver(loadbuffer);
+ } else {
+ lcd_puts(0, line, "Loading Rockbox...");
+ lcd_update();
+ rc=load_rockbox(loadbuffer);
+ }
+
+ if (rc < 0) {
+ snprintf(buf, sizeof(buf), "Rockbox error: %d",rc);
+ lcd_puts(0, line++, buf);
+ lcd_update();
}
- */
-
-
-
- /* Investigate gpio
-
- 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;
-
- 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;
-
- snprintf(buffer,sizeof(buffer),"GPIO_A: %02x GPIO_G: %02x\n",gpio_a,gpio_g);
- write(fd,buffer,sizeof(buffer));
- snprintf(buffer,sizeof(buffer),"GPIO_B: %02x GPIO_H: %02x\n",gpio_b,gpio_h);
- write(fd,buffer,sizeof(buffer));
- snprintf(buffer,sizeof(buffer),"GPIO_C: %02x GPIO_I: %02x\n",gpio_c,gpio_i);
- write(fd,buffer,sizeof(buffer));
-
- 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(buffer,sizeof(buffer),"GPIO_D: %02x GPIO_J: %02x\n",gpio_d,gpio_j);
- write(fd,buffer,sizeof(buffer));
- snprintf(buffer,sizeof(buffer),"GPIO_E: %02x GPIO_K: %02x\n",gpio_e,gpio_k);
- write(fd,buffer,sizeof(buffer));
- snprintf(buffer,sizeof(buffer),"GPIO_F: %02x GPIO_L: %02x\n",gpio_f,gpio_l);
- write(fd,buffer,sizeof(buffer));
- */
-
-
-
- /* Detect the scroller being touched
-
- int j = 0;
- for(j=0;j<1000;j++){
- if(gpio_c!=0xF7){
- snprintf(buffer, sizeof(buffer), "GPIO_C: %02x\n", gpio_c);
- write(fd,buffer,sizeof(buffer));
- }
- if(gpio_d!=0xDD){
- snprintf(buffer, sizeof(buffer), "GPIO_D: %02x\n", gpio_d);
- write(fd,buffer,sizeof(buffer));
- }
- }*/
-
-
- /* Apparently necessary for the data to be actually written to file */
- /*fsync(fd);
- udelay(1000000);*/
-
- /* This causes the device to shut off instantly
- GPIOF_OUTPUT_VAL = 0;
- */
+ memcpy((void*)DRAM_START,loadbuffer,rc);
- /*close(fd);*/
- udelay(100000000);
+ return (void*)DRAM_START;
}
/* These functions are present in the firmware library, but we reimplement