From 1920df36d8378cf75c5c7165af9ee295adae7235 Mon Sep 17 00:00:00 2001 From: Barry Wardell Date: Mon, 28 Aug 2006 08:11:32 +0000 Subject: [PATCH] Add Rockbox bootloader for H10 git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10781 a1c6a512-1295-4272-9138-f99709370657 --- bootloader/h10.c | 305 +++++++++++++++---------------- firmware/export/config-h10.h | 2 +- firmware/export/config-h10_5gb.h | 2 +- firmware/rolo.c | 4 +- tools/configure | 12 +- tools/mkmi4.sh | 2 +- tools/scramble.c | 6 +- 7 files changed, 165 insertions(+), 168 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; +/* A buffer to load the iriver firmware or Rockbox into */ +unsigned char loadbuffer[MAX_LOADSIZE]; - 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; - } -} +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); + fd = open("/.rockbox/" BOOTFILE, O_RDONLY); + if(fd < 0) + { + fd = open("/" BOOTFILE, O_RDONLY); + if(fd < 0) + return -1; + } + + 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(); - /*i=ata_init(); - disk_init(); - rc = disk_mount_all();*/ + rc = read(fd, model, 4); + if(rc < 4) + return -3; - /* 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. + model[4] = 0; - rc=load_iriver(loadbuffer); - memcpy((void*)DRAMORIG,loadbuffer,rc); - asm volatile( - "mov r0, #" SC(DRAMORIG) "\n" - "mov pc, r0 \n" - );*/ - - - /* This assumes that /test.txt exists */ - /*fd=open("/test.txt",O_RDWR);*/ - - - /* - 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; - } - + 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]; } - */ - - - - /* 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; + snprintf(str, sizeof(str), "Sum: %x", sum); + lcd_puts(0, line++ ,str); + lcd_update(); - gpio_g = GPIOG_INPUT_VAL; - gpio_h = GPIOH_INPUT_VAL; - gpio_i = GPIOI_INPUT_VAL; + if(sum != chksum) + return -5; - 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; + return len; +} - gpio_j = GPIOJ_INPUT_VAL; - gpio_k = GPIOK_INPUT_VAL; - gpio_l = GPIOL_INPUT_VAL; +void* main(void) +{ + char buf[256]; + int i; + int rc; + unsigned short* identify_info; + struct partinfo* pinfo; - 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)); - */ + 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(); + } + memcpy((void*)DRAM_START,loadbuffer,rc); - - /* 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; - */ - - /*close(fd);*/ - udelay(100000000); + return (void*)DRAM_START; } /* These functions are present in the firmware library, but we reimplement diff --git a/firmware/export/config-h10.h b/firmware/export/config-h10.h index d225baddbe..c3cf7eda5f 100644 --- a/firmware/export/config-h10.h +++ b/firmware/export/config-h10.h @@ -5,7 +5,7 @@ #define TARGET_TREE /* this target is using the target tree system */ /* For Rolo and boot loader */ -#define MODEL_NUMBER 11 +#define MODEL_NUMBER 13 /* define this if you have recording possibility */ /*#define HAVE_RECORDING 1*/ /* TODO: add support for this */ diff --git a/firmware/export/config-h10_5gb.h b/firmware/export/config-h10_5gb.h index b4ff34b612..40f8c26621 100644 --- a/firmware/export/config-h10_5gb.h +++ b/firmware/export/config-h10_5gb.h @@ -5,7 +5,7 @@ #define TARGET_TREE /* this target is using the target tree system */ /* For Rolo and boot loader */ -#define MODEL_NUMBER 13 +#define MODEL_NUMBER 14 /* define this if you have recording possibility */ /*#define HAVE_RECORDING 1*/ /* TODO: add support for this */ diff --git a/firmware/rolo.c b/firmware/rolo.c index cae5eda180..dac51fc0f3 100644 --- a/firmware/rolo.c +++ b/firmware/rolo.c @@ -31,8 +31,8 @@ #include "buffer.h" #if (CONFIG_CPU != TCC730) && !defined(IRIVER_IFP7XX_SERIES) && \ - (CONFIG_CPU != PP5002) -/* FIX: this doesn't work on Gmini, iFP or 3rd Gen ipods yet */ + (CONFIG_CPU != PP5002) && !defined(IRIVER_H10) && !defined(IRIVER_H10_5GB) +/* FIX: this doesn't work on Gmini, iFP, 3rd Gen ipods, or H10 yet */ #define IRQ0_EDGE_TRIGGER 0x80 diff --git a/tools/configure b/tools/configure index c75bc36a01..b809cfaba2 100755 --- a/tools/configure +++ b/tools/configure @@ -893,10 +893,10 @@ toolsdir='\$(ROOTDIR)/tools' target="-DIRIVER_H10" memory=32 # always arm7tdmicc - tool="$rootdir/tools/mkmi4.sh h10" + tool="$rootdir/tools/scramble -add=h10" bmp2rb_mono="$rootdir/tools/bmp2rb -f 0" bmp2rb_native="$rootdir/tools/bmp2rb -f 5" - output="H10_20GC.mi4" + output="rockbox.h10" appextra="recorder:gui" archosrom="" flash="" @@ -904,7 +904,7 @@ toolsdir='\$(ROOTDIR)/tools' codecs="libmad liba52 libffmpegFLAC libTremor libwavpack dumb libmusepack libalac libfaad libm4a" # toolset is the tools within the tools directory that we build for # this particular target. - toolset=$genericbitmaptools + toolset="$genericbitmaptools scramble" # architecture, manufacturer and model for the target-tree build t_cpu="arm" t_manufacturer="iriver" @@ -939,10 +939,10 @@ toolsdir='\$(ROOTDIR)/tools' target="-DIRIVER_H10_5GB" memory=32 # always arm7tdmicc - tool="$rootdir/tools/mkmi4.sh h10_5gb" + tool="$rootdir/tools/scramble -add=h10_5gb" bmp2rb_mono="$rootdir/tools/bmp2rb -f 0" bmp2rb_native="$rootdir/tools/bmp2rb -f 5" - output="H10.mi4" + output="rockbox.h10" appextra="recorder:gui" archosrom="" flash="" @@ -950,7 +950,7 @@ toolsdir='\$(ROOTDIR)/tools' codecs="libmad liba52 libffmpegFLAC libTremor libwavpack dumb libmusepack libalac libfaad libm4a" # toolset is the tools within the tools directory that we build for # this particular target. - toolset=$genericbitmaptools + toolset="$genericbitmaptools scramble" # architecture, manufacturer and model for the target-tree build t_cpu="arm" t_manufacturer="iriver" diff --git a/tools/mkmi4.sh b/tools/mkmi4.sh index 1085a3b76e..fbdc7ffaff 100755 --- a/tools/mkmi4.sh +++ b/tools/mkmi4.sh @@ -48,7 +48,7 @@ findtool(){ } help () { - echo "Usage: mi4fix.sh " + echo "Usage: mi4fix.sh " exit } diff --git a/tools/scramble.c b/tools/scramble.c index c91c05d6ee..c3eb1782af 100644 --- a/tools/scramble.c +++ b/tools/scramble.c @@ -84,7 +84,7 @@ void usage(void) "\t-ipod5g ipod firmware partition format (5th Gen - aka Video)\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)\n" + "\t ip3g, ip4g, mini, x5, h10, h10_5gb)\n" "\nNo option results in Archos standard player/recorder format.\n"); exit(1); @@ -196,6 +196,10 @@ int main (int argc, char** argv) modelnum = 10; else if(!strcmp(&argv[1][5], "mn2g")) modelnum = 11; + else if(!strcmp(&argv[1][5], "h10")) + modelnum = 13; + else if(!strcmp(&argv[1][5], "h10_5gb")) + modelnum = 14; else { fprintf(stderr, "unsupported model: %s\n", &argv[1][5]); return 2;