cli.s
u0.4
idt_desc_int.c
u0.2
idt_load.c
u0.2
idt_print.c
u0.2
int.h
u0.1
irq_remap.c
u0.2
isr.s
u0.1
isr_exception_name.c
u0.3
isr_exception_unrecoverable.c
u0.3
isr_irq.c
u0.3
isr_syscall.c
u0.3
sti.s
u0.4
In questa fase dello sviluppo del sistema è opportuno predisporre la tabella IDT (interrupt description table), con le eccezioni del microprocessore e le interruzioni hardware (IRQ), anche se inizialmente nulla viene gestito effettivamente.
Il file di intestazione int.h
contiene la dichiarazione delle funzioni per la gestione delle interruzioni. Viene proposto subito nella sua versione completa, anche se non tutte le funzioni dichiarate vengono presentate immediatamente.
Listato u199.1.
|
Si può osservare l'elenco delle funzioni isr_n(), per la gestione delle varie interruzioni catalogate nella tabella IDT. In particolare, l'interruzione 12810, ovvero 8016, viene usata per le chiamate di sistema. Queste funzioni sono dichiarate formalmente nel file isr.s
che viene mostrato integralmente nel listato successivo.
Listato u199.2.
|
Per facilitare la compilazione della tabella IDT viene usata la funzione idt_desc_int(), con la quale si deve specificare il numero del descrittore della tabella e i dati da inserirvi. La tabella IDT è definita nella variabile strutturata os.idt, dichiarata nel file os.h
.
Listato u199.3.
|
Per verificare il contenuto della tabella IDT viene predisposta la funzione idt_print() che richiede come parametro il puntatore all'area di memoria che descrive il registro IDTR. Così come viene proposta, la funzione mostra il contenuto completo della tabella IDT, ma questo supera generalmente le righe visualizzabili sullo schermo; pertanto, in caso di necessità, la funzione va modificata in modo da mostrare solo la porzione di proprio interesse.
Listato u199.4.
|
La funzione irq_remap() è necessaria per rimappare le interruzioni hardware nella tabella IDT, in modo che non intralcino quelle associate alle eccezioni. La funzione richiede l'indicazione del numero iniziale di interruzione per i due gruppi di IRQ (da IRQ 0 a IRQ 7 e da IRQ 8 a IRQ 15). Successivamente, nella funzione idt(), viene usata irq_remap() in modo da rimappare le interruzioni hardware a partire da 32, per finire a 47.
Listato u199.5.
|
Per caricare la tabella IDT dichiarata in memoria, occorre predisporre la copia del registro IDTR con i riferimenti necessari a raggiungerla, quindi va usata l'istruzione LIDT, con il linguaggio assemblatore. La funzione idt_load() viene usata per pilotare l'istruzione LIDT.
Listato u199.6.
|
La funzione idt() utilizza le altre descritte in questa sezione, per mettere in funzione la gestione delle interruzioni.
Listato u199.7.
|
Le funzioni isr_n() si limitano a chiamare altre funzioni scritte in linguaggio C, per la gestione delle eccezioni, delle interruzioni hardware e per le chiamate di sistema. In questa fase vengono mostrate le funzioni per la gestione delle eccezioni, anche se in forma estremamente limitata, e si propongono temporaneamente delle funzioni fittizie per la gestione degli altri casi.
Listato u199.8.
|
La funzione isr_exception_unrecoverable(), appena mostrata, viene chiamata dal file isr.s
, per le interruzioni che riguardano le eccezioni. La funzione si limita a visualizzare un messaggio di errore e a fermare il sistema. Per visualizzare il tipo di eccezione che si è verificato si avvale della funzione exception_name() che appare nel listato successivo.
Listato u199.9.
|
A proposito della funzione exception_name() va osservata la particolarità del comportamento del compilatore GNU C, il quale utilizza, senza che ciò sia stato richiesto espressamente, la funzione standard memcpy(). Pertanto, tale funzione deve essere disponibile, altrimenti, in fase di collegamento (link) la compilazione fallisce.
Per la gestione delle interruzioni hardware è competente la funzione isr_irq(), ma per il momento viene proposta una versione provvisoria, priva di alcuna gestione, dove ci si limita a inviare il messaggio «EOI» ai PIC (programmable interrupt controller) coinvolti.
Listato u199.10. Una prima versione del file
|
Anche la funzione isr_syscall() che dovrebbe prendersi cura delle chiamate di sistema, viene proposta inizialmente priva di alcun effetto.
Listato u199.11. Una prima versione del file
|
Per facilitare l'accesso alle istruzioni STI e CLI del linguaggio assemblatore, vengono predisposte due funzioni con lo stesso nome.
Listato u199.12.
|
Listato u199.13.
|
Per verificare il lavoro svolto fino a questo punto, è necessario sviluppare ulteriormente i file kernel_main.c
, dove in particolare si va a produrre un errore che causa un eccezione dovuta a una divisione per zero.
Figura u199.14. Modifiche da apportare al file
|
Dopo avere ricompilato, riavviando la simulazione si deve ottenere una schermata simile a quella seguente, dove alla fine si vede la segnalazione di errore dovuta alla divisione per zero:
|
«a2» 2013.11.11 --- Copyright © Daniele Giacomini -- appunti2@gmail.com http://informaticalibera.net