Monday, May 25, 2015

software interrupt

Kernel is a software that provides an environment to control the hardware resources of computer. The interface to the kernel is a layer of software called the system calls. Libraries of common functions are built on top of the system call interface, but applications are free to use both.

Two modes of OS:
1. Kernel mode/level: can do all operations, including privileged
2. User mode/level: can do only non-privileged operations

User level processes cannot perform core tasks in operating system for security purposes. System calls allow user-level processes to request some services from the operating system which process itself is not allowed to do directly. User level process uses kernel services. In handling the interrupt , the operating system will enter in the kernel mode, where it has access to privileged instructions, and can perform the desired service on the behalf of user-level process. Thus it uses ``software interrupt'' to transfers control to operating system kernel code. Software interrupts transfer control to the operating system kernel so that software simply needs to set up some register with the system call number needed, and execute the software interrupt.

Hardware interrupts, software interrupts, and processor exceptions are different forms of interrupt. We only concentrate on software level interrupts for x86 in this post.

Software interrupt:
Software interrupts follow int <intr_number> instruction to raise an interrupt. intr_number is an interrupt vector number  and can vary from 0-255. E.g. 0x80 is Linux convention for system call.

What happens when software interrupt is called:
In general:
       Interrupt causes CPU to transit from user mode to kernel mode
       Return from interrupt handling causes CPU to transit from kernel mode to user mode

1. CPU checks for interrupts in program:

          while (fetch next instruction) {
                run instruction;
                if (interrupt) {
                        save EIP                                         // user mode
                        find and jump to OS-provided interrupt handler // kernel mode
                        restore EIP                                      // user mode
                }
          } 


 2. When interrupt is found, control jumps to the address provided by interrupt handler
 3. The kernel stack is used to save the state of the program to return to
 4. Kernel code handles the interrupt
 5. When handle completes, return control to the program

IDT: Interrupt Descriptor Table :
OS creates an array of interrupt descriptors which are of 8 bytes in memory during booting called Interrupt Descriptor Table or IDT.  Each entry is an interrupt handler, also called interrupt routine or Interrupt Service Routine (ISR)
In modern computer systems, each processor has its own IDT table and IDTR register. IDT consists of 256 interrupt vectors :the first 32 (0-31 or 00-1F) of which are reserved for Intel 64 and IA-32 architectures for architecture defined exceptions and interrupts, while 32 to 255 are designated as user defined interrupts and are not reserved by Intel 64 and IA-32 architecture.

H/w finds interrupt handler using interrupt vector number as index into IDT
handler = IDT[intr_number] 
interrupt vector number(intr_number) is used as an index into the IDT table. Table provides entry point for the interrupt handler. IDT shows the processor what Interrupt Service Routine (ISR) to call to handle either an exception or an interrupt (in assembly).

The IDT may reside anywhere in the linear address space and the processor knows about IDT using IDTR register. To know about IDTR register, it is required to know about the IDT base address and the IDT limit.

Reference Intel manual vol 3A Part 1 6.11
The LIDT (load IDT register) and SIDT (store IDT register) instructions load and store
the contents of the IDTR register, respectively. The LIDT instruction loads the IDTR
register with the base address and limit held in a memory operand. This instruction
can be executed only when the CPL is 0.  SIDT is just reverse of LIDT and can be used from user level as well.