Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make: optionally create .ld memory sections on the fly #19692

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -721,12 +721,20 @@ _BASELIBS_VALUE_BEFORE_USAGE := $(BASELIBS)
# Only use --start-group when archives are defined
ARCHIVES_GROUP = $(if $(ARCHIVES),$(LINKFLAGPREFIX)--start-group $(ARCHIVES) -lm $(LINKFLAGPREFIX)--end-group, -lm)

LDMEMORY_RUN = mkdir -p $$(dirname $@) && \
ld-memory \
--section ram:$(RAM_START_ADDR):$(RAM_LEN) \
--section rom:$(ROM_START_ADDR):$(or $(FW_ROM_LEN), $(ROM_LEN)):$(ROM_OFFSET) \
--section bkup_ram:$(BACKUP_RAM_START):$(BACKUP_RAM_LEN) \
$(addprefix --section ,$(LDMEMORY_SECTIONS)) \
$(addprefix --include ,$(LDMEMORY_INCLUDES)) \
>

$(ELFFILE): FORCE
ifeq ($(BUILDOSXNATIVE),1)
_LINK = $(if $(CPPMIX),$(LINKXX),$(LINK)) $$(find $(BASELIBS:%.module=$(BINDIR)/%/) -name "*.o" 2> /dev/null | sort) $(ARCHIVES_GROUP) $(LINKFLAGS) $(LINKFLAGPREFIX)-no_pie
else
_LINK = $(if $(CPPMIX),$(LINKXX),$(LINK)) $$(find $(BASELIBS:%.module=$(BINDIR)/%/) -name "*.o" 2> /dev/null | sort) $(ARCHIVES_GROUP) $(LINKFLAGS) $(LINKFLAGPREFIX)-Map=$(BINDIR)/$(APPLICATION).map
endif # BUILDOSXNATIVE
_LINK = $(if $(USE_LDMEMORY),$(LDMEMORY_RUN) [email protected] &&) \
$(if $(CPPMIX),$(LINKXX),$(LINK)) $$(find $(BASELIBS:%.module=$(BINDIR)/%/) -name "*.o" 2> /dev/null | sort) \
$(if $(USE_LDMEMORY),[email protected]) \
$(ARCHIVES_GROUP) $(LINKFLAGS) $(LINKFLAGPREFIX)-Map=$(BINDIR)/$(APPLICATION).map

COMPILE_COMMANDS_PATH ?= $(RIOTBASE)/compile_commands.json
COMPILE_COMMANDS_FLAGS ?= --clangd
Expand Down
8 changes: 0 additions & 8 deletions boards/native/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,6 @@ ifneq ($(shell gcc --version | head -1 | grep -E ' (4.6|4.7)'),)
CFLAGS += -DHAVE_NO_BUILTIN_BSWAP16
endif

# clumsy way to enable building native on osx:
BUILDOSXNATIVE = 0
ifeq ($(CPU),native)
ifeq ($(OS),Darwin)
BUILDOSXNATIVE = 1
endif
endif

all: # do not override first target

all-gprof: all
Expand Down
8 changes: 7 additions & 1 deletion cpu/cc2538/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ FLASHSIZE := $(shell echo $$(( $(call _rom_len_k,$(ROM_LEN)) * $(KB))) )
CFLAGS += -DCC2538_FLASHSIZE=$(FLASHSIZE)U

# Use common ld script
LINKER_SCRIPT ?= cc2538.ld
ifeq (,$(USE_LDMEMORY))
LINKER_SCRIPT ?= cc2538.ld
endif

# ld-memory settings
LDMEMORY_SECTIONS += cca:0x0027ffd4:44:
LDMEMORY_INCLUDES += cc2538_keep_cca.ld

# The entry point `cortex_vector_base` is defined in the cca field.
# If the cca field is updated when flashing a slot then the entry
Expand Down
10 changes: 1 addition & 9 deletions cpu/cc2538/ldscripts/cc2538.ld
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,7 @@ MEMORY
ram (w!rx) : ORIGIN = _ram_start_addr, LENGTH = _ram_length
}

/* MCU Specific Section Definitions */
SECTIONS
{
.flashcca :
{
KEEP(*(.flashcca))
} > cca
}

