summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2012-12-16 01:52:19 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2012-12-16 01:52:19 +0100
commit4fc3397c5b79811dff1205a5d42ac1e573f990ab (patch)
tree9ac6ea6c194787d603d62256dbced48948b71db0
parent51604e84459be926ae1375cf940a832635fd12c2 (diff)
downloadrockbox-4fc3397c5b79811dff1205a5d42ac1e573f990ab.tar.gz
rockbox-4fc3397c5b79811dff1205a5d42ac1e573f990ab.zip
imxtools/sbtools: implement sb1 write
Change-Id: Ic36d3a8fcf09350dff5988eb860d76eb11608cc2
-rw-r--r--utils/imxtools/sbtools/sb1.c188
-rw-r--r--utils/imxtools/sbtools/sb1.h9
2 files changed, 181 insertions, 16 deletions
diff --git a/utils/imxtools/sbtools/sb1.c b/utils/imxtools/sbtools/sb1.c
index 22854036c1..576196d5bd 100644
--- a/utils/imxtools/sbtools/sb1.c
+++ b/utils/imxtools/sbtools/sb1.c
@@ -59,7 +59,123 @@ static void fix_version(struct sb1_version_t *ver)
59 59
60enum sb1_error_t sb1_write_file(struct sb1_file_t *sb, const char *filename) 60enum sb1_error_t sb1_write_file(struct sb1_file_t *sb, const char *filename)
61{ 61{
62 return SB1_ERROR; 62 /* compute image size (without userdata) */
63 uint32_t image_size = 0;
64 image_size += sizeof(struct sb1_header_t);
65 for(int i = 0; i < sb->nr_insts; i++)
66 {
67 switch(sb->insts[i].cmd)
68 {
69 case SB1_INST_LOAD:
70 image_size += 8 + ROUND_UP(sb->insts[i].size, 4);
71 break;
72 case SB1_INST_FILL:
73 case SB1_INST_JUMP:
74 case SB1_INST_CALL:
75 image_size += 12;
76 break;
77 case SB1_INST_MODE:
78 case SB1_INST_SDRAM:
79 image_size += 8;
80 break;
81 default:
82 bugp("Unknown SB instruction: %#x\n", sb->insts[i].cmd);
83 }
84 }
85 // now take crypto marks and sector size into account:
86 // there is one crypto mark per sector, ie 4 bytes for 508 = 512 (sector)
87 image_size += 4 * ((image_size + SECTOR_SIZE - 5) / (SECTOR_SIZE - 4));
88 image_size = ROUND_UP(image_size, SECTOR_SIZE);
89
90 /* allocate buffer and fill it (ignoring crypto for now) */
91 void *buf = xmalloc(image_size);
92 struct sb1_header_t *header = buf;
93 memset(buf, 0, image_size);
94 header->rom_version = sb->rom_version;
95 header->image_size = image_size + sb->userdata_size;
96 header->header_size = sizeof(struct sb1_header_t);
97 header->userdata_offset = sb->userdata ? image_size : 0;
98 memcpy(&header->product_ver, &sb->product_ver, sizeof(sb->product_ver));
99 memcpy(&header->component_ver, &sb->component_ver, sizeof(sb->component_ver));
100 header->drive_tag = sb->drive_tag;
101 strncpy((void *)header->signature, "STMP", 4);
102
103 struct sb1_cmd_header_t *cmd = (void *)(header + 1);
104 for(int i = 0; i < sb->nr_insts; i++)
105 {
106 int bytes = 0;
107 switch(sb->insts[i].cmd)
108 {
109 case SB1_INST_LOAD:
110 bytes = sb->insts[i].size;
111 cmd->addr = sb->insts[i].addr;
112 memcpy(cmd + 1, sb->insts[i].data, sb->insts[i].size);
113 memset((void *)(cmd + 1) + sb->insts[i].size, 0,
114 bytes - sb->insts[i].size);
115 break;
116 case SB1_INST_FILL:
117 bytes = 4;
118 memcpy(cmd + 1, &sb->insts[i].pattern, 4);
119 cmd->addr = sb->insts[i].addr;
120 break;
121 case SB1_INST_JUMP:
122 case SB1_INST_CALL:
123 bytes = 4;
124 cmd->addr = sb->insts[i].addr;
125 memcpy(cmd + 1, &sb->insts[i].argument, 4);
126 break;
127 case SB1_INST_MODE:
128 bytes = 4;
129 cmd->addr = sb->insts[i].mode;
130 break;
131 case SB1_INST_SDRAM:
132 bytes = 0;
133 cmd->addr = SB1_MK_ADDR_SDRAM(sb->insts[i].sdram.chip_select,
134 sb->insts[i].sdram.size_index);
135 break;
136 default:
137 bugp("Unknown SB instruction: %#x\n", sb->insts[i].cmd);
138 }
139
140 cmd->cmd = SB1_MK_CMD(sb->insts[i].cmd, sb->insts[i].datatype,
141 bytes, sb->insts[i].critical,
142 ROUND_UP(bytes, 4) / 4 + 1);
143
144 cmd = (void *)cmd + 8 + ROUND_UP(bytes, 4);
145 }
146
147 /* move everything to prepare crypto marks (start at the end !) */
148 for(int i = image_size / SECTOR_SIZE - 1; i >= 0; i--)
149 memmove(buf + i * SECTOR_SIZE, buf + i * (SECTOR_SIZE - 4), SECTOR_SIZE - 4);
150
151 union xorcrypt_key_t key[2];
152 memcpy(key, sb->key, sizeof(sb->key));
153 void *ptr = header + 1;
154 int offset = header->header_size;
155 for(unsigned i = 0; i < image_size / SECTOR_SIZE; i++)
156 {
157 int size = SECTOR_SIZE - 4 - offset;
158 uint32_t mark = xor_encrypt(key, ptr, size);
159 *(uint32_t *)(ptr + size) = mark;
160
161 ptr += size + 4;
162 offset = 0;
163 }
164
165 FILE *fd = fopen(filename, "wb");
166 if(fd == NULL)
167 return SB1_OPEN_ERROR;
168 if(fwrite(buf, image_size, 1, fd) != 1)
169 {
170 free(buf);
171 return SB1_WRITE_ERROR;
172 }
173 free(buf);
174 if(sb->userdata)
175 fwrite(sb->userdata, sb->userdata_size, 1, fd);
176 fclose(fd);
177
178 return SB1_SUCCESS;
63} 179}
64 180
65struct sb1_file_t *sb1_read_file(const char *filename, void *u, 181struct sb1_file_t *sb1_read_file(const char *filename, void *u,
@@ -237,6 +353,8 @@ struct sb1_file_t *sb1_read_memory(void *_buf, size_t filesize, void *u,
237 } 353 }
238 } 354 }
239 } 355 }
356
357 memcpy(file->key, key, sizeof(key));
240 358
241 if(!valid_key) 359 if(!valid_key)
242 fatal(SB1_NO_VALID_KEY, "No valid key found\n"); 360 fatal(SB1_NO_VALID_KEY, "No valid key found\n");
@@ -279,18 +397,6 @@ struct sb1_file_t *sb1_read_memory(void *_buf, size_t filesize, void *u,
279 printf(YELLOW, " Boot:"); 397 printf(YELLOW, " Boot:");
280 printf(RED, " %#x ", SB1_CMD_BOOT(cmd->cmd)); 398 printf(RED, " %#x ", SB1_CMD_BOOT(cmd->cmd));
281 printf(GREEN, "(%s)\n", sb1_cmd_name(SB1_CMD_BOOT(cmd->cmd))); 399 printf(GREEN, "(%s)\n", sb1_cmd_name(SB1_CMD_BOOT(cmd->cmd)));
282 printf(YELLOW, " Addr:");
283 printf(RED, " %#x", cmd->addr);
284
285 if(SB1_CMD_BOOT(cmd->cmd) == SB1_INST_SDRAM)
286 printf(GREEN, " (Chip Select=%d, Size=%d)", SB1_ADDR_SDRAM_CS(cmd->addr),
287 sb1_sdram_size_by_index(SB1_ADDR_SDRAM_SZ(cmd->addr)));
288 printf(OFF, "\n");
289 if(SB1_CMD_BOOT(cmd->cmd) == SB1_INST_FILL)
290 {
291 printf(YELLOW, " Pattern:");
292 printf(RED, " %#x\n", *(uint32_t *)(cmd + 1));
293 }
294 400
295 /* copy command */ 401 /* copy command */
296 struct sb1_inst_t inst; 402 struct sb1_inst_t inst;
@@ -305,16 +411,42 @@ struct sb1_file_t *sb1_read_memory(void *_buf, size_t filesize, void *u,
305 case SB1_INST_SDRAM: 411 case SB1_INST_SDRAM:
306 inst.sdram.chip_select = SB1_ADDR_SDRAM_CS(cmd->addr); 412 inst.sdram.chip_select = SB1_ADDR_SDRAM_CS(cmd->addr);
307 inst.sdram.size_index = SB1_ADDR_SDRAM_SZ(cmd->addr); 413 inst.sdram.size_index = SB1_ADDR_SDRAM_SZ(cmd->addr);
414 printf(YELLOW, " Ram:");
415 printf(RED, " %#x", inst.addr);
416 printf(GREEN, " (Chip Select=%d, Size=%d)\n", SB1_ADDR_SDRAM_CS(cmd->addr),
417 sb1_sdram_size_by_index(SB1_ADDR_SDRAM_SZ(cmd->addr)));
308 break; 418 break;
309 case SB1_INST_MODE: 419 case SB1_INST_MODE:
310 inst.mode = cmd->addr; 420 inst.mode = cmd->addr;
421 printf(YELLOW, " Mode:");
422 printf(RED, " %#x\n", inst.mode);
311 break; 423 break;
312 case SB1_INST_LOAD: 424 case SB1_INST_LOAD:
313 inst.data = malloc(inst.size); 425 inst.data = malloc(inst.size);
314 memcpy(inst.data, cmd + 1, inst.size); 426 memcpy(inst.data, cmd + 1, inst.size);
315 /* fallthrough */
316 default:
317 inst.addr = cmd->addr; 427 inst.addr = cmd->addr;
428 printf(YELLOW, " Addr:");
429 printf(RED, " %#x\n", inst.addr);
430 break;
431 case SB1_INST_FILL:
432 inst.addr = cmd->addr;
433 inst.pattern = *(uint32_t *)(cmd + 1);
434 printf(YELLOW, " Addr:");
435 printf(RED, " %#x\n", cmd->addr);
436 printf(YELLOW, " Pattern:");
437 printf(RED, " %#x\n", inst.pattern);
438 break;
439 case SB1_INST_CALL:
440 case SB1_INST_JUMP:
441 inst.addr = cmd->addr;
442 inst.argument = *(uint32_t *)(cmd + 1);
443 printf(YELLOW, " Addr:");
444 printf(RED, " %#x\n", cmd->addr);
445 printf(YELLOW, " Argument:");
446 printf(RED, " %#x\n", inst.pattern);
447 break;
448 default:
449 printf(GREY, "WARNING: unknown SB command !\n");
318 break; 450 break;
319 } 451 }
320 452
@@ -447,4 +579,28 @@ void sb1_dump(struct sb1_file_t *file, void *u, sb1_color_printf cprintf)
447 #undef printf 579 #undef printf
448 #undef print_hex 580 #undef print_hex
449} 581}
450 582
583static struct crypto_key_t g_default_xor_key =
584{
585 .method = CRYPTO_XOR_KEY,
586 .u.xor_key =
587 {
588 {.k = {0x67ECAEF6, 0xB31FB961, 0x118A9F4C, 0xA32A97DA,
589 0x6CC39617, 0x5BC00314, 0x9D430685, 0x4D7DB502,
590 0xA347685E, 0x3C87E86C, 0x8987AAA0, 0x24B78EF1,
591 0x893B9605, 0x9BB8C2BE, 0x6D9544E2, 0x375B525C}},
592 {.k = {0x3F424704, 0x53B5A331, 0x6AD345A5, 0x20DCEC51,
593 0x743C8D3B, 0x444B3792, 0x0AF429569, 0xB7EE1111,
594 0x583BF768, 0x9683BF9A, 0x0B032D799, 0xFE4E78ED,
595 0xF20D08C2, 0xFA0BE4A2, 0x4D89C317, 0x887B2D6F}}
596 }
597};
598
599void sb1_get_default_key(struct crypto_key_t *key)
600{
601 memcpy(key, &g_default_xor_key, sizeof(g_default_xor_key));
602 /* decrypt the xor key which is xor'ed */
603 for(int i = 0; i < 2; i++)
604 for(int j = 0; j < 16; j++)
605 key->u.xor_key[i].k[j] ^= 0xaa55aa55;
606} \ No newline at end of file
diff --git a/utils/imxtools/sbtools/sb1.h b/utils/imxtools/sbtools/sb1.h
index 8d8c2d2296..0a0c9fe69c 100644
--- a/utils/imxtools/sbtools/sb1.h
+++ b/utils/imxtools/sbtools/sb1.h
@@ -66,9 +66,14 @@ struct sb1_cmd_header_t
66#define SB1_CMD_DATATYPE(cmd) (((cmd) >> 4) & 0x3) 66#define SB1_CMD_DATATYPE(cmd) (((cmd) >> 4) & 0x3)
67#define SB1_CMD_BOOT(cmd) ((cmd) & 0xf) 67#define SB1_CMD_BOOT(cmd) ((cmd) & 0xf)
68 68
69#define SB1_MK_CMD(boot,data,bytes,crit,size) \
70 ((boot) | (data) << 4 | (bytes) << 6 | (crit) << 20 | (size) << 21)
71
69#define SB1_ADDR_SDRAM_CS(addr) ((addr) & 0x3) 72#define SB1_ADDR_SDRAM_CS(addr) ((addr) & 0x3)
70#define SB1_ADDR_SDRAM_SZ(addr) ((addr) >> 16) 73#define SB1_ADDR_SDRAM_SZ(addr) ((addr) >> 16)
71 74
75#define SB1_MK_ADDR_SDRAM(cs,sz) ((cs) | (sz) << 16)
76
72int sb1_sdram_size_by_index(int index); // returns - 1 on error 77int sb1_sdram_size_by_index(int index); // returns - 1 on error
73int sb1_sdram_index_by_size(int size); // returns -1 on error 78int sb1_sdram_index_by_size(int size); // returns -1 on error
74 79
@@ -105,6 +110,7 @@ struct sb1_inst_t
105 // <union> 110 // <union>
106 void *data; 111 void *data;
107 uint32_t pattern; 112 uint32_t pattern;
113 uint32_t argument;
108 // </union> 114 // </union>
109}; 115};
110 116
@@ -119,6 +125,7 @@ struct sb1_file_t
119 struct sb1_inst_t *insts; 125 struct sb1_inst_t *insts;
120 void *userdata; 126 void *userdata;
121 int userdata_size; 127 int userdata_size;
128 union xorcrypt_key_t key[2];
122}; 129};
123 130
124enum sb1_error_t 131enum sb1_error_t
@@ -146,6 +153,8 @@ struct sb1_file_t *sb1_read_file_ex(const char *filename, size_t offset, size_t
146struct sb1_file_t *sb1_read_memory(void *buffer, size_t size, void *u, 153struct sb1_file_t *sb1_read_memory(void *buffer, size_t size, void *u,
147 sb1_color_printf printf, enum sb1_error_t *err); 154 sb1_color_printf printf, enum sb1_error_t *err);
148 155
156void sb1_get_default_key(struct crypto_key_t *key);
157
149void sb1_dump(struct sb1_file_t *file, void *u, sb1_color_printf printf); 158void sb1_dump(struct sb1_file_t *file, void *u, sb1_color_printf printf);
150void sb1_free(struct sb1_file_t *file); 159void sb1_free(struct sb1_file_t *file);
151 160