Sistemi Operativi - unimi.it

16
Sistemi Operativi La gestione delle eccezioni in Minix Lez. 21 A.A. 2010/2011 Corso: Sistemi Operativi © Danilo Bruschi 1

Transcript of Sistemi Operativi - unimi.it

Page 1: Sistemi Operativi - unimi.it

Sistemi Operativi

La gestione delle eccezioni in Minix Lez. 21

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

1

Page 2: Sistemi Operativi - unimi.it

Per questa lezione fare riferimento al codice contenuto nei file

kernel/mpx386.s e kernel/exception.c

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

2

Page 3: Sistemi Operativi - unimi.it

Eccezioni •  Nell’architettura IA-32 fault e trap sono più

genericamente accorpati nella categoria delle eccezioni, che possono essere di tre tipi : •  Fault: una eccezione dovuta ad un errore che può

essere corretto e può consentire, dopo la correzione, la ripresa del programma che l’ha generato. In questo caso sullo stack va salvato l’indirizzo della faulting instruction

•  Trap: un richiesta esplicita di intervento attraverso un’istruzione di trapping (INT)

•  Abort: una eccezione che non consente la ripresa del programma che l’ha provocata

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

3

Page 4: Sistemi Operativi - unimi.it

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

4

La gestione delle eccezioni in Minix •  L’eccezione viene generata durante l’esecuzione di

un’istruzione o esplicitamente richiesta, e si traduce nell’accensione del bit di interrupt

•  Sentito l’interrupt il processore deve, nel caso di eccezione: •  Salvare il contesto del processo interrotto (come

nella prima fase del context switch) •  Richiamare l’exception handler in cui indirizzo è

caricato in IDT

Page 5: Sistemi Operativi - unimi.it

Cose da fare sul versante SO

•  Inizializzare opportunamente IDT •  Scrivere per ogni tipo di eccezione il relativo

gestore tenendo conto che una eccezione si può verificare anche durante l’esecuzione del kernel

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

5

Page 6: Sistemi Operativi - unimi.it

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

6

Uso IDT

Page 7: Sistemi Operativi - unimi.it

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

7

Preparazione IDT (prot_init)

Page 8: Sistemi Operativi - unimi.it

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

8

