Skip to content

Commit

Permalink
Implement Programmable Interrupt Controller
Browse files Browse the repository at this point in the history
  • Loading branch information
taikiy committed Mar 4, 2023
1 parent 7c7d979 commit 8b01fa3
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 7 deletions.
27 changes: 26 additions & 1 deletion src/idt/idt.asm
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
section .asm

global idt_load
global int21h
global int_noop

extern int21h_handler
extern int_noop_handler

idt_load:
push ebp
Expand All @@ -10,4 +15,24 @@ idt_load:
lidt [ebx]

pop ebp
ret
ret

int21h:
cli
pushad ; pushes the contents of general-purpose registers (EAX, EBX, ECX, EDX, ESP, EBP, ESI and EDI) onto the stack.

call int21h_handler

popad
sti
iret

int_noop:
cli
pushad ; pushes the contents of general-purpose registers (EAX, EBX, ECX, EDX, ESP, EBP, ESI and EDI) onto the stack.

call int_noop_handler

popad
sti
iret
19 changes: 19 additions & 0 deletions src/idt/idt.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,31 @@
#include "config.h"
#include "kernel.h"
#include "memory/memory.h"
#include "io/io.h"

struct idt_desc idt_descriptors[TOTAL_INTERRUPTS];
struct idtr_desc idtr_descriptor;

extern void idt_load(struct idtr_desc *ptr);
extern void int21h();
extern void int_noop();

void idt_zero()
{
print("Divide by zero error\n");
}

void int21h_handler()
{
print("Keyboard pressed\n");
outb(0x20, 0x20);
}

void int_noop_handler()
{
outb(0x20, 0x20);
}

void idt_set(int interrupt_number, void *address)
{
struct idt_desc *desc = &idt_descriptors[interrupt_number];
Expand All @@ -34,7 +48,12 @@ void idt_init()
idtr_descriptor.limit = sizeof(idt_descriptors) - 1;
idtr_descriptor.base = (uint32_t)idt_descriptors;

for (int i = 0; i < TOTAL_INTERRUPTS; i++)
{
idt_set(i, int_noop);
}
idt_set(0, idt_zero);
idt_set(0x21, int21h);

// Load the IDT
idt_load(&idtr_descriptor);
Expand Down
17 changes: 14 additions & 3 deletions src/kernel.asm
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,22 @@ _start:
or al, 2
out 0x92, al ; Write to the bus line 92

; Remap the master PIC
mov al, 00010001b ; Set PIC to initialization mode
out 0x20, al ; Send the *command* to master PIC via port 0x20
mov al, 0x20 ; IRQ 0 mapped to INT 0x20. Following IRQs (1-7) are also mapped accordingly.
out 0x21, al ; Send the *data* to master PIC via port 0x21
mov al, 00000001b ; Set PIC to x86 mode
out 0x21, al ; We finish the initialization by sending the mode configuration to the *data* port.

; Call our kernel
sti
call kernel_main

cld ; Clears direction flag
cli ; Disables interrupts
hlt ; This hangs the computer
jmp $ ; Go into an infinite loop. It lets us interact with the kernel instead of coming to a halt.
; cld ; Clears direction flag
; cli ; Disables interrupts
; hlt ; This hangs the computer

times 512 - ($ - $$) db 0 ; Pad the kernel code sector to 512 bytes
; This ensures that any object files written in C and linked with this assembly
Expand Down
4 changes: 1 addition & 3 deletions src/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,8 @@ void print(const char *str)
void kernel_main()
{
terminal_initialize();
print("Hello, World!\nYou are in Protected Mode!");
print("Hello, World!\nYou are in Protected Mode!\n");

// Initialize the Interrupt Descriptor Table
idt_init();

outb(0x60, 0xff);
}

0 comments on commit 8b01fa3

Please sign in to comment.