Hi all…
I'm in the process of porting a firmware project to a newer version of the GNU ARM toolchain, previously this was written for v6 of the toolchain, which is quite dated. I'm currently doing some testing with v12.2 beta 1 -- probably won't use this in production (I'll likely use 11.3r1), but since the newer release is there, I'll use that to do the initial porting to possibly shake out some bugs that v12 may bring.
One issue I'm hitting is with `ld`… I won't post the _actual_ code being used, but I'll instead post this simple little test case:
stuartl@vk4msl-ws:/tmp/test$ tail -n +0 * ==> boot.c <== #include <stdbool.h> int main(void) { while (true); return 0; } ==> boot.ld <== INCLUDE "mem.ld" ENTRY(main) SECTIONS { .reserved_app : ALIGN(4) { . = 0x00000000; application_start = .; FILL(0xff); . += LENGTH(APPLICATION) - 1; BYTE(0xff); } > APPLICATION=0xffffffff .text : ALIGN(4) { _text = .; *(.text*) *(.rodata*) KEEP(*(.init)) KEEP(*(.fini)) /* * Move vectors to top of flash to ensure 512-byte alignment. * Failure to maintain alignment will result in a double * hard-fault at boot. */ . = 0x006b40; *(.vectors) _etext = .; } > BOOTLOADER= 0 .init_array : { _init_array = .; KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array*)) _einit_array = .; } > BOOTLOADER __exidx_start = .; .ARM.exidx : ALIGN(4) { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > BOOTLOADER __exidx_end = .; .data : ALIGN(4) { _data = .; *(.data*) _edata = .; } > SRAM AT > BOOTLOADER _ldata = LOADADDR(.data); .bss : ALIGN(4) { __bss_start__ = .; *(.bss*) *(COMMON) __bss_end__ = .; } > SRAM _heap = .; end = .; .stack : ALIGN(4) { _stack = .; *(.stack) } > STACK } ==> Makefile <== CROSS_COMPILE ?= arm-none-eabi- CC = $(CROSS_COMPILE)gcc CFLAGS = -fdata-sections -ffunction-sections -Os -g -mcpu=cortex-m3 -mfloat-abi=soft -mthumb LDFLAGS = -T boot.ld -lc -lgcc -lnosys -Wl,-Map=boot.map .PHONY: clean all all: boot.elf clean: rm -f boot.o boot.elf boot.map boot.elf: boot.o $(CC) $(LDFLAGS) -o $@ $< boot.o: boot.c ==> mem.ld <== MEMORY { APP_DATA (r) : ORIGIN = 0x00200000, LENGTH = 4096 APPLICATION (rx) : ORIGIN = 0x00201000, LENGTH = 483328 METADATA (r) : ORIGIN = 0x00277000, LENGTH = 8192 BOOTLOADER (rx) : ORIGIN = 0x00279000, LENGTH = 32768 SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 27K STACK (rwx) : ORIGIN = 0x20006c00, LENGTH = 5K PERIPHERAL (rw) : ORIGIN = 0x40000000, LENGTH = 0x20000000 SYSPERIPH (rw) : ORIGIN = 0xe0000000, LENGTH = 0x00042000 }
The actual application has two parts that need to be built: one is a boot-loader, and the other is the main application. To place the parts in the right spots, I use different linker scripts, but they have _common_ sections in their linker scripts, so these are split out into different files and included in the relevant linker script.
In older releases of the toolchain, this worked beautiful:
stuartl@vk4msl-ws:/tmp/test$ make clean all CROSS_COMPILE=/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi- rm -f boot.o boot.elf boot.map /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc -fdata-sections -ffunction-sections -Os -g -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -c -o boot.o boot.c /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc -T boot.ld -lc -lgcc -lnosys -Wl,-Map=boot.map -o boot.elf boot.o stuartl@vk4msl-ws:/tmp/test$ cat boot.map Archive member included to satisfy reference by file (symbol) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/crt0.o (exit) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-impure.o) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o) (_global_impure_ptr) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-init.o) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/crt0.o (__libc_init_array) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-memset.o) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/crt0.o (memset) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o) (__call_exitprocs) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-atexit.o) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o) (atexit) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-fini.o) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o) (__libc_fini_array) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o) (__retarget_lock_acquire_recursive) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__atexit.o) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-atexit.o) (__register_exitproc) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libnosys.a(_exit.o) /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o) (_exit) Allocating common symbols Common symbol size file __lock___atexit_recursive_mutex 0x1 /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___arc4random_mutex 0x1 /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___env_recursive_mutex 0x1 /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___sinit_recursive_mutex 0x1 /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___malloc_recursive_mutex 0x1 /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___at_quick_exit_mutex 0x1 /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___dd_hash_mutex 0x1 /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___tz_mutex 0x1 /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___sfp_recursive_mutex 0x1 /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) Memory Configuration Name Origin Length Attributes APP_DATA 0x0000000000200000 0x0000000000001000 r APPLICATION 0x0000000000201000 0x0000000000076000 xr METADATA 0x0000000000277000 0x0000000000002000 r BOOTLOADER 0x0000000000279000 0x0000000000008000 xr SRAM 0x0000000020000000 0x0000000000006c00 xrw STACK 0x0000000020006c00 0x0000000000001400 xrw PERIPHERAL 0x0000000040000000 0x0000000020000000 rw SYSPERIPH 0x00000000e0000000 0x0000000000042000 rw *default* 0x0000000000000000 0xffffffffffffffff … etc …
Even the standard Ubuntu 22.04 arm-none-eabi toolchain works:
stuartl@vk4msl-ws:/tmp/test$ make clean all rm -f boot.o boot.elf boot.map arm-none-eabi-gcc -fdata-sections -ffunction-sections -Os -g -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -c -o boot.o boot.c arm-none-eabi-gcc -T boot.ld -lc -lgcc -lnosys -Wl,-Map=boot.map -o boot.elf boot.o stuartl@vk4msl-ws:/tmp/test$ arm-none-eabi-gcc --version arm-none-eabi-gcc (GNU Arm Embedded Toolchain 9-2020-q2-update) 9.3.1 20200408 (release) Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. stuartl@vk4msl-ws:/tmp/test$ cat boot.map Archive member included to satisfy reference by file (symbol) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/crt0.o (exit) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-impure.o) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o) (_global_impure_ptr) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-init.o) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/crt0.o (__libc_init_array) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-memset.o) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/crt0.o (memset) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o) (__call_exitprocs) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-atexit.o) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o) (atexit) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-fini.o) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o) (__libc_fini_array) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o) (__retarget_lock_acquire_recursive) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__atexit.o) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-atexit.o) (__register_exitproc) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libnosys.a(_exit.o) /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o) (_exit) Allocating common symbols Common symbol size file __lock___atexit_recursive_mutex 0x1 /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___arc4random_mutex 0x1 /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___env_recursive_mutex 0x1 /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___sinit_recursive_mutex 0x1 /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___malloc_recursive_mutex 0x1 /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___at_quick_exit_mutex 0x1 /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___dd_hash_mutex 0x1 /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___tz_mutex 0x1 /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) __lock___sfp_recursive_mutex 0x1 /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o) Memory Configuration Name Origin Length Attributes APP_DATA 0x0000000000200000 0x0000000000001000 r APPLICATION 0x0000000000201000 0x0000000000076000 xr METADATA 0x0000000000277000 0x0000000000002000 r BOOTLOADER 0x0000000000279000 0x0000000000008000 xr SRAM 0x0000000020000000 0x0000000000006c00 xrw STACK 0x0000000020006c00 0x0000000000001400 xrw PERIPHERAL 0x0000000040000000 0x0000000020000000 rw SYSPERIPH 0x00000000e0000000 0x0000000000042000 rw *default* 0x0000000000000000 0xffffffffffffffff
BUT… ARM's latest (beta) toolchain does not like this:
stuartl@vk4msl-ws:/tmp/test$ make clean all CROSS_COMPILE=/tmp/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/arm-none-eabi- rm -f boot.o boot.elf boot.map /tmp/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/arm-none-eabi-gcc -fdata-sections -ffunction-sections -Os -g -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -c -o boot.o boot.c /tmp/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/arm-none-eabi-gcc -T boot.ld -lc -lgcc -lnosys -Wl,-Map=boot.map -o boot.elf boot.o /tmp/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld:boot.ld:15: warning: memory region `APPLICATION=0xffffffff' not declared /tmp/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld:boot.ld:30: warning: memory region `BOOTLOADER=' not declared /tmp/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld:boot.ld:30: syntax error collect2: error: ld returned 1 exit status make: *** [Makefile:14: boot.elf] Error 1
Is there something I've missed?
I note the latest _stable_ release (11.3.rel1) does the same thing. BUT 11.2-2022.02 seems fine.