2013-03-20 14 views
5

Stiamo provando a caricare un'immagine Linux nella nostra DRAM in una posizione specifica, l'indirizzo finale DRAM è 0x80000000 che conosciamo dal log di avvio che dice "terminazione dispositivo mem" l'indirizzo è 0x80000000" .Siamo caricando la nostra immagine all'indirizzo '0x5000000' e prima che la sezione Variuos nell'immagine sempre caricato ad un certo indirizzo, che è maggiore di '0x80000000', per eaxmple di nuovo da tronchi di avvioCome caricare l'immagine Linux per appropriarsi della posizione nella memoria

loading section to address 0xc5000000 from file position 0x1000, size is 0x5ac13e 

cosa è significato di "dalla posizione del file 0x1000" nella riga sopra.

prima sezione che ha caricato è la sezione .text, qui di seguito è il nostro vmlinux discarica immagine della sezione di intestazione

[Nr]  Name   Type   Addr  Off Size ES Flg Lk Inf Al 

[ 0]      NULL   00000000 000000 000000 00  0 0 0 

[ 1] .text   PROGBITS  c5000000 001000 5ac13e 00 AX 0 0 4096 

[ 2]  .notes   NOTE   c55ac140 5ad140 000168 00 AX 0 0 4 

[ 3] __ex_table  PROGBITS  c55ac2b0 5ad2b0 000fe0 00 A 0 0 4 

[ 4] .rodata   PROGBITS  c55ae000 5af000 20a930 00 A 0 0 64 

[ 5] __bug_table  PROGBITS  c57b8930 7b9930 0075fc 00 A 0 0 1 

[ 6] .pci_fixup  PROGBITS  c57bff2c 7c0f2c 001a90 00 A 0 0 4 

[ 7] .builtin_fw  PROGBITS  c57c19bc 7c29bc 0000cc 00 A 0 0 4 

È piuttosto una grande lista, in modo da non inviare alta uniforme, ma una cosa che possiamo vedere qui. la sezione di testo è maggiore dell'indirizzo di fine DRAM, quindi l'immagine non dovrebbe essere presentata correttamente anche se non riceviamo alcun errore dopo aver caricato la prima sezione che continua a caricare altre sezioni ma dopo questo messaggio si blocca.

program load complete, entry point: 0x5000000, size: 0x92e7fc 

La mia domanda è come posso allineare queste diverse sezioni affrontano al nostro indirizzo DRAM, è programma di utilità objcopy potrebbe essere usato qui per cambiare l'indirizzo di queste sezioni diverse.

C'è un modo per impostare questi indirizzi di sezione prima della compilazione ?? Seconda cosa può essere la ragione per cui il caricamento del programma Hang afer è completo.

+0

Una taglia è buona, ma non è necessariamente andare a farti una soluzione perché la questione non è abbastanza informativo e perché non possiamo vedere il tuo codice. In pratica stai chiedendo alle persone di sparare al buio. –

+0

Sì, Alexey, hai già risposto molto bene alla mia domanda, ho pensato che avere una visione più ampia di questa domanda è una buona idea. Non voglio che la gente risolva il mio problema perché poi non imparerò da solo, volevo solo avere una coppia di buone idee –

+0

Buon punto, in realtà. –

risposta

6

from file position 0x1000 significa quello che dice. Lo avete in discarica:

[Nr]  Name   Type   Addr  Off Size ES Flg Lk Inf Al 
... 
[ 1] .text   PROGBITS  c5000000 001000 5ac13e 00 AX 0 0 4096 

E 'dove la sezione .text inizia nel file, all'offset 0x1000.

Ma una cosa che possiamo vedere qui .text sezione è maggiore di DRAM indirizzo finale

No, non è maggiore (non nel senso di grande, almeno), è compilato in attesa che venga caricato all'indirizzo 0xc5000000 nella memoria.

modo immagine non deve essere loded correttamente anche se non si ottiene alcun errore dopo il caricamento prima sezione si continua a caricare altre sezioni

L'immagine può essere caricata da nessuna parte, è solo i dati a scopo di Caricamento in corso.

OTOH, se loading section to address 0xc5000000 significa quello che dice, il file viene caricato in nulla da quando la RAM termina a 0x7fffffff.

ma dopo questo messaggio si blocca.

E questo è previsto. Il codice macchina è raramente indipendente dalla posizione e quindi se lo si carica in una posizione diversa da quella in cui dovrebbe essere caricato, non funzionerà. O se non viene nemmeno caricato, allora cosa stai per eseguire? Garbage.

C'è un modo per impostare questi indirizzi di sezione prima della compilazione ??

