Implementing Operating System #5

Tharushi Chamalsha
2 min readAug 20, 2021

Now we all know how to produce output. In this section let's get to know about input methods.

The operating system must be able to handle interrupts in order to read information from the keyboard.

What is an Interrupt?

An interrupt is a response by the processor to an event that needs attention from the software. An interrupt condition alerts the processor and serves as a request for the processor to interrupt the currently executing code when permitted so that the event can be processed in a timely manner.

An interrupt occurs when a hardware device, such as the keyboard, the serial port, or the timer, signals the CPU that the state of the device has changed. Interrupts are handled via the Interrupt Descriptor Table (IDT). The IDT describes a handler for each interrupt. There are three different kinds of handlers for interrupts:

  • Task handler
  • Interrupt handler
  • Trap handler

When an interrupt occurs the CPU will push some information about the interrupt onto the stack, then look up the appropriate interrupt handler in the IDT and jump to it.

Creating a Generic Interrupt Handler

Since the CPU does not push the interrupt number on the stack it is a little tricky to write a generic interrupt handler. The following code shows an example of how this can be done. Store it inside interrupt_handler.s file.

interrupt_handlers.s

The common_interrupt_handler does the following:

  • Push the registers on the stack.
  • Call the C function interrupt_handler.
  • Pop the registers from the stack.
  • Add 8 to esp (because of the error code and the interrupt number pushed earlier).
  • Execute iret to return to the interrupted code.

Loading the IDT

The IDT is loaded with the lidt assembly code instruction which takes the address of the first element in the table. It is easiest to wrap this instruction and use it from C.

global  load_idt

; load_idt - Loads the interrupt descriptor table (IDT).
; stack: [esp + 4] the address of the first entry in the IDT
; [esp ] the return address
load_idt:
mov eax, [esp+4] ; load the address of the IDT into register eax
lidt eax ; load the IDT
ret ; return to the calling function

Programmable Interrupt Controller (PIC)

To start using hardware interrupts you must first configure the Programmable Interrupt Controller (PIC). The PIC makes it possible to map signals from the hardware to interrupts.

Acknowledging a PIC interrupt is done by sending the byte 0x20 to the PIC that raised the interrupt. Implementing a pic_acknowledge function can thus be done as follows.

First, add the header file corresponding to the c file.

pic.h

Then add the c file with bellow code segment.

pic.c

--

--