Download Interrupts - ssucet.org

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Interrupts
Sources:
* Intel CPU manuals
* OSFaqWiki (osdev.org)
* osdever.net
1
Background
●
Interrupts
–
–
What they are
What devices cause them
●
●
Hardware
CPU itself!
2
CPU Interrupts
●
"Internal"
–
–
–
Caused by program faults or hardware errors
Bad memory address
User program executed privileged instruction
●
–
–
–
●
User mode vs. Supervisor mode
Illegal/invalid instruction opcode
Math error (division by zero)
INT instruction (create on-demand)
Numbered 0-31
3
CPU Interrupts
●
●
●
●
●
●
●
●
●
●
●
0=div by zero
1=debug
2=nmi
3=int3
4=overflow
5=bound
6=illegal opcode
7=no fpu
8=fault handler fault
9=fpu overrun
10=bad tss
●
●
●
●
●
●
●
●
●
●
11=segment absent
12=stack fault
13=illegal address
14=page fault
15=reserved
16=fpu error
17=unaligned data
18=machine check
19=sse error
20-31=reserved
4
External Interrupts
●
Source: Hardware
–
–
–
Also called IRQ's
PIC
Re-mappable to any range of 16 interrupts
CPU
PIC
5
Interrupt Handling
●
CPU procedures when interrupt pin asserted:
–
–
–
–
PUSH %eflags
PUSH %cs
PUSH %eip
PUSH errorcode (optional; depends on interrupt)
●
–
●
These are underlined in list of interrupts given before
jmp int_table[ interrupt_index ]
That's all it does!
–
You must do the rest!
6
Interrupt Table
●
Associates code addresses with interrupt
numbers
–
Just an array of 32 bit addresses
CPU
RAM
7
Interrupt Table
●
Divide into three parts:
–
Lowest level: stub: One per interrupt
●
●
●
–
Middle level
●
●
–
Pushes all registers to stack
Calls top-level handler
Top level
●
●
Pushes dummy error code if needed
Pushes interrupt number to stack
Jumps to mid-level handler
Examines interrupt type, takes action
Lowest and Middle must be written in
assembly!
8
Lowest Level
●
Basic format: for each stub
interrupt_xx:
pushl $0
//if cpu didn't push errcode
pushl $xx
//interrupt number
jmp midlevel_handler
9
Middle Level
●
●
midlevel_handler:
push %ds
push %es
...etc for fs, gs, ss...
push %eax
push %ebx
...etc... for ecx,edx,esi,edi,ebp,esp
call highlevel_interrupt_handler//c code
pop reg's in reverse order
add $8,%esp
//discard errcode, int #
iret
//return from interrupt
iret pops %eip, %cs, and %eflags
10
High Level
●
void highlevel_interrupt_handler(void)
{
...do something...
}
11
Problem!
●
How does the handler know what to do?
–
–
Needs to be told what the interrupt was
Consider stack layout just before we call C
code...
12
Stack
●
Grows down!
top of
stack
...
previous
contents
...
eflags
cs
eip
errcode
int #
ds
es
fs
gs
ss
eax
ebx
ecx
edx
esi
edi
ebp
esp
13
C Calling Convention
●
Consider code;
void foo(int a, int b, int c){
...do something...
}
int main(int argc, char* argv[])
{
foo( 1 , 3 , 5 );
return 0;
}
Push from right
to left:
●push 5
●push 3
●push 1
14
Send Pointer In!
●
pushl %esp
call highlevel_interrupt_handler
add $4, %esp
top of
stack
...
previous
contents
...
eflags
cs
eip
errcode
int #
ds
es
fs
gs
ss
eax
ebx
ecx
edx
esi
edi
ebp
esp
ptr
15
C Code
●
●
●
●
void highlevel_interrupt_handler(
StateBlock* sb );
typedef struct _StateBlock{
unsigned esp, ebp, edi, esi, edx, ...
} __attribute__((packed)) StateBlock;
C function can read the StateBlock, get info
from stack
C function can change StateBlock and this
changes info when returning from interrupt!
16
Building Interrupt Table
●
Interrupt table entry:
16 bits
addr high
8
bits
8
bits
16 bits
16 bits
0x8e
(flags)
0
selector
addr low
msb
●
lsb
Easy way: build in assembly
–
–
–
Really!
Use script, create list of functions (array)
Then use from C
17
Loading Interrupt Register
●
Tell CPU where the table is:
typedef struct _IDTLoc{
unsigned short size;
unsigned location;
}__attribute__((packed)) IDTLoc;
IDTLoc loc;
loc.size = 256*8;
loc.location = (unsigned) &(my_table);
asm volatile ( “lidt (%%eax)” : : “a” (&loc));
18
Assignment
●
●
●
●
Implement interrupt handler
In C code: just print interrupt number, then
halt
Test with forced division by zero:
int a = 5;
int b = 0;
int c = 5/0;
This should trigger interrupt zero.
19