Kernel Stack 518 !*==========================================================* !* data * !*=======================================================* 522 523 .sect .rom ! Before the string table please 524 .data2 0x526F ! this must be the first data entry (magic #) 525 526 .sect .bss 527 k_stack: 528 .space K_STACK_BYTES ! kernel stack 529 k_stktop: ! top of kernel stack 530 .comm ex_number, 4 531 .comm trap_errno, 4 532 .comm old_eip, 4 533 .comm old_cs, 4 534 .comm old_eflags, 4

Page 9: Sistemi Operativi - unimi.it

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

9

!*==============================================================* 406!* exception handlers * 407!*===========================================================* 408 _divide_error: 409 push DIVIDE_VECTOR 410 jmp exception 411 412 _single_step_exception: 413 push DEBUG_VECTOR 414 jmp exception 415 416 _nmi: 417 push NMI_VECTOR 418 jmp exception 419 420 _breakpoint_exception: 421 push BREAKPOINT_VECTOR 422 jmp exception

452 _segment_not_present: 453 push SEG_NOT_VECTOR 454 jmp errexception 455 456 _stack_exception: 457 push STACK_FAULT_VECTOR 458 jmp errexception 459

Page 10: Sistemi Operativi - unimi.it

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

10

La gestione delle eccezioni

!*=========================================================* ! exception * !*==========================================================* !This is called for all exceptions which do not push an error code. 476 477 .align 16 478 exception: 479 sseg mov (trap_errno), 0 ! clear trap_errno 480 sseg pop (ex_number) 481 jmp exception1 482

Page 11: Sistemi Operativi - unimi.it

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

11

!*=======================================================================* 484 !* errexception * 485!*====================================================================* 486 ! This is called for all exceptions which push an error code. 487 488 .align 16 489 errexception: 490 sseg pop (ex_number) 491 sseg pop (trap_errno) 492 exception1: ! Common for all exceptions. 493 push eax ! eax is scratch register 494 mov eax, 0+4(esp) ! old eip 495 sseg mov (old_eip), eax 496 movzx eax, 4+4(esp) ! old cs 497 sseg mov (old_cs), eax 498 mov eax, 8+4(esp) ! old eflags 499 sseg mov (old_eflags), eax 500 pop eax 501 call save 502 push (old_eflags) 503 push (old_cs) 504 push (old_eip) 505 push (trap_errno) 506 push (ex_number) 507 call _exception ! (ex_number, trap_errno, old_eip, 508 ! old_cs, old_eflags) 509 add esp, 5*4 510 ret

Page 12: Sistemi Operativi - unimi.it

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

12

!*=================================================================* !* save !*=================================================================* ! Save for protected mode. This is much simpler than for 8086 mode, !because the stack already point! into the process table, or has already !been switched to the kernel stack. 322 .align 16 323 save: 324 cld ! set direction flag to a known value 325 pushad ! save "general" registers 326 o16 push ds ! save ds 327 o16 push es ! save es 328 o16 push fs ! save fs 329 o16 push gs ! save gs 330 mov dx, ss ! ss is kernel data segment 331 mov ds, dx ! load rest of kernel segments 332 mov es, dx ! kernel does not use fs, gs 333 mov eax, esp ! prepare to return 334 incb (_k_reenter) ! from -1 if not reentering 335 jnz set_restart1 ! stack is already kernel stack 336 mov esp, k_stktop 337 push _restart ! build return address for int handler 338 xor ebp, ebp ! for stacktrace 339 jmp RETADR-P_STACKBASE(eax) 341 .align 4 342 set_restart1: 343 push restart1 344 jmp RETADR-P_STACKBASE(eax)

Page 13: Sistemi Operativi - unimi.it

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

13

00001 /* This file contains a simple exception handler. Exceptions in user 00002 * processes are converted to signals. Exceptions in a kernel task cause 00003 * a panic. 00004 */ 00005 00006 #include "kernel.h" 00007 #include <signal.h> 00008 #include "proc.h" 00009 00010 /*===========================================================================* 00011 * exception * 00012 *===========================================================================*/ 00013 PUBLIC void exception(vec_nr) 00014 unsigned vec_nr; 00015 { 00016 /* An exception or unexpected interrupt has occurred. */ 00017 00018 struct ex_s { 00019 char *msg; 00020 int signum; 00021 int minprocessor; 00022 }; 00023 static struct ex_s ex_data[] = { 00024 { "Divide error", SIGFPE, 86 }, 00025 { "Debug exception", SIGTRAP, 86 }, 00026 { "Nonmaskable interrupt", SIGBUS, 86 }, 00027 { "Breakpoint", SIGEMT, 86 }, 00028 { "Overflow", SIGFPE, 86 }, 00029 { "Bounds check", SIGFPE, 186 }, 00030 { "Invalid opcode", SIGILL, 186 }, 00031 { "Coprocessor not available", SIGFPE, 186 }, 00032 { "Double fault", SIGBUS, 286 }, 00033 { "Copressor segment overrun", SIGSEGV, 286 }, 00034 { "Invalid TSS", SIGSEGV, 286 }, 00035 { "Segment not present", SIGSEGV, 286 }, 00036 { "Stack exception", SIGSEGV, 286 }, /* STACK_FAULT already used */ 00037 { "General protection", SIGSEGV, 286 }, 00038 { "Page fault", SIGSEGV, 386 }, /* not close */ 00039 { NIL_PTR, SIGILL, 0 }, /* probably software trap */ 00040 { "Coprocessor error", SIGFPE, 386 }, 00041 }; 00042 register struct ex_s *ep; 00043 struct proc *saved_proc;

Page 14: Sistemi Operativi - unimi.it

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

14

45   /* Save proc_ptr, because it may be changed by debug statements. */

00046 saved_proc = proc_ptr; 00047 00048 ep = &ex_data[vec_nr]; 00049 00050 if (vec_nr == 2) { /* spurious NMI on some machines */ 00051 kprintf("got spurious NMI\n"); 00052 return; 00053 } 00054 /* If an exception occurs while running a process, the k_reenter variable * will be zero. Exceptions in interrupt handlers or system traps will make • k_reenter larger than zero.*/ 00059 if (k_reenter == 0 && ! iskernelp(saved_proc)) { 00060 cause_sig(proc_nr(saved_proc), ep->signum); 00061 return; 00062 } 00063 00064 /* Exception in system code. This is not supposed to happen. */ 00065 if (ep->msg == NIL_PTR|| machine.processor < ep->minprocessor) 00066 kprintf("\nIntel-reserved exception %d\n", vec_nr); 00067 else 00068 kprintf("\n%s\n", ep->msg); 00069 kprintf("k_reenter = %d ", k_reenter); 00070 kprintf("process %d (%s), ", proc_nr(saved_proc), saved_proc->p_name); 00071 kprintf("pc = %u:0x%x", (unsigned) saved_proc->p_reg.cs, 00072 (unsigned) saved_proc->p_reg.pc); 00073 00074 panic("exception in a kernel task", NO_NUM); 00075 } 00076

Page 15: Sistemi Operativi - unimi.it

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

15

iskernel

#define isemptyn(n) isemptyp(proc_addr(n)) #define isemptyp(p) ((p)->p_rts_flags == SLOT_FREE) #define iskernelp(p) iskerneln((p)->p_nr) #define iskerneln(n) ((n) < 0) #define isuserp(p) isusern((p)->p_nr) #define isusern(n) ((n) >= 0))

#define proc_nr(p) ! ((p)->p_nr)!

Page 16: Sistemi Operativi - unimi.it

A.A. 2010/2011 Corso: Sistemi Operativi

© Danilo Bruschi

Restart _restart: !Restart the current process or the next process if it is set

cmp (_next_ptr), 0 jz 0f

mov eax,(_next_ptr) mov (_proc_ptr), eax mov (_next_ptr), 0

0: mov esp, (_proc_ptr) lldt P_LDT_SEL(esp) lea eax, P_STACKTOP(esp) mov (_tss+TSS3_S_SP0), eax

restart1: decb (_k_reenter) o16 pop gs o16 pop fs o16 pop es o16 pop ds popad add esp,4 iretd

16