How is compiled code placed into memory?

How is compiled code placed into memory?

In microcontrollers, there are typically two memory regions: Flash and RAM. Flash is a non-volatile memory which retains the data after power cycle. It is design to store unchanged data. RAM is volatile memory which lost the data after power cycle.

There are four different types of memory: readonly code memory, readonly data memory, readwrite code memory and readwrite data memory. What kind of compiled code placed into each memory?

  • readonly code memory: text segment placed in Flash

  • readonly data memory: constant global variable placed in Flash

  • readwrite code memory: text segment placed in RAM

  • readwrite data memory: global variable and static variable placed in RAM

In linker file, each region’s start address and end address are defined. In modern architecture, there are cacheable RAM and non-cacheable RAM. For example, there are ITCM, DTCM and OCRAM in cortex M7. Both ITCM and DTCM are cacheable memory. ITCM is typically used to access critical functions, routines and Interrupt service routines. DTCM is typically used to access critical variables and frequently updated variables. For example, usage of stack and heap can fit into DTCM. OCRAM is typical RAM and non-cacheable. If some variables have to be placed in non-cacheable section, it has to store in OCRAM.

Here is a RT1064(cortex M7)’s IAR linker file(.icf):

In line 103~110 shows what kind of compiled code placed into each defined memory. At line 103, readonly includes both readonly code memory and readonly data memory. At line 104, RW includes both readwrite code memory and readwrite data memory. At line 105, ZI is all global variables which initialize as zero.

Each memory region’s start address and end address can be found in line 77 ~ 82. It is easier to visualize the memory map below:

How to find each compiled object at exact address?

After compile, this information can be found in map file.

  • readonly code memory: text segment placed in Flash

  • readonly data memory: constant global variable placed in Flash

  • readwrite code memory: text segment placed in RAM

  • readwrite data memory: global variable and static variable placed in RAM

There are few different linker file format out there. gcc comiler uses .ld linker file and IAR compiler uses .icf linker file and TASKING compiler uses .lsl linker file and so on. The example of linker file above is .icf linker file. Although the linker file format is not universal and it is very compiler specific, the intention of linker files is the same. It defines memory regions and what kind of code goes to where.

Did you find this article valuable?

Support Hyunwoo Choi by becoming a sponsor. Any amount is appreciated!