diff options
author | Dave Chapman <dave@dchapman.com> | 2007-03-15 23:26:47 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2007-03-15 23:26:47 +0000 |
commit | e815601afb0eabe1ef59a2e8d1e0a746c4c33c34 (patch) | |
tree | 69ba3d9bc54042bafa03b5917f2a45dc454a1705 /rbutil | |
parent | 4a812912846dd5f02f3c8aa81af59b2d1cb67b65 (diff) |
Implement the ability to embed a bootloader in sansapatcher - the --install option installs the embedded bootloader, and running without any parameters will cause a prompt to be displayed asking the user if they want to install, uninstall or cancel. sansapatcher now requres a PP5022.mi4 file (the Rockbox bootloader) in the current directory when building.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12794 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'rbutil')
-rw-r--r-- | rbutil/sansapatcher/Makefile | 11 | ||||
-rw-r--r-- | rbutil/sansapatcher/bin2c.c | 133 | ||||
-rw-r--r-- | rbutil/sansapatcher/main.c | 53 | ||||
-rw-r--r-- | rbutil/sansapatcher/parttypes.h | 109 | ||||
-rw-r--r-- | rbutil/sansapatcher/sansapatcher.c | 35 | ||||
-rw-r--r-- | rbutil/sansapatcher/sansapatcher.h | 4 |
6 files changed, 306 insertions, 39 deletions
diff --git a/rbutil/sansapatcher/Makefile b/rbutil/sansapatcher/Makefile index 17b3fb0047..28ba1dae6a 100644 --- a/rbutil/sansapatcher/Makefile +++ b/rbutil/sansapatcher/Makefile @@ -33,12 +33,11 @@ sansapatcher-ppc: main.c sansapatcher.c sansaio-posix.c parttypes.h bootimg.c gcc -arch ppc $(CFLAGS) -o sansapatcher-ppc main.c sansapatcher.c sansaio-posix.c bootimg.c strip sansapatcher-ppc -#mi42c: mi42c.c -# $(NATIVECC) $(CFLAGS) -o mi42c mi42c.c +bin2c: bin2c.c + $(NATIVECC) $(CFLAGS) -o bin2c bin2c.c -#bootimg.c: PP5022.mi4 mi42c -# ./mi42c PP5022.mi4 bootimg +bootimg.c: PP5022.mi4 bin2c + ./bin2c PP5022.mi4 bootimg clean: - rm -f sansapatcher.exe sansapatcher-mac sansapatcher-i386 sansapatcher-ppc sansapatcher mi42c *~ -#bootimg.c bootimg.h + rm -f sansapatcher.exe sansapatcher-mac sansapatcher-i386 sansapatcher-ppc sansapatcher bin2c bootimg.c bootimg.h *~ diff --git a/rbutil/sansapatcher/bin2c.c b/rbutil/sansapatcher/bin2c.c new file mode 100644 index 0000000000..4e9bd4a782 --- /dev/null +++ b/rbutil/sansapatcher/bin2c.c @@ -0,0 +1,133 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 Dave Chapman + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdlib.h> + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +static off_t filesize(int fd) +{ + struct stat buf; + + fstat(fd,&buf); + return buf.st_size; +} + +static int write_cfile(unsigned char* buf, off_t len, char* cname) +{ + char filename[256]; + FILE* fp; + int i; + + snprintf(filename,256,"%s.c",cname); + + fp = fopen(filename,"w+"); + if (fp == NULL) { + fprintf(stderr,"Couldn't open %s\n",filename); + return -1; + } + + fprintf(fp,"/* Generated by ipod2c */\n\n"); + fprintf(fp,"unsigned char %s[] = {",cname); + + for (i=0;i<len;i++) { + if ((i % 16) == 0) { + fprintf(fp,"\n "); + } + if (i == (len-1)) { + fprintf(fp,"0x%02x",buf[i]); + } else { + fprintf(fp,"0x%02x, ",buf[i]); + } + } + fprintf(fp,"\n};\n"); + + fclose(fp); + return 0; +} + +static int write_hfile(unsigned char* buf, off_t len, char* cname) +{ + char filename[256]; + FILE* fp; + + snprintf(filename,256,"%s.h",cname); + fp = fopen(filename,"w+"); + if (fp == NULL) { + fprintf(stderr,"Couldn't open %s\n",filename); + return -1; + } + + fprintf(fp,"/* Generated by ipod2c */\n\n"); + fprintf(fp,"#define LEN_%s %d\n",cname,(int)len); + fprintf(fp,"extern unsigned char %s[];\n",cname); + fclose(fp); + return 0; +} + +int main (int argc, char* argv[]) +{ + char* infile; + char* cname; + int fd; + unsigned char* buf; + int len; + int n; + + if (argc != 3) { + fprintf(stderr,"Usage: bin2c file cname\n"); + return 0; + } + + infile=argv[1]; + cname=argv[2]; + + fd = open(infile,O_RDONLY|O_BINARY); + if (fd < 0) { + fprintf(stderr,"Can not open %s\n",infile); + return 0; + } + + len = filesize(fd); + + buf = malloc(len); + n = read(fd,buf,len); + if (n < len) { + fprintf(stderr,"Short read, aborting\n"); + return 0; + } + close(fd); + + if (write_cfile(buf,len,cname) < 0) { + return -1; + } + if (write_hfile(buf,len,cname) < 0) { + return -1; + } + + return 0; +} diff --git a/rbutil/sansapatcher/main.c b/rbutil/sansapatcher/main.c index 0828095bae..07e44a044e 100644 --- a/rbutil/sansapatcher/main.c +++ b/rbutil/sansapatcher/main.c @@ -35,9 +35,7 @@ int verbose = 0; enum { NONE, -#ifdef WITH_BOOTOBJS INSTALL, -#endif INTERACTIVE, SHOW_INFO, LIST_IMAGES, @@ -59,9 +57,7 @@ void print_usage(void) #endif fprintf(stderr,"\n"); fprintf(stderr,"Where [action] is one of the following options:\n"); -#ifdef WITH_BOOTOBJS fprintf(stderr," --install\n"); -#endif fprintf(stderr," -l, --list\n"); fprintf(stderr," -rf, --read-firmware filename.mi4\n"); fprintf(stderr," -a, --add-bootloader filename.mi4\n"); @@ -109,9 +105,7 @@ void display_partinfo(struct sansa_t* sansa) int main(int argc, char* argv[]) { -#ifdef WITH_BOOTOBJS char yesno[4]; -#endif int i; int n; char* filename; @@ -167,33 +161,25 @@ int main(int argc, char* argv[]) } if (n != 1) { -#ifdef WITH_BOOTOBJS if (argc==1) { printf("\nPress ENTER to exit sansapatcher :"); fgets(yesno,4,stdin); } -#endif return 0; } i = 1; } -#ifdef WITH_BOOTOBJS action = INTERACTIVE; -#else - action = NONE; -#endif while (i < argc) { if ((strcmp(argv[i],"-l")==0) || (strcmp(argv[i],"--list")==0)) { action = LIST_IMAGES; i++; -#ifdef WITH_BOOTOBJS } else if (strcmp(argv[i],"--install")==0) { action = INSTALL; i++; -#endif } else if ((strcmp(argv[i],"-d")==0) || (strcmp(argv[i],"--delete-bootloader")==0)) { action = DELETE_BOOTLOADER; @@ -252,12 +238,49 @@ int main(int argc, char* argv[]) if (action==LIST_IMAGES) { list_images(&sansa); + } else if (action==INTERACTIVE) { + + printf("Enter i to install the Rockbox bootloader, u to uninstall\n or c to cancel and do nothing (i/u/c) :"); + + if (fgets(yesno,4,stdin)) { + if (yesno[0]=='i') { + if (sansa_reopen_rw(&sansa) < 0) { + return 5; + } + + if (add_bootloader(&sansa, NULL, FILETYPE_INTERNAL)==0) { + fprintf(stderr,"[INFO] Bootloader installed successfully.\n"); + } else { + fprintf(stderr,"[ERR] --install failed.\n"); + } + } else if (yesno[0]=='u') { + if (sansa_reopen_rw(&sansa) < 0) { + return 5; + } + + if (delete_bootloader(&sansa)==0) { + fprintf(stderr,"[INFO] Bootloader removed.\n"); + } else { + fprintf(stderr,"[ERR] Bootloader removal failed.\n"); + } + } + } } else if (action==READ_FIRMWARE) { if (read_firmware(&sansa, filename)==0) { fprintf(stderr,"[INFO] Firmware read to file %s.\n",filename); } else { fprintf(stderr,"[ERR] --read-firmware failed.\n"); } + } else if (action==INSTALL) { + if (sansa_reopen_rw(&sansa) < 0) { + return 5; + } + + if (add_bootloader(&sansa, NULL, FILETYPE_INTERNAL)==0) { + fprintf(stderr,"[INFO] Bootloader installed successfully.\n"); + } else { + fprintf(stderr,"[ERR] --install failed.\n"); + } } else if (action==ADD_BOOTLOADER) { if (sansa_reopen_rw(&sansa) < 0) { return 5; @@ -282,12 +305,10 @@ int main(int argc, char* argv[]) sansa_close(&sansa); -#ifdef WITH_BOOTOBJS if (action==INTERACTIVE) { printf("Press ENTER to exit sansapatcher :"); fgets(yesno,4,stdin); } -#endif return 0; } diff --git a/rbutil/sansapatcher/parttypes.h b/rbutil/sansapatcher/parttypes.h new file mode 100644 index 0000000000..f8de303553 --- /dev/null +++ b/rbutil/sansapatcher/parttypes.h @@ -0,0 +1,109 @@ +/* DOS partition types - taken from fdisk */ + +struct parttype { + unsigned char type; + char *name; +}; + +struct parttype parttypes[] = { + {0x00, "Empty"}, + {0x01, "FAT12"}, + {0x02, "XENIX root"}, + {0x03, "XENIX usr"}, + {0x04, "FAT16 <32M"}, + {0x05, "Extended"}, /* DOS 3.3+ extended partition */ + {0x06, "FAT16"}, /* DOS 16-bit >=32M */ + {0x07, "HPFS/NTFS"}, /* OS/2 IFS, eg, HPFS or NTFS or QNX */ + {0x08, "AIX"}, /* AIX boot (AIX -- PS/2 port) or SplitDrive */ + {0x09, "AIX bootable"}, /* AIX data or Coherent */ + {0x0a, "OS/2 Boot Manager"},/* OS/2 Boot Manager */ + {0x0b, "W95 FAT32"}, + {0x0c, "W95 FAT32 (LBA)"},/* LBA really is `Extended Int 13h' */ + {0x0e, "W95 FAT16 (LBA)"}, + {0x0f, "W95 Ext'd (LBA)"}, + {0x10, "OPUS"}, + {0x11, "Hidden FAT12"}, + {0x12, "Compaq diagnostics"}, + {0x14, "Hidden FAT16 <32M"}, + {0x16, "Hidden FAT16"}, + {0x17, "Hidden HPFS/NTFS"}, + {0x18, "AST SmartSleep"}, + {0x1b, "Hidden W95 FAT32"}, + {0x1c, "Hidden W95 FAT32 (LBA)"}, + {0x1e, "Hidden W95 FAT16 (LBA)"}, + {0x24, "NEC DOS"}, + {0x39, "Plan 9"}, + {0x3c, "PartitionMagic recovery"}, + {0x40, "Venix 80286"}, + {0x41, "PPC PReP Boot"}, + {0x42, "SFS"}, + {0x4d, "QNX4.x"}, + {0x4e, "QNX4.x 2nd part"}, + {0x4f, "QNX4.x 3rd part"}, + {0x50, "OnTrack DM"}, + {0x51, "OnTrack DM6 Aux1"}, /* (or Novell) */ + {0x52, "CP/M"}, /* CP/M or Microport SysV/AT */ + {0x53, "OnTrack DM6 Aux3"}, + {0x54, "OnTrackDM6"}, + {0x55, "EZ-Drive"}, + {0x56, "Golden Bow"}, + {0x5c, "Priam Edisk"}, + {0x61, "SpeedStor"}, + {0x63, "GNU HURD or SysV"}, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */ + {0x64, "Novell Netware 286"}, + {0x65, "Novell Netware 386"}, + {0x70, "DiskSecure Multi-Boot"}, + {0x75, "PC/IX"}, + {0x80, "Old Minix"}, /* Minix 1.4a and earlier */ + {0x81, "Minix / old Linux"},/* Minix 1.4b and later */ + {0x82, "Linux swap / Solaris"}, + {0x83, "Linux"}, + {0x84, "OS/2 hidden C: drive"}, + {0x85, "Linux extended"}, + {0x86, "NTFS volume set"}, + {0x87, "NTFS volume set"}, + {0x88, "Linux plaintext"}, + {0x8e, "Linux LVM"}, + {0x93, "Amoeba"}, + {0x94, "Amoeba BBT"}, /* (bad block table) */ + {0x9f, "BSD/OS"}, /* BSDI */ + {0xa0, "IBM Thinkpad hibernation"}, + {0xa5, "FreeBSD"}, /* various BSD flavours */ + {0xa6, "OpenBSD"}, + {0xa7, "NeXTSTEP"}, + {0xa8, "Darwin UFS"}, + {0xa9, "NetBSD"}, + {0xab, "Darwin boot"}, + {0xb7, "BSDI fs"}, + {0xb8, "BSDI swap"}, + {0xbb, "Boot Wizard hidden"}, + {0xbe, "Solaris boot"}, + {0xbf, "Solaris"}, + {0xc1, "DRDOS/sec (FAT-12)"}, + {0xc4, "DRDOS/sec (FAT-16 < 32M)"}, + {0xc6, "DRDOS/sec (FAT-16)"}, + {0xc7, "Syrinx"}, + {0xda, "Non-FS data"}, + {0xdb, "CP/M / CTOS / ..."},/* CP/M or Concurrent CP/M or + Concurrent DOS or CTOS */ + {0xde, "Dell Utility"}, /* Dell PowerEdge Server utilities */ + {0xdf, "BootIt"}, /* BootIt EMBRM */ + {0xe1, "DOS access"}, /* DOS access or SpeedStor 12-bit FAT + extended partition */ + {0xe3, "DOS R/O"}, /* DOS R/O or SpeedStor */ + {0xe4, "SpeedStor"}, /* SpeedStor 16-bit FAT extended + partition < 1024 cyl. */ + {0xeb, "BeOS fs"}, + {0xee, "EFI GPT"}, /* Intel EFI GUID Partition Table */ + {0xef, "EFI (FAT-12/16/32)"},/* Intel EFI System Partition */ + {0xf0, "Linux/PA-RISC boot"},/* Linux/PA-RISC boot loader */ + {0xf1, "SpeedStor"}, + {0xf4, "SpeedStor"}, /* SpeedStor large partition */ + {0xf2, "DOS secondary"}, /* DOS 3.3+ secondary */ + {0xfd, "Linux raid autodetect"},/* New (2.2.x) raid partition with + autodetect using persistent + superblock */ + {0xfe, "LANstep"}, /* SpeedStor >1024 cyl. or LANstep */ + {0xff, "BBT"}, /* Xenix Bad Block Table */ + { 0, 0 } +}; diff --git a/rbutil/sansapatcher/sansapatcher.c b/rbutil/sansapatcher/sansapatcher.c index a19c60eaa0..3c6848e6d4 100644 --- a/rbutil/sansapatcher/sansapatcher.c +++ b/rbutil/sansapatcher/sansapatcher.c @@ -539,7 +539,6 @@ int load_original_firmware(struct sansa_t* sansa, unsigned char* buf, struct mi4 } if (key_found) { -printf("Key found - %d\n",i); memcpy(buf+(mi4header->plaintext+0x200),tmpbuf,mi4header->mi4size-(mi4header->plaintext+0x200)); free(tmpbuf); } else { @@ -593,14 +592,18 @@ int add_bootloader(struct sansa_t* sansa, char* filename, int type) int n; int length; - /* 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; - } + 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); + bl_length = filesize(infile); + } else { + bl_length = LEN_bootimg; + } /* Create PPMI header */ memset(sectorbuf,0,0x200); @@ -608,12 +611,16 @@ int add_bootloader(struct sansa_t* sansa, char* filename, int type) int2le(bl_length, sectorbuf+4); int2le(0x00020000, sectorbuf+8); - /* Read bootloader into sectorbuf+0x200 */ - n = read(infile,sectorbuf+0x200,bl_length); - if (n < bl_length) { - fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n" - ,bl_length,n); - return -1; + if (type==FILETYPE_MI4) { + /* Read bootloader into sectorbuf+0x200 */ + n = read(infile,sectorbuf+0x200,bl_length); + if (n < bl_length) { + fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n" + ,bl_length,n); + return -1; + } + } else { + memcpy(sectorbuf+0x200,bootimg,LEN_bootimg); } /* Load original firmware from Sansa to the space after the bootloader */ diff --git a/rbutil/sansapatcher/sansapatcher.h b/rbutil/sansapatcher/sansapatcher.h index 97b73dd0b9..d422aa5932 100644 --- a/rbutil/sansapatcher/sansapatcher.h +++ b/rbutil/sansapatcher/sansapatcher.h @@ -28,9 +28,7 @@ extern unsigned char* sectorbuf; #define FILETYPE_MI4 0 -#ifdef WITH_BOOTOBJS - #define FILETYPE_INTERNAL 1 -#endif +#define FILETYPE_INTERNAL 1 char* get_parttype(int pt); int read_partinfo(struct sansa_t* sansa, int silent); |