OS crashes whenever I press a key
Posted: Wed Apr 05, 2017 8:16 am
Whenever I press a key, instead of sending irq 1, it crashes my os with a triple fault. It does the same with the PIT, so I have disabled it for now. I have tried to do it manually with asm("int $1"), but it still crashes. I am compiling with gcc & nasm. Here are my codes:
irq.c:
I don't think irq.h is important. Its just some .
keyboard.c
idt.c
and the assembly for interrupts:
Thanks in advance!
irq.c:
Code: Select all
#include "irq.h"
void* irq_routines[16] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
void irq_add_handler(int irq, void (*handler) (struct registers* r)) {
irq_routines[irq] = handler;
}
void irq_remove_handler(int irq) {
irq_routines[irq] = 0;
}
void irq_remap(void) {
outportb(0x20, 0x11);
outportb(0xA0, 0x11);
outportb(0x21, 0x20);
outportb(0xA1, 0x28);
outportb(0x21, 0x04);
outportb(0xA1, 0x02);
outportb(0x21, 0x01);
outportb(0xA1, 0x01);
outportb(0x21, 0x0);
outportb(0xA1, 0x0);
}
void irq_init(void) {
irq_remap();
set_idt_gate(32, (unsigned) irq0);
set_idt_gate(33, (unsigned) irq1);
set_idt_gate(34, (unsigned) irq2);
set_idt_gate(35, (unsigned) irq3);
set_idt_gate(36, (unsigned) irq4);
set_idt_gate(37, (unsigned) irq5);
set_idt_gate(38, (unsigned) irq6);
set_idt_gate(39, (unsigned) irq7);
set_idt_gate(40, (unsigned) irq8);
set_idt_gate(41, (unsigned) irq9);
set_idt_gate(42, (unsigned) irq10);
set_idt_gate(43, (unsigned) irq11);
set_idt_gate(44, (unsigned) irq12);
set_idt_gate(45, (unsigned) irq13);
set_idt_gate(46, (unsigned) irq14);
set_idt_gate(47, (unsigned) irq15);
}
void irq_handler(struct registers* r) {
void (*handler) (struct registers* r);
handler = irq_routines[r->num - 32];
if (handler) {
handler(r);
} if (r->num >= 40) {
outportb(0xA0, 0x20);
}
outportb(0x20, 0x20);
}
Code: Select all
extern void irq ... ();
keyboard.c
Code: Select all
#include "keyboard_driver.h"
static uint8 press;
static uint8 release;
void keyboard_handler(struct registers* r) {
uint8 scancode;
scancode = inportb(0x60);
println("Keypress", 0x07);
if (scancode & 0x80) release = scancode;
else press = scancode;
}
void keyboard_install(void) {
while (inportb(0x64) & 0x1) {
inportb(0x60);
}
outportb(0x64, 0xae);
outportb(0x64, 0x20);
uint8 status = (inportb(0x60) | 1) & ~0x10;
outportb(0x64, 0x60);
outportb(0x60, status);
outportb(0x60, 0xf4);
//irq_add_handler(33, keyboard_handler);
irq_add_handler(1, keyboard_handler);
}
uint8 poll_key(void) {
uint8 temp = press;
press = 127;
return temp;
}
uint8 poll_key_release(void) {
uint8 temp = release;
release = 127;
return temp;
}
Code: Select all
static uint8 flags = 0x8E;
void set_idt_gate(int n, uint32 handler) {
idt[n].high_offset = high_16(handler);
idt[n].low_offset = low_16(handler);
idt[n].sel = KERNEL_CS;
idt[n].always0 = 0;
idt[n].flags = flags;
}
void set_idt(void) {
idt_reg.limit = (uint32) &idt;
idt_reg.base = IDT_ENTRIES * sizeof(idt_gate_t) - 1;
__asm__ __volatile__("lidtl (%0)" : : "r" (&idt_reg));
}
void set_idt_flags(uint8 _flags) {
flags = _flags;
}
Code: Select all
global irq0
continues up to...
global irq15
irq0:
cli
push byte 0
push byte 32
jmp irq_common
irq1:
cli
push byte 0
push byte 33
jmp irq_common .. and so on...
extern irq_handler
irq_common:
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
mov eax, irq_handler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret