This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Separate Vectors from .text

Hello,

For more "simplicity" I have devised my own OTA update procedure. It relies on image information being embedded in a dedicated section (I have modified the linker script to do this) but now I am having trouble with the following:

I want to move the interrupt vectors to the start of my program (where they should be) and then insert this image information section after that vectors (with a known offset) and then begin the main .text/program section.

How would one go about doing this in the linker script/startup assembly? I am using mbed as my RTOS platform. The startup assembly/linker script for this platform can be found here

EDIT:

I have attempted to change the linker file to accomplish this... but it's apparently not as easy as I think it is.

The startup assembly looks like this:

 .syntax unified
 .arch armv7e-m

 .section .Vectors
 .align 2
 .globl __Vectors
 __Vectors:
.long   __StackTop                  /* Top of Stack */
.long   Reset_Handler
.long   NMI_Handler
.long   HardFault_Handler
.long   MemoryManagement_Handler
.long   BusFault_Handler
.long   UsageFault_Handler
.long   0                           /*Reserved */
.long   0                           /*Reserved */
.long   0                           /*Reserved */
.long   0                           /*Reserved */
.long   SVC_Handler
.long   0                           /*Reserved */
.long   0                           /*Reserved */
.long   PendSV_Handler
.long   SysTick_Handler

/* External Interrupts */
.long   POWER_CLOCK_IRQHandler
.long   RADIO_IRQHandler
.long   UARTE0_UART0_IRQHandler_v
.long   SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
.long   SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
.long   NFCT_IRQHandler_v
.long   GPIOTE_IRQHandler_v
.long   SAADC_IRQHandler_v
.long   TIMER0_IRQHandler_v
.long   TIMER1_IRQHandler_v
.long   TIMER2_IRQHandler_v
.long   RTC0_IRQHandler
.long   TEMP_IRQHandler_v
.long   RNG_IRQHandler
.long   ECB_IRQHandler
.long   CCM_AAR_IRQHandler
.long   WDT_IRQHandler_v
.long   RTC1_IRQHandler_v
.long   QDEC_IRQHandler_v
.long   COMP_LPCOMP_IRQHandler_v
.long   SWI0_EGU0_IRQHandler_v
.long   SWI1_EGU1_IRQHandler_v
.long   SWI2_EGU2_IRQHandler_v
.long   SWI3_EGU3_IRQHandler_v
.long   SWI4_EGU4_IRQHandler
.long   SWI5_EGU5_IRQHandler
.long   TIMER3_IRQHandler_v
.long   TIMER4_IRQHandler_v
.long   PWM0_IRQHandler_v
.long   PDM_IRQHandler_v
.long   0                           /*Reserved */
.long   0                           /*Reserved */
.long   MWU_IRQHandler
.long   PWM1_IRQHandler_v
.long   PWM2_IRQHandler_v
.long   SPIM2_SPIS2_SPI2_IRQHandler_v
.long   RTC2_IRQHandler_v
.long   I2S_IRQHandler_v
.long   FPU_IRQHandler_v


.size    __Vectors, . - __Vectors

/* Reset Handler */

.text
.thumb
.thumb_func
.align 1
.globl    Reset_Handler
.type    Reset_Handler, %function
Reset_Handler:
.fnstart

ldr    r1, =__etext
ldr    r2, =__data_start__
ldr    r3, =__data_end__

subs    r3, r2
ble     .LC0

.LC1:
subs    r3, 4
ldr    r0, [r1,r3]
str    r0, [r2,r3]
bgt    .LC1
.LC0:

LDR     R0, =SystemInit
BLX     R0
LDR     R0, =nrf_reloc_vector_table
BLX     R0
LDR     R0, =_start
BX      R0

.pool
.cantunwind
.fnend
.size   Reset_Handler,.-Reset_Handler

.section ".text"

Now it appears to me that I should be able to just relocate the ".Vectors" section to the beginning of flash, insert my image info section between them, and then keep the Reset_Handler and other ISRs at the beginning of the ".text" section. To do this, I modified the linker script to this:

MEMORY
{
   VECTORS(rx) : ORIGIN = 0, LENGTH = 0x400
   IMAGEINFO(r): ORIGIN = 0x400, LENGTH = IMAGE_INFO_OFFSET
   FLASH(rx) :  ORIGIN = 0x400+IMAGE_INFO_OFFSET, LENGTH = MBED_APP_SIZE-(IMAGE_INFO_OFFSET+0x400)
   RAM (rwx) :  ORIGIN = 0x20002ef8, LENGTH = 0xd108
}


OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")

ENTRY(Reset_Handler)


SECTIONS
{
   .vectors :
   {
   KEEP(*(.Vectors))
   } > VECTORS

.imageinfo :
{
KEEP(*(.ImageInfo))
} > IMAGEINFO

.text :
{
    /*KEEP(*(.Vectors))*/
    *(.text*)

    KEEP(*(.init))
    KEEP(*(.fini))

    /* .ctors */
    *crtbegin.o(.ctors)
    *crtbegin?.o(.ctors)
    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
    *(SORT(.ctors.*))
    *(.ctors)

    /* .dtors */
    *crtbegin.o(.dtors)
    *crtbegin?.o(.dtors)
    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
    *(SORT(.dtors.*))
    *(.dtors)

    *(.rodata*)

    KEEP(*(.eh_frame*))
} > FLASH

But now I get linker errors such as:

warning: cannot find entry symbol Reset_Handler; defaulting to 0000000000078400
BUILD/./main.o: In function `mbed::SPI::~SPI()':
main.cpp:(.text._ZN4mbed3SPID2Ev[_ZN4mbed3SPID5Ev]+0x18): undefined reference to `vtable for mbed::SPI'
BUILD/./main.o: In function `_GLOBAL__sub_I_g_PowerEnable':
main.cpp:(.text.startup._GLOBAL__sub_I_g_PowerEnable+0xc): undefined reference to `gpio_init_out'

And so on. Can someone give me some direction here? Shouldn't it be simple to just insert some data between the vector table and .text sections?

SOLUTION EDIT:

I have achieved my desired code spacing in a slightly different way (referencing the first answer to this question).

I changed the .text section in the linker script to begin with this:

 .text :
    {
        KEEP(*(.Vectors))
	FILL(0xff)
	. = 0x100;
	KEEP(*(.ImageInfo))
	. = 0x400;
        *(.text*)
    .....

And removed the .vectors section.

Related