diff --git a/platform.txt b/platform.txt index f9109293f1..25dc8544dd 100644 --- a/platform.txt +++ b/platform.txt @@ -128,7 +128,7 @@ recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} {build.i recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" ## Combine gc-sections, archives, and objects -recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} {compiler.ldflags} {compiler.arm.cmsis.ldflags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -Wl,--start-group {object_files} {compiler.libraries.ldflags} "{archive_file_path}" -lc -Wl,--end-group -lm -lgcc -lstdc++ +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} "-Wl,--default-script={build.variant.path}/{build.ldscript}" "-Wl,--script={build.system.path}/ldscript.ld" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} {compiler.ldflags} {compiler.arm.cmsis.ldflags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -Wl,--start-group {object_files} {compiler.libraries.ldflags} "{archive_file_path}" -lc -Wl,--end-group -lm -lgcc -lstdc++ ## Create output (.bin file) recipe.objcopy.bin.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.elf2bin.flags} {compiler.elf2bin.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" @@ -147,7 +147,7 @@ recipe.output.save_file={build.project_name}.{build.variant}.hex ## Compute size recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" recipe.size.regex=^(?:\.text|\.data|\.rodata)\s+([0-9]+).* -recipe.size.regex.data=^(?:\.data|\.bss)\s+([0-9]+).* +recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).* recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).* diff --git a/system/ldscript.ld b/system/ldscript.ld new file mode 100644 index 0000000000..d356b50cbc --- /dev/null +++ b/system/ldscript.ld @@ -0,0 +1,44 @@ +/* + * This script extends the default linker script to add a .noinit + * section. This section is just mapped to RAM, but it is emitted + * separately from the .data and .bss sections (both of which are + * initialized by startup code), so any variables in this section are + * untouched on startup (so they survive across resets). + * + * This script is intended to supplied to the linker's -T / --script + * option as the primary linker script. When the linker sees an INSERT + * command, this will cause it to *also* read the default linker script + * (after reading this script) and then executing the INSERT commands + * after both scripts have been read. + * + * Note that parsing of linker scripts is a bit peculiar, e.g. INSERT + * does not textually inserts, it inserts any generated output sections. + * Also, because this script is read *first*, we cannot refer to things + * in the default script. In particular, it would make sense to add > + * RAM to the output section below to ensure that the section is mapped + * into RAM, but the RAM region is not defined yet (I think it would + * work though, but produces warnings). Instead, we just rely on the + * defaults used by the linker: If no region is defined for an output + * section, it will just map to first address after the previous section + * (.bss in this case, which is fine). + */ +SECTIONS +{ + /* Define a noinit output section and mark it as NOLOAD to prevent + * putting its contents into the resulting .bin file (which is the + * default). */ + .noinit (NOLOAD) : + { + /* Ensure output is aligned */ + . = ALIGN(4); + /* Define a global _snoinit (and _enoinit below) symbol just in case + * code wants to iterate over all noinit variables for some reason */ + _snoinit = .; + /* Actually import the .noinit and .noinit* import sections */ + *(.noinit) + *(.noinit*) + . = ALIGN(4); + _enoinit = .; + } +} +INSERT AFTER .bss;