From: Stephan Baerwolf Date: Fri, 14 Mar 2014 10:55:21 +0000 (+0100) Subject: introduce new feature for the updater: UPDATECRC32 X-Git-Tag: testing-head~1 X-Git-Url: http://git.linex4red.de/pub/USBaspLoader.git/commitdiff_plain/360bfa6d963be278944fdf71e58591af6d79e95b?ds=inline introduce new feature for the updater: UPDATECRC32 In the head of Makefile.inc you now can configure "UPDATECRC32" to enable the updater to check integrity of the new firmware image. The CRC32 of polynomial 0xEDB88320 is used. This CRC is the same, the non-volatile-memory controller of ATxmega series is using. Enabling this feature will only increase the update by a few bytes (~180bytes) , but will offer more safety against bogus images. By default the CRC is NOT used, but it can be enabled to a fix value or calculated automatically during compile. Signed-off-by: Stephan Baerwolf --- diff --git a/Makefile.inc b/Makefile.inc index dd9526a..34225c3 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -11,6 +11,9 @@ DEVICE = atmega8 # where the updating firmware should be located (starting address) FLASHADDRESS = 0x0000 +# use any fix (ATxmega compatible) crc32, uncomment to disable feature or set automatically with value "0" +;UPDATECRC32 = 0 + # some MCU independent defines... #...will be extended within MCU dependend configuration below... DEFINES += -DCONFIG_NO__CHIP_ERASE -DCONFIG_NO__ONDEMAND_PAGEERASE diff --git a/updater/Makefile b/updater/Makefile index a1bc14d..db0cd8c 100644 --- a/updater/Makefile +++ b/updater/Makefile @@ -57,7 +57,15 @@ usbasploader.o: usbasploader.raw $(DEPENDS) updater.o: updater.c usbasploader.h usbasploader.raw usbasploader.o $(DEPENDS) +ifndef UPDATECRC32 $(CC) updater.c -c -o updater.o -DSIZEOF_new_firmware=$(shell stat -c %s usbasploader.raw) $(CFLAGS) +else +ifeq ($(UPDATECRC32), 0) + $(CC) updater.c -c -o updater.o -DSIZEOF_new_firmware=$(shell stat -c %s usbasploader.raw) -DUPDATECRC32=0x$(shell crc32 usbasploader.raw) $(CFLAGS) +else + $(CC) updater.c -c -o updater.o -DSIZEOF_new_firmware=$(shell stat -c %s usbasploader.raw) -DUPDATECRC32=$(UPDATECRC32) $(CFLAGS) +endif +endif # $(CC) updater.c -c -o updater.o $(CFLAGS) updater.elf: updater.o usbasploader.o $(DEPENDS) diff --git a/updater/crccheck.c b/updater/crccheck.c new file mode 100644 index 0000000..798c37a --- /dev/null +++ b/updater/crccheck.c @@ -0,0 +1,36 @@ +/****************************************************************************/ +/* CRC32 stuff taken and adapted from lib_crc version 1.16 : */ +/* Library : lib_crc */ +/* File : lib_crc.c */ +/* Author : Lammert Bies 1999-2008 */ +/* E-mail : info@lammertbies.nl */ +/****************************************************************************/ + +/* the ATxmega series NVM CRC compatible polynom */ +/* on ATxmega you can do this much faster in hardware */ +#define P_32 0xEDB88320L +#define D_32 0xFFFFFFFFL + +uint32_t crc_tab32_value(uint8_t address) { + uint32_t result; + uint8_t j; + + result = (uint32_t)address & 0xffL; + for (j=0; j<8; j++) { + if (result & 0x00000001L) result = (result >> 1) ^ P_32; + else result = result >> 1; + } + + return result; +} + +uint32_t update_crc_32(uint32_t crc, uint8_t c) { + uint32_t tmp, long_c; + + long_c = (uint32_t)c & 0xffL; + + tmp = crc ^ long_c; + crc = (crc >> 8) ^ crc_tab32_value(tmp & 0xffL); + + return crc; +} diff --git a/updater/updater.c b/updater/updater.c index f61b345..479df80 100644 --- a/updater/updater.c +++ b/updater/updater.c @@ -271,15 +271,38 @@ size_t mypgm_WRITEpage(const mypgm_addr_t byteaddress,const void* buffer, const } #endif +#if defined(UPDATECRC32) +#include "crccheck.c" +#endif + // #pragma GCC diagnostic ignored "-Wno-pointer-to-int-cast" int main(void) { +#if defined(UPDATECRC32) + uint32_t crcval; +#endif size_t i; uint8_t buffer[SPM_PAGESIZE]; wdt_disable(); cli(); +#if defined(UPDATECRC32) + // check if new firmware-image is corrupted + crcval = D_32; + for (i=0;i 65535) + crcval = update_crc_32(crcval, pgm_read_byte_far(FULLCORRECTFLASHADDRESS(&new_firmware[i]))); +#else + crcval = update_crc_32(crcval, pgm_read_byte(FULLCORRECTFLASHADDRESS(&new_firmware[i]))); +#endif + } + crcval ^= D_32; + + // allow to change the firmware + if (crcval == ((uint32_t)UPDATECRC32)) { +#endif + // check if firmware would change... buffer[0]=0; for (i=0;i