This commit is contained in:
Ben
2019-05-02 17:29:24 +01:00
parent 390fc87c20
commit 44330e8427
14 changed files with 576 additions and 18 deletions

View File

@@ -7,7 +7,7 @@ set(CMAKE_ASM_COMPILER "i686-elf-as")
set(CMAKE_C_COMPILER "i686-elf-gcc")
set(CMAKE_CXX_COMPILER "i686-elf-g++")
set(CMAKE_CXX_FLAGS "-ffreestanding -O2 -fno-rtti -Wno-write-strings -Wno-multichar -Wno-unused-parameter -Wno-overflow -Wno-narrowing -fno-exceptions -Wno-trigraphs ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "-ffreestanding -funroll-loops -O2 -fno-rtti -Wno-write-strings -Wno-multichar -Wno-unused-parameter -Wno-overflow -Wno-narrowing -fno-exceptions -Wno-trigraphs ${CMAKE_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "-T ../linker.ld -ffreestanding -O2 -nostdlib -lgcc -Wwrite-strings ${CMAKE_EXE_LINKER_FLAGS}")
include_directories(OwOS "./")

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,9 +1,12 @@
#include <kernel/multiboot.h>
#include <kernel/drivers/terminal/terminal.h>
#include <kernel/kernio.h>
#include <kernel/panic.h>
#include <kernel/pic.h>
#include <kernel/gdt.h>
#include <kernel/idt.h>
#include <lib/std/stdlib.h>
#include <lib/std/memory.h>
@@ -25,11 +28,14 @@ int kernel_main(uint32_t magic, MultibootInfo_t* multiboot) {
// Init systems
int igdt = InitGDT();
if (igdt == 1)
loggerOK("GDT Loaded");
else
GDT_Init();
loggerOK("GDT Init");
PIC_Default_Remap();
loggerOK("PIC Remapped");
IDT_Init();
loggerOK("IDT Init");
Nline(); Nline();
Write("OwO, What's This?");
@@ -45,7 +51,7 @@ int kernel_main(uint32_t magic, MultibootInfo_t* multiboot) {
SetFGColour(VGA_BRIGHT_MAGENTA);
Write("~#");
PanicKernel(0x00, "Self Triggered Panic", "kernel.cpp:48", "kernel_main(uint32_t magic, MultibootInfo_t* multiboot)");
// PanicKernel(0x00, "Self Triggered Panic", "kernel.cpp:48", "kernel_main(uint32_t magic, MultibootInfo_t* multiboot)");
for (;;)
asm("hlt");

View File

@@ -25,23 +25,22 @@ void lgdt(GDT_t GDT) {
asm ("lgdt %0" : : "m"(GDT));
}
int InitGDT() {
void GDT_Init() {
_GDTptr.limit = (sizeof(SegmentDescriptor_t) * 5) - 1;
_GDTptr.base = (uint32_t)&_GDT;
// Null segment
SetGDTGate(0, 0, 0, 0, 0);
GDT_Set_Gate(0, 0, 0, 0, 0);
// Code Base 0 limit 32 Access EXEC + RW
SetGDTGate(1, 0x00000000, 0xFFFFFFFF, GDT_ACCESS_PRESENT | GDT_ACCESS_EXEC | GDT_ACCESS_RW, GDT_FLAG_GR_PAGE | GDT_FLAG_SZ_32B);
GDT_Set_Gate(1, 0x00000000, 0xFFFFFFFF, GDT_ACCESS_PRESENT | GDT_ACCESS_EXEC | GDT_ACCESS_RW, GDT_FLAG_GR_PAGE | GDT_FLAG_SZ_32B);
// Data Base 0 Limit 32 Access RW
SetGDTGate(2, 0x00000000, 0xFFFFFFFF, GDT_ACCESS_PRESENT | GDT_ACCESS_RW, GDT_FLAG_GR_PAGE | GDT_FLAG_SZ_32B);
GDT_Set_Gate(2, 0x00000000, 0xFFFFFFFF, GDT_ACCESS_PRESENT | GDT_ACCESS_RW, GDT_FLAG_GR_PAGE | GDT_FLAG_SZ_32B);
lgdt(_GDTptr);
SEGMENTS_RELOAD();
return 1;
}
void SetGDTGate(uint32_t index, uint32_t baseAddr, uint32_t limitAddr, uint8_t accessLvl, uint8_t flags) {
void GDT_Set_Gate(uint32_t index, uint32_t baseAddr, uint32_t limitAddr, uint8_t accessLvl, uint8_t flags) {
if (index > 5) return;
_GDT[index].base_low = (baseAddr & 0xFFFF);
_GDT[index].base_middle = (baseAddr >> 16) & 0xFF;

View File

@@ -19,5 +19,5 @@ extern "C" {
extern void SEGMENTS_RELOAD(void);
}
int InitGDT();
void SetGDTGate(uint32_t index, uint32_t baseAddr, uint32_t limitAddr, uint8_t accessLvl, uint8_t flags);
void GDT_Init();
void GDT_Set_Gate(uint32_t index, uint32_t baseAddr, uint32_t limitAddr, uint8_t accessLvl, uint8_t flags);

View File

@@ -0,0 +1,81 @@
#include "idt.h"
#include <kernel/drivers/terminal/terminal.h>
#include <lib/std/stdlib.h>
struct IDT_Descriptor_t {
uint16_t offset_low;
uint16_t selector;
uint8_t zero;
uint8_t type_attr;
uint16_t offset_high;
} __attribute__((packed));
struct IDT_t {
uint16_t limit;
uint32_t base;
} __attribute__((packed));
IDT_Descriptor_t _IDT[256];
IDT_t _IDTptr;
void lidt(IDT_t IDT) {
asm("lidt %0" : : "m"(IDT));
}
void IDT_Set_Gate(uint8_t i, uint32_t offset, uint16_t selector, uint8_t attrib);
void IDT_Init() {
_IDTptr.limit = (sizeof(IDT_Descriptor_t) * 256) - 1;
_IDTptr.base = (uint32_t)&_IDT;
for (uint16_t i = 0; i < 256; i++)
IDT_Set_Gate(i, (uint32_t)&ISR_DEFAULT, 0x01, IDT_ATTR_PRESENT | IDT_TRAP_GATE | IDT_ATTR_PRIV_3);
IDT_Set_Gate(0x00, (uint32_t)&ISR0, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x01, (uint32_t)&ISR1, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x02, (uint32_t)&ISR2, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x03, (uint32_t)&ISR3, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x04, (uint32_t)&ISR4, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x05, (uint32_t)&ISR5, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x06, (uint32_t)&ISR6, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x07, (uint32_t)&ISR7, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x08, (uint32_t)&ISR8, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x09, (uint32_t)&ISR9, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x0A, (uint32_t)&ISR10, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x0B, (uint32_t)&ISR11, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x0C, (uint32_t)&ISR12, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x0D, (uint32_t)&ISR13, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x0E, (uint32_t)&ISR14, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x0F, (uint32_t)&ISR15, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x10, (uint32_t)&ISR16, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x11, (uint32_t)&ISR17, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x12, (uint32_t)&ISR18, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x13, (uint32_t)&ISR19, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x14, (uint32_t)&ISR20, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x15, (uint32_t)&ISR21, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x16, (uint32_t)&ISR22, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x17, (uint32_t)&ISR23, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x18, (uint32_t)&ISR24, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x19, (uint32_t)&ISR25, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x1A, (uint32_t)&ISR26, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x1B, (uint32_t)&ISR27, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x1C, (uint32_t)&ISR28, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x1D, (uint32_t)&ISR29, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x1E, (uint32_t)&ISR30, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x1F, (uint32_t)&ISR31, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
IDT_Set_Gate(0x21, (uint32_t)&ISR_KBD, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE);
lidt(_IDTptr);
}
void IDT_Set_Gate(uint8_t i, uint32_t offset, uint16_t selector, uint8_t attrib) {
if (i > 256) return;
_IDT[i].offset_low = offset & 0xFFFF;
_IDT[i].selector = selector * 8;
_IDT[i].zero = 0;
_IDT[i].type_attr = attrib;
_IDT[i].offset_high = (offset & 0xFFFF) >> 16;
}

View File

@@ -0,0 +1,55 @@
#pragma once
#include <lib/stdint.h>
#define IDT_ATTR_PRESENT 0x80
#define IDT_ATTR_PRIV_3 0x60
#define IDT_ATTR_PRIV_2 0x40
#define IDT_ATTR_PRIV_1 0x20
#define IDT_INT_GATE 0x0E
#define IDT_TRAP_GATE 0x0F
#define IDT_TASK_GATE 0x15
void IDT_Init();
void IDT_Set_Gate();
#define ISR_DEF(id) extern void ISRid(void)
extern "C" {
extern void ISR_DEFAULT(void);
extern void ISR_KBD(void);
extern void ISR0(void);
extern void ISR1(void);
extern void ISR2(void);
extern void ISR3(void);
extern void ISR4(void);
extern void ISR5(void);
extern void ISR6(void);
extern void ISR7(void);
extern void ISR8(void);
extern void ISR9(void);
extern void ISR10(void);
extern void ISR11(void);
extern void ISR12(void);
extern void ISR13(void);
extern void ISR14(void);
extern void ISR15(void);
extern void ISR16(void);
extern void ISR17(void);
extern void ISR18(void);
extern void ISR19(void);
extern void ISR20(void);
extern void ISR21(void);
extern void ISR22(void);
extern void ISR23(void);
extern void ISR24(void);
extern void ISR25(void);
extern void ISR26(void);
extern void ISR27(void);
extern void ISR28(void);
extern void ISR29(void);
extern void ISR30(void);
extern void ISR31(void);
}

272
kernel/isr.asm Normal file
View File

@@ -0,0 +1,272 @@
.align 4
.global ISR0
.global ISR1
.global ISR2
.global ISR3
.global ISR4
.global ISR5
.global ISR6
.global ISR7
.global ISR8
.global ISR9
.global ISR10
.global ISR11
.global ISR12
.global ISR13
.global ISR14
.global ISR15
.global ISR16
.global ISR17
.global ISR18
.global ISR19
.global ISR20
.global ISR21
.global ISR22
.global ISR23
.global ISR24
.global ISR25
.global ISR26
.global ISR27
.global ISR28
.global ISR29
.global ISR30
.global ISR31
ISR0:
cli
push $0
push $0
jmp ISR_FAULT
ISR1:
cli
push $0
push $1
jmp ISR_FAULT
ISR2:
cli
push $0
push $2
jmp ISR_FAULT
ISR3:
cli
push $0
push $3
jmp ISR_FAULT
ISR4:
cli
push $0
push $4
jmp ISR_FAULT
ISR5:
cli
push $0
push $5
jmp ISR_FAULT
ISR6:
cli
push $0
push $6
jmp ISR_FAULT
ISR7:
cli
push $0
push $7
jmp ISR_FAULT
ISR8:
cli
push $8
jmp ISR_FAULT
ISR9:
cli
push $9
jmp ISR_FAULT
ISR10:
cli
push $10
jmp ISR_FAULT
ISR11:
cli
push $11
jmp ISR_FAULT
ISR12:
cli
push $12
jmp ISR_FAULT
ISR13:
cli
push $13
jmp ISR_FAULT
ISR14:
cli
push $14
jmp ISR_FAULT
ISR15:
cli
push $15
jmp ISR_FAULT
ISR16:
cli
push $16
jmp ISR_FAULT
ISR17:
cli
push $17
jmp ISR_FAULT
ISR18:
cli
push $18
jmp ISR_FAULT
ISR19:
cli
push $19
jmp ISR_FAULT
ISR20:
cli
push $20
jmp ISR_FAULT
ISR21:
cli
push $21
jmp ISR_FAULT
ISR22:
cli
push $22
jmp ISR_FAULT
ISR23:
cli
push $23
jmp ISR_FAULT
ISR24:
cli
push $24
jmp ISR_FAULT
ISR25:
cli
push $25
jmp ISR_FAULT
ISR26:
cli
push $26
jmp ISR_FAULT
ISR27:
cli
push $27
jmp ISR_FAULT
ISR28:
cli
push 28
jmp ISR_FAULT
ISR29:
cli
push $29
jmp ISR_FAULT
ISR30:
cli
push $30
jmp ISR_FAULT
ISR31:
cli
push $31
jmp ISR_FAULT
.extern FaultHandler
ISR_FAULT:
pusha
push %ds
push %es
push %fs
push %gs
movw $0x10,%ax
movw %ax,%ds
movw %ax,%es
movw %ax,%fs
movw %ax,%gs
movl %esp,%eax
pushl %eax
call FaultHandler
popl %eax
popl %gs
popl %fs
popl %es
popl %ds
popa
addl $8,%esp
iret
.global ISR_DEFAULT
.extern DEFAULT_ISR
ISR_DEFAULT:
pushal
pushw %ds
pushw %es
pushw %fs
pushw %gs
pushl %ebx
movw $0x10,%bx
movw %bx,%ds
popl %ebx
cld /* C code following the sysV ABI requires DF to be clear on function entry */
call DEFAULT_ISR
popw %gs
popw %fs
popw %es
popw %ds
popal
iret
.global ISR_KBD
.extern KeyboardHandler
ISR_KBD:
pushal
pushw %ds
pushw %es
pushw %fs
pushw %gs
pushl %ebx
movw $0x10,%bx
movw %bx,%ds
popl %ebx
cld /* C code following the sysV ABI requires DF to be clear on function entry */
call KeyboardHandler
popw %gs
popw %fs
popw %es
popw %ds
popal
iret

68
kernel/isr.cpp Normal file
View File

@@ -0,0 +1,68 @@
#include <kernel/drivers/terminal/terminal.h>
#include <kernel/panic.h>
#include <kernel/kernio.h>
struct Regs_t {
unsigned int gs, fs, es, ds; /* pushed the segs last */
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; /* pushed by 'pusha' */
unsigned int int_no, err_code; /* our 'push byte #' and ecodes do this */
unsigned int eip, cs, eflags, useresp, ss; /* pushed by the processor automatically */
};
char *PanicMessage[] = {
"Division By Zero",
"Debug",
"Non Maskable Interrupt",
"Break Point",
"Into Detect Overflow",
"Out of bounds Exception",
"Invalid Opcode",
"No Coprocessor",
"Double Fault",
"Coprocessor Segment Overrun",
"Bad TSS Exception",
"Segment not present",
"Stack Fault",
"General Protection Fault",
"Page Fault",
"Unknown Interrupt",
"Coprocessor Fault",
"Alignement Check Exception",
"Machine Check Exception",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved"
};
extern "C" {
void DEFAULT_ISR() {
Write("SMH \n");
outb(0x20,0x20);
}
void KeyboardHandler() {
Write("Keyboard Pressed! \n");
outb(0x20,0x20);
}
void FaultHandler(struct Regs_t *r) {
uint32_t val;
asm volatile ( "mov %%cr2, %0" : "=r"(val) );
PanicKernel(val, PanicMessage[r->int_no]);
for (;;)
asm("hlt");
}
}

View File

@@ -38,8 +38,7 @@ static inline void outl(uint16_t port, uint32_t val) {
asm ( "outl %0, %1" : : "a"(val), "Nd"(port) );
}
static inline void io_wait(void) {
/* TODO: This is probably fragile. */
static inline void io_wait() {
asm ( "jmp 1f\n\t"
"1:jmp 2f\n\t"
"2:" );

53
kernel/pic.cpp Normal file
View File

@@ -0,0 +1,53 @@
#include "pic.h"
#include <kernel/kernio.h>
void PIC_Default_Remap() {
outb(0x20, 0x11);
io_wait();
outb(0xA0, 0x11);
io_wait();
outb(0x21, 0x20);
io_wait();
outb(0xA1, 0x28);
io_wait();
outb(0x21, 0x04);
io_wait();
outb(0xA1, 0x02);
io_wait();
outb(0x21, 0x01);
io_wait();
outb(0xA1, 0x01);
io_wait();
outb(0x21, 0x0);
io_wait();
outb(0xA1, 0x0);
}
void PIC_Remap(int offset1, int offset2) {
unsigned char a1, a2;
a1 = inb(PIC1_DATA); // save masks
a2 = inb(PIC2_DATA);
outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode)
io_wait();
outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
io_wait();
outb(PIC1_DATA, offset1); // ICW2: Master PIC vector offset
io_wait();
outb(PIC2_DATA, offset2); // ICW2: Slave PIC vector offset
io_wait();
outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
io_wait();
outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010)
io_wait();
outb(PIC1_DATA, ICW4_8086);
io_wait();
outb(PIC2_DATA, ICW4_8086);
io_wait();
outb(PIC1_DATA, a1); // restore saved masks.
outb(PIC2_DATA, a2);
}

25
kernel/pic.h Normal file
View File

@@ -0,0 +1,25 @@
#pragma once
#define PIC1 0x20 /* IO base address for master PIC */
#define PIC2 0xA0 /* IO base address for slave PIC */
#define PIC1_COMMAND PIC1
#define PIC1_DATA (PIC1+1)
#define PIC2_COMMAND PIC2
#define PIC2_DATA (PIC2+1)
#define PIC_EOI 0x20 /* End-of-interrupt command code */
#define ICW1_ICW4 0x01 /* ICW4 (not) needed */
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
#define ICW1_INIT 0x10 /* Initialization - required! */
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
void PIC_Default_Remap();
void PIC_Remap(int offset1, int offset2);