cancel
Showing results for 
Search instead for 
Did you mean: 

How can I get the size of Firmware and copy it ?

simoBen47
Associate III

Hey everyone,

I need to do some operations on Firmware, and i am asking on how to recover its size and store it ?

I am using STM32F401RE.

Simo

11 REPLIES 11

You can read firmware via ST-LINK Utilities, Keil has option to SAVE from debugger.

Perhaps apply some basic C skills and fopen, fseek, ftell, fread, etc to read binary file in memory and scan backward until you stop finding 0xFF characters.

Keil, IAR, etc generate linker symbols and .MAP files describing firmware sizes, and additional static data, etc. Keil's go these $$Image$$ class variables to allow you to understand the load regions, and limits. Could swear this stuff is ALL documented.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
simoBen47
Associate III

Thank you for your reply.

I need to read firmware in the device, if i save it in my host via ST-LINK Utilities or others way, i will not be able to manipulate it when i load my code.

fopen, fseek, ftell, fread You need a file somewhere to do these operations, but I do not have a mmc in the board

For the moment i read the flash memory to recover the Firmware.

Question:

In the Flash memory we have only the firmware or we can have other things with ?

Ok, so in situ the flash is between 0x08000000 and 0x0807FFFF

You can index back from 0x0807FFFC checking for 0xFFFFFFFF 32-bit words

The linker generally generates symbols or tables describing the end of the image, you could either access these directly, or use an unused vector in the table.

In Keil this should be the entire span (code, constant data, data copied to RAM)

 extern uint32_t Load$$LR$$LR_IROM1$$Limit;

 printf('Limit %08X\n', (uint32_t)&Load$$LR$$LR_IROM1$$Limit);

#EndOfFlash​ 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
simoBen47
Associate III

Thank you for your reply.

I have a firmware that is 34 kb of text in size.

Do I need to read all flash memory ? or just read the address range that corresponds to the size of the firmware ?

Simo

You only need to read the area of interest. ​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
simoBen47
Associate III

do you have any idea about how to read flash per page because I have not been able to read it by sector?

I have to read 2 memory sectors

I am under FreeRtos and I am using STM32F401RE

The flash memory is within the visible address space of the processor, you can read it just like any other memory in the device.

The second sector would start at 0x08004000 and be 0x4000 bytes in length.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Perhaps you can better explain the end goal here, as you seem to be struggling with basic concepts and implementation details.

Why do you need to "read the firmware", and what are you going to do with the data you have read?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
simoBen47
Associate III

Thank you for reply,

Basically I just want to read two sectors of flash memory that represent my firmware.

#define BASE_ADDR_SECTOR_0 0x08000000 // 16 Kbytes

#define END_ADDR_SECTOR_0 0x08003FFF

#define BASE_ADDR_SECTOR_1 0x08004000 // 16 kbytes

#define END_ADDR_SECTOR_1 0x08007FFF)

then make hash of all firmware in order to check its integrity later.

Here is my code if you want to take a look

   unsigned char msg_digest[32];
   SHA256Context ctx;
 
   uint32_t data_store0[4096] = {0};
   uint32_t data_store1[4096] = {0};
 
   uint32_t *words0 = (uint32_t *) BASE_ADDR_SECTOR_0;
   uint32_t *words1 = (uint32_t *) BASE_ADDR_SECTOR_1;
 
   unsigned int buffer_firmware[8192];
 
   int k, m, i, j, l = 0;
 
   for(i=0; i<4096; i++)
   {
      data_store0[i] += words0[i];
      buffer_firmware[i] = data_store0[i];
      printf("buffer_firmware : %x, %d \n\r", buffer_firmware[i], i);
   }
 
   for(j=0; j<4096; j++)
   {
      data_store1[j] += words1[j];
   }
 
   for(m = 0, k = 4096; k < 8192 && m < 4096; m++, k++)
   {
      buffer_firmware[k] = data_store1[m];
      printf("buffer_firmware : %x, %d \n\r", buffer_firmware[k], k);
   }
  SHA256Reset(&ctx);
  SHA256Input(&ctx, (const uint8_t *) buffer_firmware, 8192);
  SHA256Result(&ctx, msg_digest);