syscalls: start adding fork syscall, not done yet
This commit is contained in:
@@ -188,4 +188,63 @@ void destroy_page_dir(uint32_t* page_dir_virt) {
|
||||
// We need its physical address to pass to the physical memory manager.
|
||||
debug_log("freeing PD page %X\n", virt_to_phys(page_dir_virt));
|
||||
free_page((void*)virt_to_phys(page_dir_virt));
|
||||
}
|
||||
|
||||
uint32_t* copy_page_dir(uint32_t* page_dir_virt)
|
||||
{
|
||||
if(page_dir_virt == NULL)
|
||||
return 0;
|
||||
|
||||
uint32_t* new_pagedir = create_page_dir();
|
||||
|
||||
for(int i = 0; i < 768; i++)
|
||||
{
|
||||
uint32_t pde = page_dir_virt[i];
|
||||
|
||||
if(pde & PAGE_PRESENT)
|
||||
{
|
||||
debug_log("PDE %X present\n", pde);
|
||||
uint32_t* new_page_table = (uint32_t*)alloc_page();
|
||||
if(new_page_table == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get original page table (physical address from PDE)
|
||||
uint32_t* orig_page_table = (uint32_t*)phys_to_virt(pde & ~0xFFF);
|
||||
|
||||
for(int j = 0; j < 1024; j++)
|
||||
{
|
||||
uint32_t pte = orig_page_table[j];
|
||||
if(pte & PAGE_PRESENT)
|
||||
{
|
||||
void* new_phys_page = alloc_page();
|
||||
if(!new_phys_page)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* orig_phys_page = (void*)(pte & ~0xFFF);
|
||||
|
||||
debug_log("copying %X to %X...", orig_phys_page, new_phys_page);
|
||||
memcpy(new_phys_page, orig_phys_page, PAGE_SIZE);
|
||||
debug_log("done\n");
|
||||
new_page_table[j] = (uint32_t)new_phys_page | (pte & 0xFFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_page_table[j] = pte;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set the new PDE in the child's page directory
|
||||
new_pagedir[i] = (uint32_t)virt_to_phys(new_page_table) | (pde & 0xFFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_pagedir[i] = pde;
|
||||
}
|
||||
}
|
||||
debug_log("ENDENDENDEND\n");
|
||||
return new_pagedir;
|
||||
}
|
||||
Reference in New Issue
Block a user