INCLUDE cc2538_keep_cca.ld
INCLUDE cortexm_base.ld

/* @} */
8 changes: 8 additions & 0 deletions cpu/cc2538/ldscripts/cc2538_keep_cca.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
SECTIONS
{
.flashcca :
{
KEEP(*(.flashcca))
} > cca
}

15 changes: 14 additions & 1 deletion cpu/cc26xx_cc13xx/Makefile.include
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
VARIANT = $(shell echo $(CPU_VARIANT) | tr 'a-z-' 'A-Z_')
CFLAGS += -DCPU_VARIANT_$(VARIANT)

LINKER_SCRIPT ?= $(RIOTCPU)/cc26xx_cc13xx/ldscripts/cc26xx_cc13xx.ld
LINKFLAGS += -L$(RIOTCPU)/cc26xx_cc13xx/ldscripts

ifeq (,$(USE_LDMEMORY))
LINKER_SCRIPT ?= cc26xx_cc13xx.ld
else
# CCFG starts at the end of ROM
LDMEMORY_SECTIONS += ccfg:${ROM_LEN}-88:88

# GPRAM is only available when cache is disabled. When GPRAM is enabled it
# is used as a backup RAM at the expense of slower CPU execution time
LDMEMORY_SECTIONS += gpram:0x11000000:8K

LDMEMORY_INCLUDES += cc26xx_cc13xx_sections.ld
endif

INCLUDES += -I${RIOTCPU}/cc26xx_cc13xx/include
21 changes: 2 additions & 19 deletions cpu/cc26xx_cc13xx/ldscripts/cc26xx_cc13xx.ld
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,8 @@ MEMORY
ram (w!rx) : ORIGIN = _ram_start_addr, LENGTH = _ram_length
}

/* MCU Sepcific Section Definitions */
SECTIONS
{
.ccfg :
{
KEEP(*(.ccfg))
} > ccfg

.gpram :
{
} > gpram

.heap_gpram (NOLOAD) : ALIGN(4)
{
_sheap1 = . ;
_eheap1 = ORIGIN(gpram) + LENGTH(gpram);
} > gpram
}

INCLUDE bkup_ram.ld
INCLUDE cc26xx_cc13xx_sections.ld
INCLUDE cortexm_base.ld

/* @} */
18 changes: 18 additions & 0 deletions cpu/cc26xx_cc13xx/ldscripts/cc26xx_cc13xx_sections.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* MCU Sepcific Section Definitions */
SECTIONS
{
.ccfg :
{
KEEP(*(.ccfg))
} > ccfg

.gpram :
{
} > gpram

.heap_gpram (NOLOAD) : ALIGN(4)
{
_sheap1 = . ;
_eheap1 = ORIGIN(gpram) + LENGTH(gpram);
} > gpram
}
26 changes: 16 additions & 10 deletions cpu/cortexm_common/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,19 @@ ifneq (,$(ROM_START_ADDR)$(RAM_START_ADDR)$(ROM_LEN)$(RAM_LEN))
$(if $(RAM_START_ADDR),,$(error RAM_START_ADDR is not defined))
$(if $(ROM_LEN),,$(error ROM_LEN is not defined))
$(if $(RAM_LEN),,$(error RAM_LEN is not defined))
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_rom_start_addr=$(ROM_START_ADDR)
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_ram_start_addr=$(RAM_START_ADDR)
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_rom_length=$(ROM_LEN)
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_ram_length=$(RAM_LEN)
ifeq (,$(USE_LDMEMORY))
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_rom_start_addr=$(ROM_START_ADDR)
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_ram_start_addr=$(RAM_START_ADDR)
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_rom_length=$(ROM_LEN)
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_ram_length=$(RAM_LEN)
endif
endif

ifneq (,$(BACKUP_RAM_LEN))
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_backup_ram_start_addr=$(BACKUP_RAM_ADDR)
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_backup_ram_len=$(BACKUP_RAM_LEN)
ifeq (,$(USE_LDMEMORY))
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_backup_ram_start_addr=$(BACKUP_RAM_ADDR)
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_backup_ram_len=$(BACKUP_RAM_LEN)
endif
CFLAGS += -DCPU_HAS_BACKUP_RAM=1
endif

