linker - gcc for ARM - move code and stack -


i working on project arm cortex-m3 (silabs) soc. need move interrupt vector [edit] , code away bottom of flash make room "boot loader". boot loader starts @ address 0 come when core comes out of reset. function validate main image, loaded @ higher address , possibly replace main image new one.

therefore, boot loader have vector table @ 0, followed code. @ higher, fixed address, 8kb, main image, starting vector table.

i have found this page describes vector table offset register boot loader can use (with interrupts masked, obviously) point hardware new vector table.

my question how "main" image linked work when written flash, starting not @ zero. i'm not familiar arm assembly assume code not position independent.

i'm using silabs's precision32 ide uses gcc toolchain. i've found how add linker flags. question gcc flag(s) provide change base of vector table , code.

thank you.

vectors.s

.cpu cortex-m3 .thumb  .word   0x20008000  /* stack top address */ .word   _start      /* reset */ .word   hang .word   hang /* ... */  .thumb_func hang:   b .  .thumb_func .globl _start _start:     bl notmain     b hang 

notmain.c

extern void fun ( unsigned int ); void notmain ( void ) {     fun(7); } 

fun.c

void fun ( unsigned int x ) { } 

makefile

hello.elf : vectors.s fun.c notmain.c memmap     arm-none-eabi-as vectors.s -o vectors.o     arm-none-eabi-gcc -wall  -o2 -nostdlib -nostartfiles -ffreestanding -mthumb -mcpu=cortex-m3 -march=armv7-m -c notmain.c -o notmain.o     arm-none-eabi-gcc -wall  -o2 -nostdlib -nostartfiles -ffreestanding -mthumb -mcpu=cortex-m3 -march=armv7-m -c fun.c -o fun.o     arm-none-eabi-ld -o hello.elf -t memmap vectors.o notmain.o fun.o     arm-none-eabi-objdump -d hello.elf > hello.list     arm-none-eabi-objcopy hello.elf -o binary hello.bin 

so if linker script (memmap name used) looks this

memory {    rom : origin = 0x00000000, length = 0x40000    ram : origin = 0x20000000, length = 0x8000 }  sections {    .text : { *(.text*) } > rom    .bss  : { *(.bss*) } > ram } 

since of above .text, no .bss nor .data, linker takes objects listed on ld command line , places them starting @ address...

mbly of section .text:

00000000 <hang-0x10>:    0:   20008000    andcs   r8, r0, r0    4:   00000013    andeq   r0, r0, r3, lsl r0    8:   00000011    andeq   r0, r0, r1, lsl r0    c:   00000011    andeq   r0, r0, r1, lsl r0  00000010 <hang>:   10:   e7fe        b.n 10 <hang>  00000012 <_start>:   12:   f000 f801   bl  18 <notmain>   16:   e7fb        b.n 10 <hang>  00000018 <notmain>:   18:   2007        movs    r0, #7   1a:   f000 b801   b.w 20 <fun>   1e:   bf00        nop  00000020 <fun>:   20:   4770        bx  lr   22:   bf00        nop 

so work have careful put bootstrap code first on command line. can things linker script.

the order appears matter, listing specific object files first generic .text later

memory {    romx : origin = 0x00000000, length = 0x1000    romy : origin = 0x00010000, length = 0x1000    ram  : origin = 0x00030000, length = 0x1000    bob  : origin = 0x00040000, length = 0x1000    ted  : origin = 0x00050000, length = 0x1000 }  sections {    abc : { vectors.o } > romx    def : { fun.o } > ted    .text : { *(.text*) } > romy    .bss  : { *(.bss*) } > ram } 

and this

00000000 <hang-0x10>:    0:   20008000    andcs   r8, r0, r0    4:   00000013    andeq   r0, r0, r3, lsl r0    8:   00000011    andeq   r0, r0, r1, lsl r0    c:   00000011    andeq   r0, r0, r1, lsl r0  00000010 <hang>:   10:   e7fe        b.n 10 <hang>  00000012 <_start>:   12:   f00f fff5   bl  10000 <notmain>   16:   e7fb        b.n 10 <hang>  disassembly of section def:  00050000 <fun>:    50000:   4770        bx  lr    50002:   bf00        nop  disassembly of section .text:  00010000 <notmain>:    10000:   2007        movs    r0, #7    10002:   f03f bffd   b.w 50000 <fun>    10006:   bf00        nop 

