Prepare new maemo release
[maemo-rb.git] / tools / rkw.c
blobdb86b4f748c29169372c91e9a381cf3b3693604e
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
9 * Copyright (C) 2012 Marcin Bukat
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdint.h>
26 #define RKLD_MAGIC 0x4c44524b
27 #define RKW_HEADER_SIZE 0x2c
29 /* slightly modified version from crc32.c in rockbox */
30 static uint32_t rkw_crc32(const void *src, uint32_t len)
32 const unsigned char *buf = (const unsigned char *)src;
34 /* polynomial 0x04c10db7 */
35 static const uint32_t crc32_lookup[16] =
36 { /* lookup table for 4 bits at a time is affordable */
37 0x00000000, 0x04C10DB7, 0x09821B6E, 0x0D4316D9,
38 0x130436DC, 0x17C53B6B, 0x1A862DB2, 0x1E472005,
39 0x26086DB8, 0x22C9600F, 0x2F8A76D6, 0x2B4B7B61,
40 0x350C5B64, 0x31CD56D3, 0x3C8E400A, 0x384F4DBD
43 uint32_t crc32 = 0;
44 unsigned char byte;
45 uint32_t t;
47 while (len--)
49 byte = *buf++; /* get one byte of data */
51 /* upper nibble of our data */
52 t = crc32 >> 28; /* extract the 4 most significant bits */
53 t ^= byte >> 4; /* XOR in 4 bits of data into the extracted bits */
54 crc32 <<= 4; /* shift the CRC register left 4 bits */
55 crc32 ^= crc32_lookup[t]; /* do the table lookup and XOR the result */
57 /* lower nibble of our data */
58 t = crc32 >> 28; /* extract the 4 most significant bits */
59 t ^= byte & 0x0F; /* XOR in 4 bits of data into the extracted bits */
60 crc32 <<= 4; /* shift the CRC register left 4 bits */
61 crc32 ^= crc32_lookup[t]; /* do the table lookup and XOR the result */
64 return crc32;
67 static void int2le(unsigned int val, unsigned char* addr)
69 addr[0] = val & 0xFF;
70 addr[1] = (val >> 8) & 0xff;
71 addr[2] = (val >> 16) & 0xff;
72 addr[3] = (val >> 24) & 0xff;
75 int rkw_encode(char *iname, char *oname, unsigned long modelnum)
77 size_t len;
78 int length;
79 int rkwlength;
80 FILE *file;
81 uint32_t binary_crc, header_crc;
82 unsigned char *outbuf;
84 file = fopen(iname, "rb");
85 if (!file)
87 perror(iname);
88 return -1;
91 fseek(file,0,SEEK_END);
92 length = ftell(file);
94 fseek(file,0,SEEK_SET);
96 /* length of the RKW header + binary length + 4 bytes of CRC */
97 rkwlength = (length + RKW_HEADER_SIZE + 4);
99 outbuf = malloc(rkwlength);
101 if (!outbuf)
103 printf("out of memory!\n");
104 fclose(file);
105 return -1;
108 /* Clear the buffer to zero */
109 memset(outbuf, 0, rkwlength);
111 /* Build the RKW header */
112 int2le(RKLD_MAGIC, outbuf); /* magic */
113 int2le(RKW_HEADER_SIZE, outbuf+0x04); /* header size */
114 int2le(0x60000000, outbuf+0x08); /* base address */
115 int2le(0x60000000, outbuf+0x0c); /* load address */
116 int2le(0x60000000+length, outbuf+0x10); /* end address */
117 int2le(0x6035a5e4, outbuf+0x14); /* points to some unknown struct */
118 int2le(modelnum, outbuf+0x18); /* reserved (we abuse the format
119 * to store modelnum here
121 int2le(0, outbuf+0x1c); /* reserved */
122 int2le(0x60000000, outbuf+0x20); /* entry point */
123 int2le(0xe0000000, outbuf+0x24); /* flags */
125 header_crc = rkw_crc32(outbuf, RKW_HEADER_SIZE - 4);
127 int2le(header_crc, outbuf+0x28); /* header CRC */
129 /* Copy the binary */
130 len = fread(outbuf + RKW_HEADER_SIZE, 1, length, file);
131 if(len < (size_t)length)
133 perror(iname);
134 free(outbuf);
135 fclose(file);
136 return -2;
138 fclose(file);
140 /* calc binary CRC and put at the end */
141 binary_crc = rkw_crc32 (outbuf + RKW_HEADER_SIZE, length);
142 int2le(binary_crc, outbuf + rkwlength - 4);
144 file = fopen(oname, "wb");
145 if (!file)
147 perror(oname);
148 free(outbuf);
149 return -3;
152 len = fwrite(outbuf, 1, rkwlength, file);
153 if(len < (size_t)length)
155 perror(oname);
156 fclose(file);
157 free(outbuf);
158 return -4;
161 fclose(file);
162 free(outbuf);
163 fprintf(stderr, "File encoded successfully\n" );
165 return 0;