Sida 1 av 1

GNU linker script med YARGATO (ARM7)?

Postat: 6 september 2007, 08:46:04
av ucadv
Jag var lite trött på Cross Studio, Keil och IAR och bestämde mig för att testa GNU kompilatorn "bare-bone". Koden jag skrev hann inte bli så mycket större än så här innan jag stötte på problem:

Kod: Markera allt

int my_init_data = 0x42; // this is here to test data initialization
int my_bss_data;
const char *my_const_data = "bla bla bla...";

int main() {
    my_init_data++; // access data so we can trace it in the dump
    my_bss_data = 0; 
    return 0;
}
Variablen "my_init_data" ska skrivas till flash. initial värdet kopieras sen från flash till SRAM vid uppstart. För det behöver man ett linker script som kanske ser ut så här:

Kod: Markera allt

 ...
   /* end of text: */
    _etext = .;
    PROVIDE(etext = .);
        
    .stack :  /* stacks and such */
    {        *(.stack);    } >RAM
    . = ALIGN(4);    

    .data : AT(_etext)     /* initialized data */
    {
        _sdata = . ;
        *(.data);
        *(.data.*);
    } >RAM
    . = ALIGN(4);
 
    _edata = . ;
    PROVIDE(edata = .);
    ...

Och så kopierar man data från flash till SRAM vid uppstart (i startup.S):

Kod: Markera allt

    .global _etext, _sdata, e_data
    ldr r0, =_etext
    ldr r1, =_sdata
    ldr r2, =_edata
data_loop:
    cmp r1, r2
    ldrlo r3, [r0], #4
    strlo r3, [r1], #4
    blo data_loop
Men my_init_data alltid blir noll när jag kör koden. En snabb titt i list-filen visar att initialvärdet skrivs till SRAM och inte till flash:

Kod: Markera allt

// (0x4... är flash, 0x2... är SRAM)
...
.init:4000004C                 LDR     R0, =0x400000F4
.init:40000050                 LDR     R1, =0x20000400
.init:40000054                 LDR     R2, =0x20000408
.init:40000058 
.init:40000058 data_loop                               ; CODE XREF: _init_proc+64|j
.init:40000058                 CMP     R1, R2
.init:4000005C                 LDRCC   R3, [R0],#4
.init:40000060                 STRCC   R3, [R1],#4
.init:40000064                 BCC     data_loop
...
400000e4:	20616c62 	rsbcs	r6, r1, r2, ror #24 <-- detta är min sträng
400000e8:	20616c62 	rsbcs	r6, r1, r2, ror #24
400000ec:	2e616c62 	cdpcs	12, 6, cr6, cr1, cr2, {3}
400000f0:	00002e2e 	andeq	r2, r0, lr, lsr #28
_extext: <-- *** här borde min 0x42 ligga ***

Disassembly of section .stack:
20000000 <_stack_irq>:	...
20000100 <_stack_fiq>:	...
20000200 <_stack_normal>:	...

Disassembly of section .data:
20000400 <_sdata>:  <-- här är min "my_init_data", med initialvärdet i SRAM :(
20000400:	00000042 	andeq	r0, r0, r2, asr #32
20000404 <my_const_data>: <-- perkare till strängen, åter initierad i SRAM :(
20000404:	400000e4 	andmi	r0, r0, r4, ror #1

Disassembly of section .bss:
20000408 <_sbss>: <-- my_bss_data hamnar här
20000408:	00000000 	andeq	r0, r0, r0
vad är det som händer?? varför hamnar min 0x42 i SRAM istället för flash? Behöver jag köra länkaren med någon exotisk flagga för att fixa detta?