the short answer gnu tools use linker script manipulate things end up, assume want these functions in rom @ specified location. dont quite understand doing. if example trying put simple branch main() in flash main() being deeper in flash, somehow either through whatever code deeper in flash or through other method, later erase , reprogram stuff near zero. still need simple branch main() first time. can force calling vectors.o @ address 0 .text can deeper in flash putting of reset of code there, leave in flash , replace stuff @ zero.

like this

memory {    romx : origin = 0x00000000, length = 0x1000    romy : origin = 0x00010000, length = 0x1000    ram  : origin = 0x00030000, length = 0x1000    bob  : origin = 0x00040000, length = 0x1000    ted  : origin = 0x00050000, length = 0x1000 }  sections {    abc : { vectors.o } > romx    .text : { *(.text*) } > romy    .bss  : { *(.bss*) } > ram } 

giving

00000000 <hang-0x10>:    0:   20008000    andcs   r8, r0, r0    4:   00000013    andeq   r0, r0, r3, lsl r0    8:   00000011    andeq   r0, r0, r1, lsl r0    c:   00000011    andeq   r0, r0, r1, lsl r0  00000010 <hang>:   10:   e7fe        b.n 10 <hang>  00000012 <_start>:   12:   f00f fff7   bl  10004 <notmain>   16:   e7fb        b.n 10 <hang>  disassembly of section .text:  00010000 <fun>:    10000:   4770        bx  lr    10002:   bf00        nop  00010004 <notmain>:    10004:   2007        movs    r0, #7    10006:   f7ff bffb   b.w 10000 <fun>    1000a:   bf00        nop 

then leave 0x10000 stuff , replace 0x00000 stuff later.

anyway, short answer linker script need craft linker script put things want them. gnu linker scripts can extremely complicated, lean toward simple.

if want place @ other address, including vector table, perhaps this:

hop.s

.cpu cortex-m3 .thumb  .word   0x20008000  /* stack top address */ .word   _start      /* reset */ .word   hang .word   hang /* ... */  .thumb_func hang:   b .  .thumb_func     ldr r0,=_start     bx r0 

and this

memory {    romx : origin = 0x00000000, length = 0x1000    romy : origin = 0x00010000, length = 0x1000    ram  : origin = 0x00030000, length = 0x1000    bob  : origin = 0x00040000, length = 0x1000    ted  : origin = 0x00050000, length = 0x1000 }  sections {    abc : { hop.o } > romx    .text : { *(.text*) } > romy    .bss  : { *(.bss*) } > ram } 

gives this

disassembly of section abc: 00000000 <hang-0x10>:    0:   20008000    andcs   r8, r0, r0    4:   00010013    andeq   r0, r1, r3, lsl r0    8:   00000011    andeq   r0, r0, r1, lsl r0    c:   00000011    andeq   r0, r0, r1, lsl r0  00000010 <hang>:   10:   e7fe        b.n 10 <hang>   12:   4801        ldr r0, [pc, #4]    ; (18 <hang+0x8>)   14:   4700        bx  r0   16:   00130000   1a:   20410001  disassembly of section .text:  00010000 <hang-0x10>:    10000:   20008000    andcs   r8, r0, r0    10004:   00010013    andeq   r0, r1, r3, lsl r0    10008:   00010011    andeq   r0, r1, r1, lsl r0    1000c:   00010011    andeq   r0, r1, r1, lsl r0  00010010 <hang>:    10010:   e7fe        b.n 10010 <hang>  00010012 <_start>:    10012:   f000 f803   bl  1001c <notmain>    10016:   e7fb        b.n 10010 <hang>  00010018 <fun>:    10018:   4770        bx  lr    1001a:   bf00        nop  0001001c <notmain>:    1001c:   2007        movs    r0, #7    1001e:   f7ff bffb   b.w 10018 <fun>    10022:   bf00        nop 

then can change vector table 0x10000 example.

if asking different question having bootloader @ 0x00000, bootloader modifies flash add application @ 0x20000, want run application, there simpler solutions dont require modify location of vector table.


Comments

Popular posts from this blog

css - Which browser returns the correct result for getBoundingClientRect of an SVG element? -

gcc - Calling fftR4() in c from assembly -

.htaccess - Matching full URL in RewriteCond -