add lz4 to arm side

This commit is contained in:
slurdge 2020-06-05 16:24:05 +02:00
parent cb03286420
commit 1a8eff5d42
5 changed files with 78 additions and 79 deletions

View file

@ -75,13 +75,13 @@ include Standalone/Makefile.inc
#the FPGA bitstream files. Note: order matters!
FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit
#the zlib source files required for decompressing the fpga config at run time
SRC_ZLIB = inflate.c inffast.c inftrees.c adler32.c zutil.c
#additional defines required to compile zlib
ZLIB_CFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED
APP_CFLAGS += $(ZLIB_CFLAGS)
# zlib includes:
APP_CFLAGS += -I../common/zlib
#the lz4 source files required for decompressing the fpga config at run time
SRC_LZ4 = lz4.c
#additional defines required to compile lz4
LZ4_CFLAGS = -DNEED_MEMMOVE -DLZ4_MEMORY_USAGE=8
APP_CFLAGS += $(LZ4_CFLAGS)
# lz4 includes:
APP_CFLAGS += -I../common/lz4
# stdint.h provided locally until GCC 4.5 becomes C99 compliant,
# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc
@ -93,7 +93,7 @@ THUMBSRC = start.c \
$(SRC_ISO15693) \
$(SRC_NFCBARCODE) \
$(SRC_LF) \
$(SRC_ZLIB) \
$(SRC_LZ4) \
$(SRC_LEGIC) \
$(SRC_FLASH) \
$(SRC_SMARTCARD) \

View file

@ -17,10 +17,19 @@
#include "ticks.h"
#include "dbprint.h"
#include "util.h"
#include "zlib.h"
#include "fpga.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
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 uint32_t uncompressed_bytes_cnt;
#define OUTPUT_BUFFER_LEN 80
//-----------------------------------------------------------------------------
// Set up the Serial Peripheral Interface as master
// 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
// each call.
//----------------------------------------------------------------------------
static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data
compressed_fpga_stream->next_out = output_buffer;
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
static int get_from_fpga_combined_stream(lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
if (fpga_image_ptr == output_buffer + FPGA_RING_BUFFER_BYTES) { // need more data
fpga_image_ptr = output_buffer;
int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH);
if (res != Z_OK)
Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg);
if (res < 0)
int cmp_bytes = *(compressed_fpga_stream->next_in + 3);
cmp_bytes = (cmp_bytes << 8) + *(compressed_fpga_stream->next_in+2);
cmp_bytes = (cmp_bytes << 8) + *(compressed_fpga_stream->next_in+1);
cmp_bytes = (cmp_bytes << 8) + *(compressed_fpga_stream->next_in+0);
compressed_fpga_stream->next_in += 4;
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;
}
compressed_fpga_stream->next_in += cmp_bytes;
}
uncompressed_bytes_cnt++;
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:
// 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)) {
// skip undesired data belonging to other bitstream_versions
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);
}
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
//----------------------------------------------------------------------------
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];
uncompressed_bytes_cnt = 0;
// 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->next_out = output_buffer;
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
compressed_fpga_stream->zalloc = &fpga_inflate_malloc;
compressed_fpga_stream->zfree = &fpga_inflate_free;
int res = inflateInit2(compressed_fpga_stream, 0);
if (res < 0)
int res = LZ4_setStreamDecode(compressed_fpga_stream->lz4StreamDecode, NULL, 0);
if (res == 0)
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++)
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
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;
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
* 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;
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
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_wtx(1500);
z_stream compressed_fpga_stream;
uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};
bool verbose = (DBGLEVEL > 3);
@ -416,6 +414,11 @@ void FpgaDownloadAndGo(int bitstream_version) {
BigBuf_free();
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))
return;
@ -425,8 +428,6 @@ void FpgaDownloadAndGo(int bitstream_version) {
downloaded_bitstream = bitstream_version;
}
inflateEnd(&compressed_fpga_stream);
// turn off antenna
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);

View file

@ -14,49 +14,28 @@
#include "proxmark3_arm.h"
#include "appmain.h"
#include "zlib.h"
#include "lz4.h"
#include "BigBuf.h"
static uint8_t *next_free_memory;
extern struct common_area common_area;
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) {
z_stream data_section;
next_free_memory = BigBuf_get_addr();
// initialize zstream structure
data_section.next_in = (uint8_t *) &__data_src_start__;
data_section.avail_in = &__data_end__ - &__data_start__; // uncompressed size. Wrong but doesn't matter.
data_section.next_out = (uint8_t *) &__data_start__;
data_section.avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct.
data_section.zalloc = &inflate_malloc;
data_section.zfree = &inflate_free;
data_section.opaque = NULL;
int avail_in = *(&__data_start__ + 3);
avail_in = (avail_in << 8) + *(&__data_start__+2);
avail_in = (avail_in << 8) + *(&__data_start__+1);
avail_in = (avail_in << 8) + *(&__data_start__+0); // compressed size. Correct.
int avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct.
// uncompress data segment to RAM
int res = LZ4_decompress_safe(&__data_src_start__ + 4, &__data_start__, avail_in, avail_out);
// initialize zlib for inflate
int res = inflateInit2(&data_section, 15);
if (res < 0)
return;
// uncompress data segment to RAM
inflate(&data_section, Z_FINISH);
// 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);

View file

@ -182,6 +182,25 @@
#include <string.h> /* memset, memcpy */
#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

View file

@ -35,7 +35,7 @@ OBJDIR = obj
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
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