cancel
Showing results for 
Search instead for 
Did you mean: 

how to build a binary image such that the entry point is at the very beginning.

VBe.1
Associate II

I am using gnu tool chain and am trying to build an image for the Nucleo F072RB board.

It all looks good, the only problem is that the map of the image looks as follows:

08000000 t deregister_tm_clones

08000024 t register_tm_clones

0800004c t __do_global_dtors_aux

08000078 t frame_dummy

080000b4 T _mainCRTStartup

080000b4 T _start

...

persumably _start is the entry point of the program, but it is not at the beginning of the image when elf is converted to binary, so the program is not going to be started properly.

Or maybe a more open question: is there some tutorial on how to build executable images for flashing for the Nucleo board. I searched the ST site - information is related to various IDEs, but nothing for Linux command line.

TIA!

6 REPLIES 6
Guillaume K
ST Employee

in ARM Cortex M architecture the first hundreds bytes in flash memory must be the interrupts vectors table.

it's a table of 4 bytes addresses containing the addresses of the interrupts.

the size of the table depends from the processor architecture (how many interrupts on your specific SoC).

In ARM cortex M architecture there are standard ARM Cortex M interrupts (reset, ) , then SoC specific interrupts (DMA, I2C, SPI, ...).

The first address contains the stack pointer initial value.

Then at second position 0x4 (0x8000004 in STM32 case) is the address of reset interrupt handler ( _start for you).

usually the STM32 applications have an assembler file (startup.s) that contains the definition of these interrupt vectors.

This assembler file must be placed at address 0x8000000 by the linker file of your application.

VBe.1
Associate II

How do I achieve this practically, using gcc as the linker?

This is how it is invoked in my case

arm-none-eabi-gcc -mcpu=cortex-m0 -mthumb --specs=nosys.specs -Wl,-Map,app.elf.map -Wl,-Tld.lds -o app.elf main.o < a few more .o files> <a few .lib files>

and this is the linker script:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
/* ENTRY(reset) */
MEMORY
{
 FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x20000
 IRAM (rw) : ORIGIN = 0x20000000, LENGTH = 0x10000
}
SECTIONS
{
 .text : {
/* "/usr/lib/arm-none-eabi/newlib/thumb/v6-m/crt0.o" (.text) */
  *(.text*)
 } > FLASH
 . = ALIGN(4);
 .rodata : {
  *(.rodata*)
  . = ALIGN(4);
 } > FLASH
 .bss : {
__bss_start__ = .;
  *(.bss)
__bss_end__ = .;
 } > IRAM
 .data : {
  . = ALIGN(4);
  *(.data*)
 } > IRAM AT > FLASH
}

Looking at the map file, I don't think this results in a properly executable program ready for converting to binary and flashing.

Guillaume K
ST Employee

have a look at the example projects in Cube F0 package:

https://github.com/STMicroelectronics/STM32CubeF0/tree/master/Projects

in System Workbench (SW4STM32) or STM32CubeIDE folders there are examples of startup.s files and .ld files for gcc.

What your original question asks for doesn't make sense in the context of the CM0(+) core, read the TRM

You want the vector table at the front of the image, this typically comes from startup.s, and lists addresses the core pulls out for the initial SP/PC registers.

Code in startup.s unpacks the load regions from ROM into RAM, and the object file content needs to be fixed, it is not like an executable or dynamic library in Linux.

Examples of the .LD and startup.s can be found under the CubeF0 repository trees

Here an example for the F1 series, as I'm not using F0 parts

STM32Cube_FW_F1_V1.8.0\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\gcc\startup_stm32f100xb.s

STM32Cube_FW_F1_V1.8.0\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\gcc\linker\STM32F100XB_FLASH.ld

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
RMcCa
Senior II

On the f & h7s there is a section called .isr_vector in startup.s which is where all the interrupt addresses are defined. Additionally, you need to tell the linker where to put it. The first defined section for the flash in the linker script should be the .isr_vector so that it ends up at the very beginning of flash. Don't know about the interrupt structure of an M0, but I suspect it won't work without a vector table.

VBe.1
Associate II

Thank you Guillaume, this is exactly what I was missing.