From c9a036bfbb73c47fa820cd5a869281e122b0c957 Mon Sep 17 00:00:00 2001 From: Nigel Date: Mon, 13 Feb 2023 22:44:47 +0100 Subject: [PATCH] Ring 3 ready - Fixed issue with setting up the Task Segment Register --- source/kernel/boot/boot.s | 23 ++++++++++++-------- source/kernel/kernel.cpp | 13 ++++++----- source/kernel/memory/TaskStateSegment.h | 29 +++++++++++++------------ source/kernel/memory/gdt/gdtc.cpp | 3 +-- source/kernel/memory/gdt/gdtc.h | 1 - 5 files changed, 38 insertions(+), 31 deletions(-) diff --git a/source/kernel/boot/boot.s b/source/kernel/boot/boot.s index c5e9902..c5414f9 100644 --- a/source/kernel/boot/boot.s +++ b/source/kernel/boot/boot.s @@ -5,6 +5,7 @@ .section .bootstrap_stack, "aw", @nobits stack_bottom: .skip 16384 # 16 KiB +.globl stack_top stack_top: /* @@ -75,16 +76,7 @@ _start: 4: # At this point, paging is fully set up and enabled isPaging: - /* push the pointer to the Multiboot information structure*/ - pushl %ebx - /* push the magic value */ - pushl %eax - call prekernelSetup - - # Unmap the identity mapping as it is now unnecessary - # movl $0, boot_page_directory + 0 - # Reload cr3 to force tlb flush movl %cr3, %ecx movl %ecx, %cr3 @@ -97,6 +89,19 @@ isPaging: pushl $0 popf + + /* push the pointer to the Multiboot information structure*/ + pushl %ebx + + /* push the magic value */ + pushl %eax + call prekernelSetup + + # Unmap the identity mapping as it is now unnecessary + # movl $0, boot_page_directory + 0 + + + call early_main diff --git a/source/kernel/kernel.cpp b/source/kernel/kernel.cpp index 2972314..f2d056f 100644 --- a/source/kernel/kernel.cpp +++ b/source/kernel/kernel.cpp @@ -36,6 +36,8 @@ extern "C" #include "serial.h" #include "time.h" #include "definitions.h" +extern "C" void LoadGlobalDescriptorTable(); + /* Copyright © Nigel Barink 2023 @@ -50,18 +52,19 @@ extern "C" void kernel_main () startSuperVisorTerminal(); } - extern "C" void early_main() { init_serial(); kterm_init(); + setup_tss(); initGDT(); - //setup_tss(); initidt(); - - + LoadGlobalDescriptorTable(); + flush_tss(); + printf("Memory setup complete!\n"); + // Enable interrupts asm volatile("STI"); @@ -73,7 +76,7 @@ extern "C" void early_main() initHeap(); printf("Enable Protected mode and jump to kernel main\n"); - + // Set the protected bit of control register 0 // this will put the CPU into protected mode diff --git a/source/kernel/memory/TaskStateSegment.h b/source/kernel/memory/TaskStateSegment.h index c4860c1..b41a4fb 100644 --- a/source/kernel/memory/TaskStateSegment.h +++ b/source/kernel/memory/TaskStateSegment.h @@ -34,26 +34,27 @@ struct TaskStateSegment { }__attribute__((packed)); -TaskStateSegment tss0 = {}; +TaskStateSegment tss0 ={}; -inline void flush_tss(){ - asm volatile("mov (5 * 8) |0 , %eax; ltr %ax"); +inline void flush_tss() +{ + asm volatile("mov $0x2B, %ax ; ltr %ax"); } - void setup_tss(){ - - // ensure the tss is zero'd - //memset((void*)&tss0, 0, sizeof(tss0)); - tss0.ss0 = (uint32_t) &(GlobalDescriptorTable[KERNEL_DATA_SEGMENT]); - uint32_t esp_addr =0 ; - asm volatile ("movl %%esp, %0" : "=a"(esp_addr)); - tss0.esp0 = esp_addr; - + memset((void*)&tss0, 0, sizeof(tss0)); + tss0.ss0 = (uint32_t) &GlobalDescriptorTable[KERNEL_DATA_SEGMENT]; + + extern uint32_t stack_top; + tss0.esp0 = (unsigned long)&stack_top; // Task Segment Descriptor - add_descriptor(TASK_STATE_SEGMENT, (unsigned long)&tss0, sizeof(tss0), 0x89, 0x0); - flush_tss(); + + uint32_t address = (unsigned long) &tss0; + uint32_t size = sizeof(tss0); + uint32_t limit = (address + size ); + + add_descriptor(TASK_STATE_SEGMENT, address, limit- 1, 0xE9, 0x0); } diff --git a/source/kernel/memory/gdt/gdtc.cpp b/source/kernel/memory/gdt/gdtc.cpp index c7f15c9..a73b776 100644 --- a/source/kernel/memory/gdt/gdtc.cpp +++ b/source/kernel/memory/gdt/gdtc.cpp @@ -40,8 +40,7 @@ void initGDT(){ add_descriptor(USER_DATA_SEGMENT, 0, 0xFFFFFFFF, 0xF2, 0xCF); // init Gdt Descriptor - gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 5 ) - 1); + gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 6 ) - 1); gdtDescriptor.base = (unsigned int) (&GlobalDescriptorTable); - LoadGlobalDescriptorTable(); } diff --git a/source/kernel/memory/gdt/gdtc.h b/source/kernel/memory/gdt/gdtc.h index 17c8ec0..bf914a0 100644 --- a/source/kernel/memory/gdt/gdtc.h +++ b/source/kernel/memory/gdt/gdtc.h @@ -32,5 +32,4 @@ struct GlobalDescriptorTableDescriptor{ void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity ); -extern "C" void LoadGlobalDescriptorTable(); void initGDT();