0

I'm trying to move my _start function to 0x0, as it is the bootloader.

Flash ROM exists from 0x0 to the first 128MB (=1Gb), other memory is DDR3 RAM but we will map RAM to 0x80000000 to 0xFFFFFFFF.

The issue is with the directive .section ".vect", the _start address is not going into the .vect section, it is going into the .text section.

_start:
    .section ".vect"  /* I've tried .section .vect and I've tried moving above _start */
    b ResetHandler
    b UndefHandler
    b SVC_Handler
    b PrefetchAbortHandler
    b DataAbortHandler
    b NotUsedHandler
    b IRQ_Handler
    b FIQ_Handler
1:
    b 1b  /* Hang and don't return */

In my linker script, the MEMORY command and then the start of SECTIONS is:

MEMORY
{
    vect (rx) : o = 0x0, l = 1M
    rom (rx) : o = 1M, l = 127M
    ram (wx) : o = 0x80000000, l = 0x80000000
}


SECTIONS 
{
    .vect : ALIGN(64) 
    {
        . = 0x0;
        *(.vect*)
        VectTableEnd = .;
        VectTableSize = SIZEOF(.vect);
    } > vect 
    .... (.text, .bss, .data, .stack, etc are other SECTIONS entries)
}

But no matter what, the _start assembly function code gets shoved into the standard .text section, not at address 0x0. Does anyone know what I'm going wrong?

The code is targetted at bare-metal ARMv7A machines, compiled/linked with arm-none-eabi-as/ld

Cheers.

Gregory Fenn
  • 460
  • 2
  • 13

1 Answers1

1

No surprises here if your _start label ends up in .text:

/* implicitly default section .text */
_start:
/* still the same section .text */
        .section .vect
/* explicitly the section .vect */
        b       ResetHandler

You probably want to switch the section before defining the _start label to make that label end up in the intended section.

/* implicitly default section .text */
        .section .vect
/* explicitly the section .vect */
_start:
        b       ResetHandler

Using the name _start as the symbol for a vector table is a bit weird (I would have expected a symbol like __vectors or vector_table), but that is beyond the scope of this question.

ndim
  • 35,870
  • 12
  • 47
  • 57
  • The weird thing is just the choice of name for `_start`. This looks like an interrupt vector table. Or an attempt at one, since it has instructions instead of pointers? Maybe ARM works that way, IDK. The ResetHandler is startup code, though: it's code that runs after the machine is reset. – Peter Cordes Mar 21 '22 at 00:30
  • I know the AVR vector tables avr-gcc/avr-libc generate are four byte `jmp LABEL` instructions, so it would not surprise me if ARM used the same principle with `b LABEL` instructions. Using standard instructions instead of a 8086 type address table for interrupt vectors might just reduce the number of extra logic gates needed to implement interrupts on RISC processors. – ndim Mar 21 '22 at 00:43
  • 1
    I was curious so I checked: https://developer.arm.com/documentation/ddi0406/c/System-Level-Architecture/The-System-Level-Programmers--Model/Exception-handling/Exception-vectors-and-the-exception-base-address?lang=en says that ARMv7-A uses a table of addresses (*eight consecutive word-aligned memory addresses*), not instructions. And the order / naming matches up with the question, Reset, then Undefined Instruction, etc. – Peter Cordes Mar 21 '22 at 01:05
  • 1
    ARM7TMDI Resets appear to just run the code at address `0x00`, so a `b ResetHandler` instruction is what you want at address 0: https://developer.arm.com/documentation/ddi0210/c/Programmer-s-Model/Reset – ndim Mar 21 '22 at 20:23