Implement a GDT, IDT with ISR and IRQ
Basically, added error handling, interrupts and basic hardware communication is now possible. Yay.
This commit is contained in:
parent
388834ef8a
commit
31d2e10b69
|
@ -35,9 +35,4 @@ _start:
|
||||||
|
|
||||||
.size _start, . - _start
|
.size _start, . - _start
|
||||||
|
|
||||||
.global idt_load
|
|
||||||
.extern idtp
|
|
||||||
idt_load:
|
|
||||||
lidt (idtp)
|
|
||||||
ret
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
; This file is written with Intel ASM Syntax.
|
; This file is written with Intel ASM Syntax.
|
||||||
|
|
||||||
[GLOBAL load_gdt] ; Allows the C code to call gdt_flush().
|
[GLOBAL load_gdt] ; Allows the C code to call gdt_flush().
|
||||||
|
[EXTERN gp]
|
||||||
load_gdt:
|
load_gdt:
|
||||||
mov eax, [esp+4] ; Get the pointer to the GDT, passed as a parameter.
|
; Get the pointer to the GDT, passed as a parameter.
|
||||||
lgdt [eax] ; Load the new GDT pointer
|
lgdt [gp] ; Load the new GDT pointer
|
||||||
|
|
||||||
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
|
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
|
||||||
mov ds, ax ; Load all data segment selectors
|
mov ds, ax ; Load all data segment selectors
|
||||||
|
@ -12,6 +12,6 @@ load_gdt:
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
jmp 0x08:.flush ; 0x08 is the offset to our code segment: Far jump!
|
jmp 0x08:flush ; 0x08 is the offset to our code segment: Far jump!
|
||||||
.flush:
|
flush:
|
||||||
ret
|
ret
|
|
@ -21,7 +21,7 @@
|
||||||
cli
|
cli
|
||||||
push byte 0
|
push byte 0
|
||||||
push byte %2
|
push byte %2
|
||||||
jmp isr_common
|
jmp irq_common
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
ISR 0
|
ISR 0
|
||||||
|
@ -57,6 +57,22 @@ ISR 29
|
||||||
ISR_ERR 30
|
ISR_ERR 30
|
||||||
ISR 31
|
ISR 31
|
||||||
|
|
||||||
|
IRQ 0, 32
|
||||||
|
IRQ 1, 33
|
||||||
|
IRQ 2, 34
|
||||||
|
IRQ 3, 35
|
||||||
|
IRQ 4, 36
|
||||||
|
IRQ 5, 37
|
||||||
|
IRQ 6, 38
|
||||||
|
IRQ 7, 39
|
||||||
|
IRQ 8, 40
|
||||||
|
IRQ 9, 41
|
||||||
|
IRQ 10, 42
|
||||||
|
IRQ 11, 43
|
||||||
|
IRQ 12, 44
|
||||||
|
IRQ 13, 45
|
||||||
|
IRQ 14, 46
|
||||||
|
IRQ 15, 47
|
||||||
|
|
||||||
extern fault_handler
|
extern fault_handler
|
||||||
|
|
||||||
|
@ -85,3 +101,35 @@ isr_common:
|
||||||
popa
|
popa
|
||||||
add esp, 8
|
add esp, 8
|
||||||
iret
|
iret
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
global idt_load
|
||||||
|
extern idtp
|
||||||
|
idt_load:
|
||||||
|
lidt [idtp]
|
||||||
|
ret
|
|
@ -4,7 +4,8 @@ KERNEL_ARCH_LDFLAGS=
|
||||||
KERNEL_ARCH_LIBS=
|
KERNEL_ARCH_LIBS=
|
||||||
|
|
||||||
KERNEL_ARCH_OBJS= \
|
KERNEL_ARCH_OBJS= \
|
||||||
$(ARCHDIR)/boot.o \
|
$(ARCHDIR)/boot.o \
|
||||||
$(ARCHDIR)/gdt.o \
|
$(ARCHDIR)/gdt.o \
|
||||||
$(ARCHDIR)/isr.o \
|
$(ARCHDIR)/isr.o \
|
||||||
|
$(ARCHDIR)/sys_clock.o \
|
||||||
$(ARCHDIR)/tty.o
|
$(ARCHDIR)/tty.o
|
21
arch/i386/sys_clock.c
Executable file
21
arch/i386/sys_clock.c
Executable file
|
@ -0,0 +1,21 @@
|
||||||
|
#include <kernel/utils.h>
|
||||||
|
#include <kernel/descriptor_tables.h>
|
||||||
|
#include <kernel/serial.h>
|
||||||
|
|
||||||
|
size_t timer_ticks = 0;
|
||||||
|
size_t flag = 0;
|
||||||
|
void timer_handler(registers_t* r) {
|
||||||
|
timer_ticks++;
|
||||||
|
|
||||||
|
if(timer_ticks % 18 == 0) {
|
||||||
|
if(++flag % 2 == 0) {
|
||||||
|
serial_print(0x3F8, "Tick.");
|
||||||
|
} else {
|
||||||
|
serial_print(0x3F8, "Tock.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer_install() {
|
||||||
|
irq_install_handler(0, timer_handler);
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void gdt_set_gate(int, unsigned long, unsigned long, unsigned char, unsigned char);
|
void gdt_set_gate(int, unsigned long, unsigned long, unsigned char, unsigned char);
|
||||||
void gdt_install();
|
void gdt_install();
|
||||||
|
|
||||||
|
@ -16,4 +17,103 @@ typedef struct registers {
|
||||||
uint32_t eip, cs, eflags, useresp, ss;
|
uint32_t eip, cs, eflags, useresp, ss;
|
||||||
} registers_t;
|
} registers_t;
|
||||||
|
|
||||||
void isr_install();
|
//These are all reserved by Intel, and need to be here.
|
||||||
|
extern void isr0();
|
||||||
|
extern void isr1();
|
||||||
|
extern void isr2();
|
||||||
|
extern void isr3();
|
||||||
|
extern void isr4();
|
||||||
|
extern void isr5();
|
||||||
|
extern void isr6();
|
||||||
|
extern void isr7();
|
||||||
|
extern void isr8();
|
||||||
|
extern void isr9();
|
||||||
|
extern void isr10();
|
||||||
|
extern void isr11();
|
||||||
|
extern void isr12();
|
||||||
|
extern void isr13();
|
||||||
|
extern void isr14();
|
||||||
|
extern void isr15();
|
||||||
|
extern void isr16();
|
||||||
|
extern void isr17();
|
||||||
|
extern void isr18();
|
||||||
|
extern void isr19();
|
||||||
|
extern void isr20();
|
||||||
|
extern void isr21();
|
||||||
|
extern void isr22();
|
||||||
|
extern void isr23();
|
||||||
|
extern void isr24();
|
||||||
|
extern void isr25();
|
||||||
|
extern void isr26();
|
||||||
|
extern void isr27();
|
||||||
|
extern void isr28();
|
||||||
|
extern void isr29();
|
||||||
|
extern void isr30();
|
||||||
|
extern void isr31();
|
||||||
|
|
||||||
|
extern void irq0();
|
||||||
|
extern void irq1();
|
||||||
|
extern void irq2();
|
||||||
|
extern void irq3();
|
||||||
|
extern void irq4();
|
||||||
|
extern void irq5();
|
||||||
|
extern void irq6();
|
||||||
|
extern void irq7();
|
||||||
|
extern void irq8();
|
||||||
|
extern void irq9();
|
||||||
|
extern void irq10();
|
||||||
|
extern void irq11();
|
||||||
|
extern void irq12();
|
||||||
|
extern void irq13();
|
||||||
|
extern void irq14();
|
||||||
|
extern void irq15();
|
||||||
|
|
||||||
|
static void* irq_routines[16] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
void irq_install_handler(int irq, void (*handler)(registers_t* r));
|
||||||
|
|
||||||
|
void irq_uninstall_handler(int);
|
||||||
|
|
||||||
|
void irq_install();
|
||||||
|
|
||||||
|
void irq_handler(registers_t*);
|
||||||
|
|
||||||
|
void timer_install();
|
||||||
|
|
||||||
|
static const char* exception_messages[] = {
|
||||||
|
"Division by Zero",
|
||||||
|
"Debug",
|
||||||
|
"Non Maskable Interrupt",
|
||||||
|
"Breakpoint",
|
||||||
|
"Into Detected Overflow",
|
||||||
|
"Out of Bounds",
|
||||||
|
"Invalid Opcode",
|
||||||
|
"No Coprocessor",
|
||||||
|
"Double Fault",
|
||||||
|
"Coprocessor Segment Overrun",
|
||||||
|
"Bad TSS",
|
||||||
|
"Segment Not Present",
|
||||||
|
"Stack Fault",
|
||||||
|
"General Protection Fault",
|
||||||
|
"Page Fault",
|
||||||
|
"Unknown Interrupt",
|
||||||
|
"Coprocessor Fault",
|
||||||
|
"Alignment Check",
|
||||||
|
"Machine Check",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved"
|
||||||
|
};
|
|
@ -21,7 +21,7 @@ struct gdt_ptr {
|
||||||
struct gdt_item gdt[3]; //3-entry gdt
|
struct gdt_item gdt[3]; //3-entry gdt
|
||||||
struct gdt_ptr gp;
|
struct gdt_ptr gp;
|
||||||
|
|
||||||
extern void load_gdt(uint32_t);
|
extern void load_gdt();
|
||||||
|
|
||||||
void gdt_set_gate(int num, uint32_t base,
|
void gdt_set_gate(int num, uint32_t base,
|
||||||
uint32_t limit, uint8_t access,
|
uint32_t limit, uint8_t access,
|
||||||
|
@ -52,5 +52,5 @@ void gdt_install() {
|
||||||
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
||||||
|
|
||||||
//Apply changes
|
//Apply changes
|
||||||
load_gdt((uint32_t) &gp);
|
load_gdt();
|
||||||
}
|
}
|
106
kernel/idt.c
106
kernel/idt.c
|
@ -1,4 +1,5 @@
|
||||||
#include <kernel/utils.h>
|
#include <kernel/utils.h>
|
||||||
|
#include <kernel/descriptor_tables.h>
|
||||||
|
|
||||||
struct idt_entry {
|
struct idt_entry {
|
||||||
unsigned short base_low;
|
unsigned short base_low;
|
||||||
|
@ -11,7 +12,7 @@ struct idt_entry {
|
||||||
struct idt_ptr {
|
struct idt_ptr {
|
||||||
unsigned short limit;
|
unsigned short limit;
|
||||||
unsigned int base;
|
unsigned int base;
|
||||||
}__attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct idt_entry idt[256]; // Interrupt table of 256 entries
|
struct idt_entry idt[256]; // Interrupt table of 256 entries
|
||||||
struct idt_ptr idtp; // Pointer to idt table
|
struct idt_ptr idtp; // Pointer to idt table
|
||||||
|
@ -32,11 +33,110 @@ void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, uns
|
||||||
|
|
||||||
void idt_install() {
|
void idt_install() {
|
||||||
idtp.limit = (sizeof (struct idt_entry) * 256) - 1;
|
idtp.limit = (sizeof (struct idt_entry) * 256) - 1;
|
||||||
idtp.base = &idt;
|
idtp.base = (uint16_t) &idt;
|
||||||
|
|
||||||
memset(&idt, 0, sizeof(struct idt_entry) * 256);
|
memset(&idt, 0, sizeof(struct idt_entry) * 256);
|
||||||
|
|
||||||
// All ISRs go here
|
idt_set_gate(0, (unsigned)isr0, 0x08, 0x8E);
|
||||||
|
idt_set_gate(1, (unsigned)isr1, 0x08, 0x8E);
|
||||||
|
idt_set_gate(2, (unsigned)isr2, 0x08, 0x8E);
|
||||||
|
idt_set_gate(3, (unsigned)isr3, 0x08, 0x8E);
|
||||||
|
idt_set_gate(4, (unsigned)isr4, 0x08, 0x8E);
|
||||||
|
idt_set_gate(5, (unsigned)isr5, 0x08, 0x8E);
|
||||||
|
idt_set_gate(6, (unsigned)isr6, 0x08, 0x8E);
|
||||||
|
idt_set_gate(7, (unsigned)isr7, 0x08, 0x8E);
|
||||||
|
|
||||||
|
idt_set_gate(8, (unsigned)isr8, 0x08, 0x8E);
|
||||||
|
idt_set_gate(9, (unsigned)isr9, 0x08, 0x8E);
|
||||||
|
idt_set_gate(10, (unsigned)isr10, 0x08, 0x8E);
|
||||||
|
idt_set_gate(11, (unsigned)isr11, 0x08, 0x8E);
|
||||||
|
idt_set_gate(12, (unsigned)isr12, 0x08, 0x8E);
|
||||||
|
idt_set_gate(13, (unsigned)isr13, 0x08, 0x8E);
|
||||||
|
idt_set_gate(14, (unsigned)isr14, 0x08, 0x8E);
|
||||||
|
idt_set_gate(15, (unsigned)isr15, 0x08, 0x8E);
|
||||||
|
|
||||||
|
idt_set_gate(16, (unsigned)isr16, 0x08, 0x8E);
|
||||||
|
idt_set_gate(17, (unsigned)isr17, 0x08, 0x8E);
|
||||||
|
idt_set_gate(18, (unsigned)isr18, 0x08, 0x8E);
|
||||||
|
idt_set_gate(19, (unsigned)isr19, 0x08, 0x8E);
|
||||||
|
idt_set_gate(20, (unsigned)isr20, 0x08, 0x8E);
|
||||||
|
idt_set_gate(21, (unsigned)isr21, 0x08, 0x8E);
|
||||||
|
idt_set_gate(22, (unsigned)isr22, 0x08, 0x8E);
|
||||||
|
idt_set_gate(23, (unsigned)isr23, 0x08, 0x8E);
|
||||||
|
|
||||||
|
idt_set_gate(24, (unsigned)isr24, 0x08, 0x8E);
|
||||||
|
idt_set_gate(25, (unsigned)isr25, 0x08, 0x8E);
|
||||||
|
idt_set_gate(26, (unsigned)isr26, 0x08, 0x8E);
|
||||||
|
idt_set_gate(27, (unsigned)isr27, 0x08, 0x8E);
|
||||||
|
idt_set_gate(28, (unsigned)isr28, 0x08, 0x8E);
|
||||||
|
idt_set_gate(29, (unsigned)isr29, 0x08, 0x8E);
|
||||||
|
idt_set_gate(30, (unsigned)isr30, 0x08, 0x8E);
|
||||||
|
idt_set_gate(31, (unsigned)isr31, 0x08, 0x8E);
|
||||||
|
|
||||||
idt_load();
|
idt_load();
|
||||||
|
irq_install();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void irq_install_handler(int irq, void (*handler)(registers_t* r)) {
|
||||||
|
irq_routines[irq] = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void irq_uninstall_handler(int irq) {
|
||||||
|
irq_routines[irq] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void irq_remap() {
|
||||||
|
outb(0x20, 0x11);
|
||||||
|
outb(0xA0, 0x11);
|
||||||
|
outb(0x21, 0x20);
|
||||||
|
outb(0xA1, 0x28);
|
||||||
|
outb(0x21, 0x04);
|
||||||
|
outb(0xA1, 0x02);
|
||||||
|
outb(0x21, 0x01);
|
||||||
|
outb(0xA1, 0x01);
|
||||||
|
outb(0x21, 0x0);
|
||||||
|
outb(0xA1, 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void irq_install() {
|
||||||
|
irq_remap();
|
||||||
|
idt_set_gate(32, (unsigned)irq0, 0x08, 0x8E);
|
||||||
|
idt_set_gate(33, (unsigned)irq1, 0x08, 0x8E);
|
||||||
|
idt_set_gate(34, (unsigned)irq2, 0x08, 0x8E);
|
||||||
|
idt_set_gate(35, (unsigned)irq3, 0x08, 0x8E);
|
||||||
|
idt_set_gate(36, (unsigned)irq4, 0x08, 0x8E);
|
||||||
|
idt_set_gate(37, (unsigned)irq5, 0x08, 0x8E);
|
||||||
|
idt_set_gate(38, (unsigned)irq6, 0x08, 0x8E);
|
||||||
|
idt_set_gate(39, (unsigned)irq7, 0x08, 0x8E);
|
||||||
|
idt_set_gate(40, (unsigned)irq8, 0x08, 0x8E);
|
||||||
|
idt_set_gate(41, (unsigned)irq9, 0x08, 0x8E);
|
||||||
|
idt_set_gate(42, (unsigned)irq10, 0x08, 0x8E);
|
||||||
|
idt_set_gate(43, (unsigned)irq11, 0x08, 0x8E);
|
||||||
|
idt_set_gate(44, (unsigned)irq12, 0x08, 0x8E);
|
||||||
|
idt_set_gate(45, (unsigned)irq13, 0x08, 0x8E);
|
||||||
|
idt_set_gate(46, (unsigned)irq14, 0x08, 0x8E);
|
||||||
|
idt_set_gate(47, (unsigned)irq15, 0x08, 0x8E);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fault_handler(registers_t *r) {
|
||||||
|
if(r->int_no < 32) {
|
||||||
|
serial_print(exception_messages[r->int_no], strlen(exception_messages[r->int_no]));
|
||||||
|
serial_print(" Exception. Halting.\r\n");
|
||||||
|
for(;;);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void irq_handler(registers_t *r) {
|
||||||
|
void (*handler)(registers_t* r);
|
||||||
|
|
||||||
|
serial_print(0x3F8, "[INFO] Received IRQ: " + r->int_no);
|
||||||
|
handler = irq_routines[r->int_no - 32];
|
||||||
|
if(handler)
|
||||||
|
handler(r);
|
||||||
|
|
||||||
|
if(r->int_no > 39)
|
||||||
|
outb(0xA0, 0x20);
|
||||||
|
|
||||||
|
outb(0x20, 0x20);
|
||||||
}
|
}
|
110
kernel/isr.c
110
kernel/isr.c
|
@ -2,114 +2,4 @@
|
||||||
#include <kernel/tty.h>
|
#include <kernel/tty.h>
|
||||||
#include <kernel/utils.h>
|
#include <kernel/utils.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
//These are all reserved by Intel, and need to be here.
|
|
||||||
extern void isr0();
|
|
||||||
extern void isr1();
|
|
||||||
extern void isr2();
|
|
||||||
extern void isr3();
|
|
||||||
extern void isr4();
|
|
||||||
extern void isr5();
|
|
||||||
extern void isr6();
|
|
||||||
extern void isr7();
|
|
||||||
extern void isr8();
|
|
||||||
extern void isr9();
|
|
||||||
extern void isr10();
|
|
||||||
extern void isr11();
|
|
||||||
extern void isr12();
|
|
||||||
extern void isr13();
|
|
||||||
extern void isr14();
|
|
||||||
extern void isr15();
|
|
||||||
extern void isr16();
|
|
||||||
extern void isr17();
|
|
||||||
extern void isr18();
|
|
||||||
extern void isr19();
|
|
||||||
extern void isr20();
|
|
||||||
extern void isr21();
|
|
||||||
extern void isr22();
|
|
||||||
extern void isr23();
|
|
||||||
extern void isr24();
|
|
||||||
extern void isr25();
|
|
||||||
extern void isr26();
|
|
||||||
extern void isr27();
|
|
||||||
extern void isr28();
|
|
||||||
extern void isr29();
|
|
||||||
extern void isr30();
|
|
||||||
extern void isr31();
|
|
||||||
|
|
||||||
void isr_install() {
|
|
||||||
idt_set_gate(0, (unsigned)isr0, 0x00, 0x8E);
|
|
||||||
idt_set_gate(1, (unsigned)isr1, 0x00, 0x8E);
|
|
||||||
idt_set_gate(2, (unsigned)isr2, 0x00, 0x8E);
|
|
||||||
idt_set_gate(3, (unsigned)isr3, 0x00, 0x8E);
|
|
||||||
idt_set_gate(4, (unsigned)isr4, 0x00, 0x8E);
|
|
||||||
idt_set_gate(5, (unsigned)isr5, 0x00, 0x8E);
|
|
||||||
idt_set_gate(6, (unsigned)isr6, 0x00, 0x8E);
|
|
||||||
idt_set_gate(7, (unsigned)isr7, 0x00, 0x8E);
|
|
||||||
idt_set_gate(8, (unsigned)isr8, 0x00, 0x8E);
|
|
||||||
idt_set_gate(9, (unsigned)isr9, 0x00, 0x8E);
|
|
||||||
idt_set_gate(10, (unsigned)isr10, 0x00, 0x8E);
|
|
||||||
idt_set_gate(11, (unsigned)isr11, 0x00, 0x8E);
|
|
||||||
idt_set_gate(12, (unsigned)isr12, 0x00, 0x8E);
|
|
||||||
idt_set_gate(13, (unsigned)isr13, 0x00, 0x8E);
|
|
||||||
idt_set_gate(14, (unsigned)isr14, 0x00, 0x8E);
|
|
||||||
idt_set_gate(15, (unsigned)isr15, 0x00, 0x8E);
|
|
||||||
idt_set_gate(16, (unsigned)isr16, 0x00, 0x8E);
|
|
||||||
idt_set_gate(17, (unsigned)isr17, 0x00, 0x8E);
|
|
||||||
idt_set_gate(18, (unsigned)isr18, 0x00, 0x8E);
|
|
||||||
idt_set_gate(19, (unsigned)isr19, 0x00, 0x8E);
|
|
||||||
idt_set_gate(20, (unsigned)isr20, 0x00, 0x8E);
|
|
||||||
idt_set_gate(21, (unsigned)isr21, 0x00, 0x8E);
|
|
||||||
idt_set_gate(22, (unsigned)isr22, 0x00, 0x8E);
|
|
||||||
idt_set_gate(23, (unsigned)isr23, 0x00, 0x8E);
|
|
||||||
idt_set_gate(24, (unsigned)isr24, 0x00, 0x8E);
|
|
||||||
idt_set_gate(25, (unsigned)isr25, 0x00, 0x8E);
|
|
||||||
idt_set_gate(26, (unsigned)isr26, 0x00, 0x8E);
|
|
||||||
idt_set_gate(27, (unsigned)isr27, 0x00, 0x8E);
|
|
||||||
idt_set_gate(28, (unsigned)isr28, 0x00, 0x8E);
|
|
||||||
idt_set_gate(29, (unsigned)isr29, 0x00, 0x8E);
|
|
||||||
idt_set_gate(30, (unsigned)isr30, 0x00, 0x8E);
|
|
||||||
idt_set_gate(31, (unsigned)isr31, 0x00, 0x8E);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* exception_messages[] = {
|
|
||||||
"Division by Zero",
|
|
||||||
"Debug",
|
|
||||||
"Non Maskable Interrupt",
|
|
||||||
"Breakpoint",
|
|
||||||
"Into Detected Overflow",
|
|
||||||
"Out of Bounds",
|
|
||||||
"Invalid Opcode",
|
|
||||||
"No Coprocessor",
|
|
||||||
"Double Fault",
|
|
||||||
"Coprocessor Segment Overrun",
|
|
||||||
"Bad TSS",
|
|
||||||
"Segment Not Present",
|
|
||||||
"Stack Fault",
|
|
||||||
"General Protection Fault",
|
|
||||||
"Page Fault",
|
|
||||||
"Unknown Interrupt",
|
|
||||||
"Coprocessor Fault",
|
|
||||||
"Alignment Check",
|
|
||||||
"Machine Check",
|
|
||||||
"Reserved",
|
|
||||||
"Reserved",
|
|
||||||
"Reserved",
|
|
||||||
"Reserved",
|
|
||||||
"Reserved",
|
|
||||||
"Reserved",
|
|
||||||
"Reserved",
|
|
||||||
"Reserved",
|
|
||||||
"Reserved",
|
|
||||||
"Reserved",
|
|
||||||
"Reserved",
|
|
||||||
"Reserved",
|
|
||||||
"Reserved"
|
|
||||||
};
|
|
||||||
|
|
||||||
void fault_handler(registers_t *r) {
|
|
||||||
if(r->int_no < 32) {
|
|
||||||
term_write(exception_messages[r->int_no], strlen(exception_messages[r->int_no]));
|
|
||||||
puts(" Exception. Halting.");
|
|
||||||
for(;;);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,16 +11,23 @@ int kernel_main(void) {
|
||||||
|
|
||||||
// Prepare the serial console.
|
// Prepare the serial console.
|
||||||
init_serial();
|
init_serial();
|
||||||
serial_print(0x3F8, "[INFO] Serial ready.\n");
|
serial_print(0x3F8, "[INFO] Serial ready.\r\n");
|
||||||
|
|
||||||
// Prepare the GDT
|
// Prepare the GDT
|
||||||
serial_print(0x3F8, "[INFO] Beginning GDT subroutine.\n");
|
serial_print(0x3F8, "[INFO] Beginning GDT subroutine.\r\n");
|
||||||
gdt_install();
|
gdt_install();
|
||||||
|
serial_print(0x3F8, "[INFO] GDT subroutine complete.\r\n");
|
||||||
|
|
||||||
// Prepare interrupts
|
// Prepare interrupts
|
||||||
serial_print(0x3F8, "[INFO] Beginning IDT subroutine.\n");
|
serial_print(0x3F8, "[INFO] Beginning IDT subroutine.\r\n");
|
||||||
idt_install();
|
idt_install();
|
||||||
isr_install();
|
serial_print(0x3F8, "[INFO] IDT subroutine complete.\r\n[INFO] Enabling interrupts.\r\n");
|
||||||
|
asm volatile("sti");
|
||||||
|
|
||||||
|
serial_print(0x3F8, "[INFO] Starting System Clock.\r\n");
|
||||||
|
timer_install();
|
||||||
|
|
||||||
|
serial_print(0x3F8, "[INFO] All subsystems ready. Printing message.\r\n");
|
||||||
|
|
||||||
//Print a copyright message.
|
//Print a copyright message.
|
||||||
term_writes("(c)");
|
term_writes("(c)");
|
||||||
|
@ -31,6 +38,14 @@ int kernel_main(void) {
|
||||||
term_setcolor(WHITE);
|
term_setcolor(WHITE);
|
||||||
term_writes(", 2019\n");
|
term_writes(", 2019\n");
|
||||||
|
|
||||||
|
serial_print(0x3F8, "[INFO] All operations complete. Checking for other tasks...\r\n");
|
||||||
|
|
||||||
|
for(size_t i = 0; i < 3000; i++) {}
|
||||||
|
|
||||||
|
serial_print(0x3F8, "[DEBUG] Attempting a Divide by Zero error.\r\n");
|
||||||
|
//term_putchar(5/0);
|
||||||
|
serial_print(0x3F8, "[DEBUG] Survived the error!\r\n");
|
||||||
|
|
||||||
for(;;) {}
|
for(;;) {}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user