Skip to content

Commit

Permalink
We have a ring 3 thread! :D
Browse files Browse the repository at this point in the history
  • Loading branch information
Twometer committed Jan 17, 2021
1 parent 6622c92 commit 7fe39a7
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 43 deletions.
9 changes: 2 additions & 7 deletions kernel/arch/interrupts.asm
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,12 @@ irq%1:
save_all_regs
save_segments
; get the flags from the stack
; they are just for analyzing and stuff, and don't get written back
;mov dword eax, [esp + 8]
;mov dword [s_flags], eax

; call interrupt handler
; call the interrupt handler
call irq%1_handler

; load reg states back
load_segments
load_all_regs
load_segments
iret
%endmacro

Expand Down
11 changes: 5 additions & 6 deletions kernel/arch/regutil.asm
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,15 @@ s_ds: dd 0
%endmacro

%macro save_segments 0
mov ax, ds
mov [s_ds], ax
mov [s_ds], ds
%endmacro

%macro load_segments 0
mov ax, [s_ds]
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
%endmacro

%macro save_all_regs 0
Expand Down
1 change: 0 additions & 1 deletion kernel/include/tasks/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include <memory/pagedirectory.h>

#define THREAD_STACK_SIZE 4096
#define RING3_MASK 0x00

namespace Kernel
{
Expand Down
8 changes: 3 additions & 5 deletions kernel/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void testThreadEP()
{
for (;;)
{
//printf("Hello from thread #2 %d\n", TimeManager::GetInstance()->GetUptime());
printf("Hello from thread #2 %d\n", TimeManager::GetInstance()->GetUptime());
Thread::current->Sleep(1000);
}
}
Expand All @@ -43,13 +43,10 @@ void testExitingThread()

void ring3Thread()
{
// asm("int $0x80");
printf("Hello from ring 3 :3\n"); // if everything works correctly, this should crash with a GPF as it directly accesses the screen buffer
for (;;)
{
;
}
//
}

extern "C"
Expand Down Expand Up @@ -99,6 +96,7 @@ extern "C"
PageDirectory pageDir;

// Identity map the first megabyte
// IMPORTANT FIXME: The first MB is only mapped into userspace here, because the test-ring3 func is in there, and it obviously needs to be able to access itself.
for (uint32_t i = 0; i < MBYTE; i += PAGE_SIZE)
pageDir.MapPage((paddress_t)i, (vaddress_t)i, PAGE_BIT_READ_WRITE | PAGE_BIT_ALLOW_USER);

Expand Down Expand Up @@ -146,7 +144,7 @@ extern "C"
gdt.Set(SEG_USER_DATA, 0x00, 0xffffffff, GDTEntryType::Data, Ring::Ring3);
gdt.SetTssEntry(SEG_TSS);
gdt.Load();
setTss(SEG_TSS | RING3_MASK);
setTss(SEG_TSS);

printf("Setting up interrupts\n");
Interrupts::SetupIdt();
Expand Down
7 changes: 5 additions & 2 deletions kernel/memory/pagedirectory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ namespace Memory
if (virt_directory_ptr[idx] == 0x00)
{
auto table = (uint32_t)NewPage();
virt_directory_ptr[idx] = table | PAGE_BIT_PRESENT | PAGE_BIT_READ_WRITE;
virt_directory_ptr[idx] = table | PAGE_BIT_PRESENT | PAGE_BIT_READ_WRITE | PAGE_BIT_ALLOW_USER;
FlushPage(table); // Flush TLB for that page, so that we for sure have that
// Load();
}
Expand All @@ -113,14 +113,17 @@ namespace Memory
if (table == 0x00) // Allocate page table if it does not exist
{
table = (uint32_t)NewPage();
virt_directory_ptr[idx] = table | PAGE_BIT_PRESENT | PAGE_BIT_READ_WRITE;
virt_directory_ptr[idx] = table | PAGE_BIT_PRESENT | PAGE_BIT_READ_WRITE | PAGE_BIT_ALLOW_USER;
}
return (uint32_t *)table;
}
}

void PageDirectory::FlushPage(uint32_t addr)
{
if (!IS_PAGE_ALIGNED(addr))
Kernel::Panic("page_directory", "Can't flush non-page-aligned memory.");

asm volatile("invlpg (%0)" ::"r"(addr)
: "memory");
}
Expand Down
7 changes: 1 addition & 6 deletions kernel/stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,14 @@

namespace Kernel
{

Stack::Stack(void *stack_bottom, size_t size)
{
this->stack_bottom = (uint8_t *)stack_bottom;
this->stack_top = this->stack_bottom + size;
this->stack_ptr = this->stack_top;
}

Stack::~Stack()
{
delete[] stack_bottom;
}

void Stack::Push(uint32_t data)
{
size_t data_size = sizeof(data);
Expand Down
6 changes: 3 additions & 3 deletions kernel/tasks/scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <kernel/timemanager.h>
#include <tasks/scheduler.h>

#define SCHEDULER_DBG 1
#define SCHEDULER_DBG 0

namespace Kernel
{
Expand Down Expand Up @@ -89,8 +89,8 @@ namespace Kernel
{
auto &newregs = newThread->registers;
printf("scheduler: %d -> %d after %dms\n", oldThread->id, newThread->id, oldThread->GetRuntime());
printf(" old: %x, %x\n", regs->esp, regs->eax);
printf(" new: %x, %x\n", newregs.esp, newregs.eax);
printf(" old: %x, %x\n", regs->esp, regs->ds);
printf(" new: %x, %x\n", newregs.esp, newregs.ds);
}
#endif

Expand Down
23 changes: 10 additions & 13 deletions kernel/tasks/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,10 @@ namespace Kernel
// Push the kernel thread return func#
stack->Push((uint32_t)(thread_exit_func_krnl));

// put stuff on stack that an iret needs later
// note for the flags: I observed this value from the stack in an irq.
// I know that it keeps interrupts enabled. I don't know what else it does, but it works.
stack->Push(0x202); // Flags, 0x202 for now.
stack->Push(0x202); // Flags, 0x202: interrupt enable = true
stack->Push(SEG_KRNL_CODE); // Code Segment
stack->Push((uint32_t)entryPoint); // IP = entry_point
registers.ds = SEG_KRNL_DATA;
registers.esp = (uint32_t)this->stack->GetStackPtr();
}
else
Expand All @@ -63,16 +61,15 @@ namespace Kernel
stack->Push((uint32_t)(thread_exit_func_user));

// put stuff on the stack that iret needs
stack->Push(SEG_USER_DATA | RING3_MASK); // stackseg
stack->Push((uint32_t)stack_virt); // stack ptr
stack->Push(0x202); // flags
stack->Push(SEG_USER_CODE | RING3_MASK); // code seg
stack->Push((uint32_t)entryPoint); // ret ptr

registers.ds = SEG_USER_DATA | RING3_MASK;
registers.esp = (uint32_t)stack_virt;
stack->Push(SEG_USER_DATA | 0b11); // stackseg
stack->Push((uint32_t)(stack->GetStackPtr())); // stack ptr
stack->Push(0x202); // flags
stack->Push(SEG_USER_CODE | 0b11); // code seg
stack->Push((uint32_t)entryPoint); // ret ptr

registers.ds = SEG_USER_DATA | 0b11;
registers.esp = (uint32_t)stack->GetStackPtr();
}


// make sure we restore to kernel page directory before continuing
if (ring == Ring::Ring3)
Expand Down

0 comments on commit 7fe39a7

Please sign in to comment.