add a class to allocate and manage user space stacks
This commit is contained in:
parent
1db93e5b12
commit
2eefda6114
|
@ -12,6 +12,7 @@ add_executable(zion
|
|||
memory/kernel_stack_manager.cpp
|
||||
memory/paging_util.cpp
|
||||
memory/physical_memory.cpp
|
||||
memory/user_stack_manager.cpp
|
||||
memory/virtual_memory.cpp
|
||||
scheduler/context_switch.s
|
||||
scheduler/jump_user_space.s
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
#include "memory/user_stack_manager.h"
|
||||
|
||||
#include "debug/debug.h"
|
||||
#include "memory/paging_util.h"
|
||||
|
||||
uint64_t UserStackManager::NewUserStack() {
|
||||
uint64_t stack = next_stack_;
|
||||
next_stack_ -= kStackSize;
|
||||
if (stack <= kStackMin) {
|
||||
panic("Out of user stacks!");
|
||||
}
|
||||
if (stack == kStackMax) {
|
||||
// Add a additional page boudary between kernel and user space.
|
||||
stack -= 0x1000;
|
||||
}
|
||||
EnsureResident(stack - 1, 1);
|
||||
return stack;
|
||||
}
|
||||
|
||||
void UserStackManager::FreeUserStack(uint64_t stack_ptr) {
|
||||
freed_stacks_++;
|
||||
dbgln("%u freed user stacks", freed_stacks_);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Per-process class to manage user stacks.
|
||||
//
|
||||
// User stacks live at
|
||||
// 0x00007FF0 00000000 - 0x00007FFF FFFFFFFF
|
||||
// and grow downwards.
|
||||
//
|
||||
// Each user stack gets 1 MiB (0x100000 bytes)
|
||||
// less a page boundary.
|
||||
// with 1 page allocated at a time.
|
||||
// TODO: consider increasing this.
|
||||
class UserStackManager {
|
||||
public:
|
||||
UserStackManager() {}
|
||||
UserStackManager(const UserStackManager&) = delete;
|
||||
|
||||
uint64_t NewUserStack();
|
||||
void FreeUserStack(uint64_t stack_ptr);
|
||||
|
||||
private:
|
||||
const uint64_t kStackMax = 0x00008000'00000000;
|
||||
const uint64_t kStackMin = 0x00007FF0'00000000;
|
||||
const uint64_t kStackSize = 0x100000;
|
||||
|
||||
uint64_t next_stack_ = kStackMax;
|
||||
uint64_t freed_stacks_ = 0;
|
||||
};
|
|
@ -17,8 +17,8 @@ VirtualMemory::VirtualMemory() {
|
|||
InitializePml4(cr3_);
|
||||
}
|
||||
|
||||
uint64_t* VirtualMemory::AllocateKernelStack() {
|
||||
return gKernelStackManager->AllocateKernelStack();
|
||||
uint64_t VirtualMemory::AllocateUserStack() {
|
||||
return user_stacks_.NewUserStack();
|
||||
}
|
||||
|
||||
uint64_t VirtualMemory::GetNextMemMapAddr(uint64_t size) {
|
||||
|
@ -29,3 +29,7 @@ uint64_t VirtualMemory::GetNextMemMapAddr(uint64_t size) {
|
|||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
uint64_t* VirtualMemory::AllocateKernelStack() {
|
||||
return gKernelStackManager->AllocateKernelStack();
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "debug/debug.h"
|
||||
#include "memory/user_stack_manager.h"
|
||||
|
||||
// VirtualMemory class holds a memory space for an individual process.
|
||||
//
|
||||
|
@ -15,7 +16,7 @@
|
|||
// 0x00000010 00000000 - 0x0000001F FFFFFFFF : USER_HEAP (64 GiB)
|
||||
// 0x00000020 00000000 - 0x0000002F FFFFFFFF : MEM_MAP (64 GiB)
|
||||
// 0x00000040 00000000 - 0x0000004F FFFFFFFF : IPC_BUF (64 GiB)
|
||||
// 0x00007FFF 00000000 - 0x00007FFF FFFFFFFF : USER_STACK (64 GiB)
|
||||
// 0x00007FF0 00000000 - 0x00007FFF FFFFFFFF : USER_STACK (64 GiB)
|
||||
//
|
||||
// Kernel Regions (Shared across processes):
|
||||
// 0xFFFF8000 00000000 - 0xFFFF800F FFFFFFFF : HHDM (64 GiB)
|
||||
|
@ -46,14 +47,17 @@ class VirtualMemory {
|
|||
|
||||
uint64_t cr3() { return cr3_; }
|
||||
|
||||
// User Mappings.
|
||||
uint64_t AllocateUserStack();
|
||||
uint64_t GetNextMemMapAddr(uint64_t size);
|
||||
|
||||
// Kernel
|
||||
// Kernel Mappings.
|
||||
uint64_t* AllocateKernelStack();
|
||||
|
||||
private:
|
||||
VirtualMemory(uint64_t cr3) : cr3_(cr3) {}
|
||||
uint64_t cr3_ = 0;
|
||||
|
||||
UserStackManager user_stacks_;
|
||||
uint64_t next_memmap_addr_ = 0x20'00000000;
|
||||
};
|
||||
|
|
|
@ -26,7 +26,6 @@ SharedPtr<Thread> Thread::RootThread(Process& root_proc) {
|
|||
Thread::Thread(Process& proc, uint64_t tid, uint64_t entry)
|
||||
: process_(proc), id_(tid), rip_(entry) {
|
||||
uint64_t* stack_ptr = proc.vmm().AllocateKernelStack();
|
||||
dbgln("Kernel Stack at: %m", stack_ptr);
|
||||
// 0: rip
|
||||
*(stack_ptr) = reinterpret_cast<uint64_t>(thread_init);
|
||||
// 1-4: rax, rcx, rdx, rbx
|
||||
|
@ -43,8 +42,7 @@ uint64_t Thread::pid() const { return process_.id(); }
|
|||
|
||||
void Thread::Init() {
|
||||
dbgln("[%u.%u] thread start.", pid(), id_);
|
||||
uint64_t rsp = 0x80000000;
|
||||
EnsureResident(rsp - 1, 1);
|
||||
uint64_t rsp = process_.vmm().AllocateUserStack();
|
||||
SetRsp0(rsp0_start_);
|
||||
jump_user_space(rip_, rsp);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue