diff --git a/sortix/kernel.cpp b/sortix/kernel.cpp index ed299479..a0753d59 100644 --- a/sortix/kernel.cpp +++ b/sortix/kernel.cpp @@ -241,7 +241,15 @@ namespace Sortix Thread::Entry initstart = RunApplication; - // TODO: Create a new page directory here for the first process! + // Create an address space for the first process. + addr_t addrspace = VirtualMemory::CreateAddressSpace(); + + // Use the new address space! + VirtualMemory::SwitchAddressSpace(addrspace); + + // Create the first process! + Process* process = new Process(addrspace); + if ( process == 0 ) { Panic("kernel.cpp: Could not allocate the first process!"); } if ( initrd != NULL ) { @@ -258,7 +266,7 @@ namespace Sortix initstart = (Thread::Entry) loadat; } - if ( Scheduler::CreateThread(NULL, initstart) == NULL ) + if ( Scheduler::CreateThread(process, initstart) == NULL ) { Panic("Could not create a sample thread!"); } diff --git a/sortix/scheduler.cpp b/sortix/scheduler.cpp index af20957b..c42ae739 100644 --- a/sortix/scheduler.cpp +++ b/sortix/scheduler.cpp @@ -38,6 +38,16 @@ namespace Sortix { const bool LOG_SWITCHING = false; + Process::Process(addr_t addrspace) + { + _addrspace = addrspace; + } + + Process::~Process() + { + // TODO: Delete address space! + } + namespace Scheduler { // This is a very small thread that does absoluting nothing! @@ -57,6 +67,9 @@ namespace Sortix Thread::Thread(Process* process, size_t id, addr_t stack, size_t stackLength) { + ASSERT(process != NULL); + ASSERT(process->IsSane()); + _process = process; _id = id; _stack = stack; @@ -191,8 +204,14 @@ namespace Sortix firstSleeping = NULL; AllocatedThreadId = 1; + // Create an address space for the idle process. + addr_t noopaddrspace = VirtualMemory::CreateAddressSpace(); + + // Create the noop process. + Process* noopprocess = new Process(noopaddrspace); + // Initialize the thread that does nothing. - NoopThread = new ((void*) NoopThreadData) Thread(NULL, 0, NULL, 0); + NoopThread = new ((void*) NoopThreadData) Thread(noopprocess, 0, NULL, 0); NoopThread->SetState(Thread::State::NOOP); #ifdef PLATFORM_X86 NoopThread->_registers.useresp = (uint32_t) NoopThreadStack + NoopThreadStackLength; @@ -227,6 +246,10 @@ namespace Sortix Thread* CreateThread(Process* Process, Thread::Entry Start, void* Parameter1, void* Parameter2, size_t StackSize) { + ASSERT(Process != NULL); + ASSERT(Process->IsSane()); + ASSERT(Start != NULL); + // The current default stack size is 4096 bytes. if ( StackSize == SIZE_MAX ) { StackSize = 4096; } @@ -264,8 +287,9 @@ namespace Sortix uintptr_t StackPos = 0x80000000UL; uintptr_t MapTo = StackPos - 4096UL; + addr_t OldAddrSpace = VirtualMemory::SwitchAddressSpace(Process->GetAddressSpace()); + VirtualMemory::MapUser(MapTo, PhysStack); - VirtualMemory::Flush(); #else uintptr_t StackPos = (uintptr_t) PhysStack + 4096; #endif @@ -290,6 +314,11 @@ namespace Sortix // Mark the thread as running, which adds it to the scheduler's linked list. thread->SetState(Thread::State::RUNNABLE); +#ifdef PLATFORM_VIRTUAL_MEMORY + // Avoid side effects by restoring the old address space. + VirtualMemory::SwitchAddressSpace(OldAddrSpace); +#endif + return thread; } @@ -334,7 +363,9 @@ namespace Sortix Log::PrintF("Switching from thread at 0x%p to thread at 0x%p\n", currentThread); } - // TODO: If applicable, switch the virtual address space. + // If applicable, switch the virtual address space. + VirtualMemory::SwitchAddressSpace(NextThread->GetProcess()->GetAddressSpace()); + currentThread = NextThread; // Load the hardware registers of the next thread. diff --git a/sortix/scheduler.h b/sortix/scheduler.h index 4eed8ffc..a958b3b0 100644 --- a/sortix/scheduler.h +++ b/sortix/scheduler.h @@ -30,6 +30,23 @@ namespace Sortix class Thread; class Process; + class Process + { + public: + Process(addr_t addrspace); + ~Process(); + + private: + addr_t _addrspace; + + public: + addr_t GetAddressSpace() { return _addrspace; } + + public: + bool IsSane() { return _addrspace != 0; } + + }; + class Thread { public: