mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-19 04:49:38 -07:00
Add Makefile for fpga directory (Windows codepath is untested, in any case, go.bat is still there)
Retire rbt2c.pl, instead use objcopy to directly convert the .bit file into an .o that can be linked with the flash image Rename armsrc/fpga.c to armsrc/fpgaloader.c (since there is now a new fpga.o, created from fpga.bit) Remove fpgaimg.c from subversion, add fpga.bit Instead of creating fpgaimage.elf and osimage.elf separately, now create a joined fullimage.elf first (obsoleting ldscript-full), then extract only the fpga and os sections with objcopy (This creates unspecific warnings about an empty segment, need to investigate) Implement a rudimentary .bit parser in the firmware, use that to locate the bitstream in the new fpgaimage (which is just a plain copy of the fpga.bit file) and send it to the FPGA The code will check the format that's in flash and fall back to the legacy format
This commit is contained in:
parent
391a974f53
commit
e73e717239
12 changed files with 178 additions and 10651 deletions
|
@ -3,41 +3,40 @@
|
|||
APP_INCLUDES = apps.h
|
||||
|
||||
# Add the "-DWITH_LCD" flag in APP_CLFAGS to add support for LCD
|
||||
# and add SRC_LCD to SRC_MAIN
|
||||
# and add SRC_LCD to THUMBSRC
|
||||
APP_CFLAGS = -O6
|
||||
|
||||
SRC_LCD = fonts.c LCD.c
|
||||
|
||||
SRC_MAIN = start.c \
|
||||
THUMBSRC = start.c \
|
||||
appmain.c \
|
||||
fpga.c \
|
||||
lfops.c \
|
||||
iso15693.c \
|
||||
util.c \
|
||||
usb.c
|
||||
|
||||
# These are to be compiled in ARM mode
|
||||
SRC_MAIN_FAST = iso14443.c \
|
||||
iso14443a.c
|
||||
ARMSRC = iso14443.c \
|
||||
iso14443a.c \
|
||||
fpgaloader.c
|
||||
|
||||
SRC_FPGA = fpgaimg.c
|
||||
|
||||
THUMBSRC = $(SRC_MAIN) $(SRC_FPGA)
|
||||
ARMSRC = $(SRC_MAIN_FAST)
|
||||
|
||||
MAIN_OBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(SRC_MAIN) $(SRC_MAIN_FAST))
|
||||
|
||||
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}{OBJ,SRC}
|
||||
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC
|
||||
include ../common/Makefile.common
|
||||
|
||||
all: $(OBJDIR)/osimage.s19 $(OBJDIR)/fpgaimage.s19
|
||||
|
||||
$(OBJDIR)/fpgaimage.elf: $(OBJDIR)/fpgaimg.o
|
||||
$(LD) -g -Tldscript-fpga -Map=$(patsubst %.elf,%.map,$@) -o $@ $^
|
||||
$(OBJDIR)/fpga.o: fpga.bit
|
||||
$(OBJCOPY) -O elf32-littlearm -I binary -B arm --redefine-sym _binary____fpga_fpga_bit_start=_binary_fpga_bit_start --redefine-sym _binary____fpga_fpga_bit_end=_binary_fpga_bit_end --prefix-sections=fpga_bit $^ $@
|
||||
|
||||
$(OBJDIR)/osimage.elf: $(MAIN_OBJ) $(ARMLIB)/libgcc.a
|
||||
$(OBJDIR)/fullimage.elf: $(OBJDIR)/fpga.o $(THUMBOBJ) $(ARMOBJ) $(ARMLIB)/libgcc.a
|
||||
$(LD) -g -Tldscript -Map=$(patsubst %.elf,%.map,$@) -o $@ $^
|
||||
|
||||
$(OBJDIR)/fpgaimage.elf: $(OBJDIR)/fullimage.elf
|
||||
$(OBJCOPY) -F elf32-littlearm --only-section fpgaimage $^ $@
|
||||
|
||||
$(OBJDIR)/osimage.elf: $(OBJDIR)/fullimage.elf
|
||||
$(OBJCOPY) -F elf32-littlearm --remove-section fpgaimage $^ $@
|
||||
|
||||
clean:
|
||||
$(DELETE) $(OBJDIR)$(PATHSEP)*.o
|
||||
$(DELETE) $(OBJDIR)$(PATHSEP)*.elf
|
||||
|
|
10541
armsrc/fpgaimg.c
10541
armsrc/fpgaimg.c
File diff suppressed because it is too large
Load diff
|
@ -135,17 +135,10 @@ void FpgaSetupSscDma(BYTE *buf, int len)
|
|||
PDC_CONTROL(SSC_BASE) = PDC_RX_ENABLE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Download the FPGA image stored in flash (slave serial).
|
||||
//-----------------------------------------------------------------------------
|
||||
void FpgaDownloadAndGo(void)
|
||||
// Download the fpga image starting at FpgaImage and with length FpgaImageLen DWORDs (e.g. 4 bytes)
|
||||
// If bytereversal is set: reverse the byte order in each 4-byte word
|
||||
static void DownloadFPGA(const DWORD *FpgaImage, DWORD FpgaImageLen, int bytereversal)
|
||||
{
|
||||
// FPGA image lives in FLASH at base address 0x2000
|
||||
// The current board design can not accomodate anything bigger than a XC2S30
|
||||
// FPGA and the config file size is fixed at 336,768 bits = 10,524 DWORDs
|
||||
const DWORD *FpgaImage=((DWORD *)0x2000);
|
||||
const DWORD FpgaImageLen=10524;
|
||||
|
||||
int i, j;
|
||||
|
||||
PIO_OUTPUT_ENABLE = (1 << GPIO_FPGA_ON);
|
||||
|
@ -170,21 +163,128 @@ void FpgaDownloadAndGo(void)
|
|||
|
||||
for(i = 0; i < FpgaImageLen; i++) {
|
||||
DWORD v = FpgaImage[i];
|
||||
for(j = 0; j < 32; j++) {
|
||||
if(v & 0x80000000) {
|
||||
HIGH(GPIO_FPGA_DIN);
|
||||
} else {
|
||||
LOW(GPIO_FPGA_DIN);
|
||||
}
|
||||
HIGH(GPIO_FPGA_CCLK);
|
||||
LOW(GPIO_FPGA_CCLK);
|
||||
v <<= 1;
|
||||
unsigned char w;
|
||||
for(j = 0; j < 4; j++) {
|
||||
if(!bytereversal)
|
||||
w = v >>(j*8);
|
||||
else
|
||||
w = v >>((3-j)*8);
|
||||
#define SEND_BIT(x) { if(w & (1<<x) ) HIGH(GPIO_FPGA_DIN); else LOW(GPIO_FPGA_DIN); HIGH(GPIO_FPGA_CCLK); LOW(GPIO_FPGA_CCLK); }
|
||||
SEND_BIT(7);
|
||||
SEND_BIT(6);
|
||||
SEND_BIT(5);
|
||||
SEND_BIT(4);
|
||||
SEND_BIT(3);
|
||||
SEND_BIT(2);
|
||||
SEND_BIT(1);
|
||||
SEND_BIT(0);
|
||||
}
|
||||
}
|
||||
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
||||
static char *bitparse_headers_start;
|
||||
static char *bitparse_bitstream_end;
|
||||
static int bitparse_initialized;
|
||||
/* Simple Xilinx .bit parser. The file starts with the fixed opaque byte sequence
|
||||
* 00 09 0f f0 0f f0 0f f0 0f f0 00 00 01
|
||||
* After that the format is 1 byte section type (ASCII character), 2 byte length
|
||||
* (big endian), <length> bytes content. Except for section 'e' which has 4 bytes
|
||||
* length.
|
||||
*/
|
||||
static const char _bitparse_fixed_header[] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01};
|
||||
static int bitparse_init(void * start_address, void *end_address)
|
||||
{
|
||||
bitparse_initialized = 0;
|
||||
|
||||
if(memcmp(_bitparse_fixed_header, start_address, sizeof(_bitparse_fixed_header)) != 0) {
|
||||
return 0; /* Not matched */
|
||||
} else {
|
||||
bitparse_headers_start= ((char*)start_address) + sizeof(_bitparse_fixed_header);
|
||||
bitparse_bitstream_end= (char*)end_address;
|
||||
bitparse_initialized = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int bitparse_find_section(char section_name, void **section_start, unsigned int *section_length)
|
||||
{
|
||||
char *pos = bitparse_headers_start;
|
||||
int result = 0;
|
||||
|
||||
if(!bitparse_initialized) return 0;
|
||||
|
||||
while(pos < bitparse_bitstream_end) {
|
||||
char current_name = *pos++;
|
||||
unsigned int current_length = 0;
|
||||
if(current_name < 'a' || current_name > 'e') {
|
||||
/* Strange section name, abort */
|
||||
break;
|
||||
}
|
||||
current_length = 0;
|
||||
switch(current_name) {
|
||||
case 'e':
|
||||
/* Four byte length field */
|
||||
current_length += (*pos++) << 24;
|
||||
current_length += (*pos++) << 16;
|
||||
default: /* Fall through, two byte length field */
|
||||
current_length += (*pos++) << 8;
|
||||
current_length += (*pos++) << 0;
|
||||
}
|
||||
|
||||
if(current_name != 'e' && current_length > 255) {
|
||||
/* Maybe a parse error */
|
||||
break;
|
||||
}
|
||||
|
||||
if(current_name == section_name) {
|
||||
/* Found it */
|
||||
*section_start = pos;
|
||||
*section_length = current_length;
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
pos += current_length; /* Skip section */
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Find out which FPGA image format is stored in flash, then call DownloadFPGA
|
||||
// with the right parameters to download the image
|
||||
//-----------------------------------------------------------------------------
|
||||
extern char _binary_fpga_bit_start, _binary_fpga_bit_end;
|
||||
void FpgaDownloadAndGo(void)
|
||||
{
|
||||
/* Check for the new flash image format: Should have the .bit file at &_binary_fpga_bit_start
|
||||
*/
|
||||
if(bitparse_init(&_binary_fpga_bit_start, &_binary_fpga_bit_end)) {
|
||||
/* Successfully initialized the .bit parser. Find the 'e' section and
|
||||
* send its contents to the FPGA.
|
||||
*/
|
||||
void *bitstream_start;
|
||||
unsigned int bitstream_length;
|
||||
if(bitparse_find_section('e', &bitstream_start, &bitstream_length)) {
|
||||
DownloadFPGA((DWORD *)bitstream_start, bitstream_length/4, 0);
|
||||
|
||||
return; /* All done */
|
||||
}
|
||||
}
|
||||
|
||||
/* Fallback for the old flash image format: Check for the magic marker 0xFFFFFFFF
|
||||
* 0xAA995566 at address 0x2000. This is raw bitstream with a size of 336,768 bits
|
||||
* = 10,524 DWORDs, stored as DWORDS e.g. little-endian in memory, but each DWORD
|
||||
* is still to be transmitted in MSBit first order. Set the invert flag to indicate
|
||||
* that the DownloadFPGA function should invert every 4 byte sequence when doing
|
||||
* the bytewise download.
|
||||
*/
|
||||
if( *(DWORD*)0x2000 == 0xFFFFFFFF && *(DWORD*)0x2004 == 0xAA995566 )
|
||||
DownloadFPGA((DWORD *)0x2000, 10524, 1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Send a 16 bit command/data pair to the FPGA.
|
||||
// The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
|
|
@ -3,7 +3,10 @@ INCLUDE ../common/ldscript.common
|
|||
ENTRY(Vector)
|
||||
SECTIONS
|
||||
{
|
||||
.start : { obj/start.o(.text) } >osimage
|
||||
fpgaimage : {
|
||||
*(fpga_bit.data)
|
||||
} >fpgaimage
|
||||
.start : { *(.startos) } >osimage
|
||||
.text : {
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
INCLUDE ../common/ldscript.common
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
fpgaimage : {
|
||||
obj/fpgaimg.o(.text) *(.text)
|
||||
*(.rodata)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
} >fpgaimage
|
||||
.data : { *(.data) } >ram
|
||||
__bss_start__ = .;
|
||||
.bss : { *(.bss) } >ram
|
||||
__bss_end__ = .;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
SECTIONS
|
||||
{
|
||||
. = 0x00002000;
|
||||
.fpga : { obj/fpgaimg.o(.rodata) }
|
||||
. = 0x00010000;
|
||||
.start : { obj/start.o(.text) }
|
||||
.text : { *(.text) }
|
||||
.rodata : { *(.rodata) }
|
||||
. = 0x00200000;
|
||||
.data : { *(.data) }
|
||||
__bss_start__ = .;
|
||||
.bss : { *(.bss) }
|
||||
__bss_end__ = .;
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
#include <proxmark3.h>
|
||||
#include "apps.h"
|
||||
|
||||
void Vector(void)
|
||||
void __attribute__((section(".startos"))) Vector(void)
|
||||
{
|
||||
AppMain();
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ ARMSRC = fromflash.c
|
|||
THUMBSRC = usb.c bootrom.c
|
||||
ASMSRC = ram-reset.s flash-reset.s
|
||||
|
||||
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}{OBJ,SRC}
|
||||
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC
|
||||
include ../common/Makefile.common
|
||||
|
||||
all: $(OBJDIR)/bootrom.s19
|
||||
|
|
|
@ -46,8 +46,8 @@ OBJDIR = obj
|
|||
|
||||
INCLUDE = -I../include
|
||||
|
||||
# Also search prerequisites in the common directory (for usb.c)
|
||||
VPATH = . ../common/
|
||||
# Also search prerequisites in the common directory (for usb.c), and the fpga directory (for fpga.bit)
|
||||
VPATH = . ../common/ ../fpga/
|
||||
|
||||
INCLUDES = ../include/proxmark3.h ../include/at91sam7s128.h ../include/config_gpio.h ../include/usb_cmd.h $(APP_INCLUDES)
|
||||
|
||||
|
|
36
fpga/Makefile
Normal file
36
fpga/Makefile
Normal file
|
@ -0,0 +1,36 @@
|
|||
include ../common/Makefile.common
|
||||
|
||||
all: fpga.ngc fpga.ngd fpga.ncd fpga-placed.ncd fpga.bit
|
||||
clean:
|
||||
$(DELETE) fpga.bgn fpga.drc fpga.ncd fpga.ngd fpga_par.xrpt fpga-placed.pad fpga-placed.par fpga-placed.xpi fpga_usage.xml xlnx_auto_0.ise xst.srp
|
||||
$(DELETE) fpga.bit fpga.map fpga.ngc fpga_ngdbuild.xrpt fpga.pcf fpga-placed_pad.csv fpga-placed.ptwx fpga.rbt xlnx_auto_0_xdb
|
||||
$(DELETE) fpga.bld fpga.mrp fpga.ngc_xst.xrpt fpga.ngm fpga-placed.ncd fpga-placed_pad.txt fpga-placed.unroutes fpga_summary.xml netlist.lst xst
|
||||
|
||||
fpga.ngc: fpga.v fpga.ucf xst.scr util.v lo_simulate.v lo_read.v lo_passthru.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v
|
||||
$(DELETE) fpga.ngc
|
||||
$(XILINX_TOOLS_PREFIX)xst -ifn xst.scr
|
||||
|
||||
fpga.ngd: fpga.ngc
|
||||
$(DELETE) fpga.ngd
|
||||
$(XILINX_TOOLS_PREFIX)ngdbuild -aul -p xc2s30-6vq100 -nt timestamp -uc fpga.ucf fpga.ngc fpga.ngd
|
||||
|
||||
fpga.ncd: fpga.ngd
|
||||
$(DELETE) fpga.ncd
|
||||
$(XILINX_TOOLS_PREFIX)map -p xc2s30-6vq100 fpga.ngd
|
||||
|
||||
fpga-placed.ncd: fpga.ncd
|
||||
$(DELETE) fpga-placed.ncd
|
||||
$(XILINX_TOOLS_PREFIX)par fpga.ncd fpga-placed.ncd
|
||||
|
||||
fpga.bit: fpga-placed.ncd
|
||||
$(DELETE) fpga.bit fpga.drc fpga.rbt
|
||||
$(XILINX_TOOLS_PREFIX)bitgen fpga-placed.ncd fpga.bit
|
||||
|
||||
|
||||
.PHONY: all clean help
|
||||
help:
|
||||
@echo Multi-OS Makefile, you are running on $(DETECTED_OS)
|
||||
@echo Possible targets:
|
||||
@echo + all - Make fpga.bti, the FPGA bitstream
|
||||
@echo + clean - Clean intermediate files
|
||||
|
BIN
fpga/fpga.bit
Normal file
BIN
fpga/fpga.bit
Normal file
Binary file not shown.
|
@ -1,41 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# This tool converts a Xilinx xxx.rbt FPGA bitstream to a table that will
|
||||
# compile as C source code. The output format is DWORDs, MSB first.
|
||||
|
||||
local $/ = "\r\n";
|
||||
|
||||
print "// Generated by rbt2c.pl, do not edit!\n\n";
|
||||
|
||||
for(1..7) {
|
||||
chomp($_ = <>);
|
||||
print "//// $_\n";
|
||||
}
|
||||
|
||||
print <<EOT;
|
||||
|
||||
#include <proxmark3.h>
|
||||
|
||||
const DWORD FpgaImage[] = {
|
||||
EOT
|
||||
|
||||
while(<>) {
|
||||
chomp;
|
||||
$v = 0;
|
||||
for $b (split(//, $_)) {
|
||||
$v <<= 1;
|
||||
if($b eq '1') {
|
||||
$v |= 1;
|
||||
} elsif($b ne '0') {
|
||||
die;
|
||||
}
|
||||
}
|
||||
printf("\t0x%08x,\n", $v);
|
||||
}
|
||||
|
||||
print <<EOT;
|
||||
};
|
||||
|
||||
const DWORD FpgaImageLen = sizeof(FpgaImage) / sizeof(FpgaImage[0]);
|
||||
|
||||
EOT
|
Loading…
Add table
Add a link
Reference in a new issue