mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
add lz4 to arm side
This commit is contained in:
parent
cb03286420
commit
1a8eff5d42
5 changed files with 78 additions and 79 deletions
|
@ -75,13 +75,13 @@ include Standalone/Makefile.inc
|
||||||
#the FPGA bitstream files. Note: order matters!
|
#the FPGA bitstream files. Note: order matters!
|
||||||
FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit
|
FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit
|
||||||
|
|
||||||
#the zlib source files required for decompressing the fpga config at run time
|
#the lz4 source files required for decompressing the fpga config at run time
|
||||||
SRC_ZLIB = inflate.c inffast.c inftrees.c adler32.c zutil.c
|
SRC_LZ4 = lz4.c
|
||||||
#additional defines required to compile zlib
|
#additional defines required to compile lz4
|
||||||
ZLIB_CFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED
|
LZ4_CFLAGS = -DNEED_MEMMOVE -DLZ4_MEMORY_USAGE=8
|
||||||
APP_CFLAGS += $(ZLIB_CFLAGS)
|
APP_CFLAGS += $(LZ4_CFLAGS)
|
||||||
# zlib includes:
|
# lz4 includes:
|
||||||
APP_CFLAGS += -I../common/zlib
|
APP_CFLAGS += -I../common/lz4
|
||||||
|
|
||||||
# stdint.h provided locally until GCC 4.5 becomes C99 compliant,
|
# stdint.h provided locally until GCC 4.5 becomes C99 compliant,
|
||||||
# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc
|
# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc
|
||||||
|
@ -93,7 +93,7 @@ THUMBSRC = start.c \
|
||||||
$(SRC_ISO15693) \
|
$(SRC_ISO15693) \
|
||||||
$(SRC_NFCBARCODE) \
|
$(SRC_NFCBARCODE) \
|
||||||
$(SRC_LF) \
|
$(SRC_LF) \
|
||||||
$(SRC_ZLIB) \
|
$(SRC_LZ4) \
|
||||||
$(SRC_LEGIC) \
|
$(SRC_LEGIC) \
|
||||||
$(SRC_FLASH) \
|
$(SRC_FLASH) \
|
||||||
$(SRC_SMARTCARD) \
|
$(SRC_SMARTCARD) \
|
||||||
|
|
|
@ -17,10 +17,19 @@
|
||||||
#include "ticks.h"
|
#include "ticks.h"
|
||||||
#include "dbprint.h"
|
#include "dbprint.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "zlib.h"
|
|
||||||
#include "fpga.h"
|
#include "fpga.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
|
#include "lz4.h" // uncompress
|
||||||
|
|
||||||
|
typedef struct lz4_stream_s {
|
||||||
|
LZ4_streamDecode_t* lz4StreamDecode;
|
||||||
|
char * next_in;
|
||||||
|
int avail_in;
|
||||||
|
} lz4_stream;
|
||||||
|
|
||||||
|
typedef lz4_stream* lz4_streamp;
|
||||||
|
|
||||||
// remember which version of the bitstream we have already downloaded to the FPGA
|
// remember which version of the bitstream we have already downloaded to the FPGA
|
||||||
static int downloaded_bitstream = 0;
|
static int downloaded_bitstream = 0;
|
||||||
|
|
||||||
|
@ -30,8 +39,6 @@ extern uint8_t _binary_obj_fpga_all_bit_z_start, _binary_obj_fpga_all_bit_z_end;
|
||||||
static uint8_t *fpga_image_ptr = NULL;
|
static uint8_t *fpga_image_ptr = NULL;
|
||||||
static uint32_t uncompressed_bytes_cnt;
|
static uint32_t uncompressed_bytes_cnt;
|
||||||
|
|
||||||
#define OUTPUT_BUFFER_LEN 80
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Set up the Serial Peripheral Interface as master
|
// Set up the Serial Peripheral Interface as master
|
||||||
// Used to write the FPGA config word
|
// Used to write the FPGA config word
|
||||||
|
@ -180,18 +187,25 @@ bool FpgaSetupSscDma(uint8_t *buf, int len) {
|
||||||
// Uncompress (inflate) the FPGA data. Returns one decompressed byte with
|
// Uncompress (inflate) the FPGA data. Returns one decompressed byte with
|
||||||
// each call.
|
// each call.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
static int get_from_fpga_combined_stream(lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||||
if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data
|
if (fpga_image_ptr == output_buffer + FPGA_RING_BUFFER_BYTES) { // need more data
|
||||||
compressed_fpga_stream->next_out = output_buffer;
|
|
||||||
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
|
||||||
fpga_image_ptr = output_buffer;
|
fpga_image_ptr = output_buffer;
|
||||||
int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH);
|
int cmp_bytes = *(compressed_fpga_stream->next_in + 3);
|
||||||
|
cmp_bytes = (cmp_bytes << 8) + *(compressed_fpga_stream->next_in+2);
|
||||||
if (res != Z_OK)
|
cmp_bytes = (cmp_bytes << 8) + *(compressed_fpga_stream->next_in+1);
|
||||||
Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg);
|
cmp_bytes = (cmp_bytes << 8) + *(compressed_fpga_stream->next_in+0);
|
||||||
|
compressed_fpga_stream->next_in += 4;
|
||||||
if (res < 0)
|
compressed_fpga_stream->avail_in -= cmp_bytes + 4;
|
||||||
|
int res = LZ4_decompress_safe_continue(compressed_fpga_stream->lz4StreamDecode,
|
||||||
|
compressed_fpga_stream->next_in,
|
||||||
|
(char*)output_buffer,
|
||||||
|
cmp_bytes,
|
||||||
|
FPGA_RING_BUFFER_BYTES);
|
||||||
|
if (res <= 0) {
|
||||||
|
Dbprintf("inflate returned: %d", res);
|
||||||
return res;
|
return res;
|
||||||
|
}
|
||||||
|
compressed_fpga_stream->next_in += cmp_bytes;
|
||||||
}
|
}
|
||||||
uncompressed_bytes_cnt++;
|
uncompressed_bytes_cnt++;
|
||||||
return *fpga_image_ptr++;
|
return *fpga_image_ptr++;
|
||||||
|
@ -202,7 +216,7 @@ static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8
|
||||||
// are combined into one big file:
|
// are combined into one big file:
|
||||||
// 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc.
|
// 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
static int get_from_fpga_stream(int bitstream_version, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||||
while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % g_fpga_bitstream_num != (bitstream_version - 1)) {
|
while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % g_fpga_bitstream_num != (bitstream_version - 1)) {
|
||||||
// skip undesired data belonging to other bitstream_versions
|
// skip undesired data belonging to other bitstream_versions
|
||||||
get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
|
get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
|
||||||
|
@ -211,37 +225,23 @@ static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga
|
||||||
return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
|
return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static voidpf fpga_inflate_malloc(voidpf opaque, uInt items, uInt size) {
|
|
||||||
return BigBuf_malloc(items * size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// free eventually allocated BigBuf memory
|
|
||||||
static void fpga_inflate_free(voidpf opaque, voidpf address) {
|
|
||||||
BigBuf_free();
|
|
||||||
BigBuf_Clear_ext(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Initialize decompression of the respective (HF or LF) FPGA stream
|
// Initialize decompression of the respective (HF or LF) FPGA stream
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
static bool reset_fpga_stream(int bitstream_version, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||||
uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
|
uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
|
||||||
|
|
||||||
uncompressed_bytes_cnt = 0;
|
uncompressed_bytes_cnt = 0;
|
||||||
|
|
||||||
// initialize z_stream structure for inflate:
|
// initialize z_stream structure for inflate:
|
||||||
compressed_fpga_stream->next_in = &_binary_obj_fpga_all_bit_z_start;
|
compressed_fpga_stream->next_in = (char*)&_binary_obj_fpga_all_bit_z_start;
|
||||||
compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start;
|
compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start;
|
||||||
compressed_fpga_stream->next_out = output_buffer;
|
|
||||||
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
int res = LZ4_setStreamDecode(compressed_fpga_stream->lz4StreamDecode, NULL, 0);
|
||||||
compressed_fpga_stream->zalloc = &fpga_inflate_malloc;
|
if (res == 0)
|
||||||
compressed_fpga_stream->zfree = &fpga_inflate_free;
|
|
||||||
|
|
||||||
int res = inflateInit2(compressed_fpga_stream, 0);
|
|
||||||
if (res < 0)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fpga_image_ptr = output_buffer;
|
fpga_image_ptr = output_buffer + FPGA_RING_BUFFER_BYTES;
|
||||||
|
|
||||||
for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++)
|
for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++)
|
||||||
header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||||
|
@ -266,7 +266,7 @@ static void DownloadFPGA_byte(uint8_t w) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download the fpga image starting at current stream position with length FpgaImageLen bytes
|
// Download the fpga image starting at current stream position with length FpgaImageLen bytes
|
||||||
static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
static void DownloadFPGA(int bitstream_version, int FpgaImageLen, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON;
|
AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON;
|
||||||
|
@ -348,7 +348,7 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp comp
|
||||||
* (big endian), <length> bytes content. Except for section 'e' which has 4 bytes
|
* (big endian), <length> bytes content. Except for section 'e' which has 4 bytes
|
||||||
* length.
|
* length.
|
||||||
*/
|
*/
|
||||||
static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
|
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
|
||||||
uint16_t numbytes = 0;
|
uint16_t numbytes = 0;
|
||||||
|
@ -407,8 +407,6 @@ void FpgaDownloadAndGo(int bitstream_version) {
|
||||||
|
|
||||||
// Send waiting time extension request as this will take a while
|
// Send waiting time extension request as this will take a while
|
||||||
send_wtx(1500);
|
send_wtx(1500);
|
||||||
z_stream compressed_fpga_stream;
|
|
||||||
uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};
|
|
||||||
|
|
||||||
bool verbose = (DBGLEVEL > 3);
|
bool verbose = (DBGLEVEL > 3);
|
||||||
|
|
||||||
|
@ -416,6 +414,11 @@ void FpgaDownloadAndGo(int bitstream_version) {
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
BigBuf_Clear_ext(verbose);
|
BigBuf_Clear_ext(verbose);
|
||||||
|
|
||||||
|
lz4_stream compressed_fpga_stream;
|
||||||
|
LZ4_streamDecode_t lz4StreamDecode_body = {{ 0 }};
|
||||||
|
compressed_fpga_stream.lz4StreamDecode = &lz4StreamDecode_body;
|
||||||
|
uint8_t * output_buffer = BigBuf_malloc(FPGA_RING_BUFFER_BYTES);
|
||||||
|
|
||||||
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer))
|
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -425,8 +428,6 @@ void FpgaDownloadAndGo(int bitstream_version) {
|
||||||
downloaded_bitstream = bitstream_version;
|
downloaded_bitstream = bitstream_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
inflateEnd(&compressed_fpga_stream);
|
|
||||||
|
|
||||||
// turn off antenna
|
// turn off antenna
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
|
||||||
|
|
|
@ -14,49 +14,28 @@
|
||||||
|
|
||||||
#include "proxmark3_arm.h"
|
#include "proxmark3_arm.h"
|
||||||
#include "appmain.h"
|
#include "appmain.h"
|
||||||
#include "zlib.h"
|
#include "lz4.h"
|
||||||
#include "BigBuf.h"
|
#include "BigBuf.h"
|
||||||
|
|
||||||
static uint8_t *next_free_memory;
|
static uint8_t *next_free_memory;
|
||||||
extern struct common_area common_area;
|
extern struct common_area common_area;
|
||||||
extern char __data_src_start__, __data_start__, __data_end__, __bss_start__, __bss_end__;
|
extern char __data_src_start__, __data_start__, __data_end__, __bss_start__, __bss_end__;
|
||||||
|
|
||||||
static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size) {
|
|
||||||
uint8_t *allocated_memory;
|
|
||||||
|
|
||||||
allocated_memory = next_free_memory;
|
|
||||||
next_free_memory += items * size;
|
|
||||||
return allocated_memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void inflate_free(voidpf opaque, voidpf address) {
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
static void uncompress_data_section(void) {
|
static void uncompress_data_section(void) {
|
||||||
z_stream data_section;
|
|
||||||
|
|
||||||
next_free_memory = BigBuf_get_addr();
|
next_free_memory = BigBuf_get_addr();
|
||||||
|
|
||||||
// initialize zstream structure
|
int avail_in = *(&__data_start__ + 3);
|
||||||
data_section.next_in = (uint8_t *) &__data_src_start__;
|
avail_in = (avail_in << 8) + *(&__data_start__+2);
|
||||||
data_section.avail_in = &__data_end__ - &__data_start__; // uncompressed size. Wrong but doesn't matter.
|
avail_in = (avail_in << 8) + *(&__data_start__+1);
|
||||||
data_section.next_out = (uint8_t *) &__data_start__;
|
avail_in = (avail_in << 8) + *(&__data_start__+0); // compressed size. Correct.
|
||||||
data_section.avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct.
|
int avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct.
|
||||||
data_section.zalloc = &inflate_malloc;
|
// uncompress data segment to RAM
|
||||||
data_section.zfree = &inflate_free;
|
int res = LZ4_decompress_safe(&__data_src_start__ + 4, &__data_start__, avail_in, avail_out);
|
||||||
data_section.opaque = NULL;
|
|
||||||
|
|
||||||
// initialize zlib for inflate
|
|
||||||
int res = inflateInit2(&data_section, 15);
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// uncompress data segment to RAM
|
|
||||||
inflate(&data_section, Z_FINISH);
|
|
||||||
|
|
||||||
// save the size of the compressed data section
|
// save the size of the compressed data section
|
||||||
common_area.arg1 = data_section.total_in;
|
common_area.arg1 = res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__((section(".startos"))) Vector(void);
|
void __attribute__((section(".startos"))) Vector(void);
|
||||||
|
|
|
@ -182,6 +182,25 @@
|
||||||
#include <string.h> /* memset, memcpy */
|
#include <string.h> /* memset, memcpy */
|
||||||
#define MEM_INIT(p,v,s) memset((p),(v),(s))
|
#define MEM_INIT(p,v,s) memset((p),(v),(s))
|
||||||
|
|
||||||
|
#ifdef NEED_MEMMOVE
|
||||||
|
void *
|
||||||
|
memmove (void *dest, const void *src, size_t len)
|
||||||
|
{
|
||||||
|
char *d = dest;
|
||||||
|
const char *s = src;
|
||||||
|
if (d < s)
|
||||||
|
while (len--)
|
||||||
|
*d++ = *s++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *lasts = (char*)s + (len-1);
|
||||||
|
char *lastd = d + (len-1);
|
||||||
|
while (len--)
|
||||||
|
*lastd-- = *lasts--;
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
* Common Constants
|
* Common Constants
|
||||||
|
|
|
@ -35,7 +35,7 @@ OBJDIR = obj
|
||||||
INCLUDE = -I../include -I../common_arm -I../common_fpga -I../common -I.
|
INCLUDE = -I../include -I../common_arm -I../common_fpga -I../common -I.
|
||||||
|
|
||||||
# Also search prerequisites in the common directory (for usb.c), the fpga directory (for fpga.bit), and the zlib directory
|
# Also search prerequisites in the common directory (for usb.c), the fpga directory (for fpga.bit), and the zlib directory
|
||||||
VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/zlib ../fpga ../armsrc/Standalone
|
VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/lz4 ../fpga ../armsrc/Standalone
|
||||||
|
|
||||||
INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h
|
INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue