summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Robertson <aliask@rockbox.org>2007-11-27 16:35:07 +0000
committerWill Robertson <aliask@rockbox.org>2007-11-27 16:35:07 +0000
commitdb5206742eae1261627e48ac120a9b3a4b92d2bb (patch)
tree28c11b7cb6778ab1c462236b2e996712dbdddc79
parentd5430994ade92ea4f96c4b5f5456d39bdf769eea (diff)
Scramble can now generate an nk.bin file, independent of the OF. These nk.bin files will only transfer using the sendfirm tool.
Also made the gigabeats.c file 64-bit and endian safe. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15838 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--tools/gigabeats.c158
1 files changed, 56 insertions, 102 deletions
diff --git a/tools/gigabeats.c b/tools/gigabeats.c
index 0d60eae781..c109d6ad1c 100644
--- a/tools/gigabeats.c
+++ b/tools/gigabeats.c
@@ -19,6 +19,12 @@
#include <stdio.h>
#include <stdlib.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+
+/* Entry point (and load address) for the main Rockbox bootloader */
+#define BL_ENTRY_POINT 0x8a000000
+
static FILE * openinfile( const char * filename )
{
@@ -44,128 +50,76 @@ static FILE * openoutfile( const char * filename )
return F;
};
-unsigned long calc_csum(const unsigned char* pb, int cb)
+static uint32_t calc_csum(const unsigned char* pb, int cb)
{
- unsigned long l = 0;
+ uint32_t l = 0;
while (cb--)
l += *pb++;
return l;
}
+static void put_uint32le(uint32_t x, unsigned char* p)
+{
+ p[0] = x & 0xff;
+ p[1] = (x >> 8) & 0xff;
+ p[2] = (x >> 16) & 0xff;
+ p[3] = (x >> 24) & 0xff;
+}
+
int gigabeat_s_code(char *infile, char *outfile)
{
FILE *in, *out;
- unsigned long size = 0;
- unsigned long data;
- int imagelength;
+ unsigned int size;
+ unsigned int newsize;
+ unsigned char* buf;
in = openinfile(infile);
out = openoutfile(outfile);
+ /* Step 1: Load the binary file into memory */
fseek(in, 0, SEEK_END);
size = ftell(in);
- fseek(in, 0, SEEK_SET);
- unsigned long *binptr = malloc(size);
- if(binptr == NULL) {
+
+ /* 15 bytes for header, 16 for signature bypass,
+ * 12 for record header, 12 for footer */
+ newsize = 15 + 16 + 12 + size + 12;
+ buf = malloc(newsize);
+ if(buf == NULL) {
fprintf(stderr, "Not enough memory to perform the requested operation. Aborting.\n" );
return 0;
}
- fread(binptr, size/4, 4, in);
- /* 15 bytes for header, three 12 byte headers, the data for the first three
- * records, 12 byte header for code, code and the 12 byte footer
- * However, the original nk.bin's length doesn't correspond with
- * the length of the file, so I don't know what's up...
- */
-
- unsigned long header[2];
- header[0] = 0x88200000;
- /* header[1] = 15 + 12 + 4 + 12 + 8 + 12 + 4 + 12 + size + 12; */
- header[1] = 0xCC0CD8; /* The bootloader checks this value and compares */
- fwrite("B000FF\n", 7, 1, out);
- fwrite(header, sizeof(header), 1, out);
-
- unsigned long record[4];
- unsigned long extra;
-
- /*First record*/
- record[0] = 0x88200000;
- record[1] = 4;
- record[2] = 0x1eb;
- record[3] = 0xEA0003FE;
- fwrite(record, sizeof(record), 1, out);
-
- /*Second record*/
- record[0] = 0x88200040;
- record[1] = 8;
- record[2] = 0x3e9;
- record[3] = 0x43454345;
- extra = 0x88EBF274;
- fwrite(record, sizeof(record), 1, out);
- fwrite(&extra, sizeof(extra), 1, out);
-
- /*Third record*/
- record[0] = 0x88200048;
- record[1] = 4;
- record[2] = 0x231;
- record[3] = 0x00CBF274;
- fwrite(record, sizeof(record), 1, out);
-
- /*Signature bypass record*/
- unsigned long magic = 0xE3A00001;
- record[0] = 0x88065A10;
- record[1] = 4;
- record[2] = calc_csum((unsigned char*)&magic,4);
- record[3] = magic;
- fwrite(record, sizeof(record), 1, out);
-
- /*The actual code*/
- header[0] = 0x88201000;
- header[1] = size;
- extra = calc_csum((unsigned char*)binptr, size);
- fwrite(header, sizeof(header), 1, out);
- fwrite(&extra, sizeof(extra), 1, out);
- fwrite(binptr, size, 1, out);
-
- /* Table of contents. It's a start, but it still won't boot.
- * Looks like it needs the file/module info as well... */
- binptr[0] = 0x02000000;
- binptr[1] = 0x02000000;
- binptr[2] = 0x88040000;
- binptr[3] = 0x88076338;
- binptr[4] = 0x1;
- binptr[5] = 0x88080000;
- binptr[6] = 0x8809C000;
- binptr[7] = 0x88100000;
- binptr[8] = 0x0;
- binptr[9] = 0x0;
- binptr[10] = 0x0;
- binptr[11] = 0x0;
- binptr[12] = 0x0;
- binptr[13] = 0x0;
- binptr[14] = 0x80808080;
- binptr[15] = 0x0;
- binptr[16] = 0x0;
- binptr[17] = 0x201C2;
- binptr[18] = 0x88050940;
- binptr[19] = 0x0;
- binptr[20] = 0x0;
- header[0] = 0x88EBF274;
- header[1] = 0x54;
- extra = calc_csum((unsigned char*)binptr, 84);
- fwrite(header, sizeof(header), 1, out);
- fwrite(&extra, sizeof(extra), 1, out);
- fwrite(binptr, 84, 1, out);
-
- /*The footer*/
- header[0] = 0;
- header[1] = 0x88201000;
- extra = 0;
- fwrite(header, sizeof(header), 1, out);
- fwrite(&extra, sizeof(extra), 1, out);
+ fseek(in, 0, SEEK_SET);
+ fread(buf + 43, size, 1, in);
+ fclose(in);
+
+ /* Step 2: Create the file header */
+ sprintf(buf, "B000FF\n");
+ put_uint32le(0x88200000, buf+7);
+ /* If the value below is too small, the update will attempt to flash.
+ * Be careful when changing this (leaving it as is won't cause issues) */
+ put_uint32le(0xCC0CD8, buf+11);
+
+ /* Step 3: Add the signature bypass record */
+ put_uint32le(0x88065A10, buf+15);
+ put_uint32le(4, buf+19);
+ put_uint32le(0xE3A00001, buf+27);
+ put_uint32le(calc_csum(buf+27,4), buf+23);
+
+ /* Step 4: Create a record for the actual code */
+ put_uint32le(BL_ENTRY_POINT, buf+31);
+ put_uint32le(size, buf+35);
+ put_uint32le(calc_csum(buf + 43, size), buf+39);
+
+ /* Step 5: Write the footer */
+ put_uint32le(0, buf+newsize-12);
+ put_uint32le(BL_ENTRY_POINT, buf+newsize-8);
+ put_uint32le(0, buf+newsize-4);
+
+ /* Step 6: Write the resulting file */
+ fwrite(buf, newsize, 1, out);
+ fclose(out);
fprintf(stderr, "File processed successfully\n" );
- fclose(in);
- fclose(out);
return(0);
}