Expand All @@ -25,10 +29,12 @@ TOOLCHAINS_SUPPORTED = gnu llvm
# Only define the linker symbol if the variable is set
# The variable can be set using target specific variable thanks to lazy evaluation

# ROM_OFFSET: offset in rom to start linking, allows supporting a bootloader
LINKFLAGS += $(if $(ROM_OFFSET),$(LINKFLAGPREFIX)--defsym=_rom_offset=$(ROM_OFFSET))
# FW_ROM_LEN: rom length to use for firmware linking. Allows linking only in a section of the rom.
LINKFLAGS += $(if $(FW_ROM_LEN),$(LINKFLAGPREFIX)--defsym=_fw_rom_length=$(FW_ROM_LEN))
ifeq (,$(USE_LDMEMORY))
# ROM_OFFSET: offset in rom to start linking, allows supporting a bootloader
LINKFLAGS += $(if $(ROM_OFFSET),$(LINKFLAGPREFIX)--defsym=_rom_offset=$(ROM_OFFSET))
# FW_ROM_LEN: rom length to use for firmware linking. Allows linking only in a section of the rom.
LINKFLAGS += $(if $(FW_ROM_LEN),$(LINKFLAGPREFIX)--defsym=_fw_rom_length=$(FW_ROM_LEN))
endif

# Cortex-M riotboot settings

Expand Down
8 changes: 8 additions & 0 deletions cpu/cortexm_common/ldscripts/bkup_ram.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
_backup_ram_start_addr = DEFINED( _backup_ram_start_addr ) ? _backup_ram_start_addr : 0x0 ;
_backup_ram_len = DEFINED( _backup_ram_len ) ? _backup_ram_len : 0x0 ;

MEMORY
{
/* not all Cortex-M platforms use cortexm.ld yet */
bkup_ram (w!rx) : ORIGIN = _backup_ram_start_addr, LENGTH = _backup_ram_len
}
1 change: 1 addition & 0 deletions cpu/cortexm_common/ldscripts/cortexm.ld
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ MEMORY
ram (w!rx) : ORIGIN = _ram_start_addr, LENGTH = _ram_length
}

INCLUDE bkup_ram.ld
INCLUDE cortexm_base.ld
9 changes: 0 additions & 9 deletions cpu/cortexm_common/ldscripts/cortexm_base.ld
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,6 @@ SEARCH_DIR(.)
/* This is only used by gdb to understand where to start */
ENTRY(reset_handler_default)

_backup_ram_start_addr = DEFINED( _backup_ram_start_addr ) ? _backup_ram_start_addr : 0x0 ;
_backup_ram_len = DEFINED( _backup_ram_len ) ? _backup_ram_len : 0x0 ;

/* not all Cortex-M platforms use cortexm.ld yet */
MEMORY
{
bkup_ram (w!rx) : ORIGIN = _backup_ram_start_addr, LENGTH = _backup_ram_len
}

