Prepare for cloning address spaces, not there yet
This commit is contained in:
parent
e43777bd31
commit
1c3377fc98
@ -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;
|
||||
};
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
kdbgln("Reclaimed %ld pages from address space!", pages_freed);
|
||||
m_cloned = false;
|
||||
}
|
||||
|
||||
AddressSpace AddressSpace::clone()
|
||||
{
|
||||
AddressSpace result;
|
||||
result.m_pml4 = m_pml4;
|
||||
result.m_cloned = true;
|
||||
return result;
|
||||
}
|
@ -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.
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user