1
0
Fork 0
forked from len0rd/rockbox

sansapatcher: factor out handling of bundled bootloaders.

Instead of handling bundled bootloaders in the sansapatcher functions leave
that to the caller. This removes the need to have Rockbox Utility specific
parts in sansapatcher. sansa_add_bootloader() now operates on an already loaded
bootloader. For loading a convenience function sansa_read_bootloader() is
added. This also introduces a new check on loading to prevent installing an
e200 bootloader on a c200 (and vice versa).

These changes will allow building a libsansapatcher for linking with Rockbox
Utility later.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31144 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Dominik Riebeling 2011-12-04 19:40:43 +00:00
parent 38890ac6dc
commit 38f03d4eae
4 changed files with 80 additions and 66 deletions

View file

@ -31,6 +31,8 @@
#include "sansapatcher.h"
#include "sansaio.h"
#include "parttypes.h"
#include "bootimg_c200.h"
#include "bootimg_e200.h"
#define VERSION "0.8 with v6.0 bootloaders"
@ -135,9 +137,10 @@ int main(int argc, char* argv[])
int n;
char* filename;
int action = SHOW_INFO;
int type;
struct sansa_t sansa;
int res = 0;
unsigned char* buf = NULL;
unsigned int len;
fprintf(stderr,"sansapatcher v" VERSION " - (C) Dave Chapman 2006-2007\n");
fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n");
@ -213,7 +216,6 @@ int main(int argc, char* argv[])
} else if ((strcmp(argv[i],"-a")==0) ||
(strcmp(argv[i],"--add-bootloader")==0)) {
action = ADD_BOOTLOADER;
type = FILETYPE_MI4;
i++;
if (i == argc) { print_usage(); return 1; }
filename=argv[i];
@ -286,8 +288,14 @@ int main(int argc, char* argv[])
if (sansa_reopen_rw(&sansa) < 0) {
res = 5;
}
if (sansa_add_bootloader(&sansa, NULL, FILETYPE_INTERNAL)==0) {
if (strcmp(sansa.targetname,"c200") == 0) {
len = LEN_bootimg_c200;
buf = bootimg_c200;
} else {
len = LEN_bootimg_e200;
buf = bootimg_e200;
}
if (sansa_add_bootloader(&sansa, buf, len)==0) {
fprintf(stderr,"[INFO] Bootloader installed successfully.\n");
} else {
fprintf(stderr,"[ERR] --install failed.\n");
@ -317,7 +325,15 @@ int main(int argc, char* argv[])
return 5;
}
if (sansa_add_bootloader(&sansa, NULL, FILETYPE_INTERNAL)==0) {
if (strcmp(sansa.targetname,"c200") == 0) {
len = LEN_bootimg_c200;
buf = bootimg_c200;
} else {
len = LEN_bootimg_e200;
buf = bootimg_e200;
}
if (sansa_add_bootloader(&sansa, buf, len)==0) {
fprintf(stderr,"[INFO] Bootloader installed successfully.\n");
} else {
fprintf(stderr,"[ERR] --install failed.\n");
@ -327,10 +343,13 @@ int main(int argc, char* argv[])
return 5;
}
if (sansa_add_bootloader(&sansa, filename, type)==0) {
fprintf(stderr,"[INFO] Bootloader %s written to device.\n",filename);
} else {
fprintf(stderr,"[ERR] --add-bootloader failed.\n");
len = sansa_read_bootloader(&sansa, filename, &buf);
if (len > 0) {
if (sansa_add_bootloader(&sansa, buf, len)==0) {
fprintf(stderr,"[INFO] Bootloader %s written to device.\n",filename);
} else {
fprintf(stderr,"[ERR] --add-bootloader failed.\n");
}
}
} else if (action==DELETE_BOOTLOADER) {
if (sansa_reopen_rw(&sansa) < 0) {

View file

@ -31,10 +31,6 @@
#include "sansaio.h"
#include "sansapatcher.h"
#ifndef RBUTIL
#include "bootimg_c200.h"
#include "bootimg_e200.h"
#endif
/* The offset of the MI4 image header in the firmware partition */
#define PPMI_OFFSET 0x80000
#define NVPARAMS_OFFSET 0x780000
@ -683,34 +679,55 @@ int sansa_read_firmware(struct sansa_t* sansa, const char* filename)
return 0;
}
unsigned int sansa_read_bootloader(struct sansa_t* sansa, const char* filename, unsigned char** bl_buffer)
{
/* Step 1 - read bootloader into RAM. */
int infile;
unsigned int n;
unsigned int len;
infile=open(filename,O_RDONLY|O_BINARY);
if (infile < 0) {
fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename);
return 0;
}
int sansa_add_bootloader(struct sansa_t* sansa, const char* filename, int type)
len = filesize(infile);
unsigned char* b = malloc(len);
if (b == NULL) {
fprintf(stderr,"[ERR] Could not allocate memory for bootloader\n");
close(infile);
return 0;
}
n = read(infile,b,len);
close(infile);
if (n < len) {
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
,len,n);
return 0;
}
if (memcmp(b+0x1f8,"RBBL",4)!=0) {
fprintf(stderr,"[ERR] %s is not a Rockbox bootloader, aborting.\n",
filename);
return 0;
}
if (memcmp(b+0x1fc,sansa->targetname,4)!=0) {
fprintf(stderr,"[ERR] %s is not a Rockbox bootloader for %s, aborting.\n",
filename, sansa->targetname);
return 0;
}
*bl_buffer = b;
return len;
}
int sansa_add_bootloader(struct sansa_t* sansa, const unsigned char* bootloader, const unsigned int bl_length)
{
int res;
int infile = -1; /* Prevent an erroneous "may be used uninitialised" gcc warning */
int bl_length = 0; /* Keep gcc happy when building for rbutil */
struct mi4header_t mi4header;
int n;
int length;
if (type==FILETYPE_MI4) {
/* 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;
}
bl_length = filesize(infile);
} else {
#ifndef RBUTIL
if (strcmp(sansa->targetname,"c200") == 0) {
bl_length = LEN_bootimg_c200;
} else {
bl_length = LEN_bootimg_e200;
}
#endif
}
int n;
/* Create PPMI header */
memset(sansa_sectorbuf,0,0x200);
@ -718,30 +735,8 @@ int sansa_add_bootloader(struct sansa_t* sansa, const char* filename, int type)
int2le(bl_length, sansa_sectorbuf+4);
int2le(0x00020000, sansa_sectorbuf+8);
if (type==FILETYPE_MI4) {
/* Read bootloader into sansa_sectorbuf+0x200 */
n = read(infile,sansa_sectorbuf+0x200,bl_length);
close(infile);
if (n < bl_length) {
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
,bl_length,n);
return -1;
}
if (memcmp(sansa_sectorbuf+0x200+0x1f8,"RBBL",4)!=0) {
fprintf(stderr,"[ERR] %s is not a Rockbox bootloader, aborting.\n",
filename);
return -1;
}
} else {
#ifndef RBUTIL
if (strcmp(sansa->targetname,"c200") == 0) {
memcpy(sansa_sectorbuf+0x200,bootimg_c200,LEN_bootimg_c200);
} else {
memcpy(sansa_sectorbuf+0x200,bootimg_e200,LEN_bootimg_e200);
}
#endif
}
/* copy bootloader to sansa_sectorbuf+0x200 */
memcpy(sansa_sectorbuf+0x200,bootloader,bl_length);
/* Load original firmware from Sansa to the space after the bootloader */
res = load_original_firmware(sansa,sansa_sectorbuf+0x200+bl_length,&mi4header);

View file

@ -34,14 +34,12 @@ extern int sansa_verbose;
#define BUFFER_SIZE 8*1024*1024
extern unsigned char* sansa_sectorbuf;
#define FILETYPE_MI4 0
#define FILETYPE_INTERNAL 1
int sansa_read_partinfo(struct sansa_t* sansa, int silent);
int is_sansa(struct sansa_t* sansa);
int sansa_scan(struct sansa_t* sansa);
int sansa_read_firmware(struct sansa_t* sansa, const char* filename);
int sansa_add_bootloader(struct sansa_t* sansa, const char* filename, int type);
unsigned int sansa_read_bootloader(struct sansa_t* sansa, const char* filename, unsigned char** bl_buffer);
int sansa_add_bootloader(struct sansa_t* sansa, const unsigned char* buf, unsigned int len);
int sansa_delete_bootloader(struct sansa_t* sansa);
int sansa_update_of(struct sansa_t* sansa,const char* filename);
int sansa_update_ppbl(struct sansa_t* sansa,const char* filename);