diff --git a/bootloader/gigabeat-s.c b/bootloader/gigabeat-s.c index 25b9ab5..190dca5 100644 --- a/bootloader/gigabeat-s.c +++ b/bootloader/gigabeat-s.c @@ -28,6 +28,7 @@ #include "kernel.h" #include "thread.h" #include "ata.h" +#include "dir.h" #include "fat.h" #include "disk.h" #include "font.h" @@ -47,13 +48,38 @@ #include char version[] = APPSVERSION; +char buf[5][MAX_PATH]; + +void ls_dir(const char *path, int level) +{ + struct dirent_uncached* entry; + DIR_UNCACHED* dir; + dir = opendir_uncached(path); + + printf("listing %s:", path); + + while ((entry = readdir_uncached(dir))) + { + if (*entry->d_name != '.') + printf("%s: %d, %ld", entry->d_name, entry->attribute, entry->size); + + if (level < 5 && entry->attribute == ATTR_DIRECTORY && *entry->d_name != '.') + { + snprintf(buf[level], sizeof(buf[level]), "%s%s/", path, entry->d_name); + ls_dir(buf[level], level+1); + } + } + + printf("end"); +} void main(void) { lcd_clear_display(); printf("Hello world!"); - printf("Gigabeat S Rockbox Bootloader v.00000001"); + printf("Gigabeat S Rockbox Bootloader v.00000001"); kernel_init(); + printf("kernel init done"); int rc; rc = ata_init(); @@ -62,8 +88,10 @@ void main(void) reset_screen(); error(EATA, rc); } + printf("ata init done"); disk_init(); + printf("disk init done"); rc = disk_mount_all(); if (rc<=0) @@ -71,6 +99,10 @@ void main(void) error(EDISK,rc); } + /* Directory listing */ + + ls_dir("/", 0); + printf("Congratulations!"); while(1); diff --git a/firmware/boot.lds b/firmware/boot.lds index d4c72b5..7e20cf0 100644 --- a/firmware/boot.lds +++ b/firmware/boot.lds @@ -292,7 +292,7 @@ SECTIONS } #elif (CONFIG_CPU==IMX31L) { - . = 0x88201000; + . = 0x89000000; .vectors : { KEEP(*(.vectors*)); diff --git a/firmware/common/disk.c b/firmware/common/disk.c index 563bb05..5d00379 100644 --- a/firmware/common/disk.c +++ b/firmware/common/disk.c @@ -150,7 +150,7 @@ int disk_mount(int drive) /* The Elio's hard drive has no partition table and probing for partitions causes Rockbox to crash - so we temporarily disable the probing until we fix the real problem. */ - for (i=0; volume != -1 && i<4; i++) + for (i=1; volume != -1 && i<4; i++) { #ifdef MAX_LOG_SECTOR_SIZE int j; diff --git a/firmware/debug.c b/firmware/debug.c index 6b638c1..8f62f0b 100644 --- a/firmware/debug.c +++ b/firmware/debug.c @@ -25,6 +25,7 @@ #ifdef HAVE_GDB_API #include "gdb_api.h" #endif +#include "../bootloader/common.h" #ifdef DEBUG static char debugmembuf[200]; @@ -241,7 +242,8 @@ void debugf(const char *fmt, ...) va_start(ap, fmt); vsnprintf(debugmembuf, sizeof(debugmembuf), fmt, ap); va_end(ap); - debug(debugmembuf); + //debug(debugmembuf); + printf(debugmembuf); #else (void)fmt; #endif diff --git a/firmware/export/config-gigabeat-s.h b/firmware/export/config-gigabeat-s.h index 285b381..67b2ee8 100644 --- a/firmware/export/config-gigabeat-s.h +++ b/firmware/export/config-gigabeat-s.h @@ -5,6 +5,8 @@ #define TOSHIBA_GIGABEAT_S 1 +// #define DEBUG + /* For Rolo and boot loader */ #define MODEL_NUMBER 19 diff --git a/firmware/kernel.c b/firmware/kernel.c index 803c224..de66556 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c @@ -27,6 +27,7 @@ #if CONFIG_CPU == IMX31L #include "avic-imx31.h" #endif +#include "debug.h" /* Make this nonzero to enable more elaborate checks on objects */ #ifdef DEBUG @@ -65,6 +66,7 @@ static struct ****************************************************************************/ void kernel_init(void) { + DEBUGF("Testing, testing, 123"); /* Init the threading API */ init_threads(); diff --git a/firmware/thread.c b/firmware/thread.c index 126cc41..3b68cf6 100644 --- a/firmware/thread.c +++ b/firmware/thread.c @@ -28,6 +28,7 @@ #ifdef RB_PROFILE #include #endif +#include "debug.h" /* Define THREAD_EXTRA_CHECKS as 1 to enable additional state checks */ #ifdef DEBUG @@ -2555,6 +2556,8 @@ void init_threads(void) remove_thread(NULL); #endif /* NUM_CORES */ } + + DEBUGF("init_threads done"); } /*--------------------------------------------------------------------------- diff --git a/tools/mknkboot.c b/tools/mknkboot.c index c5e89f6..ad49704 100644 --- a/tools/mknkboot.c +++ b/tools/mknkboot.c @@ -27,6 +27,12 @@ #include #include +/* New entry point for nk.bin - where our dualboot code is inserted */ +#define NK_ENTRY_POINT 0x88200000 + +/* Entry point (and load address) for the main Rockbox bootloader */ +#define BL_ENTRY_POINT 0x89000000 + /* Description of nk.bin from @@ -65,11 +71,35 @@ mknkboot.c appends two images: #define O_BINARY 0 #endif - #define DISABLE_ADDR 0x88065A10 /* in EBoot */ #define DISABLE_INSN 0xe3a00001 #define DISABLE_SUM (0xe3+0xa0+0x00+0x01) +/* Code to dual-boot - this is inserted at NK_ENTRY_POINT */ + +/* Define the following to load Rockbox on hold switch, otherwise + Rockbox is loaded by default, and the OF if hold is on */ +//#define ROCKBOX_ON_HOLD + +static uint32_t dualboot[] = +{ + 0xe59f900c, /* ldr r9, [pc, #12] -> 0x53fa4000 */ + 0xe5999000, /* ldr r9, [r9] */ + 0xe3190010, /* tst r9, #16 ; 0x10 */ +#if 1 + /* Branch to Rockbox if hold is on */ + 0x159ff004, /* ldrne pc, [pc, #4] -> 0x89000000 */ +#else + /* Branch to Rockbox if hold is off */ + 0x059ff004, /* ldreq pc, [pc, #4] -> 0x89000000 */ +#endif + /* Branch to original firmware */ + 0xea0003fa, /* b 0x1000 */ + + 0x53fa4000, /* GPIO3_DR */ + BL_ENTRY_POINT /* RB bootloader load address/entry point */ +}; + static void put_uint32le(uint32_t x, unsigned char* p) { p[0] = x & 0xff; @@ -105,6 +135,7 @@ int main(int argc, char *argv[]) int inlength,bootlength,newlength; unsigned char* buf; unsigned char* boot; + unsigned char* boot2; unsigned char* disable; uint32_t sum; @@ -133,9 +164,9 @@ int main(int argc, char *argv[]) bootlength = filesize(fdboot); /* Create buffer for original nk.bin, plus our bootloader (with 12 - byte header), plus the 16-byte "disable record" */ + byte header), plus the 16-byte "disable record", plus our dual-boot code */ - newlength = inlength + (bootlength + 12) + 16; + newlength = inlength + (bootlength + 12) + 16 + (12 + 28); buf = malloc(newlength); if (buf==NULL) @@ -156,6 +187,8 @@ int main(int argc, char *argv[]) /****** STEP 2 - Move EOF record to the new EOF */ memcpy(buf + newlength - 12, buf + inlength - 12, 12); + /* Overwrite default entry point with NK_ENTRY_POINT */ + put_uint32le(NK_ENTRY_POINT, buf + newlength - 8); /****** STEP 3 - Create a record to disable the firmware signature check in EBoot */ @@ -177,17 +210,35 @@ int main(int argc, char *argv[]) /****** STEP 5 - Create header for bootloader record */ - /* Calculate simple checksum */ + /* Calculate checksum */ sum = 0; for (i = 0; i < bootlength; i++) { sum += boot[12 + i]; } - put_uint32le(0x88201000, boot); /* nk.exe start address */ + put_uint32le(BL_ENTRY_POINT, boot); /* Our entry point */ put_uint32le(bootlength, boot + 4); put_uint32le(sum, boot + 8); - /****** STEP 6 - Now write the output file */ + /****** STEP 6 - Insert our dual-boot code */ + boot2 = boot + bootlength + 12; + + /* Copy dual-boot code in an endian-safe way */ + for (i = 0; i < sizeof(dualboot) / 4; i++) { + put_uint32le(dualboot[i], boot2 + 12 + i*4); + } + + /* Calculate checksum */ + sum = 0; + for (i = 0; i < sizeof(dualboot); i++) { + sum += boot2[i+12]; + } + + put_uint32le(NK_ENTRY_POINT, boot2); /* New entry point for our nk.bin */ + put_uint32le(sizeof(dualboot), boot2 + 4); + put_uint32le(sum, boot2 + 8); + + /****** STEP 7 - Now write the output file */ fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644); if (fdout < 0)