From 54f8aa54c1d0c6139119db68001b677fc84c919b Mon Sep 17 00:00:00 2001 From: Edgaru089 Date: Sun, 14 Nov 2021 17:31:11 +0800 Subject: [PATCH] interrupt, smp: fix GDT code/data segment order, fix GDT size --- interrupt/init.c | 19 ++++++++++--------- interrupt/interrupt.h | 10 +++++----- interrupt/interrupt_testcode.S | 8 +++++++- interrupt/load_gdt.S | 7 +++---- interrupt/map_handler.S | 2 +- smp/kthread.c | 2 +- 6 files changed, 27 insertions(+), 21 deletions(-) diff --git a/interrupt/init.c b/interrupt/init.c index c5980d5..b0ec1eb 100644 --- a/interrupt/init.c +++ b/interrupt/init.c @@ -5,6 +5,7 @@ #include "../runtime/stdio.h" #include "../runtime/panic_assert.h" #include "testcode.h" +#include "string.h" bool interrupt_Enabled; @@ -28,7 +29,7 @@ SYSV_ABI void interrupt_MapHandler(void *handler, int interrupt) { */ // defined in assembly -SYSV_ABI void interrupt_MapHandler(void *handler, int interrupt); +//SYSV_ABI void interrupt_MapHandler(void *handler, int interrupt); void interrupt_Init() { @@ -40,21 +41,21 @@ void interrupt_Init() { io_WriteConsoleASCII("interrupt_Init() calling\n"); // set the 2 dummy gdts - uint64_t *gdt = (uint64_t *)KERNEL_GDT_MAPPING; - gdt[0] = 0; - gdt[1] = GDT_EXEC; - gdt[2] = GDT_DATA; - gdt[3] = GDT_EXEC_RING3; - gdt[4] = GDT_DATA_RING3; + uint64_t *gdt = (uint64_t *)KERNEL_GDT_MAPPING; + gdt[0] = 0; + gdt[GDT_DATA_SELECTOR >> 3] = GDT_DATA; + gdt[GDT_EXEC_SELECTOR >> 3] = GDT_EXEC; + gdt[GDT_DATA_RING3_SELECTOR >> 3] = GDT_DATA_RING3; + gdt[GDT_EXEC_RING3_SELECTOR >> 3] = GDT_EXEC_RING3; io_WriteConsoleASCII("GDT Installed\n"); - interrupt_LoadGDT(4 * GDT_SIZE_BYTES - 1, (void *)KERNEL_GDT_MAPPING); // set it! + interrupt_LoadGDT(5 * GDT_SIZE_BYTES - 1, (void *)KERNEL_GDT_MAPPING); // set it! io_WriteConsoleASCII("GDT OK\n"); //interrupt_Testcode(); io_WriteConsoleASCII("Testcode OK\n"); - + memset((void *)KERNEL_IDT_MAPPING, 0, KERNEL_IDT_SIZE); interrupt_MapHandler(interrupt_Int0, 0); interrupt_MapHandler(interrupt_Int1, 1); interrupt_MapHandler(interrupt_Int2, 2); diff --git a/interrupt/interrupt.h b/interrupt/interrupt.h index 2fa2d36..3c1c6c5 100644 --- a/interrupt/interrupt.h +++ b/interrupt/interrupt.h @@ -8,16 +8,16 @@ extern "C" { #endif -#define GDT_SIZE_BYTES 4 +#define GDT_SIZE_BYTES 8 #define GDT_EXEC 0x00AF9A000000FFFFull // Base=0, Limit=max, Access=Present|Ring0|TypeUser|Exec|Readable, Flag=GranularityPage|Long #define GDT_DATA 0x00EF92000000FFFFull // Base=0, Limit=max, Access=Present|Ring0|TypeUser|Writable, Flag=GranularityPage|Size #define GDT_EXEC_RING3 0x00AFFA000000FFFFull // Base=0, Limit=max, Access=Present|Ring3|TypeUser|Exec|Readable, Flag=GranularityPage|Long #define GDT_DATA_RING3 0x00EFF2000000FFFFull // Base=0, Limit=max, Access=Present|Ring3|TypeUser|Writable, Flag=GranularityPage|Size -#define GDT_EXEC_SELECTOR 0x08 // SelectorIndex=1, TableIndicator=GDT(0), Privilege=Ring0 -#define GDT_DATA_SELECTOR 0x10 // SelectorIndex=2, TableIndicator=GDT(0), Privilege=Ring0 -#define GDT_EXEC_RING3_SELECTOR 0x1B // SelectorIndex=3, TableIndicator=GDT(0), Privilege=Ring3 -#define GDT_DATA_RING3_SELECTOR 0x23 // SelectorIndex=4, TableIndicator=GDT(0), Privilege=Ring3 +#define GDT_DATA_SELECTOR 0x08 // SelectorIndex=1, TableIndicator=GDT(0), Privilege=Ring0 +#define GDT_EXEC_SELECTOR 0x10 // SelectorIndex=2, TableIndicator=GDT(0), Privilege=Ring0 +#define GDT_DATA_RING3_SELECTOR 0x1B // SelectorIndex=3, TableIndicator=GDT(0), Privilege=Ring3 +#define GDT_EXEC_RING3_SELECTOR 0x23 // SelectorIndex=4, TableIndicator=GDT(0), Privilege=Ring3 #define IDT_PRESENT (1ull << 47) #define IDT_RING0 0 diff --git a/interrupt/interrupt_testcode.S b/interrupt/interrupt_testcode.S index a88423c..2428b0f 100644 --- a/interrupt/interrupt_testcode.S +++ b/interrupt/interrupt_testcode.S @@ -46,12 +46,18 @@ interrupt_Testcode: lidt [idtr] mov rax, int_handler mov [idt+49*16], ax - mov word [idt+49*16+2], 0x08 + mov word [idt+49*16+2], 0x10 mov word [idt+49*16+4], 0x8e00 shr rax, 16 mov [idt+49*16+6], ax shr rax, 16 mov [idt+49*16+8], rax + ; load the CS segment reg with 0x10 + lea rax, [.realint] + push qword 0x10 + push rax + retfq +.realint: int 49 ret diff --git a/interrupt/load_gdt.S b/interrupt/load_gdt.S index 21aac5b..4a90e2f 100644 --- a/interrupt/load_gdt.S +++ b/interrupt/load_gdt.S @@ -11,19 +11,18 @@ section '.text' executable ; ; Clobbers: rax interrupt_ReloadSegments: - ;mov eax, 0x10 ; my data segment - xor ax, ax + mov ax, 0x08 ; my data segment mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax - ;jmp 0x08:.flush + ;jmp 0x10:.flush ; as in https://forum.osdev.org/viewtopic.php?f=1&t=30739 ; farjump does not work in long mode, you need to do a far return: pop rax - push qword 0x08 ; my code segment + push qword 0x10 ; my code segment push rax retfq diff --git a/interrupt/map_handler.S b/interrupt/map_handler.S index b3b3905..ad15afd 100644 --- a/interrupt/map_handler.S +++ b/interrupt/map_handler.S @@ -16,7 +16,7 @@ interrupt_MapHandler: shl rsi, 4 ; rsi *= 16 add rsi, rax ; rsi += KERNEL_IDT_MAPPING mov [rsi], di - mov word [rsi+2], 0x08 ; GDT_EXEC_SELECTOR (index=1) + mov word [rsi+2], 0x10 ; GDT_EXEC_SELECTOR (index=2) mov word [rsi+4], 0x8e00 shr rdi, 16 mov [rsi+6], di diff --git a/smp/kthread.c b/smp/kthread.c index 30fe57d..80a3260 100644 --- a/smp/kthread.c +++ b/smp/kthread.c @@ -72,7 +72,7 @@ smp_thread_ID smp_thread_Start(void *entry, const smp_thread_Arguments *args, un t->waitCondition = NULL; t->state.cs = GDT_EXEC_SELECTOR; - t->state.ss = 0; + t->state.ss = GDT_DATA_SELECTOR; t->state.rip = (uint64_t)__smp_thread_EntryPoint; t->state.rax = (uint64_t)entry;