STM32-P405 Startup Code – Build System

To remove the tedium of having to type build commands by hand, and also having to type commands into GDB to load and execute the startup code a build system can be used which uses the GNU make command and an init file for GDB.

To begin create a file called Makefile in the startup code source directory ($HOME/arm/cortex/stm32p405/examples/introduction/000_simple_startup/src) with the following contents:

OBJ := vector_table.o 
LDFLAGS := -g -o
ASMFLAGS := -g -o

all: $(TARGET)

%.o: %.s
 $(CROSS)as $(ASMFLAGS) $@ $<


 $(RM) *.o *.elf

debug: $(TARGET)
 $(CROSS)gdb -x gdbinit

and a file called gdbinit with the following contents:

target remote localhost:3333
load startup.elf
file startup.elf
break reset_handler
info reg

The Makefile can now be used to build the ELF file and also launch GDB which will read the and execute the commands to connect to the OpnOCD GDB interface, then load the image onto the board, set a breakpoint and show the state of the registers when the function reset_handler() is called, for example:

arm-none-eabi-as -g -o vector_table.o vector_table.s
arm-none-eabi-ld -g -o startup.elf -T startup.ld vector_table.o 

make debug
arm-none-eabi-gdb -x gdbinit
GNU gdb (
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
Find the GDB manual and other documentation resources online at:
For help, type "help".
Type "apropos word" to search for commands related to "word".
0x08000040 in ?? ()
Loading section .text, size 0x4c lma 0x8000000
Start address 0x8000000, load size 76
Transfer rate: 118 bytes/sec, 76 bytes/write.
Breakpoint 1 at 0x8000040: file vector_table.s, line 29.
Note: automatically using hardware breakpoints for read-only addresses.

Breakpoint 1, reset_handler () at vector_table.s:29
29 bl reset_handler
r0 0x0 0
r1 0x0 0
r2 0x0 0
r3 0x0 0
r4 0x0 0
r5 0x0 0
r6 0x0 0
r7 0x0 0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
sp 0x20001000 0x20001000
lr 0xffffffff -1
pc 0x8000040 0x8000040 <reset_handler>
xPSR 0x41000000 1090519040
(gdb) quit
A debugging session is active.

 Inferior 1 [Remote target] will be detached.

Quit anyway? (y or n) y
Detaching from program: /home/akeane/arm/cortex/stm32p405/blog/000_simple_startup/src/startup.elf, Remote target
Ending remote debugging.

The Makefile also has a target: clean, which is used to remove any object file or ELF files, for example:

make clean
rm -f *.o *.elf

Now the build system is in place we can explore some of the concepts of the ARM Cortex M architecture using this startup code as a base.