diff --git a/cpu/cortexm_common/Makefile.include b/cpu/cortexm_common/Makefile.include
index 65463a1859f57bd95b99059db55f071ddbe5d4f2..b1be7aff71fbf04ed87ba44eb160a664b1c25e9a 100644
--- a/cpu/cortexm_common/Makefile.include
+++ b/cpu/cortexm_common/Makefile.include
@@ -2,13 +2,24 @@
 INCLUDES += -I$(RIOTCPU)/cortexm_common/include
 INCLUDES += -I$(RIOTCPU)/cortexm_common/include/vendor
 
-ifneq (,$(ROM_OFFSET))
-  LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_rom_offset=$(ROM_OFFSET)
-endif
-
+# All variables must be defined in the CPU configuration when using the common
+# `ldscripts/cortexm.ld`
 ifneq (,$(ROM_START_ADDR)$(RAM_START_ADDR)$(ROM_LEN)$(RAM_LEN))
+  $(if $(ROM_START_ADDR),,$(error ROM_START_ADDR is not defined))
+  $(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)
 endif
+
+
+# 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))
diff --git a/cpu/cortexm_common/ldscripts/cortexm.ld b/cpu/cortexm_common/ldscripts/cortexm.ld
index cb19c10935b11b3d165bbdb85c31da77f15ee50d..1ce102459594efd13cc91edbac7b864329cbff01 100644
--- a/cpu/cortexm_common/ldscripts/cortexm.ld
+++ b/cpu/cortexm_common/ldscripts/cortexm.ld
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2017 Inria
+ *               2018 Freie Universität Berlin
  *
  * This file is subject to the terms and conditions of the GNU Lesser
  * General Public License v2.1. See the file LICENSE in the top level
@@ -14,16 +15,20 @@
  * @brief           Memory definitions for the Cortex-M family
  *
  * @author          Francisco Acosta <francisco.acosta@inria.fr>
+ *                  Gaëtan Harter <gaetan.harter@inria.fr>
  *
  * @}
  */
 
-_boot_offset = DEFINED( _rom_offset ) ? _rom_offset : 0x0 ;
+_rom_offset = DEFINED( _rom_offset ) ? _rom_offset : 0x0;
+_fw_rom_length = DEFINED( _fw_rom_length ) ? _fw_rom_length : _rom_length - _rom_offset;
+
+ASSERT((_fw_rom_length <= _rom_length - _rom_offset), "Specified firmware size does not fit in ROM");
 
 MEMORY
 {
-    rom (rx)    : ORIGIN = _rom_start_addr + _boot_offset, LENGTH = _rom_length - _boot_offset
-    ram (w!rx)  : ORIGIN = _ram_start_addr,                LENGTH = _ram_length
+    rom (rx)    : ORIGIN = _rom_start_addr + _rom_offset, LENGTH = _fw_rom_length
+    ram (w!rx)  : ORIGIN = _ram_start_addr,               LENGTH = _ram_length
 }
 
 INCLUDE cortexm_base.ld
