]>
Commit | Line | Data |
---|---|---|
6658905f | 1 | #include <usb.h> |
2 | #include <stdio.h> | |
3 | #include <unistd.h> | |
4 | #include <stdlib.h> | |
5 | #include <strings.h> | |
6 | #include <string.h> | |
7 | #include <errno.h> | |
8 | #include <ctype.h> | |
9 | ||
10 | #include "translate.h" | |
11 | #include "../winsrc/prox.h" | |
12 | #include "proxmark3.h" | |
13 | ||
14 | static DWORD ExpectedAddr; | |
15 | static BYTE QueuedToSend[256]; | |
16 | static BOOL AllWritten; | |
17 | ||
18 | static void FlushPrevious(void) | |
19 | { | |
20 | UsbCommand c; | |
21 | memset(&c, 0, sizeof(c)); | |
22 | ||
23 | printf("expected = %08x flush, ", ExpectedAddr); | |
24 | ||
25 | int i; | |
26 | for(i = 0; i < 240; i += 48) { | |
27 | c.cmd = CMD_SETUP_WRITE; | |
28 | memcpy(c.d.asBytes, QueuedToSend+i, 48); | |
29 | c.ext1 = (i/4); | |
30 | SendCommand(&c, TRUE); | |
31 | } | |
32 | ||
33 | c.cmd = CMD_FINISH_WRITE; | |
34 | c.ext1 = (ExpectedAddr-1) & (~255); | |
35 | printf("c.ext1 = %08x\r", c.ext1); | |
36 | memcpy(c.d.asBytes, QueuedToSend+240, 16); | |
37 | SendCommand(&c, TRUE); | |
38 | ||
39 | AllWritten = TRUE; | |
40 | } | |
41 | ||
42 | static void GotByte(DWORD where, BYTE which) | |
43 | { | |
44 | AllWritten = FALSE; | |
45 | ||
46 | if(where != ExpectedAddr) { | |
47 | printf("bad: got at %08x, expected at %08x\n", where, ExpectedAddr); | |
48 | exit(-1); | |
49 | } | |
50 | QueuedToSend[where & 255] = which; | |
51 | ExpectedAddr++; | |
52 | ||
53 | if((where & 255) == 255) { | |
54 | // we have completed a full page | |
55 | FlushPrevious(); | |
56 | } | |
57 | } | |
58 | ||
59 | static int HexVal(int c) | |
60 | { | |
61 | c = tolower(c); | |
62 | if(c >= '0' && c <= '9') { | |
63 | return c - '0'; | |
64 | } else if(c >= 'a' && c <= 'f') { | |
65 | return (c - 'a') + 10; | |
66 | } else { | |
67 | printf("bad hex digit '%c'\n", c); | |
68 | exit(-1); | |
69 | } | |
70 | } | |
71 | ||
72 | static BYTE HexByte(char *s) | |
73 | { | |
74 | return (HexVal(s[0]) << 4) | HexVal(s[1]); | |
75 | } | |
76 | ||
77 | static void LoadFlashFromSRecords(char *file, int addr) | |
78 | { | |
79 | ExpectedAddr = addr; | |
80 | ||
81 | FILE *f = fopen(file, "r"); | |
82 | if(!f) { | |
83 | printf("couldn't open file\n"); | |
84 | exit(-1); | |
85 | } | |
86 | ||
87 | char line[512]; | |
88 | while(fgets(line, sizeof(line), f)) { | |
89 | if(memcmp(line, "S3", 2)==0) { | |
90 | char *s = line + 2; | |
91 | int len = HexByte(s) - 5; | |
92 | s += 2; | |
93 | ||
94 | char addrStr[9]; | |
95 | memcpy(addrStr, s, 8); | |
96 | addrStr[8] = '\0'; | |
97 | DWORD addr; | |
98 | sscanf(addrStr, "%x", &addr); | |
99 | s += 8; | |
100 | ||
101 | int i; | |
102 | for(i = 0; i < len; i++) { | |
103 | while((addr+i) > ExpectedAddr) { | |
104 | GotByte(ExpectedAddr, 0xff); | |
105 | } | |
106 | GotByte(addr+i, HexByte(s)); | |
107 | s += 2; | |
108 | } | |
109 | } | |
110 | } | |
111 | ||
112 | if(!AllWritten) FlushPrevious(); | |
113 | ||
114 | fclose(f); | |
115 | printf("\ndone.\n"); | |
116 | } | |
117 | ||
118 | int main(int argc, char **argv) { | |
119 | unsigned int addr = 0; | |
431ae7e0 | 120 | BOOL fastflash = 0, flashboth = 0; |
6658905f | 121 | UsbCommand c; |
122 | ||
431ae7e0 | 123 | if (argc != 3 && ! ((argc == 4 && *argv[3] == 'f') || (argc == 5 && *argv[4] == 'f'))) { |
124 | fprintf(stderr,"Usage: %s {bootrom|os|fpga} image.s19 [f]ast\n", argv[0]); | |
125 | fprintf(stderr," %s {both} osimage.s19 fpgaimage.s19 [f]ast\n", argv[0]); | |
6658905f | 126 | exit(EXIT_FAILURE); |
127 | } | |
128 | ||
129 | if (!strcmp(argv[1],"bootrom")) { | |
130 | addr = 0; | |
131 | } else if (!strcmp(argv[1],"os")) { | |
431ae7e0 | 132 | addr = FLASH_ADDR_OS; |
6658905f | 133 | } else if (!strcmp(argv[1],"fpga")) { |
431ae7e0 | 134 | addr = FLASH_ADDR_FPGA; |
135 | } else if (!strcmp(argv[1],"both")) { | |
136 | flashboth = 1; | |
6658905f | 137 | } else { |
138 | fprintf(stderr,"Unknown action '%s'!\n", argv[1]); | |
139 | exit(EXIT_FAILURE); | |
140 | } | |
141 | ||
431ae7e0 | 142 | if((argc == 4 && *argv[3] == 'f') || (argc == 5 && *argv[4] == 'f')) { |
143 | fastflash= 1; | |
144 | fprintf(stderr,"Fastflash - device already in FLASH mode...\n"); | |
145 | } | |
146 | ||
6658905f | 147 | usb_init(); |
148 | ||
149 | fprintf(stderr,"Waiting for Proxmark to appear on USB...\n"); | |
150 | while(!(devh=OpenProxmark(0))) { sleep(1); } | |
151 | fprintf(stderr,"Found...\n"); | |
152 | ||
431ae7e0 | 153 | if(!fastflash){ |
154 | fprintf(stderr,"Entering flash-mode...\n"); | |
155 | bzero(&c, sizeof(c)); | |
156 | c.cmd = CMD_START_FLASH; | |
157 | SendCommand(&c, FALSE); | |
158 | CloseProxmark(); | |
159 | sleep(1); | |
160 | ||
161 | fprintf(stderr,"Waiting for Proxmark to reappear on USB...\n"); | |
162 | fprintf(stderr,"(Press and hold down button NOW if your bootloader requires it)\n"); | |
163 | while(!(devh=OpenProxmark(0))) { sleep(1); } | |
164 | fprintf(stderr,"Found...\n"); | |
165 | } | |
6658905f | 166 | |
431ae7e0 | 167 | if(!flashboth) |
168 | LoadFlashFromSRecords(argv[2], addr); | |
169 | else { | |
170 | fprintf(stderr,"Flashing os...\n"); | |
171 | LoadFlashFromSRecords(argv[2],FLASH_ADDR_OS); | |
172 | fprintf(stderr,"Flashing fpga...\n"); | |
173 | LoadFlashFromSRecords(argv[3],FLASH_ADDR_FPGA); | |
174 | } | |
6658905f | 175 | |
176 | bzero(&c, sizeof(c)); | |
177 | c.cmd = CMD_HARDWARE_RESET; | |
178 | SendCommand(&c, FALSE); | |
179 | ||
180 | CloseProxmark(); | |
181 | ||
182 | fprintf(stderr,"Have a nice day!\n"); | |
183 | ||
184 | return 0; | |
185 | } |