Prepare for cloning address spaces, not there yet

This commit is contained in:
apio 2022-10-14 18:17:57 +02:00
parent e43777bd31
commit 1c3377fc98
5 changed files with 28 additions and 68 deletions

View File

@ -7,13 +7,21 @@ struct AddressSpace
void destroy();
void reset();
void detach();
AddressSpace clone();
PageTable* get_pml4()
{
return m_pml4;
}
bool is_cloned()
{
return m_cloned;
}
private:
PageTable* m_pml4;
bool m_cloned;
};

View File

@ -10,7 +10,8 @@ namespace Scheduler
void exit(int status);
void sleep(unsigned long ms);
void add_kernel_task(void (*task)(void));
void add_user_task(void* task);
Task* create_user_task();
void load_user_task(const char* filename);

View File

@ -15,6 +15,11 @@ AddressSpace AddressSpace::create()
void AddressSpace::destroy()
{
if (m_cloned)
{
kdbgln("Will not destroy a cloned address space, I don't own it");
return;
}
uint64_t pages_freed = 0;
for (int i = 0; i < 512; i++)
{
@ -71,60 +76,18 @@ void AddressSpace::destroy()
kdbgln("Reclaimed %ld pages from address space!", pages_freed);
}
void AddressSpace::reset()
void AddressSpace::detach()
{
uint64_t pages_freed = 0;
for (int i = 0; i < 512; i++)
{
PageDirectoryEntry& pdp_pde = m_pml4->entries[i];
if (!pdp_pde.present) continue;
if (pdp_pde.larger_pages)
{
pages_freed++;
PMM::free_page((void*)pdp_pde.get_address());
continue;
}
PageTable* pdp = (PageTable*)pdp_pde.get_address();
for (int j = 0; j < 511; j++) // skip the last page directory, it's the kernel one
{
PageDirectoryEntry& pd_pde = pdp->entries[j];
if (!pd_pde.present) continue;
if (pd_pde.larger_pages)
{
pages_freed++;
PMM::free_page((void*)pd_pde.get_address());
continue;
}
PageTable* pd = (PageTable*)pd_pde.get_address();
for (int k = 0; k < 512; k++)
{
PageDirectoryEntry& pt_pde = pd->entries[k];
if (!pt_pde.present) continue;
if (pt_pde.larger_pages)
{
pages_freed++;
PMM::free_page((void*)pt_pde.get_address());
continue;
}
PageTable* pt = (PageTable*)pt_pde.get_address();
for (int l = 0; l < 512; l++)
{
PageDirectoryEntry& pde = pt->entries[l];
if (!pde.present) continue;
pages_freed++;
PMM::free_page((void*)pde.get_address());
}
pages_freed++;
PMM::free_page(pt);
}
pages_freed++;
PMM::free_page(pd);
}
pages_freed++;
PMM::free_page(pdp);
}
if (!m_cloned) return;
m_pml4 = (PageTable*)PMM::request_page();
VMM::install_kernel_page_directory_into_address_space(*this);
m_cloned = false;
}
kdbgln("Reclaimed %ld pages from address space!", pages_freed);
AddressSpace AddressSpace::clone()
{
AddressSpace result;
result.m_pml4 = m_pml4;
result.m_cloned = true;
return result;
}

View File

@ -75,10 +75,6 @@ void sys_exec(Context* context, const char* pathname)
// At this point, pretty much nothing can fail.
// task->address_space.reset();
// VMM::switch_to_user_address_space(task->address_space);
ELFImage* image = ELFLoader::load_elf_from_vfs(program);
ASSERT(image); // If check_elf_image succeeded, load_elf_from_vfs MUST succeed, unless something has gone terribly
// wrong.

View File

@ -87,21 +87,16 @@ void Scheduler::add_kernel_task(void (*task)(void))
new_task->id, new_task->regs.rsp, task_num);
}
void Scheduler::add_user_task(void* task)
Task* Scheduler::create_user_task()
{
Task* new_task = new Task;
ASSERT(new_task);
memset(&new_task->regs, 0, sizeof(Context));
new_task->user_task = true;
new_task->id = free_tid++;
new_task->regs.rip = (uint64_t)task;
new_task->allocated_stack = (uint64_t)MemoryManager::get_pages(
TASK_PAGES_IN_STACK, MAP_READ_WRITE | MAP_USER); // 16 KB is enough for everyone, right?
new_task->regs.rsp = get_top_of_stack(new_task->allocated_stack, TASK_PAGES_IN_STACK);
new_task->regs.cs = 0x18 | 0x03;
new_task->regs.ss = 0x20 | 0x03;
new_task->regs.ds = 0x20 | 0x03;
new_task->regs.rflags = (1 << 21) | (1 << 9); // enable interrupts
new_task->task_sleep = 0;
new_task->task_time = 0;
new_task->cpu_time = 0;
@ -110,10 +105,7 @@ void Scheduler::add_user_task(void* task)
base_task->prev_task = new_task;
new_task->next_task = base_task;
end_task = new_task;
new_task->state = new_task->Running;
task_num++;
kinfoln("Adding user task: starts at %lx, tid %ld, stack at %lx, total tasks: %ld", new_task->regs.rip,
new_task->id, new_task->regs.rsp, task_num);
}
void Scheduler::load_user_task(const char* filename)