x86 interrupts

Fri 07 August 2015 by Saruta

Let's see how x86 interrupts work.

Interrupts

There are three types of interrupts:

  • Exceptions: synchronous with program execution.
    Exemple: division by zero or invalid address access.

  • hardware interrupts: asynchronous with program execution. They are generated by devices external to the CPU.
    Exemple: key pressed

  • software interrupts: synchronous with program execution. They are generated by x86 instructions such as int or syscall.
    Exemple: int 0x80 - syscall

Interrupt Description Table (IDT)

All the interrupts have a common interrupt vector called the Interrupt Description Table, commonly called the IDT.

This table can be seen as a C array of Interrupt Descriptors.

There are three types of interrupt descriptors:

  • the Task Gate: it's used for the tss, it will be describe in the next chapter about AtomOS.
  • the Trap Gate: contains the routine to jump on.
  • the Interrupt Gate: idem, but disable the hardware interrupts.

In fact, when the processor got a interrupt n, it will jump on the routine pointer contained in the interrupt descriptor at index n in the IDT.

IDT register

An image is better than a long explication (It is almost the same with the GDT).

idt_registers

Load the IDT

To load the IDT, you need to use the lid x86 instruction.

struct idt_s idt_reg;
idt_reg.base = (u32)idt_entry;
idt_reg.limit = sizeof(idt_entry) -1;

__asm__  volatile (
  "lidt %0\n"
::"m"(idt_reg):"memory"
);

Exceptions

The simpler type of interrupts is the exceptions, so let's see how it works...

The 32 first intel interrupts are reserved for the exceptions. Here is a list of the x86 exceptions:

exceptions_list

Interrupt Subroutines (ISR)

Context Switch

Most of the time in the i386 intel architecture, the interrupts routines are assembly wrappers which call the real routines. They are called Interrupt SubRoutines (ISR). Moreover, the context must be saved by the developer. Here is an example of exception ISR:

.globl no_error_wrapper
  pusha
  push $0
  call error_isr
  add $0x04, %esp
  popa
  iret

.globl error_wrapper
error_wrapper:
  pusha
  call error_isr
  popa
  iret

You can remark that the no_error_wrapper calls the same routine than the error_wrapper. The difference is that it gives a fake error code.

iret instruction

context_switching

Hardware Interrupts

Programmable Interrupt Controller (i8259)

Links:

bitbucket link


Be protected !

Fri 24 July 2015 by Saruta

A quick tour of multiboot, segmentation and intel protected mode.

read more