Commit 328ba56d3a5169c8c0d6dc2c850f301d8952e7f2

Authored by oliverhaag
1 parent 33dd7c54

Input files as parameters instead of hardcoded strings

dsoextractfw/ChangeLog
... ... @@ -23,3 +23,7 @@
23 23 * Silent make if available
24 24 * Fixed DSO-2100 USB vid/pid
25 25 * Added --with-firmware-dir configure option and udev-rules file generation
  26 +
  27 +2011-02-03 Oliver Haag <oliver.haag@gmail.com>
  28 +* Input files are given as commandline parameters (Not hardcoded anymore)
  29 +* Cleaned up the code
... ...
dsoextractfw/INSTALL
... ... @@ -5,7 +5,7 @@ $ ./configure
5 5 $ make
6 6  
7 7 Now place the DSO*1.SYS file that came with the windows driver for your oscilloscope into the same directory and run:
8   -$ ./dsoextractfw
  8 +$ ./dsoextractfw <driver file>
9 9  
10 10 This should create two .hex files. Copy them to /usr/local/share/hantekdso/ and copy the 90-hantek-dso.rules file to /etc/udev/rules.d/. To load the firmware you have to install fxload.
11 11 After restarting udev your oscilloscope should be initialized automatically after connecting it to the computer (You have to reconnect it after installing this package).
... ...
dsoextractfw/dsoextractfw.c
... ... @@ -4,7 +4,7 @@
4 4 // dsoextractfw.c
5 5 // Copyright (C) 2008 Oleg Khudyakov
6 6 // prcoder@potrebitel.ru
7   -// Copyright (C) 2010 Oliver Haag
  7 +// Copyright (C) 2010, 2011 Oliver Haag
8 8 // oliver.haag@gmail.com
9 9 //
10 10 // This program is free software: you can redistribute it and/or modify it
... ... @@ -23,184 +23,234 @@
23 23 ////////////////////////////////////////////////////////////////////////////////
24 24  
25 25  
26   -#include <stdio.h>
  26 +#include <ctype.h>
27 27 #include <malloc.h>
  28 +#include <stdio.h>
28 29 #include <string.h>
  30 +
29 31 #include <bfd.h>
30 32  
31   -static const char *strFirmware = "_firmware";
32   -static const char *strLoader = "_loader";
33   -static const char *strHex = ".hex";
34   -static const char *strDriver = "1.SYS";
35   -static const char *strModels[] = { "DSO2090", "DSO2100", "DSO2150", "DSO2250", "DSO5200", "DSO520A", NULL };
36 33  
37   -int writeIntelHex(const char *filename, unsigned char *ptr, bfd_size_type len);
38   -int extractFirmware(const char* model);
  34 +int extractFirmware(const char *filenameDriver, const char *filenameFirmware, const char *filenameLoader);
  35 +int writeIntelHex(const char *filename, unsigned char *data, unsigned int length);
  36 +
  37 +static const char *filenameEndFirmware = "-firmware.hex";
  38 +static const char *filenameEndLoader = "-loader.hex";
  39 +static const char *filenameEndDriver = "1.sys";
  40 +static const char *nameTarget = "pei-i386";
  41 +static const char *nameSection = ".data";
  42 +static const char *nameSymbolFirmware = "_firmware";
  43 +static const char *nameSymbolLoader = "_loader";
