mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 05:13:46 -07:00
chg: reading / writing flashmem works better now.
This commit is contained in:
parent
fd52946ef8
commit
a746699f5f
4 changed files with 164 additions and 54 deletions
|
@ -1081,7 +1081,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
// arg2 = RFU
|
// arg2 = RFU
|
||||||
//Dbprintf("transfer to client parameters: %" PRIu32 " | %" PRIu32 " | %" PRIu32, startidx, numofbytes, c->arg[2]);
|
//Dbprintf("transfer to client parameters: %" PRIu32 " | %" PRIu32 " | %" PRIu32, startidx, numofbytes, c->arg[2]);
|
||||||
|
|
||||||
for(size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) {
|
for (size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) {
|
||||||
len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
|
len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
|
||||||
isok = cmd_send(CMD_DOWNLOADED_EML_BIGBUF, i, len, 0, mem + startidx + i, len);
|
isok = cmd_send(CMD_DOWNLOADED_EML_BIGBUF, i, len, 0, mem + startidx + i, len);
|
||||||
if (!isok)
|
if (!isok)
|
||||||
|
@ -1096,11 +1096,48 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
ReadMem(c->arg[0]);
|
ReadMem(c->arg[0]);
|
||||||
break;
|
break;
|
||||||
#ifdef WITH_FLASH
|
#ifdef WITH_FLASH
|
||||||
case CMD_READ_FLASH_MEM:
|
case CMD_READ_FLASH_MEM: {
|
||||||
case CMD_WRITE_FLASH_MEM:
|
|
||||||
|
LED_B_ON();
|
||||||
|
uint16_t isok = 0;
|
||||||
|
size_t len = 0;
|
||||||
|
uint32_t startidx = c->arg[0];
|
||||||
|
uint16_t numofbytes = c->arg[1];
|
||||||
|
|
||||||
|
Dbprintf("FlashMem read | %d - %d", startidx, numofbytes);
|
||||||
|
|
||||||
|
uint8_t *mem = BigBuf_malloc(USB_CMD_DATA_SIZE);
|
||||||
|
|
||||||
|
for(size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) {
|
||||||
|
len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
|
||||||
|
|
||||||
|
Dbprintf("FlashMem reading | %d | %d | %d", startidx + i, i, len);
|
||||||
|
|
||||||
|
isok = Flash_ReadData(startidx + i, mem, len);
|
||||||
|
if ( isok == len ) {
|
||||||
|
print_result("Chunk: ", mem, len);
|
||||||
|
} else {
|
||||||
|
Dbprintf("FlashMem reading failed | %d | %d", len, isok);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Trigger a finish downloading signal with an ACK frame
|
||||||
|
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
||||||
|
LED_B_OFF();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_WRITE_FLASH_MEM: {
|
||||||
|
LED_B_ON();
|
||||||
|
uint32_t startidx = c->arg[0];
|
||||||
|
uint16_t len = c->arg[1];
|
||||||
|
uint16_t res = Flash_WriteData(startidx, c->d.asBytes, len);
|
||||||
|
uint8_t isok = (res == len) ? 1 : 0;
|
||||||
|
cmd_send(CMD_ACK, isok, 0, 0, 0, 0);
|
||||||
|
LED_B_OFF();
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CMD_UPLOAD_FLASH_MEM:
|
case CMD_UPLOAD_FLASH_MEM:
|
||||||
case CMD_DOWNLOAND_FLASH_MEM:
|
case CMD_DOWNLOAND_FLASH_MEM:
|
||||||
EXFLASH_TEST();
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case CMD_SET_LF_DIVISOR:
|
case CMD_SET_LF_DIVISOR:
|
||||||
|
|
|
@ -207,7 +207,12 @@ void Flash_UniqueID(uint8_t *uid) {
|
||||||
uid[0] = FlashSendLastByte(0xFF);
|
uid[0] = FlashSendLastByte(0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
||||||
|
|
||||||
|
if (!FlashInit()) return 0;
|
||||||
|
|
||||||
|
Flash_ReadStat1();
|
||||||
|
|
||||||
// length should never be zero
|
// length should never be zero
|
||||||
if (!len || Flash_CheckBusy(1000)) return 0;
|
if (!len || Flash_CheckBusy(1000)) return 0;
|
||||||
|
|
||||||
|
@ -221,17 +226,50 @@ uint8_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
||||||
out[i] = FlashSendByte(0xFF);
|
out[i] = FlashSendByte(0xFF);
|
||||||
|
|
||||||
out[i] = FlashSendLastByte(0xFF);
|
out[i] = FlashSendLastByte(0xFF);
|
||||||
|
|
||||||
|
FlashStop();
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write data
|
// Write data
|
||||||
uint8_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
|
|
||||||
// length should never be zero
|
// length should never be zero
|
||||||
if (!len || Flash_CheckBusy(1000)) return 0;
|
if (!len) {
|
||||||
|
Dbprintf("Flash_WriteData len is zero error");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FlashInit()) {
|
||||||
|
Dbprintf("Flash_WriteData init fail");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Flash_ReadStat1();
|
||||||
|
|
||||||
|
Flash_WriteEnable();
|
||||||
|
|
||||||
|
if ( len < 0x1000 )
|
||||||
|
Flash_Erase4k(0x00);
|
||||||
|
else if ( len >= 0x1000 && len < 0x7FFF )
|
||||||
|
Flash_Erase32k(0x00);
|
||||||
|
else
|
||||||
|
Flash_Erase64k(0x00);
|
||||||
|
|
||||||
|
// busy after erasing
|
||||||
|
if (Flash_CheckBusy(1000)) {
|
||||||
|
Dbprintf("Flash_WriteData check busy");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// ²»ÄÜ¿çÔ½ 256 ×ֽڱ߽ç
|
// ²»ÄÜ¿çÔ½ 256 ×ֽڱ߽ç
|
||||||
if (((address & 255) + len) > 256) return 0;
|
if (((address & 255) + len) > 256) {
|
||||||
|
Dbprintf("Flash_WriteData 256 fail");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Flash_WriteEnable();
|
||||||
|
|
||||||
FlashSendByte(PAGEPROG);
|
FlashSendByte(PAGEPROG);
|
||||||
FlashSendByte((address >> 16) & 0xFF);
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
FlashSendByte((address >> 8) & 0xFF);
|
FlashSendByte((address >> 8) & 0xFF);
|
||||||
|
@ -242,6 +280,8 @@ uint8_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
FlashSendByte(in[i]);
|
FlashSendByte(in[i]);
|
||||||
|
|
||||||
FlashSendLastByte(in[i]);
|
FlashSendLastByte(in[i]);
|
||||||
|
|
||||||
|
FlashStop();
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +308,7 @@ bool Flash_Erase4k(uint32_t address) {
|
||||||
// erase 32K at one time
|
// erase 32K at one time
|
||||||
bool Flash_Erase32k(uint32_t address) {
|
bool Flash_Erase32k(uint32_t address) {
|
||||||
if (address & (32*1024 - 1)) {
|
if (address & (32*1024 - 1)) {
|
||||||
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase4k : Address is not align at 4096");
|
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
FlashSendByte(BLOCK32ERASE);
|
FlashSendByte(BLOCK32ERASE);
|
||||||
|
@ -280,9 +320,8 @@ bool Flash_Erase32k(uint32_t address) {
|
||||||
|
|
||||||
// erase 64k at one time
|
// erase 64k at one time
|
||||||
bool Flash_Erase64k(uint32_t address) {
|
bool Flash_Erase64k(uint32_t address) {
|
||||||
|
|
||||||
if (address & (64*1024 - 1)) {
|
if (address & (64*1024 - 1)) {
|
||||||
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase4k : Address is not align at 4096");
|
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase64k : Address is not align at 4096");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
FlashSendByte(BLOCK64ERASE);
|
FlashSendByte(BLOCK64ERASE);
|
||||||
|
@ -312,37 +351,6 @@ bool FlashInit(void) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EXFLASH_TEST(void) {
|
|
||||||
uint8_t data[256] = { 0x00, 0x01, 0x02 };
|
|
||||||
uint8_t data2[256] = { 0x00};
|
|
||||||
|
|
||||||
if (!FlashInit()) return;
|
|
||||||
|
|
||||||
Flash_ReadStat1();
|
|
||||||
|
|
||||||
Dbprintf("Flash test write: 012 to 0x00 0x01 0x02");
|
|
||||||
Flash_WriteEnable();
|
|
||||||
Flash_Erase4k(0x00);
|
|
||||||
if (Flash_CheckBusy(1000)) {
|
|
||||||
Dbprintf("Flash_Erase4k CheckBusy Error.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Flash_ReadData(0, data2, 256);
|
|
||||||
Flash_WriteEnable();
|
|
||||||
Flash_WriteData(0x12, data, sizeof(data)); // this will never run, cuz out of 256byte boundary
|
|
||||||
Flash_WriteData(0x12, data, 3);
|
|
||||||
|
|
||||||
if (Flash_CheckBusy(1000)) {
|
|
||||||
Dbprintf("Flash_WriteDate CheckBusy Error.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Flash_ReadData(0, data2, 256);
|
|
||||||
FlashStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Flashmem_print_status(void) {
|
void Flashmem_print_status(void) {
|
||||||
DbpString("Flash memory");
|
DbpString("Flash memory");
|
||||||
|
|
||||||
|
@ -375,5 +383,5 @@ void Flashmem_print_status(void) {
|
||||||
uid[3], uid[2], uid[1], uid[0]
|
uid[3], uid[2], uid[1], uid[0]
|
||||||
);
|
);
|
||||||
|
|
||||||
FlashStop();
|
FlashStop();
|
||||||
}
|
}
|
|
@ -117,13 +117,18 @@ bool Flash_WaitIdle(void);
|
||||||
uint8_t Flash_ReadStat1(void);
|
uint8_t Flash_ReadStat1(void);
|
||||||
uint8_t Flash_ReadStat2(void);
|
uint8_t Flash_ReadStat2(void);
|
||||||
uint16_t FlashSendByte(uint32_t data);
|
uint16_t FlashSendByte(uint32_t data);
|
||||||
|
|
||||||
|
void Flash_WriteEnable();
|
||||||
|
bool Flash_Erase4k(uint32_t address);
|
||||||
|
bool Flash_Erase32k(uint32_t address);
|
||||||
|
bool Flash_Erase64k(uint32_t address);
|
||||||
|
|
||||||
bool FlashInit();
|
bool FlashInit();
|
||||||
void EXFLASH_TEST(void);
|
|
||||||
|
|
||||||
void Flash_UniqueID(uint8_t *uid);
|
void Flash_UniqueID(uint8_t *uid);
|
||||||
uint8_t Flash_ReadID(void);
|
uint8_t Flash_ReadID(void);
|
||||||
uint8_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len);
|
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len);
|
||||||
uint8_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len);
|
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len);
|
||||||
void Flashmem_print_status(void);
|
void Flashmem_print_status(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -461,15 +461,75 @@ char* pb(uint32_t b) {
|
||||||
|
|
||||||
int CmdAnalyseA(const char *Cmd){
|
int CmdAnalyseA(const char *Cmd){
|
||||||
|
|
||||||
UsbCommand c = {CMD_READ_FLASH_MEM, {0,0,0}};
|
int hexlen = 0;
|
||||||
clearCommandBuffer();
|
uint8_t cmdp = 0;
|
||||||
SendCommand(&c);
|
bool errors = false;
|
||||||
UsbCommand resp;
|
uint32_t startindex = 0, len = 0, cmd = 0;
|
||||||
|
uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
|
||||||
|
|
||||||
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
|
case 'l':
|
||||||
|
len = param_get32ex(Cmd, cmdp+1, 0, 10);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
startindex = param_get32ex(Cmd, cmdp+1, 0, 10);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
cmd = param_get8ex(Cmd, cmdp+1, 0, 10);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
param_gethex_ex(Cmd, cmdp+1, data, &hexlen);
|
||||||
|
if ( hexlen != sizeof(data) ) {
|
||||||
|
PrintAndLogEx(WARNING, "Read %d bytes of %u", hexlen, sizeof(data) );
|
||||||
|
}
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
return usage_analyse_checksum();
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Validations
|
||||||
|
if (errors || cmdp == 0 ) return usage_analyse_checksum();
|
||||||
|
|
||||||
|
UsbCommand c, resp;
|
||||||
|
|
||||||
|
switch ( cmd ) {
|
||||||
|
case 0:
|
||||||
|
c = (UsbCommand) {CMD_READ_FLASH_MEM, {startindex, len, 0}};
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommand(&c);
|
||||||
|
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) {
|
||||||
|
PrintAndLogEx(NORMAL, "timeout while waiting for reply.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
c = (UsbCommand) {CMD_WRITE_FLASH_MEM, {startindex, len, 0}};
|
||||||
|
memcpy(c.d.asBytes, data, len);
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommand(&c);
|
||||||
|
|
||||||
|
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) {
|
||||||
|
PrintAndLogEx(NORMAL, "timeout while waiting for reply.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
uint8_t isok = resp.arg[0] & 0xFF;
|
||||||
|
if (isok)
|
||||||
|
PrintAndLogEx(SUCCESS, "Flash write ok");
|
||||||
|
else
|
||||||
|
PrintAndLogEx(FAILED, "Flash write ok");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) {
|
|
||||||
PrintAndLogEx(NORMAL, "timeout while waiting for reply.");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "-- " _BLUE_(its my message) "\n");
|
PrintAndLogEx(NORMAL, "-- " _BLUE_(its my message) "\n");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue