2013-09-05 7 views
10

Ho cercato in lungo e in largo per come farlo e non sono riuscito a trovare una risposta.Linker Script - Posizionamento di una sezione alla fine di un'area di memoria

mio layout di memoria è la seguente:

Fake Address | Section 
    0  | text 
    7  | relocate 
    15  | bss 
    23  | stack 

Alla fine dello stack pongo mucchio. Che cresce e lo stack è uno stack discendente completo per il chip ARM che sto usando.

Ora, quello che voglio fare è posizionare una singola sezione, chiamiamola .persist, nella mia memoria ram. Voglio che risieda alla fine della RAM e voglio programmarlo nel mio script linker. Tuttavia, questa dimensione della sezione .persist non è stata definita da me ma è calcolata dal compilatore dai simboli che contiene.

Finora non ho trovato un buon modo per farlo. Dal momento che conosco l'indirizzo di inizio RAM e SIZE sarebbe banale calcolare dove dovrebbe andare la sezione se conoscessi la dimensione della sezione. Tuttavia, secondo the GNU linker documentation (pg 74) sembra che:

SIZEOF (sezione) restituisce la dimensione in byte del sezione denominata, se tale sezione è stato assegnato. Se la sezione non è stata assegnata quando viene valutata, il linker emetterà un errore .

quindi non riesco a calcolare la dimensione della sezione nello script linker (poiché voglio calcolare la dimensione PRIMA che lo metti/lo alleni).

Qualcuno sa un buon modo per farlo?

+0

Ho lo stesso problema. Questo ti aiuta? http://stackoverflow.com/a/19348569/911550 – parvus

+0

È una soluzione parziale, ma non è quello che sto cercando. È ancora il più vicino a cui chiunque altro sia venuto ad aiutare. Grazie! – nonsensickle

risposta

0

quello che voglio fare è posizionare una singola sezione, chiamiamola .persist, nella mia memoria ram. Voglio che risieda alla fine della RAM e voglio programmarlo nel mio script linker.

script del linker trovi variabile speciale chiamata Location Counter che consente di modificare l'indirizzo corrente, e come tale la dimensione o l'indirizzo di una sezione o un simbolo, creando lacune o fori nello spazio di indirizzi.

+0

Sì, ne sono consapevole. Ti sei perso quello che ho detto dopo l'operatore 'SIZEOF' che non ti ha dato la dimensione della sezione ** finché ** non lo hai * posto *. Ho bisogno di ottenere la dimensione della sezione ** prima **. La posiziono affinché funzioni. – nonsensickle

+0

L'unica soluzione sarebbe se potessi posizionare la sezione, ottenere la dimensione e poi aprirla e spostarla altrove ... – nonsensickle

0

È possibile forzare le sezioni in posizioni specifiche.

Ad esempio, in questa documentazione Red Hat GNU Linker page, è possibile definire la sezione .data per iniziare all'indirizzo 0x8000000:

SECTIONS 
{ 
    . = 0x10000; 
    .text : { *(.text) } 
    . = 0x8000000; 
    .data : { *(.data) } 
    .bss : { *(.bss) } 
} 
+0

Sì, ne sono consapevole. Tuttavia, questo non mi consente di memorizzare la mia sezione in modo che * termini con un particolare indirizzo *. Voglio ottenere la dimensione della mia sezione, sottrarla da un indirizzo dandomi un indirizzo di risultato e quindi posizionarlo all'indirizzo dei risultati. In questo modo posso posizionare la mia sezione, che ha una dimensione variabile, ** alla fine ** del mio blocco di memoria RAM. Ho trovato questo non è possibile ed è di questo che si tratta. – nonsensickle

5

sono stato in grado di realizzare qualcosa di simile facendo collegando un processo in due fasi . Per prima cosa compilo la sezione in questione sul suo stesso file oggetto. Nel mio caso ho avuto una sezione di metadati generata da un file di assembly. gcc -c compilerà la sorgente in file oggetto, ma non li collegherà.

gcc -c metadata.s -o metadata.o 

Si potrebbe anche costruire insieme il programma, quindi estrarre solo il tratto in questione con objcopy.

gcc -c main.cc -o main.o 
objcopy --only-section=.metadata main.o metadata.o 

Ora costruire e collegare il resto del programma, e includere il file oggetto tra l'ingresso del linker.

gcc metadata.o ../main.o -o Program.elf -T linkerscript.ld 

Il linker legge la sezione .metadata dal file oggetto, e posso riferire la sua dimensione nello script del linker.

+0

È passato molto tempo dall'ultima volta che ho lavorato a questo progetto, ma la tua risposta sembra la cosa più vicina a renderlo possibile. Dovrò verificarlo prima di contrassegnarlo come corretto ma per ora +1. – nonsensickle

0

ho avuto un problema simile ho fatto in questo modo

/* heap section */ 
.heap (NOLOAD): 
{ 
    . = ALIGN(8); 
    _sheap = .; 
    . = . + HEAP_SIZE; 
    . = ALIGN(8); 
    _eheap = .; 
} > ram 

_ram_end_ = ORIGIN(ram) + LENGTH(ram) -1 ; 
_stack_size = _ram_end_ - _eheap ; 

/* stack section */ 
.stack (NOLOAD): 
{ 
    . = ALIGN(8); 
    _sstack = .; 
    . = . + _stack_size; 
    . = ALIGN(8); 
    _estack = .; 
} > ram 

.LastSection (NOLOAD): /* for test in dump file */ 
{ 
    . = ALIGN(8); 
} > ram 
+0

Anche se ho considerato questo la domanda è chiedere il posizionamento di una sezione alla fine della ram in modo che l'ultimo byte di quella sezione occupi l'indirizzo '_ram_end'. Da quello che posso vedere, stai posizionando lo stack alla fine della RAM e lo stack occupa semplicemente tutti i restanti byte. Sto chiedendo di farlo con una sezione che, a differenza dello stack, ha una dimensione statica che non dipende dalle dimensioni delle altre sezioni. Effettivamente, in questo esempio lo stack occupa tutta la memoria rimanente nella RAM. – nonsensickle

Problemi correlati