diff --git a/tests/cortexm_common_ldscript/Makefile b/tests/cortexm_common_ldscript/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..4db91761d16b59201f9372bd869b0b4805f4c6a7
--- /dev/null
+++ b/tests/cortexm_common_ldscript/Makefile
@@ -0,0 +1,144 @@
+BOARD ?= samr21-xpro
+include ../Makefile.tests_common
+
+
+# Normally all boards using `cortexm_common/ldscripts/cortexm.ld` linkerscript
+# Only tested on these ones for the moment
+BOARD_WHITELIST += iotlab-a8-m3
+BOARD_WHITELIST += iotlab-m3
+BOARD_WHITELIST += samr21-xpro
+# Boards using a bootloader and ROM_OFFSET by default
+BOARD_WHITELIST += arduino-mkr1000
+BOARD_WHITELIST += arduino-mkrfox1200
+BOARD_WHITELIST += arduino-mkrzero
+BOARD_WHITELIST += bluepill
+BOARD_WHITELIST += feather-m0
+BOARD_WHITELIST += opencm904
+BOARD_WHITELIST += spark-core
+BOARD_WHITELIST += stm32mindev
+
+include $(RIOTBASE)/Makefile.include
+
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# Compile time tests for ROM_OFFSET and FW_ROM_LENGTH #
+# # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+COMPILE_TESTS  = test-elffile-overflow test-elffile-fw_rom_length
+COMPILE_TESTS += tests-offsets tests-fw_rom_len tests-rom-overflow
+
+all: compile-tests
+
+compile-tests: $(COMPILE_TESTS)
+.PHONY: 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))))
+
+
+# test-elffile-overflow depends on $(BINFILE) to prevent:
+# * ROM_LEN to be passed to $(ELFFILE) generation
+# * dummy error message of wc not finding the .bin file (ELFFILE is not enough)
+test-elffile-overflow: $(BINFILE) _test-elffile-overflow-runtest
+
+.PHONY: _test-elffile-overflow-runtest
+_test-elffile-overflow-runtest: ROM_LEN=$(firstword $(shell wc -c $(BINFILE)))-1+$(if $(ROM_OFFSET),$(ROM_OFFSET),0)
+_test-elffile-overflow-runtest: $(BINFILE)
+	$(Q)echo -n "Test rom offset 1 byte overflow detection: "
+	$(Q)\
+	{ $(_LINK) -o /dev/null  2>&1 | grep -q "region \`rom' overflowed by 1 byte" ; } \
+	  && echo [OK] || { echo [ERROR] Compilation should have failed >&2; exit 1; }
+
+
+# Test `ROM_OFFSET` is removed from firmware rom length if the board defines it
+test-elffile-fw_rom_length: $(ELFFILE)
+	$(Q)echo -n "Test rom offset substracted 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}'); \
+	  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; \
+	    exit 1;\
+	  fi ;\
+	  echo [OK] ; \
+	else \
+	  echo "[SKIP](Reason: board does not have a ROM_OFFSET configured)" ;\
+	fi
+
+
+# Test elffiles must not have $(ELFFILE) prerequisite as target specific
+# variables are used for configuration and they also apply to prerequisites.
+#
+# https://www.gnu.org/software/make/manual/make.html#Target_002dspecific
+
+ELFFILES_DEPS = $(BASELIBS) FORCE
+
+
+# Compile elf files with different ROM_OFFSET
+# and verify the offset is taken into account
+
+OFFSETS_TESTS = 0x1000 0x2000
+tests-offsets: $(OFFSETS_TESTS:%=test-offset_%)
+
+.PHONY: test-offset_%
+test-offset_%: $(BINDIR)/$(APPLICATION)_offset_%.elf
+	$(Q)echo -n "Test compilation with offset $*: "
+	$(Q)\
+	TEST_START_ADDR=$$($(PREFIX)readelf --section-headers $^ 2>/dev/null | awk '/.text/{printf "0x%s\n", $$5}'); \
+	EXPECT_START_ADDR=$$(printf "0x%08x" $$(( $(ROM_START_ADDR) + $* ))); \
+	if test $${TEST_START_ADDR} != $${EXPECT_START_ADDR}; then \
+	  echo "[ERROR] Linker offset not used $${TEST_START_ADDR} != $${EXPECT_START_ADDR}" >&2; \
+	  exit 1;\
+	fi
+	$(Q)echo [OK]
+
+$(BINDIR)/$(APPLICATION)_offset_%.elf: ROM_OFFSET=$*
+$(BINDIR)/$(APPLICATION)_offset_%.elf: $(ELFFILES_DEPS)
+	$(Q)$(_LINK) -o $@
+.PRECIOUS: $(BINDIR)/$(APPLICATION)_offset_%.elf
+
+
+# Compile elf files with FW_ROM_LEN and verify the length is taken into account
+#   I arbitrarily do 'half' size because I needed to take a value and
+#   that it is similar to what is required for doing dual firmware in rom ota
+
+tests-fw_rom_len: test-fw_len_half_rom
+
+.PHONY: 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}'); \
+	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; \
+	  exit 1;\
+	fi
+	$(Q)echo [OK]
+$(BINDIR)/$(APPLICATION)_fw_len_half_rom.elf: FW_ROM_LEN=$$(($(ROM_LEN_BYTES)/2))
+$(BINDIR)/$(APPLICATION)_fw_len_half_rom.elf: $(ELFFILES_DEPS)
+	$(Q)$(_LINK) -o $@
+.PRECIOUS: $(BINDIR)/$(APPLICATION)_fw_len_half_rom.elf
+
+
+# Test FW_ROM_LEN overflow detection
+
+OVERFLOW_TESTS = too_big_for_rom offset_and_romlen
+tests-rom-overflow: $(OVERFLOW_TESTS:%=test-assert_overflow_%)
+
+
+# Simple FW_ROM_LEN overflow
+test-assert_overflow_too_big_for_rom: FW_ROM_LEN=$$(($(ROM_LEN_BYTES) + 1))
+
+# ROM_OFFSET and FW_ROM_LEN set ROM_LEN
+test-assert_overflow_offset_and_romlen: ROM_OFFSET=0x1000
+test-assert_overflow_offset_and_romlen: FW_ROM_LEN=$(ROM_LEN_BYTES)
+
+.PHONY: test-assert_overflow_%
+test-assert_overflow_%: $(ELFFILES_DEPS)
+	$(Q) echo -n "Test ROM overflow detection ($*): "
+	$(Q)\
+	{ $(_LINK) -o /dev/null 2>&1 | grep -q 'Specified firmware size does not fit in ROM' ; } \
+	  && echo [OK] || { echo [ERROR] Compilation should have failed >&2; exit 1; }
diff --git a/tests/cortexm_common_ldscript/README.md b/tests/cortexm_common_ldscript/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..5571d4adc47fd2547476c4dbc20372c2f1485101
--- /dev/null
+++ b/tests/cortexm_common_ldscript/README.md
@@ -0,0 +1,45 @@
+Cortexm-common ldscript
+=======================
+
+This test checks the support for building firmwares with a rom offset and
+specific sized firmwares using `cortexm-common` ldscript.
+
+When building `all`, the `compile-tests` target is also build and executes build
+time compilation tests checking different firmwares configurations verified by
+inspecting the result elf files.
+
+
+Test output
+-----------
+
+For a board that does not have a `ROM_OFFSET` variable configured by default
+(== a board without bootloader installed), it produces the following output
+after the normal compilation:
+
+```
+make all BOARD=iotlab-m3
+...
+Test rom offset 1 byte overflow detection: [OK]
+Test rom offset substracted from rom length in elffile: [SKIP](Reason: board does not have a ROM_OFFSET configured)
+Test compilation with offset 0x1000: [OK]
+Test compilation with offset 0x2000: [OK]
+Test compilation with half ROM length: [OK]
+Test ROM overflow detection (too_big_for_rom): [OK]
+Test ROM overflow detection (offset_and_romlen): [OK]
+```
+
+For a bord that have a `ROM_OFFSET` variable configured by default (== a board
+with bootloader installed), it produces the following output after the normal
+compilation:
+
+```
+make BOARD=bluepill  PROGRAMMER=dfu-util
+...
+Test rom offset 1 byte overflow detection: [OK]
+Test rom offset substracted from rom length in elffile: [OK]
+Test compilation with offset 0x1000: [OK]
+Test compilation with offset 0x2000: [OK]
+Test compilation with half ROM length: [OK]
+Test ROM overflow detection (too_big_for_rom): [OK]
+Test ROM overflow detection (offset_and_romlen): [OK]
+```
diff --git a/tests/cortexm_common_ldscript/main.c b/tests/cortexm_common_ldscript/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..59d2d4dcce298b471294968cbceae72197190060
--- /dev/null
+++ b/tests/cortexm_common_ldscript/main.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2018 Freie Universität Berlin
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser General
+ * Public License v2.1. See the file LICENSE in the top level directory for more
+ * details.
+ */
+
+/**
+ * @ingroup     tests
+ * @{
+ *
+ * @file
+ * @brief       Empty main file
+ *
+ * @author      Gaëtan Harter <gaetan.harter@fu-berlin.de>
+ *
+ * @}
+ */
+
+int main(void)
+{
+    /* The important rules are in the Makefile */
+    return 0;
+}