From ed72f34be5c4be7080fdc0588ba771e30d16a0aa Mon Sep 17 00:00:00 2001 From: oliverhaag Date: Wed, 9 Feb 2011 19:09:00 +0000 Subject: [PATCH] Final extractfw 0.7.0 release, changed name to openhantek-extractfw and added fwget.sh script. --- openhantek-extractfw/90-hantek-dso.rules.in | 23 ----------------------- openhantek-extractfw/90-hantek.rules.in | 23 +++++++++++++++++++++++ openhantek-extractfw/ChangeLog | 5 +++++ openhantek-extractfw/Makefile.am | 10 +++++----- openhantek-extractfw/configure.in | 8 ++++---- openhantek-extractfw/dsoextractfw.c | 256 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- openhantek-extractfw/extractfw.c | 256 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ openhantek-extractfw/fwget.sh | 41 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 334 insertions(+), 288 deletions(-) delete mode 100644 openhantek-extractfw/90-hantek-dso.rules.in create mode 100644 openhantek-extractfw/90-hantek.rules.in delete mode 100644 openhantek-extractfw/dsoextractfw.c create mode 100644 openhantek-extractfw/extractfw.c create mode 100755 openhantek-extractfw/fwget.sh diff --git a/openhantek-extractfw/90-hantek-dso.rules.in b/openhantek-extractfw/90-hantek-dso.rules.in deleted file mode 100644 index 9736d13..0000000 --- a/openhantek-extractfw/90-hantek-dso.rules.in +++ /dev/null @@ -1,23 +0,0 @@ -# Hantek DSO-2090 -SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="4b4/2090/*", RUN+="/sbin/fxload -t fx2 -I @hantekfirmwaredir@/DSO2090_firmware.hex -s @hantekfirmwaredir@/DSO2090_loader.hex -D $env{DEVNAME}" -SYSFS{idVendor}=="04b5", SYSFS{idProduct}=="2090", MODE="0660", GROUP="plugdev" - -# Hantek DSO-2100 -SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="547/1006/*", RUN+="/sbin/fxload -t an21 -I @hantekfirmwaredir@/DSO2100_firmware.hex -s @hantekfirmwaredir@/DSO2100_loader.hex -D $env{DEVNAME}" -SYSFS{idVendor}=="0547", SYSFS{idProduct}=="1002", MODE="0660", GROUP="plugdev" - -# Hantek DSO-2150 -SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="4b4/2150/*", RUN+="/sbin/fxload -t fx2 -I @hantekfirmwaredir@/DSO2150_firmware.hex -s @hantekfirmwaredir@/DSO2150_loader.hex -D $env{DEVNAME}" -SYSFS{idVendor}=="04b5", SYSFS{idProduct}=="2150", MODE="0660", GROUP="plugdev" - -# Hantek DSO-2250 -SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="4b4/2250/*", RUN+="/sbin/fxload -t fx2 -I @hantekfirmwaredir@/DSO2250_firmware.hex -s @hantekfirmwaredir@/DSO2250_loader.hex -D $env{DEVNAME}" -SYSFS{idVendor}=="04b5", SYSFS{idProduct}=="2250", MODE="0660", GROUP="plugdev" - -# Hantek DSO-5200 -SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="4b4/5200/*", RUN+="/sbin/fxload -t fx2 -I @hantekfirmwaredir@/DSO5200_firmware.hex -s @hantekfirmwaredir@/DSO5200_loader.hex -D $env{DEVNAME}" -SYSFS{idVendor}=="04b5", SYSFS{idProduct}=="5200", MODE="0660", GROUP="plugdev" - -# Hantek DSO-5200A -SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="4b4/520A/*", RUN+="/sbin/fxload -t fx2 -I @hantekfirmwaredir@/DSO520A_firmware.hex -s @hantekfirmwaredir@/DSO520A_loader.hex -D $env{DEVNAME}" -SYSFS{idVendor}=="04b5", SYSFS{idProduct}=="520A", MODE="0660", GROUP="plugdev" diff --git a/openhantek-extractfw/90-hantek.rules.in b/openhantek-extractfw/90-hantek.rules.in new file mode 100644 index 0000000..945d7da --- /dev/null +++ b/openhantek-extractfw/90-hantek.rules.in @@ -0,0 +1,23 @@ +# Hantek DSO-2090 +SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="4b4/2090/*", RUN+="/sbin/fxload -t fx2 -I @hantekfirmwaredir@/dso2090-firmware.hex -s @hantekfirmwaredir@/dso2090-loader.hex -D $env{DEVNAME}" +SYSFS{idVendor}=="04b5", SYSFS{idProduct}=="2090", MODE="0660", GROUP="plugdev" + +# Hantek DSO-2100 +SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="547/1006/*", RUN+="/sbin/fxload -t an21 -I @hantekfirmwaredir@/dso2100-firmware.hex -s @hantekfirmwaredir@/dso2100-loader.hex -D $env{DEVNAME}" +SYSFS{idVendor}=="0547", SYSFS{idProduct}=="1002", MODE="0660", GROUP="plugdev" + +# Hantek DSO-2150 +SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="4b4/2150/*", RUN+="/sbin/fxload -t fx2 -I @hantekfirmwaredir@/dso2150-firmware.hex -s @hantekfirmwaredir@/dso2150-loader.hex -D $env{DEVNAME}" +SYSFS{idVendor}=="04b5", SYSFS{idProduct}=="2150", MODE="0660", GROUP="plugdev" + +# Hantek DSO-2250 +SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="4b4/2250/*", RUN+="/sbin/fxload -t fx2 -I @hantekfirmwaredir@/dso2250-firmware.hex -s @hantekfirmwaredir@/dso2250-loader.hex -D $env{DEVNAME}" +SYSFS{idVendor}=="04b5", SYSFS{idProduct}=="2250", MODE="0660", GROUP="plugdev" + +# Hantek DSO-5200 +SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="4b4/5200/*", RUN+="/sbin/fxload -t fx2 -I @hantekfirmwaredir@/dso5200-firmware.hex -s @hantekfirmwaredir@/dso5200-loader.hex -D $env{DEVNAME}" +SYSFS{idVendor}=="04b5", SYSFS{idProduct}=="5200", MODE="0660", GROUP="plugdev" + +# Hantek DSO-5200A +SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="4b4/520A/*", RUN+="/sbin/fxload -t fx2 -I @hantekfirmwaredir@/dso520a-firmware.hex -s @hantekfirmwaredir@/dso520a-loader.hex -D $env{DEVNAME}" +SYSFS{idVendor}=="04b5", SYSFS{idProduct}=="520A", MODE="0660", GROUP="plugdev" diff --git a/openhantek-extractfw/ChangeLog b/openhantek-extractfw/ChangeLog index 114ddb7..cc52458 100644 --- a/openhantek-extractfw/ChangeLog +++ b/openhantek-extractfw/ChangeLog @@ -27,3 +27,8 @@ 2011-02-03 Oliver Haag * Input files are given as commandline parameters (Not hardcoded anymore) * Cleaned up the code + +2011-02-08 Oliver Haag +* Version 0.7.0: +* Renamed this extraction tool to openhantek-extractfw +* Added fwget.sh for automatic driver download and firmware extraction diff --git a/openhantek-extractfw/Makefile.am b/openhantek-extractfw/Makefile.am index bc38f1c..06d3904 100644 --- a/openhantek-extractfw/Makefile.am +++ b/openhantek-extractfw/Makefile.am @@ -1,6 +1,6 @@ METASOURCES = AUTO -dsoextractfw_LDFLAGS = $(all_libraries) -bin_PROGRAMS = dsoextractfw -dsoextractfw_LDADD = -lbfd -dsoextractfw_SOURCES = dsoextractfw.c -noinst_DATA = 90-hantek-dso.rules +bin_PROGRAMS = openhantek-extractfw +openhantek_extractfw_LDFLAGS = $(all_libraries) +openhantek_extractfw_LDADD = -lbfd +openhantek_extractfw_SOURCES = extractfw.c +noinst_DATA = 90-hantek.rules diff --git a/openhantek-extractfw/configure.in b/openhantek-extractfw/configure.in index 74a0656..38fe7f2 100644 --- a/openhantek-extractfw/configure.in +++ b/openhantek-extractfw/configure.in @@ -1,5 +1,5 @@ -AC_INIT([dsoextract], [0.6.2], [oliver.haag@gmail.com]) -AC_CONFIG_SRCDIR([dsoextractfw.c]) +AC_INIT([openhantek-extractfw], [0.7.0], [oliver.haag@gmail.com]) +AC_CONFIG_SRCDIR([extractfw.c]) # Generates a config.h #AC_CONFIG_HEADERS([config.h]) @@ -32,12 +32,12 @@ AC_ARG_WITH( [firmware-dir], [with_firmware_dir="/usr/local/share"], ) -hantekfirmwaredir="$with_firmware_dir/hantekdso" +hantekfirmwaredir="$with_firmware_dir/hantek" AC_SUBST(hantekfirmwaredir) AC_CONFIG_FILES( [Makefile] - [90-hantek-dso.rules] + [90-hantek.rules] ) AC_OUTPUT diff --git a/openhantek-extractfw/dsoextractfw.c b/openhantek-extractfw/dsoextractfw.c deleted file mode 100644 index 89ab26c..0000000 --- a/openhantek-extractfw/dsoextractfw.c +++ /dev/null @@ -1,256 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// OpenHantek -// dsoextractfw.c -// Copyright (C) 2008 Oleg Khudyakov -// prcoder@potrebitel.ru -// Copyright (C) 2010, 2011 Oliver Haag -// oliver.haag@gmail.com -// -// This program is free software: you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation, either version 3 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. -// -// You should have received a copy of the GNU General Public License along with -// this program. If not, see . -// -//////////////////////////////////////////////////////////////////////////////// - - -#include -#include -#include -#include - -#include - - -int extractFirmware(const char *filenameDriver, const char *filenameFirmware, const char *filenameLoader); -int writeIntelHex(const char *filename, unsigned char *data, unsigned int length); - -static const char *filenameEndFirmware = "-firmware.hex"; -static const char *filenameEndLoader = "-loader.hex"; -static const char *filenameEndDriver = "1.sys"; -static const char *nameTarget = "pei-i386"; -static const char *nameSection = ".data"; -static const char *nameSymbolFirmware = "_firmware"; -static const char *nameSymbolLoader = "_loader"; - - -/// \brief Parse commandline arguments. -/// \return 0 on success, negative on error. -int main(int argc, char **argv) { - char *filenameDriver, *filenameFirmware, *filenameLoader; - char *charPointer; - int prefixLength; - - if(argc < 2) { - fprintf(stderr, "Usage: %s [] []\n", argv[0]); - return -1; - } - filenameDriver = argv[1]; - - prefixLength = strlen(filenameDriver) - strlen(filenameEndDriver); - - if(argc < 3) { - // Guess correct filename for firmware - filenameFirmware = malloc(prefixLength + strlen(filenameEndFirmware) + 1); - memcpy(filenameFirmware, filenameDriver, prefixLength); - strcpy(filenameFirmware + prefixLength, filenameEndFirmware); - - // Convert filename to lowercase - charPointer = strrchr(filenameFirmware, '/'); - if(charPointer == NULL) - charPointer = filenameFirmware; - for(; *charPointer != 0; charPointer++) - *charPointer = tolower(*charPointer); - } - else { - filenameFirmware = argv[2]; - } - - if(argc < 4) { - // Guess correct filename for loader - filenameLoader = malloc(prefixLength + strlen(filenameEndLoader) + 1); - memcpy(filenameLoader, filenameDriver, prefixLength); - strcpy(filenameLoader + prefixLength, filenameEndLoader); - - // Convert filename to lowercase - charPointer = strrchr(filenameLoader, '/'); - if(charPointer == NULL) - charPointer = filenameLoader; - for(; *charPointer != 0; charPointer++) - *charPointer = tolower(*charPointer); - } - else { - filenameFirmware = argv[3]; - } - - return extractFirmware(filenameDriver, filenameFirmware, filenameLoader); -} - -/// \brief Extract firmware and loader data from original driver file. -/// \param filenameDriver Name of the original driver file. -/// \param filenameFirmware Name of the file where the firmware should be saved. -/// \param filenameDriver Name of the file where the loader should be saved. -/// \return 0 on success, negative on error. -int extractFirmware(const char *filenameDriver, const char *filenameFirmware, const char *filenameLoader) { - bfd *bfdDriver; - asection *sectionData; - - asymbol **symbols; - unsigned int symbolCount; - unsigned currentSymbol; - const char *symbolName; - - bfd_size_type offsetFirmware = 0, offsetLoader = 0; - bfd_size_type lengthFirmware = 0, lengthLoader = 0; - unsigned char *bufferFirmware, *bufferLoader; - - // Initialize bfd and open driver file - bfd_init(); - bfdDriver = bfd_openr(filenameDriver, nameTarget); - if(!bfdDriver) { - bfd_perror("Error opening file"); - return -1; - } - - if(!bfd_check_format(bfdDriver, bfd_object)) { - bfd_perror("bfd_check_format"); - bfd_close(bfdDriver); - return -2; - } - - // Search for the data section - for(sectionData = bfdDriver->sections; sectionData != NULL; sectionData = sectionData->next) - if(strcmp(sectionData->name, nameSection) == 0) - break; - if(sectionData == NULL) { - fprintf(stderr, "Section %s not found\n", nameSection); - return -3; - } - printf("Section %s found (starting at 0x%04lx, %li bytes)\n", nameSection, (unsigned long int) sectionData->filepos, (long int) sectionData->size); - - // Search for the symbols we want - symbols = malloc(bfd_get_symtab_upper_bound(bfdDriver)); - symbolCount = bfd_canonicalize_symtab(bfdDriver, symbols); - for(currentSymbol = 0; currentSymbol < symbolCount; currentSymbol++) { - symbolName = bfd_asymbol_name(symbols[currentSymbol]); - - if(strcmp(symbolName, nameSymbolFirmware) == 0) - offsetFirmware = symbols[currentSymbol]->value; - if(strcmp(symbolName, nameSymbolLoader) == 0) - offsetLoader = symbols[currentSymbol]->value; - } - free(symbols); - - // Calculate position in section and length - offsetFirmware -= sectionData->filepos; - offsetLoader -= sectionData->filepos; - lengthFirmware = offsetLoader - offsetFirmware; - lengthLoader = sectionData->size - lengthFirmware; - - printf("Symbol %s found (offset 0x%04lx, %li bytes)\n", nameSymbolFirmware, (unsigned long int) offsetFirmware, (long int) lengthFirmware); - printf("Symbol %s found (offset 0x%04lx, %li bytes)\n", nameSymbolLoader, (unsigned long int) offsetLoader, (long int) lengthLoader); - - // Extract data - bufferFirmware = malloc(lengthFirmware); - bufferLoader = malloc(lengthLoader); - if (bufferFirmware == NULL || bufferLoader == NULL) { - fprintf(stderr, "Can't allocate memory\n"); - bfd_close(bfdDriver); - return -4; - } - - if(!bfd_get_section_contents(bfdDriver, sectionData, bufferFirmware, offsetFirmware, lengthFirmware)) { - bfd_perror("Can't get firmware contents"); - bfd_close(bfdDriver); - return -5; - } - - if(!bfd_get_section_contents(bfdDriver, sectionData, bufferLoader, offsetLoader, lengthLoader)) { - bfd_perror("Can't get loader contents"); - bfd_close(bfdDriver); - return -6; - } - - printf("Saving firmware as %s\n", filenameFirmware); - writeIntelHex(filenameFirmware, bufferFirmware, lengthFirmware); - free(bufferFirmware); - - printf("Saving loader as %s\n", filenameLoader); - writeIntelHex(filenameLoader, bufferLoader, lengthLoader); - free(bufferLoader); - - bfd_close(bfdDriver); - - return 0; -} - -/// \brief Save data to a file in intel hex format. -/// \param filename Name of the output file. -/// \param data Pointer to the binary data that should be stored. -/// \param length Size of the data that should be stored. -/// \return 0 on success, negative on error. -int writeIntelHex(const char *filename, unsigned char *data, unsigned int length) -{ - FILE *file; - unsigned char crc, eof; - unsigned int dataIndex, byteIndex, byteCount; - unsigned char *dataPointer; - - file = fopen(filename, "wt"); - if(!file) { - fprintf(stderr, "Can't open %s for writing\n", filename); - fclose(file); - return -1; - } - - for(dataIndex = 0; dataIndex < length; dataIndex += 22) { - eof = -1; // Always check for End of File Record - dataPointer = data + dataIndex; - - // Start code and byte count - byteCount = *dataPointer; - fprintf(file, ":%02X", byteCount); - if(byteCount != 0) - eof = 0; - crc = -*dataPointer++; - dataPointer++; - - // Address - fprintf(file, "%04X", *(unsigned short *) dataPointer); - if(*(unsigned short *) dataPointer != 0) - eof = 0; - crc -= *dataPointer++; - crc -= *dataPointer++; - - // Record type - fprintf(file, "%02X", *dataPointer); - if(*dataPointer != 0x01) - eof = 0; - crc -= *dataPointer++; - - // Data - for(byteIndex = 0; byteIndex < byteCount; byteIndex++) { - fprintf(file, "%02X", *dataPointer); - crc -= *dataPointer++; - } - - // CRC - fprintf(file, "%02X\n", crc); - - if(eof) - break; - } - - fclose(file); - - return 0; -} diff --git a/openhantek-extractfw/extractfw.c b/openhantek-extractfw/extractfw.c new file mode 100644 index 0000000..89ab26c --- /dev/null +++ b/openhantek-extractfw/extractfw.c @@ -0,0 +1,256 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// OpenHantek +// dsoextractfw.c +// Copyright (C) 2008 Oleg Khudyakov +// prcoder@potrebitel.ru +// Copyright (C) 2010, 2011 Oliver Haag +// oliver.haag@gmail.com +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . +// +//////////////////////////////////////////////////////////////////////////////// + + +#include +#include +#include +#include + +#include + + +int extractFirmware(const char *filenameDriver, const char *filenameFirmware, const char *filenameLoader); +int writeIntelHex(const char *filename, unsigned char *data, unsigned int length); + +static const char *filenameEndFirmware = "-firmware.hex"; +static const char *filenameEndLoader = "-loader.hex"; +static const char *filenameEndDriver = "1.sys"; +static const char *nameTarget = "pei-i386"; +static const char *nameSection = ".data"; +static const char *nameSymbolFirmware = "_firmware"; +static const char *nameSymbolLoader = "_loader"; + + +/// \brief Parse commandline arguments. +/// \return 0 on success, negative on error. +int main(int argc, char **argv) { + char *filenameDriver, *filenameFirmware, *filenameLoader; + char *charPointer; + int prefixLength; + + if(argc < 2) { + fprintf(stderr, "Usage: %s [] []\n", argv[0]); + return -1; + } + filenameDriver = argv[1]; + + prefixLength = strlen(filenameDriver) - strlen(filenameEndDriver); + + if(argc < 3) { + // Guess correct filename for firmware + filenameFirmware = malloc(prefixLength + strlen(filenameEndFirmware) + 1); + memcpy(filenameFirmware, filenameDriver, prefixLength); + strcpy(filenameFirmware + prefixLength, filenameEndFirmware); + + // Convert filename to lowercase + charPointer = strrchr(filenameFirmware, '/'); + if(charPointer == NULL) + charPointer = filenameFirmware; + for(; *charPointer != 0; charPointer++) + *charPointer = tolower(*charPointer); + } + else { + filenameFirmware = argv[2]; + } + + if(argc < 4) { + // Guess correct filename for loader + filenameLoader = malloc(prefixLength + strlen(filenameEndLoader) + 1); + memcpy(filenameLoader, filenameDriver, prefixLength); + strcpy(filenameLoader + prefixLength, filenameEndLoader); + + // Convert filename to lowercase + charPointer = strrchr(filenameLoader, '/'); + if(charPointer == NULL) + charPointer = filenameLoader; + for(; *charPointer != 0; charPointer++) + *charPointer = tolower(*charPointer); + } + else { + filenameFirmware = argv[3]; + } + + return extractFirmware(filenameDriver, filenameFirmware, filenameLoader); +} + +/// \brief Extract firmware and loader data from original driver file. +/// \param filenameDriver Name of the original driver file. +/// \param filenameFirmware Name of the file where the firmware should be saved. +/// \param filenameDriver Name of the file where the loader should be saved. +/// \return 0 on success, negative on error. +int extractFirmware(const char *filenameDriver, const char *filenameFirmware, const char *filenameLoader) { + bfd *bfdDriver; + asection *sectionData; + + asymbol **symbols; + unsigned int symbolCount; + unsigned currentSymbol; + const char *symbolName; + + bfd_size_type offsetFirmware = 0, offsetLoader = 0; + bfd_size_type lengthFirmware = 0, lengthLoader = 0; + unsigned char *bufferFirmware, *bufferLoader; + + // Initialize bfd and open driver file + bfd_init(); + bfdDriver = bfd_openr(filenameDriver, nameTarget); + if(!bfdDriver) { + bfd_perror("Error opening file"); + return -1; + } + + if(!bfd_check_format(bfdDriver, bfd_object)) { + bfd_perror("bfd_check_format"); + bfd_close(bfdDriver); + return -2; + } + + // Search for the data section + for(sectionData = bfdDriver->sections; sectionData != NULL; sectionData = sectionData->next) + if(strcmp(sectionData->name, nameSection) == 0) + break; + if(sectionData == NULL) { + fprintf(stderr, "Section %s not found\n", nameSection); + return -3; + } + printf("Section %s found (starting at 0x%04lx, %li bytes)\n", nameSection, (unsigned long int) sectionData->filepos, (long int) sectionData->size); + + // Search for the symbols we want + symbols = malloc(bfd_get_symtab_upper_bound(bfdDriver)); + symbolCount = bfd_canonicalize_symtab(bfdDriver, symbols); + for(currentSymbol = 0; currentSymbol < symbolCount; currentSymbol++) { + symbolName = bfd_asymbol_name(symbols[currentSymbol]); + + if(strcmp(symbolName, nameSymbolFirmware) == 0) + offsetFirmware = symbols[currentSymbol]->value; + if(strcmp(symbolName, nameSymbolLoader) == 0) + offsetLoader = symbols[currentSymbol]->value; + } + free(symbols); + + // Calculate position in section and length + offsetFirmware -= sectionData->filepos; + offsetLoader -= sectionData->filepos; + lengthFirmware = offsetLoader - offsetFirmware; + lengthLoader = sectionData->size - lengthFirmware; + + printf("Symbol %s found (offset 0x%04lx, %li bytes)\n", nameSymbolFirmware, (unsigned long int) offsetFirmware, (long int) lengthFirmware); + printf("Symbol %s found (offset 0x%04lx, %li bytes)\n", nameSymbolLoader, (unsigned long int) offsetLoader, (long int) lengthLoader); + + // Extract data + bufferFirmware = malloc(lengthFirmware); + bufferLoader = malloc(lengthLoader); + if (bufferFirmware == NULL || bufferLoader == NULL) { + fprintf(stderr, "Can't allocate memory\n"); + bfd_close(bfdDriver); + return -4; + } + + if(!bfd_get_section_contents(bfdDriver, sectionData, bufferFirmware, offsetFirmware, lengthFirmware)) { + bfd_perror("Can't get firmware contents"); + bfd_close(bfdDriver); + return -5; + } + + if(!bfd_get_section_contents(bfdDriver, sectionData, bufferLoader, offsetLoader, lengthLoader)) { + bfd_perror("Can't get loader contents"); + bfd_close(bfdDriver); + return -6; + } + + printf("Saving firmware as %s\n", filenameFirmware); + writeIntelHex(filenameFirmware, bufferFirmware, lengthFirmware); + free(bufferFirmware); + + printf("Saving loader as %s\n", filenameLoader); + writeIntelHex(filenameLoader, bufferLoader, lengthLoader); + free(bufferLoader); + + bfd_close(bfdDriver); + + return 0; +} + +/// \brief Save data to a file in intel hex format. +/// \param filename Name of the output file. +/// \param data Pointer to the binary data that should be stored. +/// \param length Size of the data that should be stored. +/// \return 0 on success, negative on error. +int writeIntelHex(const char *filename, unsigned char *data, unsigned int length) +{ + FILE *file; + unsigned char crc, eof; + unsigned int dataIndex, byteIndex, byteCount; + unsigned char *dataPointer; + + file = fopen(filename, "wt"); + if(!file) { + fprintf(stderr, "Can't open %s for writing\n", filename); + fclose(file); + return -1; + } + + for(dataIndex = 0; dataIndex < length; dataIndex += 22) { + eof = -1; // Always check for End of File Record + dataPointer = data + dataIndex; + + // Start code and byte count + byteCount = *dataPointer; + fprintf(file, ":%02X", byteCount); + if(byteCount != 0) + eof = 0; + crc = -*dataPointer++; + dataPointer++; + + // Address + fprintf(file, "%04X", *(unsigned short *) dataPointer); + if(*(unsigned short *) dataPointer != 0) + eof = 0; + crc -= *dataPointer++; + crc -= *dataPointer++; + + // Record type + fprintf(file, "%02X", *dataPointer); + if(*dataPointer != 0x01) + eof = 0; + crc -= *dataPointer++; + + // Data + for(byteIndex = 0; byteIndex < byteCount; byteIndex++) { + fprintf(file, "%02X", *dataPointer); + crc -= *dataPointer++; + } + + // CRC + fprintf(file, "%02X\n", crc); + + if(eof) + break; + } + + fclose(file); + + return 0; +} diff --git a/openhantek-extractfw/fwget.sh b/openhantek-extractfw/fwget.sh new file mode 100755 index 0000000..42f3fe8 --- /dev/null +++ b/openhantek-extractfw/fwget.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +BASEURL="http://www.hantek.com.cn/Product/32Driver" +TARGETDIR="./firmware" +ARCHIVE="Driver.rar" +EXTRACTFW="openhantek-extractfw" + +if [ -x "./$EXTRACTFW" ]; then + EXTRACTFW="./$EXTRACTFW" +fi + +if [ $# -ge 1 ]; then + TARGETDIR="$1" +fi + +if [ ! -d "$TARGETDIR" ]; then + mkdir -p "$TARGETDIR" +fi + +for MODEL in "2090" "2150" "2250" "5200" "5200A"; do + echo "Downloading official drivers for DSO$MODEL..." + wget -O "$ARCHIVE" -q "$BASEURL/$MODEL/$ARCHIVE" + + echo "Extracting useful parts from driver archive..." + unrar e -inul -n"Driver/*1.*" -y "Driver.rar" "$TARGETDIR" +done + +if [ -e "$ARCHIVE" ]; then + rm "$ARCHIVE" +fi + +ORIGINALIFS="$IFS" +IFS=" +" +for FILENAME in $(find "$TARGETDIR" -iname "*.sys"); do + echo "" + echo "Extracting firmware from $FILENAME..." + "$EXTRACTFW" "$FILENAME" 2>&1 | grep -v "^BFD:.*IMAGE_SCN_MEM_NOT_PAGED" + rm "$FILENAME" +done +IFS="$ORIGINALIFS" -- libgit2 0.21.4