c - Dump Flash Memory through a single GPIO pin -
i'm working infineon's xmc4500 relax kit , i'm trying extract firmware through single gpio pin.
my naive idea dump 1 bit @ time through gpio pin , somehow "sniff" data logic analyzer.
pseudocode:
while(word word memory copy hasn't finished) ... register = value; temp_value = value , 0x1; pin = temp_value; value = value >> 1; ...
am on right track? have better/nicer idea how archive this?
### edit ###
actually requirement of (shell)code needs tiny. found this nifty trick on how dump firmware blinking leds.
however i'm struggling receive correct values saleae logic analyzer.
basically i'm doing is:
- setup gpio pin directions output
- blink led1 (pin 1.1) clock (spi serial clock)
- blink led2 (pin 1.0) data bits (spi mosi)
- sniff pins logic analyzer
here's c code:
#include "xmc4500.h" #define del 1260 void init() { // p1.0 output, push pull port1->iocr0 = 0x80ul << 0; // p1.1 output, push pull port1->iocr0 |= 0x80ul << 8; } void delay(int i) { while(--i) { asm("nop\n"); asm("nop\n"); } } // sets pin high // p1.0 = spi mosi // p1.1 = spi clock void output_high(int i) { // p1.0 high if(i == 0) { port1->out |= 0x1ul; } // p1.1 high if(i == 1) { port1->out |= 0x2ul; } } // sets pin low // p1.0 = spi mosi // p1.1 = spi clock void output_low(int i) { // p1.0 low if(i == 0) { port1->out &= (~0x1ul); } // p1.1 low if(i == 1) { port1->out &= (~0x2ul); } } // spi bit banging void spi_send_byte(unsigned char data) { int i; // send bits 7..0 (i = 0; < 8; i++) { // sets p1.1 low (serial clock) output_low(1); // consider leftmost bit // set line high if bit 1, low if bit 0 if (data & 0x80) // sets p1.0 high (mosi) output_high(0); else // sets p1.0 low (mosi) output_low(0); delay(del); // sets p1.1 high (serial clock) output_high(1); // shift byte left next bit leftmost data <<= 1; } } int main() { init(); while(1) { spi_send_byte('t'); spi_send_byte('e'); spi_send_byte('s'); spi_send_byte('t'); } return 0; }
### 2nd edit ###
dumping flash memory working fine following code:
#include "xmc4500.h" // spi bit banging void spi_send_word(uint32_t data) { int i; // lsb first, 32 bits per transfer (i = 0; < 32; i++) { // set pin 1.1 low (spi clock) port1->out &= (~0x2ul); // set line high if bit 1, low if bit 0 if (data & 0x1) { // set pin 1.0 high (spi mosi) port1->out |= 0x1ul; } else { // set pin 1.0 low (spi mosi) port1->out &= (~0x1ul); } // set pin 1.1 high (spi clock) port1->out |= 0x2ul; data >>= 1; } } int main() { // start dumping @ memory address 0x08000000 unsigned int *p; p = (uint32_t *)(0x08000000u); // configure pin 1.0 , pin 1.1 output (push-pull) port1->iocr0 = 0x8080ul; while(1) { spi_send_word(*p); p++; } }
the biggest problem solution recovering timing information - knowing 1 word starts , ends. simpler output data on uart tx pin - uart adds start , stop bits , manages timing you, , output can read directly via regular pc serial port.
if cannot use uart, emulating uart bit-banging gpio uart timing still allow conventional serial port used receive data directly.
an example software uart implementation can found here. in case of course need transmit capability.
Comments
Post a Comment