A seconda del sistema si può avere una delle due sotto opzioni o entrambe:

  • istituito traduzione pagina in modo tale che gli indirizzi virtuali da 0xc5000000 e fino mappa per gli indirizzi fisici da 0x5000000 e per l'intero programma
  • trovare lo script del linker che il compilatore sta usando e cambiare l'indirizzo tratto iniziale 0xc5000000-0x5000000, google, vedere la documentazione del compilatore/linker

Inoltre, è un po 'strano che il punto di ingresso sia 0x5000000. Non che questo sia necessariamente sbagliato, è solo che raramente è il caso. Mi assicurerei che l'etichetta (o _start o qualsiasi cosa sia) effettivamente riceve lo stesso indirizzo dell'inizio della sezione .text. Se, per qualche ragione, non è il caso, c'è qualcosa di sbagliato sia con lo script linker o le opzioni della riga di comando del compilatore/linker o con il loader.

+0

Grazie a @Alexey per la tua cortese risposta. Molte delle cose vorrebbero condividere con te che ho perso nella mia domanda, il punto di ingresso 0x5000000 è cambiato da noi modificando il file .config del kernel perché non è stato possibile caricare l'immagine all'indirizzo predefinito 0x1000000. La seconda cosa è che abbiamo precedentemente caricato ed eseguito un'immagine del kernel basata su QNX sulla stessa DRAM, ora possiamo usare gli stessi indirizzi per le sezioni e l'indirizzo del punto di ingresso che sono stati usati per l'immagine QNX qui per l'immagine del kernel Linux e un altro punto che hai sollevato è entry point fa parte della sezione .text. –

+0

E 'ora possibile utilizzare gli stessi indirizzi per le sezioni e l'indirizzo del punto di ingresso che sono stati utilizzati per l'immagine QNX qui per l'immagine del kernel di Linux? Una domanda? Non capisco il tuo punto. –

+0

Ciao Alesxey come hai suggerito dopo aver cambiato il valore di offset della pagina, ottenuto l'indirizzo della sezione entro i 2 GB dell'intervallo e dopo il caricamento del programma completato, messaggio la nostra immagine non si blocca ma abbiamo incontrato altri problemi, presto il suo programma dice che il caricamento è completo, La CPU viene ripristinata invece di dare il controllo all'immagine del kernel Linux, vorrebbe sentire una o due parole da parte vostra a riguardo. –

3

Che caricatore usi? Qual è la forma dell '"immagine"? Immagine di avvio U, grezzo, file ELF di vmlinux? Immagino che l'ultimo a giudicare dall'esistenza di sezioni, ecc. Dal file ELF non dovresti caricare sezioni ma piuttosto intestazioni di programma. Per esempio questo è l'OpenRISC intestazioni di programma kernel Linux messa in vendita (ottenuta utilizzando readelf -l):

Elf file type is EXEC (Executable file) 
Entry point 0xc0000000 
There are 2 program headers, starting at offset 52 

Program Headers: 
    Type   Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align 
    LOAD   0x002000 0xc0000000 0x00000000 0x231728 0x232000 RWE 0x2000 
    LOAD   0x234000 0xc0232000 0x00232000 0x17c78c 0x18bfcc RWE 0x2000 

Section to Segment mapping: 
    Segment Sections... 
    00  .text .rodata __ksymtab __ksymtab_gpl __ksymtab_strings __param __modver 
    01  .data __ex_table .head.text .init.text .init.data .bss 

vedere la differenza tra VirtAddr e PhysAddr (sceso c a causa di solito la mappatura del kernel Linux). Naturalmente, l'indirizzo fisico dovrebbe essere usato per il caricamento.

Il motivo per cui il kernel utilizza gli indirizzi virtuali per simboli, sezioni ecc. È che durante l'avvio si inserisce rapidamente il momento in cui la MMU viene inizializzata, gli indirizzi virtuali sono quindi gli unici validi.

E infine, sul cambio di quegli indirizzi. In effetti, come indicato da Alexey, la chiave del linker script è la chiave. Puoi trovarli in arch/(your arch)/kernel/vmlinux.lds.S. Ma il punto è che questo non è il tuo problema, il problema sta probabilmente nel caricatore o nelle sue opzioni.

1

Controlla il tuo arco/braccio/mach-xxx/Makefile.boot (Si utilizza bordo braccio destro?)

zreladdr-y  += 0x80008000 
params_phys-y  := 0x80000100 
initrd_phys-y  := 0x80800000 

Questo è da Ti circuito integrato OMAP3.

come penso sarà necessario lo stesso

+0

Grazie per la risposta @liyaoshi ma siamo sulla scheda x86 –

+0

Scusate per questa risposta, ho fatto un errore. Pensavo che il 0x80000000 fosse l'indirizzo iniziale della tua scheda. – liyaoshi