HOW CAN CREATE OWN OPERATING SYSTEM #05

What is an interrupt?

1.Interrupts Handlers

  • Task handler
  • Interrupt handler
  • Trap handler

2.Creating an Entry in the IDT

Bit:     | 31              16 | 15 | 14 13 | 12 | 11 | 10 9 8 | 7 6 5 | 4 3 2 1 0 |
Content: | offset high | P | DPL | 0 | D | 1 1 0 | 0 0 0 | reserved |
Bit:     | 31              16 | 15              0 |
Content: | segment selector | offset low |
    0xDEAD8E00
0x0008BEEF
    idt[0] = 0xDEAD8E00
idt[1] = 0x0008BEEF

3.Handling an Interrupt

    [esp + 12] eflags
[esp + 8] cs
[esp + 4] eip
[esp] error code?
    struct cpu_state {
unsigned int eax;
unsigned int ebx;
unsigned int ecx;
.
.
.
unsigned int esp;
} __attribute__((packed));

struct stack_state {
unsigned int error_code;
unsigned int eip;
unsigned int cs;
unsigned int eflags;
} __attribute__((packed));

void interrupt_handler(struct cpu_state cpu, struct stack_state stack, unsigned int interrupt);

4.Creating a Generic Interrupt Handler

    %macro no_error_code_interrupt_handler %1
global interrupt_handler_%1
interrupt_handler_%1:
push dword 0 ; push 0 as error code
push dword %1 ; push the interrupt number
jmp common_interrupt_handler ; jump to the common handler
%endmacro

%macro error_code_interrupt_handler %1
global interrupt_handler_%1
interrupt_handler_%1:
push dword %1 ; push the interrupt number
jmp common_interrupt_handler ; jump to the common handler
%endmacro

common_interrupt_handler: ; the common parts of the generic interrupt handler
; save the registers
push eax
push ebx
.
.
.
push ebp

; call the C function
call interrupt_handler

; restore the registers
pop ebp
.
.
.
pop ebx
pop eax

; restore the esp
add esp, 8

; return to the code that got interrupted
iret

no_error_code_interrupt_handler 0 ; create handler for interrupt 0
no_error_code_interrupt_handler 1 ; create handler for interrupt 1
.
.
.
error_code_handler 7 ; create handler for interrupt 7
.
.
.
  • 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.

5.Loading the IDT

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

6.Programmable Interrupt Controller (PIC)

  • Remap the interrupts. The PIC uses interrupts 0–15 for hardware interrupts by default, which conflicts with the CPU interrupts. Therefore the PIC interrupts must be remapped to another interval.
  • Select which interrupts to receive. You probably don’t want to receive interrupts from all devices since you don’t have code that handles these interrupts anyway.
  • Set up the correct mode for the PIC.
#include "io.h"

#define PIC1_PORT_A 0x20
#define PIC2_PORT_A 0xA0

/* The PIC interrupts have been remapped */
#define PIC1_START_INTERRUPT 0x20
#define PIC2_START_INTERRUPT 0x28
#define PIC2_END_INTERRUPT PIC2_START_INTERRUPT + 7

#define PIC_ACK 0x20

/** pic_acknowledge:
* Acknowledges an interrupt from either PIC 1 or PIC 2.
*
* @param num The number of the interrupt
*/
void pic_acknowledge(unsigned integer interrupt)
{
if (interrupt < PIC1_START_INTERRUPT || interrupt > PIC2_END_INTERRUPT) {
return;
}

if (interrupt < PIC2_START_INTERRUPT) {
outb(PIC1_PORT_A, PIC_ACK);
} else {
outb(PIC2_PORT_A, PIC_ACK);
}
}

7.Reading Input from the Keyboard

    #include "io.h"

#define KBD_DATA_PORT 0x60

/** read_scan_code:
* Reads a scan code from the keyboard
*
* @return The scan code (NOT an ASCII character!)
*/
unsigned char read_scan_code(void)
{
return inb(KBD_DATA_PORT);
}

Output the Input

Further Reading:

  • The OSDev wiki has a great page on interrupts, http://wiki.osdev.org/Interrupts
  • Chapter 6 of Intel Manual 3a [33] describes everything there is to know about interrupts.
Thank you

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store