From 080889a135bb5a1e34f8acae3c0a330d6bd620f5 Mon Sep 17 00:00:00 2001 From: Barry Wardell Date: Sun, 14 Oct 2007 18:09:40 +0000 Subject: [PATCH] Add support for installing/replacing the bootloader in the PPBL section of the firmware partition. Allows installation of the Rockbox bootloader in place of the Sandisk one. This expects a plain bootloader binary with no header. Our Rockbox bootloader successfully boots both Rockbox and the OF when installed in this way. This makes it easy to get to a state where e200tool is required, so care is advised. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15108 a1c6a512-1295-4272-9138-f99709370657 --- rbutil/sansapatcher/main.c | 30 +++++++++++++++++++- rbutil/sansapatcher/sansapatcher.c | 44 ++++++++++++++++++++++++++++++ rbutil/sansapatcher/sansapatcher.h | 1 + 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/rbutil/sansapatcher/main.c b/rbutil/sansapatcher/main.c index 4b07af14ec..fb87aec2a4 100644 --- a/rbutil/sansapatcher/main.c +++ b/rbutil/sansapatcher/main.c @@ -48,7 +48,8 @@ enum { WRITE_FIRMWARE, READ_PARTITION, WRITE_PARTITION, - UPDATE_OF + UPDATE_OF, + UPDATE_PPBL }; void print_usage(void) @@ -67,6 +68,7 @@ void print_usage(void) fprintf(stderr," -a, --add-bootloader filename.mi4\n"); fprintf(stderr," -d, --delete-bootloader\n"); fprintf(stderr," -of --update-original-firmware filename.mi4\n"); + fprintf(stderr," -bl --update-ppbl filename.bin\n"); fprintf(stderr,"\n"); #ifdef __WIN32__ @@ -225,6 +227,13 @@ int main(int argc, char* argv[]) if (i == argc) { print_usage(); return 1; } filename=argv[i]; i++; + } else if ((strcmp(argv[i],"-bl")==0) || + (strcmp(argv[i],"--update-ppbl")==0)) { + action = UPDATE_PPBL; + i++; + if (i == argc) { print_usage(); return 1; } + filename=argv[i]; + i++; } else if ((strcmp(argv[i],"-rf")==0) || (strcmp(argv[i],"--read-firmware")==0)) { action = READ_FIRMWARE; @@ -345,6 +354,25 @@ int main(int argc, char* argv[]) } else { fprintf(stderr,"[ERR] --update-original-firmware failed.\n"); } + } else if (action==UPDATE_PPBL) { + printf("[WARN] PPBL installation will overwrite your bootloader. This will lead to a\n"); + printf(" Sansa that won't boot if the bootloader file is invalid. Only continue if\n"); + printf(" you're sure you know what you're doing.\n"); + printf(" Continue (y/n)? "); + + if (fgets(yesno,4,stdin)) { + if (yesno[0]=='y') { + if (sansa_reopen_rw(&sansa) < 0) { + return 5; + } + + if (sansa_update_ppbl(&sansa, filename)==0) { + fprintf(stderr,"[INFO] PPBL updated successfully.\n"); + } else { + fprintf(stderr,"[ERR] --update-ppbl failed.\n"); + } + } + } } } diff --git a/rbutil/sansapatcher/sansapatcher.c b/rbutil/sansapatcher/sansapatcher.c index 1f74067344..2d44e75303 100644 --- a/rbutil/sansapatcher/sansapatcher.c +++ b/rbutil/sansapatcher/sansapatcher.c @@ -886,3 +886,47 @@ int sansa_update_of(struct sansa_t* sansa, char* filename) return 0; } +/* Update the PPBL (bootloader) image in the hidden firmware partition */ +int sansa_update_ppbl(struct sansa_t* sansa, char* filename) +{ + int n; + int infile = -1; /* Prevent an erroneous "may be used uninitialised" gcc warning */ + int ppbl_length = 0; /* Keep gcc happy when building for rbutil */ + + /* Step 1 - read bootloader into RAM. */ + infile=open(filename,O_RDONLY|O_BINARY); + if (infile < 0) { + fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename); + return -1; + } + + ppbl_length = filesize(infile); + + n = read(infile,sectorbuf+0x200,ppbl_length); + close(infile); + if (n < ppbl_length) { + fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n", ppbl_length, n); + return -1; + } + + /* Step 2 - Build the header */ + memset(sectorbuf,0,0x200); + memcpy(sectorbuf,"PPBL",4); + int2le(ppbl_length, sectorbuf+4); + int2le(0x00010000, sectorbuf+8); + + /* Step 3 - write the bootloader to the Sansa */ + if (sansa_seek(sansa, sansa->start) < 0) { + fprintf(stderr,"[ERR] Seek to 0x%08llx in sansa_update_ppbl failed.\n", sansa->start); + return -1; + } + + n=sansa_write(sansa, sectorbuf, ppbl_length + 0x200); + if (n < (ppbl_length+0x200)) { + fprintf(stderr,"[ERR] Short write in sansa_update_ppbl\n"); + return -1; + } + + return 0; +} + diff --git a/rbutil/sansapatcher/sansapatcher.h b/rbutil/sansapatcher/sansapatcher.h index bb9e0f1340..7f113ec083 100644 --- a/rbutil/sansapatcher/sansapatcher.h +++ b/rbutil/sansapatcher/sansapatcher.h @@ -37,6 +37,7 @@ int sansa_read_firmware(struct sansa_t* sansa, char* filename); int sansa_add_bootloader(struct sansa_t* sansa, char* filename, int type); int sansa_delete_bootloader(struct sansa_t* sansa); int sansa_update_of(struct sansa_t* sansa,char* filename); +int sansa_update_ppbl(struct sansa_t* sansa,char* filename); void sansa_list_images(struct sansa_t* sansa); #endif