Ver código fonte

working on broken system

greatbridf 2 anos atrás
pai
commit
7c311199cb

+ 2 - 1
Makefile

@@ -1,4 +1,5 @@
-QEMU_ARGS=-drive file=build/boot.img,format=raw -no-reboot -no-shutdown -enable-kvm
+# disable kvm to debug triple faults
+QEMU_ARGS=-drive file=build/boot.img,format=raw -no-reboot -no-shutdown -d cpu_reset,int # -enable-kvm
 .PHONY: run
 run: build
 	qemu-system-i386 $(QEMU_ARGS) -display curses -S -s

+ 3 - 1
include/asm/sys.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include <kernel/mem.h>
+#include <types/types.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -9,7 +10,8 @@ extern "C" {
 void asm_enable_paging(page_directory_entry* pd_addr);
 
 // the limit should be set on the higher 16bit
-void asm_load_gdt(uint32_t limit, uint32_t addr);
+// e.g. (n * sizeof(segment_descriptor) - 1) << 16
+void asm_load_gdt(uint32_t limit, phys_ptr_t addr);
 
 void asm_load_tr(uint16_t index);
 

+ 6 - 0
include/kernel/mem.h

@@ -143,6 +143,12 @@ typedef struct segment_descriptor_struct {
 } segment_descriptor;
 
 void init_gdt_with_tss(void* kernel_esp, uint16_t kernel_ss);
+void create_segment_descriptor(
+        segment_descriptor* sd,
+        uint32_t base,
+        uint32_t limit,
+        uint32_t flags,
+        uint32_t access);
 
 #ifdef __cplusplus
 }

+ 3 - 0
include/kernel/tty.h

@@ -17,6 +17,9 @@ struct tty
     char data[12];
 };
 
+// in kernel_main.c
+extern struct tty* console;
+
 void tty_print(struct tty* p_tty, const char* str);
 
 int make_serial_tty(struct tty* p_tty, int id);

+ 2 - 1
src/kernel/hw/serial.c

@@ -12,7 +12,8 @@ int32_t init_serial_port(port_id_t port)
    asm_outb(port + 1, 0x00);    //                  (hi byte)
    asm_outb(port + 3, 0x03);    // 8 bits, no parity, one stop bit
    asm_outb(port + 2, 0xC7);    // Enable FIFO, clear them, with 14-byte threshold
-   asm_outb(port + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+   // TODO: IRQ disabled
+   // asm_outb(port + 4, 0x0B);    // IRQs enabled, RTS/DSR set
    asm_outb(port + 4, 0x1E);    // Set in loopback mode, test the serial chip
    asm_outb(port + 0, 0xAE);    // Test serial chip (send byte 0xAE and check if serial returns same byte)
 

+ 2 - 0
src/kernel/hw/timer.c

@@ -1,4 +1,5 @@
 #include <asm/port_io.h>
+#include <kernel/tty.h>
 #include <kernel/hw/timer.h>
 
 static time_t _current_ticks = 0;
@@ -16,6 +17,7 @@ void init_pit(void)
 
 void inc_tick(void)
 {
+    tty_print(console, "tick");
     ++_current_ticks;
 }
 

+ 16 - 0
src/kernel/mem.c

@@ -341,3 +341,19 @@ void init_gdt_with_tss(void* kernel_esp, uint16_t kernel_ss)
     asm_load_gdt((6 * sizeof(segment_descriptor) - 1) << 16, (uint32_t)gdt);
     asm_load_tr((6 - 1) * 8);
 }
+
+void create_segment_descriptor(
+        segment_descriptor* sd,
+        uint32_t base,
+        uint32_t limit,
+        uint32_t flags,
+        uint32_t access)
+{
+    sd->base_low   = base  & 0x0000ffff;
+    sd->base_mid   = ((base  & 0x00ff0000) >> 16);
+    sd->base_high  = ((base  & 0xff000000) >> 24);
+    sd->limit_low  = limit & 0x0000ffff;
+    sd->limit_high = ((limit & 0x000f0000) >> 16);
+    sd->access     = access;
+    sd->flags      = flags;
+}

+ 16 - 1
src/kernel_main.c

@@ -2,6 +2,7 @@
 
 #include <asm/boot.h>
 #include <asm/port_io.h>
+#include <asm/sys.h>
 #include <kernel/event/event.h>
 #include <kernel/hw/keyboard.h>
 #include <kernel/hw/serial.h>
@@ -26,7 +27,7 @@ void call_constructors_for_cpp(void)
 #define KERNEL_MAIN_BUF_SIZE (128)
 
 
-static struct tty* console = NULL;
+struct tty* console = NULL;
 #define printkf(x...)                       \
     snprintf(buf, KERNEL_MAIN_BUF_SIZE, x); \
     tty_print(console, buf)
@@ -120,11 +121,25 @@ static inline void show_mem_info(char* buf)
     printkf("kernel size: %x\n", kernel_size);
 }
 
+static segment_descriptor new_gdt[5];
+
+void load_new_gdt(void)
+{
+    create_segment_descriptor(new_gdt+0, 0,  0, 0, 0);
+    create_segment_descriptor(new_gdt+1, 0, ~0, 0b1100, SD_TYPE_CODE_SYSTEM);
+    create_segment_descriptor(new_gdt+2, 0, ~0, 0b1100, SD_TYPE_DATA_SYSTEM);
+    create_segment_descriptor(new_gdt+3, 0, ~0, 0b1100, SD_TYPE_CODE_USER);
+    create_segment_descriptor(new_gdt+4, 0, ~0, 0b1100, SD_TYPE_DATA_USER);
+    asm_load_gdt((5 * 8 - 1) << 16, (phys_ptr_t)new_gdt);
+}
+
 void kernel_main(void)
 {
     MAKE_BREAK_POINT();
     save_loader_data();
 
+    load_new_gdt();
+
     char buf[KERNEL_MAIN_BUF_SIZE];
 
     init_serial_port(PORT_SERIAL0);