From c0f25565eb2e65c4689880fea48d5527adb423be Mon Sep 17 00:00:00 2001 From: danieltherealyang <54683830+danieltherealyang@users.noreply.github.com> Date: Mon, 20 Nov 2023 21:04:14 -0800 Subject: [PATCH] Kernel fix (#28) * cleaned up stuff * fixed the looping issue on interrupts. it was the motherfucking kernel_entry page directory offset. * yoinked aaron's GDT code to test paging issue. turns out it was. * GDT fix --- Makefile | 6 ++++++ source/kernel/gdt.c | 16 ++++++++++++++++ source/kernel/gdt_flush.asm | 15 +++++++++++++++ source/kernel/idt.c | 33 --------------------------------- source/kernel/include/gdt.h | 22 ++++++++++++++++++++++ source/kernel/isr.c | 4 ++++ source/kernel/kernel.c | 29 +++-------------------------- source/kernel/memory.c | 3 ++- 8 files changed, 68 insertions(+), 60 deletions(-) create mode 100644 source/kernel/gdt.c create mode 100644 source/kernel/gdt_flush.asm create mode 100644 source/kernel/include/gdt.h diff --git a/Makefile b/Makefile index b158ff0..e74437c 100644 --- a/Makefile +++ b/Makefile @@ -51,6 +51,12 @@ image: boot kernel run: default $(QEMU) -drive format=raw,file=$(BUILD_DIR)/os_image -serial stdio +monitor: default + $(QEMU) -drive format=raw,file=$(BUILD_DIR)/os_image -serial stdio -monitor unix:qemu-monitor-socket,server,nowait + +connect: + socat -,echo=0,icanon=0 unix-connect:qemu-monitor-socket + gdb: default # Need to have GEF installed for this to work $(QEMU) -drive format=raw,file=$(BUILD_DIR)/os_image -s -S & gdb -ex "gef-remote --qemu-user localhost 1234" build/kernel.elf diff --git a/source/kernel/gdt.c b/source/kernel/gdt.c new file mode 100644 index 0000000..a6a9e00 --- /dev/null +++ b/source/kernel/gdt.c @@ -0,0 +1,16 @@ +#include "gdt.h" +#include + +gdt_t gdt; + +void init_gdt() { + gdt_entry_t null_entry = {0,0,0,0,0,0}; + gdt_entry_t code_segment = {0xffff,0,0,0b10011010,0b11001111,0}; + gdt_entry_t data_segment = {0xffff,0,0,0b10010010,0b11001111,0}; + gdt = (gdt_t) { + .limit = sizeof(gdt.entries)-1, + .base = (uint32_t) &gdt.entries, + .entries = {null_entry, code_segment, data_segment} + }; + gdt_flush((uint32_t) &gdt); +} \ No newline at end of file diff --git a/source/kernel/gdt_flush.asm b/source/kernel/gdt_flush.asm new file mode 100644 index 0000000..6219275 --- /dev/null +++ b/source/kernel/gdt_flush.asm @@ -0,0 +1,15 @@ +global gdt_flush +gdt_flush: + mov eax, [esp+4] ; eax = gdt_ptr + lgdt [eax] ; load the GDT pointer + + mov ax, 0x10 ; 0x10 is kernel segment data descriptor offset + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + jmp 0x08:.flush ; 0x08 is kernel segment code descriptor offset + ; far jump to .flush +.flush: + ret \ No newline at end of file diff --git a/source/kernel/idt.c b/source/kernel/idt.c index d5651ec..37f358f 100644 --- a/source/kernel/idt.c +++ b/source/kernel/idt.c @@ -19,39 +19,6 @@ __attribute__((aligned(0x10))) static idt_entry_t idt[NUM_IDTS]; // define the idtr static idtr_t idtr; -static uint32_t has_triggered = 0; -static uint32_t hits = 0; -static uint32_t oopsie_woopsie = 0; - -uint32_t get_hits(void) { return oopsie_woopsie; } - -// we no-inline because I don't want it inlined :lemonthink: -// also i want the actual isr to only have save register, call, then iret -__attribute__((noinline)) static void actual_exception_handler(void) -{ - oopsie_woopsie++; -} - -// this currently will triple-fault on pressing a keyboard -__attribute__((noinline)) static void actualirq1Handler(void) -{ - // seems to triple fault before reaching here, idk pls can we get serial - // driver - hits++; - if (terminal_driver_loaded() && !has_triggered) { - terminal_putchar('U'); - terminal_update_cursor(); - // inb(0x60) is the port containing the key pressed - terminal_put64(inb(0x60)); - terminal_update_cursor(); - - // send eoi to the master PIC - // this is needed in the PIC remapping, don't question it - outb(0x20, 0x20); - __asm__ volatile("cli"); - } -} - void idt_set_entry(int idx, uint32_t handler_ptr, uint16_t code_selector, uint8_t attributes) { diff --git a/source/kernel/include/gdt.h b/source/kernel/include/gdt.h new file mode 100644 index 0000000..95d9e14 --- /dev/null +++ b/source/kernel/include/gdt.h @@ -0,0 +1,22 @@ +#pragma once +#include + +#define GDT_ENTRIES 3 + +typedef struct { + uint16_t limit; + uint16_t base_low; + uint8_t base_mid; + uint8_t access; + uint8_t granularity; + uint8_t base_high; +} __attribute__((packed)) gdt_entry_t; + +typedef struct { + uint16_t limit; + uint32_t base; + gdt_entry_t entries[GDT_ENTRIES]; +} __attribute__((packed)) gdt_t; + +void init_gdt(); +extern void gdt_flush(uint32_t gdt_descriptor_ptr); \ No newline at end of file diff --git a/source/kernel/isr.c b/source/kernel/isr.c index c9addbf..5be82ad 100644 --- a/source/kernel/isr.c +++ b/source/kernel/isr.c @@ -21,6 +21,8 @@ void breakpoint(registers_t *frame) { printf("breakpoint\n"); } void overflow(registers_t *frame) { printf("overflow trap\n"); } +void pagefault(registers_t *frame) { printf("page fault\n"); asm volatile("hlt");} + void init_isr() { for (int i = 0; i < 256; i++) @@ -31,6 +33,8 @@ void init_isr() register_interrupt_handler(3, &breakpoint); register_interrupt_handler(4, &overflow); + register_interrupt_handler(0xe, &pagefault); + // irq handlers register_interrupt_handler(33, &keyboard_irq); diff --git a/source/kernel/kernel.c b/source/kernel/kernel.c index f1fe5bd..7dbf9a1 100644 --- a/source/kernel/kernel.c +++ b/source/kernel/kernel.c @@ -7,37 +7,14 @@ #include "terminal_driver.h" #include "timer.h" #include +#include "gdt.h" void main() { + init_gdt(); init_drivers(); terminal_clear(); - init_paging(); terminal_update_cursor(); init_idt(); - asm volatile("int $0x3"); - asm volatile("int $0x4"); - - write_serial(COM1, "Hello From SecureOS!"); - // printf(s.data); - - // init_paging(); - // string s; - // s.data = - // "HEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEELLLLLLLLLLLLLLLLLLLLLLLLLLL" - // "LLOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"; - // s.len = 96; - // printf(&s); - // uint32_t* wow = (uint32_t*) 0x12340000; - // palloc(wow, PAGE_PRESENT | PAGE_RW); - // *wow = 0x42042069; - // terminal_put64(*wow); - // for (int i = 0; i < 30; i ++) { - // uint32_t* smol = kalloc(200); - // *smol = 0x12345678; - // terminal_put64(smol); - // terminal_putchar(' '); - // terminal_put64(*smol); - // terminal_putchar('\n'); - // } + init_paging(); } diff --git a/source/kernel/memory.c b/source/kernel/memory.c index 978d696..9eaa9f7 100644 --- a/source/kernel/memory.c +++ b/source/kernel/memory.c @@ -1,7 +1,7 @@ #include "memory.h" #include "terminal_driver.h" +#include "io.h" #include -#include uint32_t l2_page_table[1024] __attribute__((aligned(4096))); @@ -263,6 +263,7 @@ void print_chunks() printf("}\n\n"); } +#include "serial.h" void init_paging() { // unmap lower page