/* Section Definitions */
SECTIONS
{
Expand Down
4 changes: 3 additions & 1 deletion cpu/nrf5x_common/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ CFLAGS += -DCPU_FAM_$(call uppercase_and_underscore,$(CPU_FAM))
ROM_START_ADDR ?= 0x00000000
RAM_START_ADDR ?= 0x20000000

LINKER_SCRIPT ?= cortexm.ld
ifeq (,$(USE_LDMEMORY))
LINKER_SCRIPT ?= cortexm.ld
endif

INCLUDES += -I$(RIOTCPU)/nrf5x_common/include
4 changes: 3 additions & 1 deletion cpu/sam0_common/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ CFLAGS += -DDONT_USE_PREDEFINED_CORE_HANDLERS
CFLAGS += -DDONT_USE_PREDEFINED_PERIPHERALS_HANDLERS

# For Cortex-M cpu we use the common cortexm.ld linker script
LINKER_SCRIPT ?= cortexm.ld
ifeq (,$(USE_LDMEMORY))
LINKER_SCRIPT ?= cortexm.ld
endif

INCLUDES += -I$(RIOTCPU)/sam0_common/include

Expand Down
4 changes: 3 additions & 1 deletion cpu/sam_common/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ RAM_START_ADDR ?= 0x20070000
ROM_LEN ?= 0x80000
RAM_LEN ?= 0x18000

LINKER_SCRIPT ?= cortexm.ld
ifeq (,$(USE_LDMEMORY))
LINKER_SCRIPT ?= cortexm.ld
endif

INCLUDES += -I$(RIOTCPU)/sam_common/include
23 changes: 16 additions & 7 deletions cpu/stm32/Makefile.include
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
CFLAGS += -DCPU_FAM_STM32$(call uppercase_and_underscore,$(CPU_FAM))

# For stm32 cpu's we use the generic stm32.ld linker script
LINKER_SCRIPT ?= stm32.ld
ifeq (,$(USE_LDMEMORY))
# For stm32 cpu's we use the generic stm32.ld linker script
LINKER_SCRIPT ?= stm32.ld
else
LDMEMORY_INCLUDES += stm32_sram4_heap.ld

LDMEMORY_SECTIONS += ccmram:0x10000000:$(CCMRAM_LEN)
LDMEMORY_SECTIONS += sram4:0x28000000:$(SRAM4_LEN)
endif

# Include riotboot specific variables
include $(RIOTCPU)/stm32/stm32_riotboot.mk
Expand Down Expand Up @@ -58,11 +65,13 @@ info-stm32:
@$(COLOR_ECHO) "\tRAM size:\t$(RAM_LEN_K)KiB"


ifneq (,$(CCMRAM_LEN))
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_ccmram_length=$(CCMRAM_LEN)
endif
ifneq (,$(SRAM4_LEN))
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_sram4_length=$(SRAM4_LEN)
ifeq (,$(USE_LDMEMORY))
ifneq (,$(CCMRAM_LEN))
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_ccmram_length=$(CCMRAM_LEN)
endif
ifneq (,$(SRAM4_LEN))
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_sram4_length=$(SRAM4_LEN)
endif
endif

VECTORS_O ?= $(BINDIR)/stm32_vectors/$(CPU_LINE).o
Expand Down
10 changes: 1 addition & 9 deletions cpu/stm32/ldscripts/stm32.ld
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,5 @@ MEMORY
sram4 : ORIGIN = 0x28000000, LENGTH = sram4_length
}

SECTIONS
{
.heap2 ALIGN(4) (NOLOAD) :
{
_sheap2 = . ;
_eheap2 = ORIGIN(sram4) + LENGTH(sram4);
} > sram4
}

INCLUDE stm32_sram4_heap.ld
INCLUDE cortexm.ld
9 changes: 9 additions & 0 deletions cpu/stm32/ldscripts/stm32_sram4_heap.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
SECTIONS
{
.heap2 ALIGN(4) (NOLOAD) :
{
_sheap2 = . ;
_eheap2 = ORIGIN(sram4) + LENGTH(sram4);
} > sram4
}

11 changes: 9 additions & 2 deletions makefiles/arch/cortexm.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,15 @@ CFLAGS += $(CFLAGS_CPU) $(CFLAGS_LINK) $(CFLAGS_DBG) $(CFLAGS_OPT)

ASFLAGS += $(CFLAGS_CPU)
LINKFLAGS += -L$(RIOTCPU)/$(CPU)/ldscripts -L$(RIOTCPU)/cortexm_common/ldscripts
LINKER_SCRIPT ?= $(CPU_MODEL).ld
LINKFLAGS += -T$(LINKER_SCRIPT) -Wl,--fatal-warnings
ifeq (,$(USE_LDMEMORY))
LINKER_SCRIPT ?= $(CPU_MODEL).ld
else
LDMEMORY_INCLUDES += cortexm_base.ld
endif

LINKFLAGS += $(if $(LINKER_SCRIPT), -T$(LINKER_SCRIPT))

LINKFLAGS += -Wl,--fatal-warnings

