[Zion] Access the KernelStackManager through the VMM.
This commit is contained in:
parent
c5b9d20c7e
commit
07e6e3028d
|
@ -93,8 +93,6 @@ void InitGdt() {
|
||||||
: "rax");
|
: "rax");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIst1(uint64_t* ist1) {
|
void SetIst1(uint64_t ist1) { gTaskStateSegment.ist1 = ist1; }
|
||||||
gTaskStateSegment.ist1 = reinterpret_cast<uint64_t>(ist1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetRsp0(uint64_t rsp0) { gTaskStateSegment.rsp0 = rsp0; }
|
void SetRsp0(uint64_t rsp0) { gTaskStateSegment.rsp0 = rsp0; }
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
|
|
||||||
void InitGdt();
|
void InitGdt();
|
||||||
|
|
||||||
void SetIst1(uint64_t* ist1);
|
void SetIst1(uint64_t ist1);
|
||||||
|
|
||||||
void SetRsp0(uint64_t rsp0);
|
void SetRsp0(uint64_t rsp0);
|
||||||
|
|
|
@ -2,30 +2,28 @@
|
||||||
|
|
||||||
#include "common/gdt.h"
|
#include "common/gdt.h"
|
||||||
#include "debug/debug.h"
|
#include "debug/debug.h"
|
||||||
|
#include "interrupt/interrupt.h"
|
||||||
#include "memory/paging_util.h"
|
#include "memory/paging_util.h"
|
||||||
|
|
||||||
#define KERNEL_STACK_START 0xFFFFFFFF'90000000
|
#define KERNEL_STACK_START 0xFFFFFFFF'90000000
|
||||||
#define KERNEL_STACK_LIMIT 0xFFFFFFFF'9FFFFFFF
|
#define KERNEL_STACK_LIMIT 0xFFFFFFFF'9FFFFFFF
|
||||||
#define KERNEL_STACK_OFFSET 0x4000
|
#define KERNEL_STACK_OFFSET 0x4000
|
||||||
|
|
||||||
KernelStackManager* gKernelStackManager;
|
|
||||||
|
|
||||||
void KernelStackManager::Init() {
|
|
||||||
gKernelStackManager = new KernelStackManager();
|
|
||||||
|
|
||||||
SetIst1(gKernelStackManager->AllocateKernelStack());
|
|
||||||
}
|
|
||||||
|
|
||||||
KernelStackManager::KernelStackManager()
|
KernelStackManager::KernelStackManager()
|
||||||
: next_stack_addr_(KERNEL_STACK_START) {}
|
: next_stack_addr_(KERNEL_STACK_START) {}
|
||||||
|
|
||||||
uint64_t* KernelStackManager::AllocateKernelStack() {
|
void KernelStackManager::SetupInterruptStack() {
|
||||||
|
SetIst1(AllocateKernelStack());
|
||||||
|
UpdateFaultHandlersToIst1();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t KernelStackManager::AllocateKernelStack() {
|
||||||
next_stack_addr_ += KERNEL_STACK_OFFSET;
|
next_stack_addr_ += KERNEL_STACK_OFFSET;
|
||||||
if (next_stack_addr_ >= KERNEL_STACK_LIMIT) {
|
if (next_stack_addr_ >= KERNEL_STACK_LIMIT) {
|
||||||
panic("No more kernelstack space");
|
panic("No more kernelstack space");
|
||||||
}
|
}
|
||||||
EnsureResident(next_stack_addr_ - 0x3000, 0x3000);
|
EnsureResident(next_stack_addr_ - 0x3000, 0x3000);
|
||||||
return reinterpret_cast<uint64_t*>(next_stack_addr_) - 1;
|
return next_stack_addr_ - 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelStackManager::FreeKernelStack(uint64_t stack_base) {
|
void KernelStackManager::FreeKernelStack(uint64_t stack_base) {
|
||||||
|
|
|
@ -14,14 +14,15 @@
|
||||||
// class.
|
// class.
|
||||||
class KernelStackManager {
|
class KernelStackManager {
|
||||||
public:
|
public:
|
||||||
static void Init();
|
KernelStackManager();
|
||||||
|
|
||||||
uint64_t* AllocateKernelStack();
|
void SetupInterruptStack();
|
||||||
|
|
||||||
|
uint64_t AllocateKernelStack();
|
||||||
|
|
||||||
void FreeKernelStack(uint64_t stack_base);
|
void FreeKernelStack(uint64_t stack_base);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KernelStackManager();
|
|
||||||
uint64_t next_stack_addr_;
|
uint64_t next_stack_addr_;
|
||||||
uint64_t freed_stack_cnt_ = 0;
|
uint64_t freed_stack_cnt_ = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,12 +13,18 @@ KernelVmm::KernelVmm() {
|
||||||
panic("KernelVmm double init.");
|
panic("KernelVmm double init.");
|
||||||
}
|
}
|
||||||
gKernelVmm = this;
|
gKernelVmm = this;
|
||||||
|
stack_manager_ = glcr::MakeUnique<KernelStackManager>();
|
||||||
|
stack_manager_->SetupInterruptStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t KernelVmm::AcquireSlabHeapRegion(uint64_t slab_size_bytes) {
|
uint64_t KernelVmm::AcquireSlabHeapRegion(uint64_t slab_size_bytes) {
|
||||||
return gKernelVmm->AcquireSlabHeapRegionInternal(slab_size_bytes);
|
return gKernelVmm->AcquireSlabHeapRegionInternal(slab_size_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t KernelVmm::AcquireKernelStack() {
|
||||||
|
return gKernelVmm->stack_manager_->AllocateKernelStack();
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t KernelVmm::AcquireSlabHeapRegionInternal(uint64_t slab_size_bytes) {
|
uint64_t KernelVmm::AcquireSlabHeapRegionInternal(uint64_t slab_size_bytes) {
|
||||||
uint64_t next_slab = next_slab_heap_page_;
|
uint64_t next_slab = next_slab_heap_page_;
|
||||||
if (next_slab >= kKernelBuddyHeapEnd) {
|
if (next_slab >= kKernelBuddyHeapEnd) {
|
||||||
|
|
|
@ -3,15 +3,25 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "memory/constants.h"
|
#include "memory/constants.h"
|
||||||
|
#include "memory/kernel_heap.h"
|
||||||
|
#include "memory/kernel_stack_manager.h"
|
||||||
|
|
||||||
class KernelVmm {
|
class KernelVmm {
|
||||||
public:
|
public:
|
||||||
KernelVmm();
|
KernelVmm();
|
||||||
|
|
||||||
|
// TODO: Create a "MemoryRegion" style class to hold the return
|
||||||
|
// types from this object.
|
||||||
static uint64_t AcquireSlabHeapRegion(uint64_t slab_size_bytes);
|
static uint64_t AcquireSlabHeapRegion(uint64_t slab_size_bytes);
|
||||||
|
|
||||||
|
static uint64_t AcquireKernelStack();
|
||||||
|
|
||||||
|
static void FreeKernelStack(uint64_t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t next_slab_heap_page_ = kKernelSlabHeapStart;
|
uint64_t next_slab_heap_page_ = kKernelSlabHeapStart;
|
||||||
|
KernelHeap heap_;
|
||||||
|
glcr::UniquePtr<KernelStackManager> stack_manager_;
|
||||||
|
|
||||||
uint64_t AcquireSlabHeapRegionInternal(uint64_t slab_size_bytes);
|
uint64_t AcquireSlabHeapRegionInternal(uint64_t slab_size_bytes);
|
||||||
};
|
};
|
||||||
|
|
|
@ -153,10 +153,10 @@ void InitBootstrapPageAllocation() {
|
||||||
// if we limit the number of pages this should be fine.
|
// if we limit the number of pages this should be fine.
|
||||||
// Currently set to the minimum of 3 for one kernel heap allocation:
|
// Currently set to the minimum of 3 for one kernel heap allocation:
|
||||||
// PageDirectory + PageTable + Page
|
// PageDirectory + PageTable + Page
|
||||||
if (entry.type == 0 && entry.length >= 0x5000) {
|
if (entry.type == 0 && entry.length >= 0x9000) {
|
||||||
gBootstrap.init_page = entry.base;
|
gBootstrap.init_page = entry.base;
|
||||||
gBootstrap.next_page = entry.base;
|
gBootstrap.next_page = entry.base;
|
||||||
gBootstrap.max_page = entry.base + 0x4000;
|
gBootstrap.max_page = entry.base + 0x9000;
|
||||||
gBootstrapEnabled = true;
|
gBootstrapEnabled = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
#include "object/address_space.h"
|
#include "object/address_space.h"
|
||||||
|
|
||||||
#include "debug/debug.h"
|
#include "debug/debug.h"
|
||||||
#include "memory/kernel_stack_manager.h"
|
#include "memory/kernel_vmm.h"
|
||||||
#include "memory/paging_util.h"
|
#include "memory/paging_util.h"
|
||||||
#include "memory/physical_memory.h"
|
#include "memory/physical_memory.h"
|
||||||
|
|
||||||
#define K_VMAS_DEBUG 0
|
#define K_VMAS_DEBUG 0
|
||||||
|
|
||||||
extern KernelStackManager* gKernelStackManager;
|
|
||||||
|
|
||||||
glcr::RefPtr<AddressSpace> AddressSpace::ForRoot() {
|
glcr::RefPtr<AddressSpace> AddressSpace::ForRoot() {
|
||||||
uint64_t cr3 = 0;
|
uint64_t cr3 = 0;
|
||||||
asm volatile("mov %%cr3, %0;" : "=r"(cr3));
|
asm volatile("mov %%cr3, %0;" : "=r"(cr3));
|
||||||
|
@ -49,8 +47,8 @@ uint64_t AddressSpace::MapInMemoryObject(
|
||||||
return vaddr;
|
return vaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t* AddressSpace::AllocateKernelStack() {
|
uint64_t AddressSpace::AllocateKernelStack() {
|
||||||
return gKernelStackManager->AllocateKernelStack();
|
return KernelVmm::AcquireKernelStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddressSpace::HandlePageFault(uint64_t vaddr) {
|
bool AddressSpace::HandlePageFault(uint64_t vaddr) {
|
||||||
|
|
|
@ -75,7 +75,7 @@ class AddressSpace : public KernelObject {
|
||||||
uint64_t MapInMemoryObject(const glcr::RefPtr<MemoryObject>& mem_obj);
|
uint64_t MapInMemoryObject(const glcr::RefPtr<MemoryObject>& mem_obj);
|
||||||
|
|
||||||
// Kernel Mappings.
|
// Kernel Mappings.
|
||||||
uint64_t* AllocateKernelStack();
|
uint64_t AllocateKernelStack();
|
||||||
|
|
||||||
// Returns true if the page fault has been resolved.
|
// Returns true if the page fault has been resolved.
|
||||||
bool HandlePageFault(uint64_t vaddr);
|
bool HandlePageFault(uint64_t vaddr);
|
||||||
|
|
|
@ -30,7 +30,8 @@ glcr::RefPtr<Thread> Thread::Create(Process& proc, uint64_t tid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::Thread(Process& proc, uint64_t tid) : process_(proc), id_(tid) {
|
Thread::Thread(Process& proc, uint64_t tid) : process_(proc), id_(tid) {
|
||||||
uint64_t* stack_ptr = proc.vmas()->AllocateKernelStack();
|
uint64_t* stack_ptr =
|
||||||
|
reinterpret_cast<uint64_t*>(proc.vmas()->AllocateKernelStack());
|
||||||
// 0: rip
|
// 0: rip
|
||||||
*(stack_ptr) = reinterpret_cast<uint64_t>(thread_init);
|
*(stack_ptr) = reinterpret_cast<uint64_t>(thread_init);
|
||||||
// 1-4: rax, rcx, rdx, rbx
|
// 1-4: rax, rcx, rdx, rbx
|
||||||
|
|
|
@ -24,10 +24,16 @@ extern "C" void zion() {
|
||||||
|
|
||||||
dbgln("[boot] Init Physical Memory Manager.");
|
dbgln("[boot] Init Physical Memory Manager.");
|
||||||
phys_mem::InitBootstrapPageAllocation();
|
phys_mem::InitBootstrapPageAllocation();
|
||||||
|
|
||||||
|
// - Must happen after BootstrapPageAllocation
|
||||||
|
// due to the heap using page allocations.
|
||||||
|
// - Must happen after InitIdt() as the kernel
|
||||||
|
// stack manager will update ist1.
|
||||||
KernelVmm kvmm;
|
KernelVmm kvmm;
|
||||||
KernelHeap heap;
|
|
||||||
|
// Must happen after KernelVmm init as it
|
||||||
|
// will do allocations to build the free list.
|
||||||
phys_mem::InitPhysicalMemoryManager();
|
phys_mem::InitPhysicalMemoryManager();
|
||||||
phys_mem::DumpRegions();
|
|
||||||
|
|
||||||
dbgln("[boot] Memory allocations available now.");
|
dbgln("[boot] Memory allocations available now.");
|
||||||
|
|
||||||
|
@ -38,13 +44,6 @@ extern "C" void zion() {
|
||||||
Apic::Init();
|
Apic::Init();
|
||||||
ApicTimer::Init();
|
ApicTimer::Init();
|
||||||
|
|
||||||
dbgln("[boot] Init Kernel Stack Manager.");
|
|
||||||
KernelStackManager::Init();
|
|
||||||
|
|
||||||
// The KernelStackManager sets Ist1 as a part of initialization so we can use
|
|
||||||
// it now.
|
|
||||||
UpdateFaultHandlersToIst1();
|
|
||||||
|
|
||||||
dbgln("[boot] Init syscalls.");
|
dbgln("[boot] Init syscalls.");
|
||||||
InitSyscall();
|
InitSyscall();
|
||||||
|
|
||||||
|
@ -55,9 +54,6 @@ extern "C" void zion() {
|
||||||
dbgln("[boot] Loading sys init program.");
|
dbgln("[boot] Loading sys init program.");
|
||||||
LoadInitProgram();
|
LoadInitProgram();
|
||||||
|
|
||||||
dbgln("[boot] Allocs during boot:");
|
|
||||||
heap.DumpDebugData();
|
|
||||||
|
|
||||||
dbgln("[boot] Init finished, yielding.");
|
dbgln("[boot] Init finished, yielding.");
|
||||||
gScheduler->Enable();
|
gScheduler->Enable();
|
||||||
gScheduler->Yield();
|
gScheduler->Yield();
|
||||||
|
|
Loading…
Reference in New Issue