Help building bare-metal bootloader

I’m having issues building a bare-metal bootloader for stm32. The code is here: GitHub - Spongman/STM32duino-bootloader: Bootloader for STM32F103 boards, for use with the Arduino_STM32 repo and the Arduino IDE I’m trying to build the env:generic-pc13 target.

The relevant parts of the platformio.ini file:

[platformio]
src_dir = .
framework=

[env]
platform = ststm32
board_build.ldscript = stm32_lib/c_only_md_high_density.ld
src_filter = +<*> -<sketch_combiner/> -<stm32_lib/c_only_startup_user.s>

[common]
build_flags = --specs=nosys.specs -Istm32_lib -Iusb_lib --verbose -Wl,--verbose  -nostartfiles -nodefaultlibs -nostdlib -Wl,-nolibc  -Wl,--gc-sections -ffreestanding -fno-builtin

[env:generic-pc13]
board = genericSTM32F103C8
build_flags = ${common.build_flags} -DTARGET_GENERIC_F103_PC13

the problem is that, for some reason, the compiler insists on linking with libc/libgcc, and that’s causing various link-time errors, like :

attempt to open c:/users/user/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc.a succeeded
(c:/users/user/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc.a)lib_a-exit.o
(c:/users/user/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc.a)lib_a-impure.o
(c:/users/user/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc.a)lib_a-init.o
(c:/users/user/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc.a)lib_a-memset.o
(c:/users/user/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc.a)lib_a-__call_atexit.o
(c:/users/user/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc.a)lib_a-atexit.o
(c:/users/user/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc.a)lib_a-fini.o
(c:/users/user/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc.a)lib_a-lock.o
(c:/users/user/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m\libc.a)lib_a-__atexit.o

libc section `._usrstack' will not fit in region `RAM'
section .init LMA [08001910,08001913] overlaps section .data LMA [08001910,0800200b]
region `RAM' overflowed by 128 bytes

I don’t have a framework specified, i’m throwing all sorts of compiler flags to avoid this, but none of it is working. anyone know how to get this to build?

You could try specifying the cmsis of libopencm3 framework - they both have minimal runtimes when not calling into anything, and you can override whatever else is left.

thanks, that doesn’t seem to help. i just get duplicate definitions of things like g_pfnVectors and USBWakeUp_IRQHandler. this is a bootloader, it doesn’t need any library/framework code. i just can’t work out how to disable including that in platformio.

there’s a bunch of older issues on here talking about ensuring that no framework= is specified, but that doesn’t seem to work any more, since i’m doing that.

The weird thing is that if I use the Makefile in that directory to build it using the cross-compiler installed using apt-get, it seems to work fine:

Linking: build/maple_boot.elf
arm-none-eabi-gcc -mthumb -g -mcpu=cortex-m3 -mthumb-interwork -I.  -Os -ffunction-sections -fdata-sections -Wall -Wimplicit -Wcast-align -Wpointer-arith -Wswitch -Wredundant-decls 
-Wreturn-type -Wshadow -Wunused -Wa,-adhlns=build/build/usb.lst -I./stm32_lib -I./usb_lib -DTARGET_GENERIC_F103_PC13  -MD -MP -MF .dep/maple_boot.elf.d  build/stm32_lib/c_only_startup.o  build/stm32_lib/cortexm3_macro.o  build/usb.o  build/usb_callbacks.o  build/usb_descriptor.o  build/main.o  build/hardware.o  build/dfu.o  build/usb_lib/usb_regs.o  build/usb_lib/usb_int.o  build/usb_lib/usb_init.o  build/usb_lib/usb_core.o  build/usb_lib/usb_mem.o --output build/maple_boot.elf -nostartfiles -Wl,-Map=build/maple_boot.map,--cref,--gc-sections -lc -lgcc -Tstm32_lib/c_only_md_high_density.ld

Ah, you’re also supplying your own vector table (and reset handler no doubt).

I’ve gone through similar gyrations at some point (also for an STM32 boot loader). First off, you can supply your own .ld file, and use a different section name for the vector table, iso .isr_vector. Likewise for changing ENTRY(Reset_Handler). Then, none of the framework code will be referenced, as far as I can tell.

With rm -rf .pio; pio run -v you can check what gcc commands are being generated by PIO.

you can supply your own .ld file

like this?

board_build.ldscript = stm32_lib/c_only_md_high_density.ld

it’ all there in the github project. i also included the relevant parts of the platformio.ini file above…