LINKFLAGS += $(CFLAGS_CPU) $(CFLAGS_DBG) $(CFLAGS_OPT) -static -lgcc -nostartfiles
LINKFLAGS += -Wl,--gc-sections
Expand Down
1 change: 1 addition & 0 deletions makefiles/boot/riotboot.mk
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ riotboot/bootloader/%: $$(if $$(filter riotboot/bootloader/clean,$$@),,$$(BUILDD
EXTERNAL_BOARD_DIRS="$(EXTERNAL_BOARD_DIRS)" BOARD=$(BOARD)\
DEBUG_ADAPTER_ID=$(DEBUG_ADAPTER_ID) \
IOTLAB_NODE=$(IOTLAB_NODE) \
USE_LDMEMORY=$(USE_LDMEMORY) \
PROGRAMMER=$(PROGRAMMER) PROGRAMMER_QUIET=$(PROGRAMMER_QUIET) \
$(MAKE) --no-print-directory -C $(RIOTBOOT_DIR) $*

Expand Down
16 changes: 13 additions & 3 deletions tests/build_system/cortexm_common_ldscript/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ include $(RIOTBASE)/Makefile.include
# # # # # # # # # # # # # # # # # # # # # # # # # # # #

COMPILE_TESTS = test-elffile-overflow test-elffile-fw_rom_length
COMPILE_TESTS += tests-offsets tests-fw_rom_len tests-rom-overflow
COMPILE_TESTS += tests-offsets tests-fw_rom_len

# this test currently doesn't work when using ld-memory .ld file generation
ifeq (,$(USE_LDMEMORY))
COMPILE_TESTS += tests-rom-overflow
endif

# The tests should only be executed in build environment
ifneq ($(BUILD_IN_DOCKER),1)
Expand All @@ -48,6 +53,11 @@ compile-tests: $(COMPILE_TESTS)
# iotlab-m3 defines ROM_LEN as 512K which is not handled by bash math operations
ROM_LEN_BYTES = $(shell printf "0x%x\n" $$(($(ROM_LEN:%K=%*1024))))

ifneq (,$(USE_LDMEMORY))
FW_ROM_LEN_SYMBOL = _rom_length
else
FW_ROM_LEN_SYMBOL = _fw_rom_len
endif

# test-elffile-overflow depends on $(BINFILE) to prevent:
# * ROM_LEN to be passed to $(ELFFILE) generation
Expand All @@ -68,7 +78,7 @@ test-elffile-fw_rom_length: $(ELFFILE)
$(Q)echo -n "Test rom offset subtracted from rom length in elffile: "
$(Q)\
if test -n "$(ROM_OFFSET)"; then \
TEST_FW_LEN=$$($(PREFIX)readelf --symbols $^ 2>/dev/null | awk '/_fw_rom_length/{printf "0x%s\n", $$2}'); \
TEST_FW_LEN=$$($(PREFIX)readelf --symbols $^ 2>/dev/null | awk '/$(FW_ROM_LEN_SYMBOL)/{printf "0x%s\n", $$2}'); \
EXPECT_FW_LEN=$$(printf "0x%08x" $$(( $(ROM_LEN_BYTES) - $(ROM_OFFSET) ))); \
if test $${TEST_FW_LEN} != $${EXPECT_FW_LEN}; then \
echo "[ERROR] Rom offset not taken into account for firmware length $${TEST_FW_LEN} != $${EXPECT_FW_LEN}" >&2; \
Expand Down Expand Up @@ -127,7 +137,7 @@ tests-fw_rom_len: test-fw_len_half_rom
test-fw_len_half_rom: $(BINDIR)/$(APPLICATION)_fw_len_half_rom.elf
$(Q)echo -n "Test compilation with half ROM length: "
$(Q)\
TEST_FW_LEN=$$($(PREFIX)readelf --symbols $^ 2>/dev/null | awk '/_fw_rom_length/{printf "0x%s\n", $$2}'); \
TEST_FW_LEN=$$($(PREFIX)readelf --symbols $^ 2>/dev/null | awk '/$(FW_ROM_LEN_SYMBOL)/{printf "0x%s\n", $$2}'); \
EXPECT_FW_LEN=$$(printf "0x%08x" $$(( $(ROM_LEN_BYTES) / 2 ))); \
if test $${TEST_FW_LEN} != $${EXPECT_FW_LEN}; then \
echo "[ERROR] Linker firmware length not used $${TEST_FW_LEN} != $${EXPECT_FW_LEN}" >&2; \
Expand Down