forked from len0rd/rockbox
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
This commit is contained in:
parent
e6e597594d
commit
080889a135
3 changed files with 74 additions and 1 deletions
|
@ -48,7 +48,8 @@ enum {
|
||||||
WRITE_FIRMWARE,
|
WRITE_FIRMWARE,
|
||||||
READ_PARTITION,
|
READ_PARTITION,
|
||||||
WRITE_PARTITION,
|
WRITE_PARTITION,
|
||||||
UPDATE_OF
|
UPDATE_OF,
|
||||||
|
UPDATE_PPBL
|
||||||
};
|
};
|
||||||
|
|
||||||
void print_usage(void)
|
void print_usage(void)
|
||||||
|
@ -67,6 +68,7 @@ void print_usage(void)
|
||||||
fprintf(stderr," -a, --add-bootloader filename.mi4\n");
|
fprintf(stderr," -a, --add-bootloader filename.mi4\n");
|
||||||
fprintf(stderr," -d, --delete-bootloader\n");
|
fprintf(stderr," -d, --delete-bootloader\n");
|
||||||
fprintf(stderr," -of --update-original-firmware filename.mi4\n");
|
fprintf(stderr," -of --update-original-firmware filename.mi4\n");
|
||||||
|
fprintf(stderr," -bl --update-ppbl filename.bin\n");
|
||||||
fprintf(stderr,"\n");
|
fprintf(stderr,"\n");
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
|
@ -225,6 +227,13 @@ int main(int argc, char* argv[])
|
||||||
if (i == argc) { print_usage(); return 1; }
|
if (i == argc) { print_usage(); return 1; }
|
||||||
filename=argv[i];
|
filename=argv[i];
|
||||||
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) ||
|
} else if ((strcmp(argv[i],"-rf")==0) ||
|
||||||
(strcmp(argv[i],"--read-firmware")==0)) {
|
(strcmp(argv[i],"--read-firmware")==0)) {
|
||||||
action = READ_FIRMWARE;
|
action = READ_FIRMWARE;
|
||||||
|
@ -345,6 +354,25 @@ int main(int argc, char* argv[])
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,"[ERR] --update-original-firmware failed.\n");
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -886,3 +886,47 @@ int sansa_update_of(struct sansa_t* sansa, char* filename)
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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_add_bootloader(struct sansa_t* sansa, char* filename, int type);
|
||||||
int sansa_delete_bootloader(struct sansa_t* sansa);
|
int sansa_delete_bootloader(struct sansa_t* sansa);
|
||||||
int sansa_update_of(struct sansa_t* sansa,char* filename);
|
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);
|
void sansa_list_images(struct sansa_t* sansa);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue