data segment is itself stored after the end of the. For our intents we can note that the sections named.
Refer the LD documentation for more information on the syntax of the script. This file is input to the linker, and allows the linker to map the text/data/bss regions in every object file into real physical addresses and also influences the merging of all the sections together into the final executable file. _data_load_end = _data_load_start + SIZEOF(.data) data : AT (ADDR (.text) + SIZEOF (.text)) The FT32 linker script file looks like this: The details of this memory map used during execution and while building the executable is specified in the linker script file. Thus the BSS was born and claims all those globals left uninitialized by lazy programmers along with those specifically initialized to zero. Luckily, back in the day when men didn't shave their chests someone figured out that most of the globals are usually initialized to zero, and we could save some flash space if we put all of these zero-initialized globals in a separate block of RAM, and just specify the start address + length of this section. The typical map of a bin/hex file is shown belowĪs a consequence, when you declare a global variable initialized to some non-zero value, you not only consume RAM but also Flash!
Usually this data is stored after all the code in the program. What this means is that the initial values of all the data that a program uses must itself be stored in the program executable file, otherwise there is no way that the RAM can be initialized by the crt0. On C based systems this boot code is called the ctr0 (the C runtime zero). How did it come to be that when the program was running the global data that the program access happen to have the right values and the memory map looks nice and orderly as above? The answer is that the program executable contains bootstrap code that initializes the RAM to the program correct memory map before any of the code that refers the data executes. However there was a time in space before the big bang when the program was living entirely on the flash and the RAM was just a jumble of random bits. This is the what the memory looks like when we are executing a program. The data used by a program can be split into statically allocated global data regions - the initialized DATA segment and the zero-initialised BSS segment and the runtime allocated memory - the Stack and the Heap. The code in an embedded system goes into the flash the the data goes into the RAM if it's mutable and flash or RAM if it's read-only. At the highest level the program can be divided into components - the code and the data it manipulates.
In this post I will first talk about the data that's exposed (and not exposed) in a map file followed by a description of the program itself.Ī simple embedded system typically has the memory map shown below (ignoring peripheral memory). However since the FT32 toolchain is based on GCC, the application code can be easily configured/updated to work with other GCC + BINUTILS based toolchains (I have tried it on Microchip's XC16 toolchain).
The application was developed while I was writing firmware for the FT900 micro-controller which is a new 32 bit micro-controller by FTDI.
This article is available in PDF format for easy printing