2019-06-20 01:07 PM
I am using the CCMRAM to store some large array which should be zero-initialized.
My definition for the arrays is similar to:
__attribute__ ((section (".ccmram")))
uint32_t large_array[4096];
Obviously, there is no constructor for these and there should not be a need to store the initial value of this array in flash. However, that is what the linker is doing.
The relevant portion of my linker script is as follows:
CCMRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K
...
/* uninitialized data in CCMRAM */
.ccmram :
{
. = ALIGN(4);
_sccmram = .; /* create a global symbol at ccmram start */
*(.ccmram)
*(.ccmram*)
. = ALIGN(4);
_eccmram = .; /* create a global symbol at ccmram end */
} >CCMRAM AT >FLASH
How do I get the linker to not store these in flash?
I tried removing the ">FLASH" from the previous line, however the binary file produced grew fro ~200kB to 200MB, which is not desired.
If I move these arrays to RAM and remove the __attribute__ line, it works as desired.
I'm using GNU for ARM compiler/linker targeting an STM32F429ZI.
Solved! Go to Solution.
2019-06-20 01:27 PM
Beyond all the FLASH/RAM nonsense
.CCMRAM (NOLOAD):
{
*(.ccmram)
*(.ccmram*)
} > CCM_RAM
2019-06-20 01:27 PM
Beyond all the FLASH/RAM nonsense
.CCMRAM (NOLOAD):
{
*(.ccmram)
*(.ccmram*)
} > CCM_RAM
2019-06-20 05:30 PM
Thanks Clive,
Is there a user manual for the linker somewhere? It seems like the most obtuse piece of software. I I google "gnu arm linker" I get mostly example linker files, and even the user-manualy hits don't have anything about NOLOAD.
For example, why would NOLOAD be necessary for this in CCMRAM but not for variables in RAM? Everything I know about linker files has been through reverse engineering, which is not the way it should be.
2019-06-20 07:33 PM
The real problem is that the GNU/GCC tools, and the methods for unpacking the load region(s) are extremely poor. The linker was originally designed for ELF executables in the LINUX sense (EXE/DLL) and not ROMable code that must unpack itself, rather than load into RAM from disk. The code in startup.s does the unpacking, and that involves either a) copying data from ROM/FLASH to RAM, or b) zeroing the statics (BSS). There are a lot of dependencies on order and symbols created by the linker script. On things like Keil this much more elegant as the linker builds tables, and adds functions to unpack.
The ELF format has NOBITS section type indicating sections of the executable image don't have any file content behind them. These are like NOINIT sections in other tools, and the GNU linker flags them using NOLOAD
Thinks are compounded if you want binary files, and the memory regions are significantly dispersed through memory, ie some in 0x10000000, and some in 0x20000000. The .HEX files can describe sparse memory, .BIN must describe a massive blob with a large unused space between the two.
I learned about Assemblers, Linkers and Loaders while I was in High School, and have had to write several over the years, so I have an appreciation of the mechanics, if not the specifics in a given instance.
2019-06-21 12:08 AM
For the linker manual, go to your GCC directory and then: \share\doc\gcc-arm-none-eabi\pdf\ld.pdf
That same directory has a lot of the other manuals. If you go one more level down to gcc i.e. \share\doc\gcc-arm-none-eabi\pdf\gcc you will find the gcc manual called gcc.pdf.
Or you can go to the GCC directory and type dir /s ld.pdf and it will find it.
Or you can go to the root directory on the drive GCC is on and do dir /s ld.pdf and a few seconds later, you should know where ld.pdf is.
Sadly, as pointed out by Clive, the explanation of how to setup the linker file is poor.