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
Post a Comment