diff --git a/Makefile b/Makefile index 8ce2faf..96c7aa1 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/README.md b/README.md index cea59aa..2af8b99 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/include/exceptions.h b/include/exceptions.h new file mode 100644 index 0000000..77182a0 --- /dev/null +++ b/include/exceptions.h @@ -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 diff --git a/include/idt.h b/include/idt.h index 521e42d..46872b2 100644 --- a/include/idt.h +++ b/include/idt.h @@ -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 diff --git a/include/irq.h b/include/irq.h deleted file mode 100644 index 631f220..0000000 --- a/include/irq.h +++ /dev/null @@ -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 diff --git a/include/isrs.h b/include/isrs.h deleted file mode 100644 index 5483a97..0000000 --- a/include/isrs.h +++ /dev/null @@ -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 diff --git a/include/keyboard.h b/include/keyboard.h index 6421ede..cb27ff0 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -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 diff --git a/include/pic.h b/include/pic.h new file mode 100644 index 0000000..f861164 --- /dev/null +++ b/include/pic.h @@ -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 diff --git a/include/screen.h b/include/screen.h index 589469f..7d2567f 100644 --- a/include/screen.h +++ b/include/screen.h @@ -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); } diff --git a/include/syscall.h b/include/syscall.h new file mode 100644 index 0000000..b854d96 --- /dev/null +++ b/include/syscall.h @@ -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 diff --git a/include/system.h b/include/system.h index 071a121..d35faa9 100644 --- a/include/system.h +++ b/include/system.h @@ -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 diff --git a/src/entry.asm b/src/entry.asm index 7e2e899..f9b973b 100644 --- a/src/entry.asm +++ b/src/entry.asm @@ -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 - diff --git a/src/kernel.c b/src/kernel.c index 4f78095..05deb80 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -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,14 +36,27 @@ 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 - + clear(); print("kern.\n\n"); 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 @@ -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"); diff --git a/src/stage2.asm b/src/stage2.asm index 289ce56..3a41d99 100644 --- a/src/stage2.asm +++ b/src/stage2.asm @@ -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 diff --git a/todo.txt b/todo.txt index c7f952a..4b175e1 100644 --- a/todo.txt +++ b/todo.txt @@ -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