diff options
-rw-r--r-- | tools/creative.c | 89 | ||||
-rw-r--r-- | tools/creative.h | 10 |
2 files changed, 61 insertions, 38 deletions
diff --git a/tools/creative.c b/tools/creative.c index b9041ca513..2d54630595 100644 --- a/tools/creative.c +++ b/tools/creative.c | |||
@@ -30,17 +30,31 @@ static const char null_key_v2[] = "CTL:N0MAD|PDE0.DPMP."; | |||
30 | static const char null_key_v3[] = "CTL:Z3N07|PDE0.DPMP."; | 30 | static const char null_key_v3[] = "CTL:Z3N07|PDE0.DPMP."; |
31 | static const char null_key_v4[] = "CTL:N0MAD|PDE0.DPFP."; | 31 | static const char null_key_v4[] = "CTL:N0MAD|PDE0.DPFP."; |
32 | 32 | ||
33 | static const struct device_info devices[] = | 33 | static const unsigned char bootloader_v1[] = |
34 | { | 34 | { |
35 | {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0e\0n\0 \0V\0i\0s\0i\0o\0n\0:\0M", | 35 | 0xD3, 0xF0, 0x29, 0xE3, /* MSR CPSR_cf, #0xD3 */ |
36 | 42, null_key_v2}, | 36 | 0x09, 0xF6, 0xA0, 0xE3 /* MOV PC, #0x900000 */ |
37 | {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0e\0n\0 \0V\0i\0s\0i\0o\0n\0:\0M\0 \0G\0o\0!", | ||
38 | 50, null_key_v2}, | ||
39 | {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0e\0n\0 \0V\0i\0s\0i\0o\0n\0 \0©\0T\0L", | ||
40 | 48, null_key_v2}, | ||
41 | {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0E\0N\0 \0V", 42, null_key_v4} | ||
42 | }; | 37 | }; |
43 | 38 | ||
39 | static const unsigned char bootloader_v2[] = | ||
40 | { | ||
41 | 0xD3, 0xF0, 0x29, 0xE3, /* MSR CPSR_cf, #0xD3 */ | ||
42 | 0x09, 0xF6, 0xA0, 0xE3 /* MOV PC, #0x40000000 */ | ||
43 | }; | ||
44 | |||
45 | static const unsigned char bootloader_v3[] = | ||
46 | { | ||
47 | 0 /* Unknown */ | ||
48 | }; | ||
49 | |||
50 | static const struct device_info devices[] = | ||
51 | { | ||
52 | {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0e\0n\0 \0V\0i\0s\0i\0o\0n\0:\0M", 42, null_key_v2, bootloader_v1, sizeof(bootloader_v1), 0x00900000}, | ||
53 | {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0e\0n\0 \0V\0i\0s\0i\0o\0n\0:\0M\0 \0G\0o\0!", 50, null_key_v2, bootloader_v1, sizeof(bootloader_v1), 0x00900000}, | ||
54 | {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0e\0n\0 \0V\0i\0s\0i\0o\0n\0 \0©\0T\0L", 48, null_key_v2, bootloader_v1, sizeof(bootloader_v1), 0x00900000}, | ||
55 | {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0E\0N\0 \0V", 42, null_key_v4, bootloader_v3, sizeof(bootloader_v3), 0x00000000}, | ||
56 | {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0E\0N", 48, null_key_v3, bootloader_v2, sizeof(bootloader_v2), 0x40000000} | ||
57 | }; | ||
44 | 58 | ||
45 | /* | 59 | /* |
46 | Create a Zen Vision:M FRESCUE structure file | 60 | Create a Zen Vision:M FRESCUE structure file |
@@ -49,7 +63,7 @@ extern void int2le(unsigned int val, unsigned char* addr); | |||
49 | extern unsigned int le2int(unsigned char* buf); | 63 | extern unsigned int le2int(unsigned char* buf); |
50 | 64 | ||
51 | 65 | ||
52 | static int make_ciff_file(unsigned char *inbuf, int length, | 66 | static int make_ciff_file(unsigned char *inbuf, unsigned int length, |
53 | unsigned char *outbuf, int device) | 67 | unsigned char *outbuf, int device) |
54 | { | 68 | { |
55 | unsigned char key[20]; | 69 | unsigned char key[20]; |
@@ -74,14 +88,11 @@ static int make_ciff_file(unsigned char *inbuf, int length, | |||
74 | return length+0x90+0x1C+8; | 88 | return length+0x90+0x1C+8; |
75 | } | 89 | } |
76 | 90 | ||
77 | static int make_jrm_file(unsigned char *inbuf, int length, | 91 | static int make_jrm_file(unsigned char *inbuf, unsigned int length, |
78 | unsigned char *outbuf) | 92 | unsigned char *outbuf, int device) |
79 | { | 93 | { |
80 | int i; | 94 | unsigned int i; |
81 | unsigned int sum = 0; | 95 | unsigned int sum = 0; |
82 | /* Calculate checksum for later use in header */ | ||
83 | for(i=0; i<length; i+= 4) | ||
84 | sum += le2int(&inbuf[i]) + (le2int(&inbuf[i])>>16); | ||
85 | 96 | ||
86 | /* Clear the header area to zero */ | 97 | /* Clear the header area to zero */ |
87 | memset(outbuf, 0, 0x18); | 98 | memset(outbuf, 0, 0x18); |
@@ -89,34 +100,42 @@ static int make_jrm_file(unsigned char *inbuf, int length, | |||
89 | /* Header (EDOC) */ | 100 | /* Header (EDOC) */ |
90 | memcpy(outbuf, "EDOC", 4); | 101 | memcpy(outbuf, "EDOC", 4); |
91 | /* Total Size */ | 102 | /* Total Size */ |
92 | int2le(length+0x20, &outbuf[0x4]); | 103 | #define SIZEOF_BOOTLOADER_CODE devices[device].bootloader_size |
104 | int2le(4+0xC+SIZEOF_BOOTLOADER_CODE+0xC+length, &outbuf[0x4]); | ||
93 | /* 4 bytes of zero */ | 105 | /* 4 bytes of zero */ |
94 | 106 | memset(&outbuf[0x8], 0, 0x4); | |
95 | /* Address = 0x900000 */ | 107 | |
96 | int2le(0x900000, &outbuf[0xC]); | 108 | /* First block starts here ... */ |
109 | /* Address = 0x0 */ | ||
110 | memset(&outbuf[0xC], 0, 0x4); | ||
97 | /* Size */ | 111 | /* Size */ |
98 | int2le(length, &outbuf[0x10]); | 112 | int2le(SIZEOF_BOOTLOADER_CODE, &outbuf[0x10]); |
99 | /* Checksum */ | 113 | /* Checksum */ |
114 | for(i=0; i<SIZEOF_BOOTLOADER_CODE; i+= 4) | ||
115 | sum += le2int((unsigned char*)&devices[device].bootloader[i]) + (le2int((unsigned char*)&devices[device].bootloader[i])>>16); | ||
100 | int2le(sum, &outbuf[0x14]); | 116 | int2le(sum, &outbuf[0x14]); |
101 | outbuf[0x16] = 0; | 117 | outbuf[0x16] = 0; |
102 | outbuf[0x17] = 0; | 118 | outbuf[0x17] = 0; |
103 | /* Data starts here... */ | 119 | /*Data */ |
104 | memcpy(&outbuf[0x18], inbuf, length); | 120 | memcpy(&outbuf[0x18], devices[device].bootloader, SIZEOF_BOOTLOADER_CODE); |
105 | 121 | ||
106 | /* Second block starts here ... */ | 122 | /* Second block starts here ... */ |
107 | /* Address = 0x0 */ | 123 | /* Address = depends on target */ |
124 | #define SB_START (0x18+SIZEOF_BOOTLOADER_CODE) | ||
125 | int2le(devices[device].memory_address, &outbuf[SB_START]); | ||
108 | /* Size */ | 126 | /* Size */ |
109 | int2le(0x4, &outbuf[0x18+length+0x4]); | 127 | int2le(length, &outbuf[SB_START+0x4]); |
110 | /* Checksum */ | 128 | /* Checksum */ |
111 | outbuf[0x18+length+0x8] = 0xA9; | 129 | sum = 0; |
112 | outbuf[0x18+length+0x9] = 0xD9; | 130 | for(i=0; i<length; i+= 4) |
113 | /* Data: MOV PC, 0x900000 */ | 131 | sum += le2int(&inbuf[i]) + (le2int(&inbuf[i])>>16); |
114 | outbuf[0x18+length+0xC] = 0x09; | 132 | int2le(sum, &outbuf[SB_START+0x8]); |
115 | outbuf[0x18+length+0xD] = 0xF6; | 133 | outbuf[SB_START+0xA] = 0; |
116 | outbuf[0x18+length+0xE] = 0xA0; | 134 | outbuf[SB_START+0xB] = 0; |
117 | outbuf[0x18+length+0xF] = 0xE3; | 135 | /* Data */ |
118 | 136 | memcpy(&outbuf[SB_START+0xC], inbuf, length); | |
119 | return length+0x18+0x10; | 137 | |
138 | return SB_START+0xC+length; | ||
120 | } | 139 | } |
121 | 140 | ||
122 | int zvm_encode(char *iname, char *oname, int device) | 141 | int zvm_encode(char *iname, char *oname, int device) |
@@ -156,7 +175,7 @@ int zvm_encode(char *iname, char *oname, int device) | |||
156 | printf("out of memory!\n"); | 175 | printf("out of memory!\n"); |
157 | return -1; | 176 | return -1; |
158 | } | 177 | } |
159 | length = make_jrm_file(buf, len, outbuf); | 178 | length = make_jrm_file(buf, len, outbuf, device); |
160 | free(buf); | 179 | free(buf); |
161 | buf = (unsigned char*)malloc(length+0x200); | 180 | buf = (unsigned char*)malloc(length+0x200); |
162 | memset(buf, 0, length+0x200); | 181 | memset(buf, 0, length+0x200); |
diff --git a/tools/creative.h b/tools/creative.h index ff8b4a019d..b8b8f53737 100644 --- a/tools/creative.h +++ b/tools/creative.h | |||
@@ -25,15 +25,19 @@ enum | |||
25 | ZENVISIONM = 0, | 25 | ZENVISIONM = 0, |
26 | ZENVISIONM60 = 1, | 26 | ZENVISIONM60 = 1, |
27 | ZENVISION = 2, | 27 | ZENVISION = 2, |
28 | ZENV = 3 | 28 | ZENV = 3, |
29 | ZEN = 4 | ||
29 | }; | 30 | }; |
30 | 31 | ||
31 | struct device_info | 32 | struct device_info |
32 | { | 33 | { |
33 | const char* cinf; /*Must be Unicode encoded*/ | 34 | const char* cinf; /*Must be Unicode encoded*/ |
34 | const int cinf_size; | 35 | const unsigned int cinf_size; |
35 | const char* null; | 36 | const char* null; |
36 | } device_info; | 37 | const unsigned char* bootloader; |
38 | const unsigned int bootloader_size; | ||
39 | const unsigned int memory_address; | ||
40 | }; | ||
37 | 41 | ||
38 | int zvm_encode(char *iname, char *oname, int device); | 42 | int zvm_encode(char *iname, char *oname, int device); |
39 | 43 | ||