Gestione della memoria

Transcript

Gestione della memoria
44
FRAMEWORK PER L'ESECUZIONE DI
APPLICAZIONI ASSEMBLY SUL
MODELLO VERILOG DI UN SISTEMA
DI ELABORAZIONE BASATO SUL
PROCESSORE eMIPS-sc
45
MODELLO VERILOG DEL PROCESSORE
MODELLO VERILOG DEL SISTEMA COMPLETO
La gerarchia del modello verilog del sistema è la seguente:
testbench.v (istanza testbench)
instructions_ROM.v (istanza InstrROM)
data_RAM.v (istanza DataRAM)
eMIPS_sc.v (istanza MIPS)
pc_reg.v (istanza PC)
pc_adder.v (istanza NPC)
....
46
FRAMEWORK DI SVILUPPO (I)
MIPS
ASSEMBLER
file
instructions.hex
MEMORIA
ISTRUZIONI
(MODELLO
VERILOG)
DATI
INIZIALI
CON CONVERSIONE IN UN
FORMATO LEGGIBILE DAL
SIMULATORE VERILOG
(READMEMH)
INSTRUCTIONS
BUS
INSTR ADDRESSES
DATA
MIPS
(MODELLO
VERILOG)
BUS
DATA ADDRESSES
BUS
BUS
CONVERSIONE IN UN
FORMATO LEGGIBILE
DAL SIMULATORE
VERILOG (READMEMH)
CODICE
ASSEMBLY
MEMORIA
DATI
(MODELLO
VERILOG)
file
data_RAM.hex
SIMULATORE
VERILOG
(MODELSIM)
FRAMEWORK DI SVILUPPO (II)
STRUTTURA DI FILE E DIRECTORY
‰ eMIPS-sc_S3
ƒ
ƒ
ƒ
‰
S1.mpf
compila.bat
eMIPS_S3.asm
HEX
ƒ instructions.hex
ƒ data_ram.hex
‰ ASM
ƒ
file eseguibili dell'assembler.....
‰ VERILOG
ƒ testbench_eMIPS_S3.v
‰ Memories
‰ eMIPS-sc
47
48
ESECUZIONE DI APPLICAZIONI SU
SISTEMI EMBEDDED MIPS-based
SPECIFICA MISTA C-ASSEMBLY, UTILIZZO
DELLA MEMORIA A BASSO LIVELLO,
CONVENZIONI DI CHIAMATA A
SUBROUTINE
INTERFACCIA HW/SW
‰ L’utilizzo di programmi scritti in linguaggi ad alto livello (c/c++) sul
processore di un sistema embedded richiede la specifica di una serie di
informazioni
supplementari
(dimensione
della
memoria,
partizionamento e mappa della memoria, routine di boot, routine di
interrupt, ecc.) che non possono essere definite a livello di software c
stesso, ma vanno definite a livello assembly-sistema operativo.
‰ Si rende necessaria l’integrazione di specifiche scritte a livelli diversi:
c e assembly
‰ Si rende inoltre necessario la conoscenza della strategia usata dal
compilatore c utilizzato (nel nostro caso il gcc 2.95.3) per la gestione a
basso livello della memoria
49
INTERFACCIA HW/SW
‰ Per fissare i primi concetti legati al funzionamento del compilatore e
all'utilizzo dei tool di compilazione semplificati (compilatore + assembler)
sviluppati per questo corso, utilizzeremo un semplice sistema processorememoria senza periferiche
‰ La microarchitettura MIPS che utilizzeremo è la MIPS-mc. L'architettura di
memoria di Von Neumann: vi è una sola memoria condivisa da dati ed
istruzioni
WriteEnable Signal
global
clk
MIPS-mc
Instructions / Data
Buses
reset
System
Addresses
Bus
INSTRUCTIONS
/ DATA
MEMORY
50
51
GESTIONE DELLA MEMORIA PER I
SISTEMI MONOPROGRAMMATI
IN MODALITA’ REALE
INTERFACCIA HW/SW
CONVENZIONI PER LA GESTIONE DELLA MEMORIA
52
INTERFACCIA HW/SW
UTILIZZO DELLA MEMORIA (VERSIONE SEMPLIFICATA) (I)
‰ Il compilatore utilizza la memoria dividendola in due parti: lo Stack e lo
Heap.
‰ Lo stack è la porzione di memoria gestita automaticamente dal processore,
inizia a partire dalle locazioni con indirizzo più alto e ha una dimensione
variabile in funzione dello spazio di cui ha bisogno il programma.
‰ Lo heap è invece la zona di memoria gestita dinamicamente, con le funzioni
malloc e calloc.
‰ Lo Heap inizia dalle locazioni di memoria più basse e si riempie verso
locazioni di indirizzo più elevato.
‰ Non avendo a disposizione le funzioni di libreria malloc e calloc allocheremo
i dati in memoria in maniera esplicita tramite i puntatori.
‰ Utilizzeremo inoltre una zona di memoria per il salvataggio dei dati relativi
alle routine di interrupt o ad altre routine speciali.
‰ Chiameremo la memoria utilizzata in questo modo MEMORIA ALLOCATA
MANUALMENTE (MAM)
‰ In un sistema di Von Neumann, la parte della memoria di indirizzi più bassi,
da zero in poi, viene utilizzata per le istruzioni.
53
54
INTERFACCIA HW/SW
UTILIZZO DELLA MEMORIA (VERSIONE SEMPLIFICATA) (II)
‰ A partire dagli indirizzi di memoria
più alti sta la funzione main, il
compilatore alloca ricorsivamente lo
spazio per le procedure allocando e
disallocando zone di memoria.
‰ Ogni procedura ha a disposizione
una zona di memoria privata definita
frame di attivazione. Lo spazio dei
frame di attivazione è lo stack
‰ La memoria di tipo dinamico viene
allocata a partire dagli indirizzi bassi
e si espande verso quelli alti, a
partire da un certo indirizzo in poi.
‰ La MAM si può allocare o fra lo
heap (sotto lo heap) e la memoria
istruzioni (sopra la mem istruzioni)
oppure sopra lo stack
‰ Per sistemi a memoria condivisa fra
dati ed istruzioni la parte più bassa
della memoria è dedicata alle
istruzioni.
TOP OF MEMORY
main FP
M.A.M.
MAIN DATA
FUNC 1 DATA
MEMORIA
DATI
GESTITA
DAL
COMPILATORE
FUNC 2 DATA
HEAP
M.A.M.
SPAZIO
ISTRUZIONI
locazione 0
STACK:
MEMORIA AUTOMATICA
ALLOCATA DAL
COMPILATORE
TEXT
HEAP:
MEMORIA DINAMICA
ALLOCATA DAL
COMPILATORE TRAMITE
MALLOC O CALLOC
INTERFACCIA HW/SW
MECCANISMO DI CHIAMATA DI PROCEDURA
‰ Un opportuno sottoinsieme delle istruzioni dell'IS MIPS viene utilizzato
per supportare la chiamata di una procedura (funzione), ed una volta
terminata la sua esecuzione, il ritorno alla istruzione successiva alla
chiamata
‰ Ogni volta che deve essere convertita in assembly una chiamata a
funzione viene utilizzata una istruzione che forza il salto all'indirizzo
della prima istruzione della procedura, e simultaneamente salva quello
dell'istruzione successiva nel registro $31. Tale istruzione è
jal label_procedura
‰ Ogni procedura deve terminare con una istruzione che forza il valore del
PC all'indirizzo della istruzione successiva a quella di chiamata, cioè
all'indirizzo salvato in $31. Tale istruzione è
jr $31
‰ Per gestire la possibilità che una funzione ne chiami a sua volta un'altra,
sovrascrivendo l'indirizzo di ritorno in $31, è necessario che questo venga
salvato in memoria
‰ E' necessaria una convenzione che definisca come salvare in memoria
l'indirizzo di ritorno nonchè i parametri passati alla procedura, i dati
locali, ecc.
55
56
INTERFACCIA HW-SW
GESTIONE DELLO STACK (I)
‰ Quando viene eseguita una funzione
viene riservata ad essa una porzione
dello stack detta frame. La
dimensione del frame dipende dal
numero di dati relativi alla funzione
che è necessario scrivere in memoria FRAME$30POINTER
e può essere anche nulla se non ci
sono dati da memorizzare.
‰ Le informazioni da memorizzare per
ogni frame sono:
ƒ parametri della funzione invocata oltre il
quarto (i primi quattro parametri sono
salvati nei registri da $4 a $7)
ƒ indirizzo di ritorno
ƒ dati locali della funzione
ƒ registri temporanei che verranno
sovrascritti durante l'esecuzione della
funzione
$29
STACK POINTER
PARAMETRO N
PARAMETRO 5
PARAMETRI
DELLA
FUNZIONE
(oltre il quarto)
FP DELLA FUNZ CHIAMANTE
INDIRIZZO DI RITORNO
LOCAL DATA 1
DATI LOCALI
DELLA FUNZIONE
LOCAL DATA N
VALORE SALVATO DI $8
VALORE SALVATO DI $n
VALORE SALVATO
DEI REGISTRI
UTILIZZATI
DURANTE
LA FUNZIONE
57
INTERFACCIA HW-SW
CONVENZIONE DI CHIAMATA DI PROCEDURA PER MIPS
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
58
INTERFACCIA HW-SW
GESTIONE DELLO STACK (II) ESEMPIO
void _main( void ) {
int a[2];
int i;
int *pointer;
pointer = (int*) 0x1000;
for( i=0; i<2; i++)
a[i] = i;
*pointer = a[0]+a[1];
}
INTERFACCIA HW-SW
GESTIONE DELLO STACK (III) ESEMPIO
alloca la memoria per il frame di attivazione
del main. La dim minima è di 16 locazioni.
main:
;# vars= 16, regs= 0/0, args= 0, extra= 0
subu
$sp,$sp,16
li
$3,1
addu
$2,$sp,4
$L6:
sw
addu
addu
bgez
lw
lw
#nop
addu
sw
addu
j
.end
..
$3,0($2)
$2,$2,-4
$3,$3,-1
$3,$L6
$2,0($sp)
$3,4($sp)
$2,$2,$3
$2,4096
$sp,$sp,16
$31
_main
inizializza i registri che utilizzerà come
indici
esegue il loop, usa $2 come puntatore alla
locazione dell'elemento del vettore utilizzato
ed $3 come indice per il conteggio. Calcola il
valore degli elementi del vettore e li salva
nello stack
carica gli elementi del vettore dallo stack,
calcola la somma e la salva nella MAM
dealloca la memoria (frame di
attivazione del main) e ripristina il PC
59
INTERFACCIA HW-SW
GESTIONE DELLO STACK (IV)
‰ Il frame viene gestito attraverso due registri che sono utilizzati come puntatori: lo
Stack Pointer ($sp), che punta all’indirizzo della locazione più bassa del frame, e il
Frame Pointer ($fp), che punta alla locazione più alta. Mentre il primo è
indispensabile il secondo può in certi casi non essere utilizzato a seconda del
compilatore, del livello di ottimizzazione utilizzato e del programma in esecuzione.
‰ Lo stack pointer serve da riferimento per accedere alle locazioni del frame: per
esempio una scrittura su una locazione del frame verrà specificata con:
sw $31,20($sp)
‰ Le informazioni sul numero di dati da salvare in memoria sono forniti dal
compilatore come commenti nel programma assembly in uscita.
ƒ #vars indica il numero di locazioni utilizzate per memorizzare le variabili locali.
Se non sono dichiarati arrays questo numero è nullo.
ƒ #regs indica il numero di registri che devono essere salvati in memoria. In genere
non ce ne sono se non viene invocata una funzione.
ƒ #args indica il numero di locazioni destinate ai parametri di una funzione
invocata. Se non viene invocata nessuna funzione questo numero è zero ma se
viene invocata una funzione questo numero è sempre maggiore o uguale a 16,
anche se la funzione invocata non ha parametri.
60
61
INTERFACCIA HW-SW
GESTIONE DELLO STACK (V)
‰ All’inizio dell’esecuzione del programma lo Stack Pointer punta all’indirizzo
successivo a quello più alto in memoria, perché lo stack deve occupare la
memoria a partire dagli indirizzi più alti.
‰ Le prime istruzioni prodotte dal compilatore riguardano la gestione
automatica di memoria e registri. Ogni funzione, se ha bisogno di dati da
memorizzare, inizia con l’istruzione che fa scendere lo Stack Pointer in modo
da allocare lo spazio sufficiente. Seguono eventualmente i salvataggi dei
registri che saranno sovrascritti.
‰ La chiamata a funzione inizia sempre con un istruzione jal che porta il
processore ad eseguire la prima istruzione della funzione chiamata. A questo
punto viene creato un altro frame e così via. Alla fine di ogni funzione
l’eventuale valore restituito viene scritto sul registro $2 o $3, vengono
ripristinati i registri sovrascritti con i valori salvati in memoria e viene deallocato il frame riportando lo stack pointer alla posizione che aveva prima
della chiamata a funzione.
‰ Con l’istruzione
Jr $ra
si torna alla funzione chiamante.
62
INTERFACCIA HW-SW
SPECIFICA C E BOOT FILE
‰ Anche il main viene gestito come una funzione qualunque. Ma come viene
effettuata la chiamata al main?
‰ Nel caso di Sistema Operativo, vi saranno un assembler ed un linker che si
occupano di gestire la cosa in maniera trasparente per il programmatore
‰ Nel nostro caso vogliamo che tutto sia gestito in maniera esplicita, non vi è
un SO e neppure un vero linker.
‰ La chiamata del main viene eseguita tramite una specifica assembly separata
codificata in un file detto file di boot
‰ Tale file verrà unito alla traduzione assembly della specifica c dando vita ad
una specifica assembly completa, su singolo file, che può essere tradotta in
linguaggio macchina (cioè nel file di codifica delle locazioni di memoria
dedicate alle istruzioni)
INTERFACCIA HW-SW
FILE DI BOOT
‰ Il file di boot che utilizzeremo inizialmente si occupa esclusivamente delle cose essenziali,
vedremo in seguito delle specifiche più complete
‰ La prima istruzione salta sempre alla routine di inizializzazione del sistema, che in
questo caso consiste solo nell'inizializzazione dello stack pointer
‰ Una volta inizializzato il sistema viene eseguita la chiamata del main
‰ Quando si vuole che lo stack allocato automaticamente dal compilatore si estenda a partire
dalle locazioni di indirizzo massimo della memoria, il valore di inizializzazione dello
stack pointer coincide con la dimensione della memoria
J RESET_HANDLER
RESET_HANDLER: ; routine di inizializzazione del sistema
li $29,0x3000; ; inizializzazione dello stack pointer
; fine della routine di inizializzazione
jal _main ; avvia l'esecuzione del programma principale
; La simulazione termina con il blocco del PC
stop:
j stop
63