39 44  
40   -int writeIntelHex(const char *filename, unsigned char *ptr, bfd_size_type len)
41   -{
42   - unsigned char n, *p, crc=0, eof;
43   - bfd_size_type i, t;
44   - FILE *f;
45 45  
46   - if ((f=fopen(filename, "wt")) == NULL)
47   - {
48   - perror("Cant' open file for writing");
49   - fclose(f);
  46 +/// \brief Parse commandline arguments.
  47 +/// \return 0 on success, negative on error.
  48 +int main(int argc, char **argv) {
  49 + char *filenameDriver, *filenameFirmware, *filenameLoader;
  50 + char *charPointer;
  51 + int prefixLength;
  52 +
  53 + if(argc < 2) {
  54 + fprintf(stderr, "Usage: %s <input> [<firmware>] [<loader>]\n", argv[0]);
50 55 return -1;
51 56 }
52   -
53   - for(t=0; t <len; t+=22)
54   - {
55   - eof = -1; // Always check for End of File Record
56   - p = ptr + t;
57   - n = *p;
58   - fprintf(f, ":%02X", n);
59   - if(n != 0)
60   - eof = 0;
61   - crc = *p++;
62   - p++;
63   - fprintf(f, "%04X", *(unsigned short *)p);
64   - if(*(unsigned short *)p != 0)
65   - eof = 0;
66   - crc += *p++;
67   - crc += *p++;
68   - fprintf(f, "%02X", *p);
69   - if(*p != 0x01)
70   - eof = 0;
71   - crc += *p++;
72   - for(i=0; i<n; i++)
73   - {
74   - fprintf(f,"%02X", *p);
75   - crc += *p++;
76   - }
77   - crc = 1 + ~crc;
78   - fprintf(f, "%02X\n", crc);
  57 + filenameDriver = argv[1];
  58 +
  59 + prefixLength = strlen(filenameDriver) - strlen(filenameEndDriver);
  60 +
  61 + if(argc < 3) {
  62 + // Guess correct filename for firmware
  63 + filenameFirmware = malloc(prefixLength + strlen(filenameEndFirmware) + 1);
  64 + memcpy(filenameFirmware, filenameDriver, prefixLength);
  65 + strcpy(filenameFirmware + prefixLength, filenameEndFirmware);
79 66  
80   - if(eof)
81   - break;
  67 + // Convert filename to lowercase
  68 + charPointer = strrchr(filenameFirmware, '/');
  69 + if(charPointer == NULL)
  70 + charPointer = filenameFirmware;
  71 + for(; *charPointer != 0; charPointer++)
  72 + *charPointer = tolower(*charPointer);
82 73 }
83   - fclose(f);
84   -
85   - return 0;
  74 + else {
  75 + filenameFirmware = argv[2];
  76 + }
  77 +
  78 + if(argc < 4) {
  79 + // Guess correct filename for loader
  80 + filenameLoader = malloc(prefixLength + strlen(filenameEndLoader) + 1);
  81 + memcpy(filenameLoader, filenameDriver, prefixLength);
  82 + strcpy(filenameLoader + prefixLength, filenameEndLoader);
  83 +
  84 + // Convert filename to lowercase
  85 + charPointer = strrchr(filenameLoader, '/');
  86 + if(charPointer == NULL)
  87 + charPointer = filenameLoader;
  88 + for(; *charPointer != 0; charPointer++)
  89 + *charPointer = tolower(*charPointer);
  90 + }
  91 + else {
  92 + filenameFirmware = argv[3];
  93 + }
  94 +
  95 + return extractFirmware(filenameDriver, filenameFirmware, filenameLoader);
86 96 }
87 97  
88   -int extractFirmware(const char* model)
89   -{
90   - bfd *file;
91   - asection *section;
92   - unsigned storage;
93   - asymbol **syms = NULL;
94   - asymbol *asym;
95   - unsigned nsyms, i;
96   - const char *sname;
97   - bfd_size_type offsetData = 0, lenData = 0;
98   - bfd_size_type offsetFirmware = 0, offsetLoader = 0;
99   - bfd_size_type lenFirmware = 0, lenLoader = 0;
100   - unsigned char *ptrFirmware, *ptrLoader;
101   - char filename[256];
  98 +/// \brief Extract firmware and loader data from original driver file.
  99 +/// \param filenameDriver Name of the original driver file.
  100 +/// \param filenameFirmware Name of the file where the firmware should be saved.
  101 +/// \param filenameDriver Name of the file where the loader should be saved.
  102 +/// \return 0 on success, negative on error.
  103 +int extractFirmware(const char *filenameDriver, const char *filenameFirmware, const char *filenameLoader) {
  104 + bfd *bfdDriver;
  105 + asection *sectionData;
102 106  
103   - strcpy(filename, model);
104   - strcat(filename, strDriver);
105   - printf("Searching %s\n", filename);
  107 + asymbol **symbols;
  108 + unsigned int symbolCount;
  109 + unsigned currentSymbol;
  110 + const char *symbolName;
106 111  
  112 + bfd_size_type offsetFirmware = 0, offsetLoader = 0;
  113 + bfd_size_type lengthFirmware = 0, lengthLoader = 0;
  114 + unsigned char *bufferFirmware, *bufferLoader;
  115 +
  116 + // Initialize bfd and open driver file
107 117 bfd_init();
108   - file = bfd_openr(filename, 0);//"efi-app-ia32");
109   - if (!file)
110   - {
  118 + bfdDriver = bfd_openr(filenameDriver, nameTarget);
  119 + if(!bfdDriver) {
111 120 bfd_perror("Error opening file");
112 121 return -1;
113 122 }
114 123  
115   - if (!bfd_check_format(file, bfd_object))
116   - {
  124 + if(!bfd_check_format(bfdDriver, bfd_object)) {
117 125 bfd_perror("bfd_check_format");
118   - bfd_close (file);
119   - return -1;
  126 + bfd_close(bfdDriver);
  127 + return -2;
120 128 }
121 129  
122   - section = bfd_get_section_by_name(file, ".data");
123   - if (section != NULL)
124   - {
125   - lenData = section->size;
126   - offsetData = section->filepos;
127   - printf(".data section found at %p, length %li bytes\n", (void*)offsetData, lenData);
128   -
129   - storage = bfd_get_symtab_upper_bound(file);
130   - syms = malloc(storage);
131   - nsyms = bfd_canonicalize_symtab(file, syms);
132   - for(i=0; i<nsyms; i++)
133   - {
134   - asym = syms[i];
135   - sname = bfd_asymbol_name(asym);
136   - if (strcmp(sname, strFirmware) == 0)
137   - offsetFirmware = asym->value;
138   - if (strcmp(sname, strLoader) == 0)
139   - offsetLoader = asym->value;
140   - }
141   - free(syms);
142   -
143   - offsetFirmware -= offsetData;
144   - offsetLoader -= offsetData;
145   - lenFirmware = offsetLoader - offsetFirmware;
146   - lenLoader = lenData - lenFirmware;
147   - printf("Firmware found at offset 0x%lX, length %li bytes\n", offsetFirmware, lenFirmware);
148   - printf("Loader found at offset 0x%lX, length %li bytes\n", offsetLoader, lenLoader);
149   -
150   - ptrFirmware = malloc(lenFirmware);
151   - ptrLoader = malloc(lenLoader);
152   - if (ptrFirmware == NULL || ptrLoader == NULL)
153   - {
154   - perror("Can't allocate memory");
155   - bfd_close(file);
156   - return -1;
157   - }
158   -
159   - if (!bfd_get_section_contents(file, section, ptrFirmware, offsetFirmware, lenFirmware))
160   - {
161   - bfd_perror("Can't get firmware contents");
162   - bfd_close(file);
163   - return -1;
164   - }
165   -
166   - if (!bfd_get_section_contents(file, section, ptrLoader, offsetLoader, lenLoader))
167   - {
168   - bfd_perror("Can't get loader contents");
169   - bfd_close(file);
170   - return -1;
171   - }
172   -
173   - strcpy(filename, model);
174   - strcat(filename, strFirmware);
175   - strcat(filename, strHex);
176   - printf("Writing %s\n", filename);
177   - writeIntelHex(filename, ptrFirmware, lenFirmware);
178   -
179   - strcpy(filename, model);
180   - strcat(filename, strLoader);
181   - strcat(filename, strHex);
182   - printf("Writing %s\n", filename);
183   - writeIntelHex(filename, ptrLoader, lenLoader);
  130 + // Search for the data section
  131 + for(sectionData = bfdDriver->sections; sectionData != NULL; sectionData = sectionData->next)
  132 + if(strcmp(sectionData->name, nameSection) == 0)
  133 + break;
  134 + if(sectionData == NULL) {
  135 + fprintf(stderr, "Section %s not found\n", nameSection);
  136 + return -3;
  137 + }
  138 + printf("Section %s found (starting at 0x%04lx, %li bytes)\n", nameSection, (unsigned long int) sectionData->filepos, (long int) sectionData->size);
  139 +
  140 + // Search for the symbols we want
  141 + symbols = malloc(bfd_get_symtab_upper_bound(bfdDriver));
  142 + symbolCount = bfd_canonicalize_symtab(bfdDriver, symbols);
  143 + for(currentSymbol = 0; currentSymbol < symbolCount; currentSymbol++) {
  144 + symbolName = bfd_asymbol_name(symbols[currentSymbol]);
184 145  
185   - free(ptrFirmware);
186   - free(ptrLoader);
  146 + if(strcmp(symbolName, nameSymbolFirmware) == 0)
  147 + offsetFirmware = symbols[currentSymbol]->value;
  148 + if(strcmp(symbolName, nameSymbolLoader) == 0)
  149 + offsetLoader = symbols[currentSymbol]->value;
  150 + }
  151 + free(symbols);
  152 +
  153 + // Calculate position in section and length
  154 + offsetFirmware -= sectionData->filepos;
  155 + offsetLoader -= sectionData->filepos;
  156 + lengthFirmware = offsetLoader - offsetFirmware;
  157 + lengthLoader = sectionData->size - lengthFirmware;
  158 +
  159 + printf("Symbol %s found (offset 0x%04lx, %li bytes)\n", nameSymbolFirmware, (unsigned long int) offsetFirmware, (long int) lengthFirmware);
  160 + printf("Symbol %s found (offset 0x%04lx, %li bytes)\n", nameSymbolLoader, (unsigned long int) offsetLoader, (long int) lengthLoader);
  161 +
  162 + // Extract data
  163 + bufferFirmware = malloc(lengthFirmware);
  164 + bufferLoader = malloc(lengthLoader);
  165 + if (bufferFirmware == NULL || bufferLoader == NULL) {
  166 + fprintf(stderr, "Can't allocate memory\n");
  167 + bfd_close(bfdDriver);
  168 + return -4;
187 169 }
188   - else
189   - {
190   - fprintf(stderr, "Section .data not found\n");
  170 +
  171 + if(!bfd_get_section_contents(bfdDriver, sectionData, bufferFirmware, offsetFirmware, lengthFirmware)) {
  172 + bfd_perror("Can't get firmware contents");
  173 + bfd_close(bfdDriver);
  174 + return -5;
191 175 }
192 176  
193   - bfd_close(file);
  177 + if(!bfd_get_section_contents(bfdDriver, sectionData, bufferLoader, offsetLoader, lengthLoader)) {
  178 + bfd_perror("Can't get loader contents");
  179 + bfd_close(bfdDriver);
  180 + return -6;
  181 + }
  182 +
  183 + printf("Saving firmware as %s\n", filenameFirmware);
  184 + writeIntelHex(filenameFirmware, bufferFirmware, lengthFirmware);
  185 + free(bufferFirmware);
  186 +
  187 + printf("Saving loader as %s\n", filenameLoader);
  188 + writeIntelHex(filenameLoader, bufferLoader, lengthLoader);
  189 + free(bufferLoader);
  190 +
  191 + bfd_close(bfdDriver);
194 192  
195 193 return 0;
196 194 }
197 195  
198   -int main()
  196 +/// \brief Save data to a file in intel hex format.
  197 +/// \param filename Name of the output file.
  198 +/// \param data Pointer to the binary data that should be stored.
  199 +/// \param length Size of the data that should be stored.
  200 +/// \return 0 on success, negative on error.
  201 +int writeIntelHex(const char *filename, unsigned char *data, unsigned int length)
199 202 {
200   - int i;
  203 + FILE *file;
  204 + unsigned char crc, eof;
  205 + unsigned int dataIndex, byteIndex, byteCount;
  206 + unsigned char *dataPointer;
  207 +
  208 + file = fopen(filename, "wt");
  209 + if(!file) {
  210 + fprintf(stderr, "Can't open %s for writing\n", filename);
  211 + fclose(file);
  212 + return -1;
  213 + }
  214 +
  215 + for(dataIndex = 0; dataIndex < length; dataIndex += 22) {
  216 + eof = -1; // Always check for End of File Record
  217 + dataPointer = data + dataIndex;
  218 +
  219 + // Start code and byte count
  220 + byteCount = *dataPointer;
  221 + fprintf(file, ":%02X", byteCount);
  222 + if(byteCount != 0)
  223 + eof = 0;
  224 + crc = -*dataPointer++;
  225 + dataPointer++;
  226 +
  227 + // Address
  228 + fprintf(file, "%04X", *(unsigned short *) dataPointer);
  229 + if(*(unsigned short *) dataPointer != 0)
  230 + eof = 0;
  231 + crc -= *dataPointer++;
  232 + crc -= *dataPointer++;
  233 +
  234 + // Record type
  235 + fprintf(file, "%02X", *dataPointer);
  236 + if(*dataPointer != 0x01)
  237 + eof = 0;
  238 + crc -= *dataPointer++;
  239 +
  240 + // Data
  241 + for(byteIndex = 0; byteIndex < byteCount; byteIndex++) {
  242 + fprintf(file, "%02X", *dataPointer);
  243 + crc -= *dataPointer++;
  244 + }
  245 +
  246 + // CRC
  247 + fprintf(file, "%02X\n", crc);
  248 +
  249 + if(eof)
  250 + break;
  251 + }
201 252  
202   - for(i=0; strModels[i]!=NULL; i++)
203   - extractFirmware(strModels[i]);
  253 + fclose(file);
204 254  
205 255 return 0;
206 256 }
... ...