[ BIG CHANGE ] Properly Implemented IDT

- New include files: idt.h, pic.h, syscall.h and exceptions.h
- Proper exception handling (still could be improved
- PIC properly initiated and irqs all masked
- BREAKS Keyboard - The keyboard IRQ is not handled anymore
- convertColor() is kinda broken :/ (More in README.md)
This commit is contained in:
2024-05-05 21:03:21 +02:00
parent 29418eb46b
commit 1d71a4e384
15 changed files with 448 additions and 617 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ CC = i386-elf-gcc
LD = i386-elf-ld
AS = nasm
CFLAGS = -ffreestanding -m32 -Iinclude -Wall -Wextra
CFLAGS = -ffreestanding -fno-builtin -fno-stack-protector -nostdinc -mgeneral-regs-only -m32 -march=i386 -Iinclude -Wall
SRC = ./src
BUILD = ./build
+1
View File
@@ -55,6 +55,7 @@ _These images may be outdated, Idk_
## Known issues
- If you run kernel.bin from shell, it will clear the memory map so when you load anything it will override the kernel code
- fillCircle() in graphics.h is broken. No idea why, so no filled circles for you (i commented out the boundaryFill call in the function)
- convertColor() doesn't work right, because i should be using floating point, but -mgeneral-regs-only doesn't let me :(
## [Old Version](https://github.com/Tom-on64/old-kern)
+203
View File
@@ -0,0 +1,203 @@
#ifndef ISRS_H
#define ISRS_H
#include "idt.h"
#include "screen.h"
/*
Alignment Check
Machine Check
Reserved
...
Reserved
*/
// TODO: Make proper handlers
__attribute__ ((naked)) // Temporary handler
void excpHandler(void) {
__asm__ volatile (
".intel_syntax\n"
"iretd\n"
".att_syntax"
);
}
// Exception handlers
__attribute__ ((interrupt))
void excp_divideErr(intFrame_t* iframe) { // ISR 0
fgColor = RED;
print("[ Division Error ]\n");
__asm__ volatile ("cli; hlt"); // Halt system
}
__attribute__ ((interrupt))
void excp_debugErr(intFrame_t* iframe) { // ISR 1
fgColor = RED;
print("[ Debug Exception ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_nmiInterrupt(intFrame_t* iframe) { // ISR 2
fgColor = RED;
print("[ Non-maskable Interrupt ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_breakpoint(intFrame_t* iframe) { // ISR 3
fgColor = RED;
print("[ Breakpoint ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_overflow(intFrame_t* iframe) { // ISR 4
fgColor = RED;
print("[ Overflow Error ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_boundRangeExceed(intFrame_t* iframe) { // ISR 5
fgColor = RED;
print("[ Bound Range Exceeded ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_invalidOpcode(intFrame_t* iframe) { // ISR 6
fgColor = RED;
print("[ Invalid OpCode ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_deviceNA(intFrame_t* iframe) { // ISR 7
fgColor = RED;
print("[ Device Not Available ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_doubleFault(intFrame_t* iframe, uint32_t errCode) { // ISR 8
fgColor = RED;
print("[ Double Fault : 0x");
print(itoa(errCode, 16));
print(" ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_coprocOverrun(intFrame_t* iframe) { // ISR 9
fgColor = RED;
print("[ Coprocessor Segment Overrun ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_invalidTss(intFrame_t* iframe, uint32_t errCode) { // ISR 10
fgColor = RED;
print("[ Invalid TSS : 0x");
print(itoa(errCode, 16));
print(" ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_noSegment(intFrame_t* iframe, uint32_t errCode) { // ISR 11
fgColor = RED;
print("[ Segment Not Present : 0x");
print(itoa(errCode, 16));
print(" ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_stackSegmentFault(intFrame_t* iframe, uint32_t errCode) { // ISR 12
fgColor = RED;
print("[ Stack-Segment Fault : 0x");
print(itoa(errCode, 16));
print(" ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_generalProtectionFault(intFrame_t* iframe, uint32_t errCode) { // ISR 13
fgColor = RED;
print("[ General Protection Fault : 0x");
print(itoa(errCode, 16));
print(" ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_pageFault(intFrame_t* iframe, uint32_t errCode) { // ISR 14
fgColor = RED;
print("[ Page Fault : 0x");
print(itoa(errCode, 16));
print(" ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_reserved(intFrame_t* iframe) { // ISR 15
fgColor = RED;
print("[ Reserved Exception ]\n"); // Shouldn't get this one
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_floatingPointErr(intFrame_t* iframe) { // ISR 16
fgColor = RED;
print("[ x87 FPU Floating-Point Error ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_alignCheck(intFrame_t* iframe, uint32_t errCode) { // ISR 17
fgColor = RED;
print("[ Alignment Check : 0x");
print(itoa(errCode, 16));
print(" ]\n");
__asm__ volatile ("cli; hlt");
}
__attribute__ ((interrupt))
void excp_machineCheck(intFrame_t* iframe) { // ISR 18
fgColor = RED;
print("[ Machine Check ]\n");
__asm__ volatile ("cli; hlt");
}
// TODO: Add more (because there's always more)
// Repetative isr definitions
void setupExceptions() {
for (uint8_t i = 0; i < 32; i++) {
idtSetGate(i, excp_reserved, TRAP_GATE_FLAGS);
}
idtSetGate(0, excp_divideErr, TRAP_GATE_FLAGS);
idtSetGate(1, excp_debugErr, TRAP_GATE_FLAGS);
idtSetGate(2, excp_nmiInterrupt, TRAP_GATE_FLAGS);
idtSetGate(3, excp_breakpoint, TRAP_GATE_FLAGS);
idtSetGate(4, excp_overflow, TRAP_GATE_FLAGS);
idtSetGate(5, excp_boundRangeExceed, TRAP_GATE_FLAGS);
idtSetGate(6, excp_invalidOpcode, TRAP_GATE_FLAGS);
idtSetGate(7, excp_deviceNA, TRAP_GATE_FLAGS);
idtSetGate(8, excp_doubleFault, TRAP_GATE_FLAGS);
idtSetGate(9, excp_coprocOverrun, TRAP_GATE_FLAGS);
idtSetGate(10, excp_invalidTss, TRAP_GATE_FLAGS);
idtSetGate(11, excp_noSegment, TRAP_GATE_FLAGS);
idtSetGate(12, excp_stackSegmentFault, TRAP_GATE_FLAGS);
idtSetGate(13, excp_generalProtectionFault, TRAP_GATE_FLAGS);
idtSetGate(14, excp_pageFault, TRAP_GATE_FLAGS);
idtSetGate(15, excp_reserved, TRAP_GATE_FLAGS);
idtSetGate(16, excp_floatingPointErr, TRAP_GATE_FLAGS);
idtSetGate(17, excp_alignCheck, TRAP_GATE_FLAGS);
idtSetGate(18, excp_machineCheck, TRAP_GATE_FLAGS);
// Other are reserved
}
#endif
+30 -24
View File
@@ -2,48 +2,54 @@
#define IDT_H
#include "stdint.h"
#include "system.h"
#include "screen.h"
struct idtEntry {
#define TRAP_GATE_FLAGS 0x8f // P = 1, DPL = 00, S = 0, Type = 1111 (32-bit Trap gate)
#define INT_GATE_FLAGS 0x8e // P = 1, DPL = 00, S = 0, Type = 1110 (32-bit Int gate)
#define USR_INT_GAME_FLAGS 0xee // P = 1, DPL = 11, S = 0, Type = 1110 (32-bit Int gate)
typedef struct {
uint16_t offsetLow;
uint16_t selector;
uint8_t zero;
uint8_t typeAttr;
uint16_t offsetHigh;
} __attribute__((packed));
} __attribute__ ((packed)) idtEntry_t;
struct idtPointer {
typedef struct {
uint16_t limit;
uint32_t base;
} __attribute__((packed));
} __attribute__ ((packed)) idtp_t;
struct idtEntry idt[256] = { 0 };
struct idtPointer idtp;
typedef struct {
uint32_t eip;
uint32_t cs;
uint32_t eflags;
uint32_t esp;
uint32_t ss;
} __attribute__ ((packed)) intFrame_t;
extern void idtLoad();
__attribute__ ((aligned(0x10))) // For performance
idtEntry_t idt[256] = { 0 };
idtp_t idtp;
void idtSetGate(uint8_t i, uint32_t offset, uint16_t selector, uint8_t typeAttr) {
idt[i].offsetLow = (uint16_t)offset;
idt[i].selector = selector;
idt[i].zero = 0;
idt[i].typeAttr = typeAttr;
idt[i].offsetHigh = (uint16_t)(offset >> 16);
void idtSetGate(uint8_t i, void* handler, uint8_t flags) {
uint32_t offset = (uint32_t)handler;
idtEntry_t* entry = &idt[i];
entry->offsetLow = (uint16_t)offset;
entry->selector = 0x08;
entry->zero = 0;
entry->typeAttr = flags;
entry->offsetHigh = (uint16_t)(offset >> 16);
}
void setupIdt() {
idtp.limit = sizeof(struct idtEntry) * 256;
idtp.limit = sizeof(idtEntry_t) * 256;
idtp.base = (uint32_t)&idt;
idtLoad();
__asm__ volatile ("lidt %0" : : "m"(idtp));
}
// Contains values of registers and exception info from isrs
struct regs {
unsigned int gs, fs, es, ds;
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;
unsigned int intNo, errCode;
unsigned int eip, cs, eflags, useresp, ss;
};
#endif
-80
View File
@@ -1,80 +0,0 @@
#ifndef IRQ_H
#define IRQ_H
#include "stdint.h"
#include "idt.h"
void* irqRoutines[16] = { 0 };
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();
void installIrqHandler(uint32_t irq, void (*handler)(struct regs* r)) {
irqRoutines[irq] = handler;
}
void uninstallIrqHandler(uint32_t irq) {
irqRoutines[irq] = 0;
}
void irqHandler(struct regs* r) {
void (*handler)(struct regs* r);
handler = irqRoutines[r->intNo - 32]; // Offset by 32 because of isrs
if (handler) handler(r);
// Something about master and slave handlers
if (r->intNo >= 40) outb(0xa0, 0x20);
outb(0x20, 0x20);
}
void irqRemap(void) {
outb(0xa0, 0x11);
outb(0x20, 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 setupIrqs() {
irqRemap();
// Same as isrs, but differnet handlers :o
idtSetGate(32, (unsigned)irq0, 0x08, 0x8e);
idtSetGate(33, (unsigned)irq1, 0x08, 0x8e);
idtSetGate(34, (unsigned)irq2, 0x08, 0x8e);
idtSetGate(35, (unsigned)irq3, 0x08, 0x8e);
idtSetGate(36, (unsigned)irq4, 0x08, 0x8e);
idtSetGate(37, (unsigned)irq5, 0x08, 0x8e);
idtSetGate(38, (unsigned)irq6, 0x08, 0x8e);
idtSetGate(39, (unsigned)irq7, 0x08, 0x8e);
idtSetGate(40, (unsigned)irq8, 0x08, 0x8e);
idtSetGate(41, (unsigned)irq9, 0x08, 0x8e);
idtSetGate(42, (unsigned)irq10, 0x08, 0x8e);
idtSetGate(43, (unsigned)irq11, 0x08, 0x8e);
idtSetGate(44, (unsigned)irq12, 0x08, 0x8e);
idtSetGate(45, (unsigned)irq13, 0x08, 0x8e);
idtSetGate(46, (unsigned)irq14, 0x08, 0x8e);
idtSetGate(47, (unsigned)irq15, 0x08, 0x8e);
}
#endif
-128
View File
@@ -1,128 +0,0 @@
#ifndef ISRS_H
#define ISRS_H
#include "idt.h"
#include "screen.h"
#include "system.h"
#include "string.h"
char* exceptionMessages[] = {
"Divide By Zero Error",
"Debug Exception",
"NMI Interrupt",
"Breakpoint",
"Overflow",
"BOUND Range Exceeded",
"Invalid Opcode",
"Device Not Available",
"Double Fault",
"Coprocessor Segment Overrun",
"Invalid TSS",
"Segment Not Present",
"Stack-Segment Fault",
"General Protection Fault",
"Page Fault",
"Reserved",
"x87 FPU Floating-Point Error",
"Alignment Check",
"Machine Check",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
};
// Repetative isr definitions
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 setupIsrs() {
idtSetGate(0, (unsigned)isr0, 0x08, 0x8e);
idtSetGate(1, (unsigned)isr1, 0x08, 0x8e);
idtSetGate(2, (unsigned)isr2, 0x08, 0x8e);
idtSetGate(3, (unsigned)isr3, 0x08, 0x8e);
idtSetGate(4, (unsigned)isr4, 0x08, 0x8e);
idtSetGate(5, (unsigned)isr5, 0x08, 0x8e);
idtSetGate(6, (unsigned)isr6, 0x08, 0x8e);
idtSetGate(7, (unsigned)isr7, 0x08, 0x8e);
idtSetGate(8, (unsigned)isr8, 0x08, 0x8e);
idtSetGate(9, (unsigned)isr9, 0x08, 0x8e);
idtSetGate(10, (unsigned)isr10, 0x08, 0x8e);
idtSetGate(11, (unsigned)isr11, 0x08, 0x8e);
idtSetGate(12, (unsigned)isr12, 0x08, 0x8e);
idtSetGate(13, (unsigned)isr13, 0x08, 0x8e);
idtSetGate(14, (unsigned)isr14, 0x08, 0x8e);
idtSetGate(15, (unsigned)isr15, 0x08, 0x8e);
idtSetGate(16, (unsigned)isr16, 0x08, 0x8e);
idtSetGate(17, (unsigned)isr17, 0x08, 0x8e);
idtSetGate(18, (unsigned)isr18, 0x08, 0x8e);
idtSetGate(19, (unsigned)isr19, 0x08, 0x8e);
idtSetGate(20, (unsigned)isr20, 0x08, 0x8e);
idtSetGate(21, (unsigned)isr21, 0x08, 0x8e);
idtSetGate(22, (unsigned)isr22, 0x08, 0x8e);
idtSetGate(23, (unsigned)isr23, 0x08, 0x8e);
idtSetGate(24, (unsigned)isr24, 0x08, 0x8e);
idtSetGate(25, (unsigned)isr25, 0x08, 0x8e);
idtSetGate(26, (unsigned)isr26, 0x08, 0x8e);
idtSetGate(27, (unsigned)isr27, 0x08, 0x8e);
idtSetGate(28, (unsigned)isr28, 0x08, 0x8e);
idtSetGate(29, (unsigned)isr29, 0x08, 0x8e);
idtSetGate(30, (unsigned)isr30, 0x08, 0x8e);
idtSetGate(31, (unsigned)isr31, 0x08, 0x8e);
}
void faultHandler(struct regs* r) {
if (r->intNo < 32) {
print(exceptionMessages[r->intNo]);
if (r->errCode) {
print(": 0x");
print(itoa(r->errCode, 16));
}
cli();
hlt();
}
}
#endif
+3 -2
View File
@@ -1,8 +1,8 @@
#ifndef KEYBOARD_H
#define KEYBOARD_H
#include "irq.h"
#include "idt.h"
#include "pic.h"
#include "system.h"
#include "screen.h"
#include "stdint.h"
@@ -92,7 +92,8 @@ char* read(char terminator) {
}
void setupKeyboard() {
installIrqHandler(1, keyboardHandler);
idtSetGate(33, keyboardHandler, INT_GATE_FLAGS);
setIrqMask(1);
}
#endif
+95
View File
@@ -0,0 +1,95 @@
#ifndef PIC_H
#define PIC_H
#include "system.h"
// PIC I/O Ports
#define PIC_1_CMD 0x20
#define PIC_1_DATA 0x21
#define PIC_2_CMD 0xA0
#define PIC_2_DATA 0xA1
// IRQs
#define NEW_IRQ_0 0x20 // IRQ 0 : int 32
#define NEW_IRQ_8 0x28 // IRQ 8 : int 40
// Commands
#define PIC_EOI 0x20 // End Of Interrupt
#define PIC_DISABLE 0xff
void sendPicEOI(uint8_t irq) {
if (irq >= 8) {
outb(PIC_2_CMD, PIC_EOI);
}
outb(PIC_1_CMD, PIC_EOI);
}
void disableIrqs() {
outb(PIC_2_DATA, PIC_DISABLE);
outb(PIC_1_DATA, PIC_DISABLE);
}
void setIrqMask(uint8_t irq) {
uint16_t port;
uint8_t value;
if (irq < 8) {
port = PIC_1_DATA;
} else {
irq -= 8;
port = PIC_2_DATA;
}
value = inb(port) | (1 << irq);
outb(port, value);
}
void unsetIrqMask(uint8_t irq) {
uint16_t port;
uint8_t value;
if (irq < 8) {
port = PIC_1_DATA;
} else {
irq -= 8;
port = PIC_2_DATA;
}
value = inb(port) & ~(1 << irq);
outb(port, value);
}
void remapPic() {
uint8_t pic1Mask = inb(PIC_1_DATA);
uint8_t pic2Mask = inb(PIC_2_DATA);
// Send Init Control Word 1-4 to both PICs
// ICW 1: bit 0 - send up to 4 ICWs, bit 4 - Init PIC
outb(PIC_1_CMD, 0x11);
ioWait(); // For slower machines
outb(PIC_2_CMD, 0x11);
ioWait();
// ICW 2: Where to map IRW bases in IDT
outb(PIC_1_DATA, NEW_IRQ_0);
ioWait();
outb(PIC_2_DATA, NEW_IRQ_8);
ioWait();
// ICW 3: Which IRQ in PIC1 is PIC2; Mapping PIC2 to IRQ 2
outb(PIC_1_DATA, 0x04);
ioWait();
outb(PIC_2_DATA, 0x02);
ioWait();
// ICW 4 - Set x86 mode
outb(PIC_1_DATA, 0x01);
ioWait();
outb(PIC_2_DATA, 0x01);
ioWait();
outb(PIC_1_DATA, pic1Mask);
outb(PIC_2_DATA, pic2Mask);
}
#endif
+5 -3
View File
@@ -93,9 +93,11 @@ uint32_t convertColor(uint32_t color) {
return color & 0xff;
}
uint8_t red = ((color >> 16) & 0xff) * (((1 << gfxMode->linearRedMaskSize) - 1) / 255.0);
uint8_t green = ((color >> 8 ) & 0xff) * (((1 << gfxMode->linearGreenMaskSize) - 1) / 255.0);
uint8_t blue = ((color ) & 0xff) * (((1 << gfxMode->linearBlueMaskSize) - 1) / 255.0);
// TODO: !! Important !! - Is should be divided by 255.0 (for floats), but using '-mgeneral-regs-only' removes fp-registers and
// wants to use some dumb functions for converting fp numbers in the stdlib (that we don't have)
uint8_t red = ((color >> 16) & 0xff) * (((1 << gfxMode->linearRedMaskSize) - 1) / 255);
uint8_t green = ((color >> 8 ) & 0xff) * (((1 << gfxMode->linearGreenMaskSize) - 1) / 255);
uint8_t blue = ((color ) & 0xff) * (((1 << gfxMode->linearBlueMaskSize) - 1) / 255);
return (red << gfxMode->redFieldPos) | (green << gfxMode->greenFieldPos) | (blue << gfxMode->blueFieldPos);
}
+77
View File
@@ -0,0 +1,77 @@
#ifndef SYSCALL_H
#define SYSCALL_H
#include "screen.h"
// System call count
#define MAX_SYSCALLS 2
void sys_test0() {
fgColor = YELLOW;
print("Syscall 0 - Test\n");
fgColor = FG_COLOR;
}
void sys_test1() {
fgColor = CYAN;
print("Syscall 1 - Test\n");
fgColor = FG_COLOR;
}
// System call table
void* syscalls[MAX_SYSCALLS] = {
sys_test0,
sys_test1,
};
// int 0x80 - Syscall interrupt, handled by this function
// eax : Syscall number
__attribute__ ((naked)) // No prologue or epilogue, just assembly
void syscallHandler(void) {
// Interrupt - Stack should contain: ss, esp, eflags, cs, eip
// We should also push these regs: ax, gs, fs, es, ds, bp, di, si, dx, cx, bx
__asm__ volatile (
".intel_syntax noprefix\n" // We use intel syntax
".equ MAX_SYSCALLS, 2\n" // Define MAX_SYSCALLS again
// Check if syscall exists
"cmp eax, MAX_SYSCALLS - 1\n"
"ja invalidSyscall\n"
// Call the syscall
"push eax\n" // Push required values
"push gs\n"
"push fs\n"
"push es\n"
"push ds\n"
"push ebp\n"
"push edi\n"
"push esi\n"
"push edx\n"
"push ecx\n"
"push ebx\n"
"push esp\n" // Push stack pointer again (for variables and such idk)
"call [syscalls + eax * 4]\n" // Call syscall from table. Syscall number should be in eax
"add esp, 4\n"
"pop ebx\n" // Pop pushed values
"pop ecx\n"
"pop edx\n"
"pop esi\n"
"pop edi\n"
"pop ebp\n"
"pop ds\n"
"pop es\n"
"pop fs\n"
"pop gs\n"
"add esp, 4\n" // Save eax value
"iretd\n" // Return from interrupt
// TODO: Send an error or something here
"invalidSyscall:\n"
"iretd\n"
".att_syntax" // Switch back to Att Syntax (Just in case)
);
}
#endif
+3 -12
View File
@@ -24,18 +24,9 @@ void outw(uint16_t port, uint16_t data) {
asm volatile("outw %0, %1" :: "a"(data), "Nd"(port));
}
// Assembly stuff
void cli() {
asm volatile("cli");
}
void sti() {
asm volatile("sti");
}
void hlt() {
asm volatile("hlt");
void ioWait() {
// Waits ~1 I/O Cycle (Linux uses this so it should be good)
asm volatile("outb %%al, $0x80" : : "a"(0));
}
#endif
-345
View File
@@ -3,9 +3,6 @@
[global driveNum]
[extern main]
[extern idtp]
[extern faultHandler]
[extern irqHandler]
;; Calls the main function in 'main.c'
_start:
@@ -23,345 +20,3 @@ _start:
driveNum: db 0
;;
;; --- IDT ---
;;
[global idtLoad]
idtLoad:
lidt [idtp]
ret
;; Isrs (exceptions)
[global isr0]
isr0:
cli
push 0
push 0
jmp isrCommon
[global isr1]
isr1:
cli
push 0
push 1
jmp isrCommon
[global isr2]
isr2:
cli
push 0
push 2
jmp isrCommon
[global isr3]
isr3:
cli
push 0
push 3
jmp isrCommon
[global isr4]
isr4:
cli
push 0
push 4
jmp isrCommon
[global isr5]
isr5:
cli
push 0
push 5
jmp isrCommon
[global isr6]
isr6:
cli
push 0
push 6
jmp isrCommon
[global isr7]
isr7:
cli
push 0
push 7
jmp isrCommon
[global isr8]
isr8:
cli
push 8
jmp isrCommon
[global isr9]
isr9:
cli
push 0
push 9
jmp isrCommon
[global isr10]
isr10:
cli
push 10
jmp isrCommon
[global isr11]
isr11:
cli
push 11
jmp isrCommon
[global isr12]
isr12:
cli
push 12
jmp isrCommon
[global isr13]
isr13:
cli
push 13
jmp isrCommon
[global isr14]
isr14:
cli
push 14
jmp isrCommon
[global isr15]
isr15:
cli
push 0
push 15
jmp isrCommon
[global isr16]
isr16:
cli
push 0
push 16
jmp isrCommon
[global isr17]
isr17:
cli
push 0
push 17
jmp isrCommon
[global isr18]
isr18:
cli
push 0
push 18
jmp isrCommon
[global isr19]
isr19:
cli
push 0
push 19
jmp isrCommon
[global isr20]
isr20:
cli
push 0
push 20
jmp isrCommon
[global isr21]
isr21:
cli
push 0
push 21
jmp isrCommon
[global isr22]
isr22:
cli
push 0
push 22
jmp isrCommon
[global isr23]
isr23:
cli
push 0
push 23
jmp isrCommon
[global isr24]
isr24:
cli
push 0
push 24
jmp isrCommon
[global isr25]
isr25:
cli
push 0
push 25
jmp isrCommon
[global isr26]
isr26:
cli
push 0
push 26
jmp isrCommon
[global isr27]
isr27:
cli
push 0
push 27
jmp isrCommon
[global isr28]
isr28:
cli
push 0
push 28
jmp isrCommon
[global isr29]
isr29:
cli
push 0
push 29
jmp isrCommon
[global isr30]
isr30:
cli
push 0
push 30
jmp isrCommon
[global isr31]
isr31:
cli
push 0
push 31
jmp isrCommon
isrCommon: ; No clue how this works, i'm pretty sure it calls the C function and has to push the registers or something idk
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, faultHandler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret
;; IRQs
[global irq0]
irq0:
cli
push 0
push 32
jmp irqCommon
[global irq1]
irq1:
cli
push 0
push 33
jmp irqCommon
[global irq2]
irq2:
cli
push 0
push 34
jmp irqCommon
[global irq3]
irq3:
cli
push 0
push 35
jmp irqCommon
[global irq4]
irq4:
cli
push 0
push 36
jmp irqCommon
[global irq5]
irq5:
cli
push 0
push 37
jmp irqCommon
[global irq6]
irq6:
cli
push 0
push 38
jmp irqCommon
[global irq7]
irq7:
cli
push 0
push 39
jmp irqCommon
[global irq8]
irq8:
cli
push 0
push 40
jmp irqCommon
[global irq9]
irq9:
cli
push 0
push 41
jmp irqCommon
[global irq10]
irq10:
cli
push 0
push 42
jmp irqCommon
[global irq11]
irq11:
cli
push 0
push 43
jmp irqCommon
[global irq12]
irq12:
cli
push 0
push 44
jmp irqCommon
[global irq13]
irq13:
cli
push 0
push 45
jmp irqCommon
[global irq14]
irq14:
cli
push 0
push 46
jmp irqCommon
[global irq15]
irq15:
cli
push 0
push 47
jmp irqCommon
irqCommon: ; Simular to isrCommon, probaly calls the C function
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, irqHandler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret
+21 -18
View File
@@ -1,14 +1,14 @@
#include "physicalMemManager.h" // TODO: Name this better
#include "disk.h"
#include "screen.h"
#include "idt.h"
#include "isrs.h"
#include "irq.h"
#include "keyboard.h"
#include "timer.h"
#include "exceptions.h"
#include "syscall.h"
#include "pic.h"
#include "system.h"
#include "disk.h"
#include "string.h"
#include "graphics.h"
#include "physicalMemManager.h" // TODO: Name this better
#include "keyboard.h"
#define PROMPT "#> "
@@ -20,16 +20,6 @@ void printFiletable(char* ft);
void printPhysicalMemmap();
void main() {
// Interrupts
setupIdt();
setupIsrs();
setupIrqs();
sti();
setupKeyboard();
setupTimer();
timerPhase(1000); // 1 tick per ~1ms
// Memory manager setup
uint32_t smapEntryCount = *(uint32_t*)0x8500;
smapEntry_t* smapEntries = (smapEntry_t*)0x8504;
@@ -46,7 +36,6 @@ void main() {
deinitMemoryRegion(0x1000, 0x9000); // Reserve kernel memory (under 0xa000)
deinitMemoryRegion(memmapAddr, maxBlocks / BLOCKS_PER_BYTE);
// Screen setup
// TODO: Find font in filetable
diskRead(36, 4, font); // Read font from disk
@@ -55,6 +44,20 @@ void main() {
diskRead(5, 1, filetable); // Read the filetable and store it in memory
// Interrupts
setupIdt();
setupExceptions();
idtSetGate(0x80, syscallHandler, USR_INT_GAME_FLAGS); // Setup Syscall handler in IDT for int 0x80
disableIrqs();
remapPic();
__asm__ volatile ("sti");
// Syscall Test!
__asm__ volatile ("movl $0, %eax; int $0x80"); // Syscall(0);
__asm__ volatile ("movl $1, %eax; int $0x80"); // Syscall(1);
//setupKeyboard();
// Run Interactive Shell Program
// TODO: Make it in another file
while (1) {
@@ -164,7 +167,7 @@ void main() {
drawCircle(1500, 600, 300, WHITE);
fillCircle(950, 750, 75, rgb(0xa2, 0xd6, 0xf9));
read('q'); // Wait until we get a 'q'
//read('q'); // Wait until we get a 'q'
clear();
} else if (strcmp(input, "help") == 0) {
print("Available Commands:\n");
+3 -3
View File
@@ -372,9 +372,9 @@ DATA_SEG equ GDT.dataDescriptor - GDT.start
;; VBE Stuff
;; !! IF YOU WANT TO SELECT ANY VALUE IN THE SETUP, SET THESE TO ZERO !!
width: dw 0
height: dw 0
bpp: db 0
width: dw 1920
height: dw 1080
bpp: db 32
offset: dw 0
_segment: dw 0 ; segment is a keyword
+5
View File
@@ -35,6 +35,11 @@ Legend:
- [x] Rectange :)
- [x] Circle!
- [_] Filled verisons
- [ ] Interrupts
- [x] IDT Setup (idt.h)
- [x] Exception handling
- [ ] Hardware/software interrupts
- [ ] Syscalls! (int 0x80)
- [ ] Math
- [ ] Trigonometry
- [ ] Sine