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.

Parents
  • You have properly put

    .section .Vectors
    

    at the top to switch to the .Vectors section. However you need to switch out of it again back to .text before you define the Reset_handler (else it won't actually go into a section because it won't match anything). However you've just put

    .text
    

    not

    .section .text
    

    to do that. I suspect if you check the linker map file you'll find some/lots/at least Reset_handler marked as in the vectors section .Vectors.Reset_handler and discarded.

    I don't even know what a naked .text. does in the middle of the file, you'd expect a linker warning.

    Switch the section properly and see if that improves life. If it doesn't, hit the map file and start seeing what the linker is doing on a trivial example.

  • From documentation here the naked .text directive tells the assembler to place the following code at the beginning of the code .text section.

    The startup assembly is unmodified from the mbed version. I have achieved my desired code placement in a slightly different way and have detailed it in my original post.

Reply Children
No Data
Related