summaryrefslogtreecommitdiff
path: root/kernel/vmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/vmem.c')
-rw-r--r--kernel/vmem.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/kernel/vmem.c b/kernel/vmem.c
index ffa9099..ade0a01 100644
--- a/kernel/vmem.c
+++ b/kernel/vmem.c
@@ -313,7 +313,8 @@ pdirectory* vmem_kernel_dir()
pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only)
{
- pdirectory* dir = vmem_clean_dir();
+ pdirectory* dir = vmem_clean_dir(); //let's start with a fresh page directory
+
//link non-user pages.
for(int i=0;i<1024;i++)
{
@@ -324,41 +325,49 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only)
vmem_add_alloc(dir,VMEM_USER_PROG,1024*4,true);
vmem_add_alloc(dir,VMEM_USER_STACK_TOP-4096*VMEM_USER_STACK_PAGES,VMEM_USER_STACK_PAGES,true);
- x86_cli(); // plese dear timer, do not schedule us away
- pdirectory* orig=x86_get_page_directory();
- x86_set_page_directory(dir);
+ pdirectory* mydir=x86_get_page_directory();
- //copy user pages.
- //TODO: stack only!
+ //copy user pages (TODO: stack only version for cloning!)
uint32_t virt=0;
for(int i=0;i<1024;i++)
{
uint32_t src_pt=copy_dir->m_entries [i];
+ uint32_t dst_pt=dir->m_entries [i];
+
if(pt_entry_is_user(src_pt))
{
- ptable *table=pt_entry_get_frame(&src_pt);
+ ptable *src_table=pt_entry_get_frame(&src_pt);
+ ptable *dst_table=pt_entry_get_frame(&dst_pt);
+
for(int j=0;j<1024;j++)
{
- uint32_t src_pd=table->m_entries[j];
- uint32_t phys=pd_entry_get_frame(&src_pd);
+ uint32_t src_pd=src_table->m_entries[j];
+ uint32_t dst_pd=dst_table->m_entries[j];
+
+ uint32_t src_phys=pd_entry_get_frame(&src_pd);
+ uint32_t dst_phys=pd_entry_get_frame(&dst_pd);
+
if(src_pd)
{
- // klog("copy %x to %x",phys,virt);
- vmem_clear_one(dir,VMEM_COPY_PAGE);
- vmem_add_remap(dir,phys,VMEM_COPY_PAGE,1,false);
+ klog("copy virt: %x / phys: %x -> %x",virt,src_phys,dst_phys);
+
+ vmem_clear_one(mydir,VMEM_COPY_PAGE);
+ vmem_clear_one(mydir,VMEM_COPY_PAGE+4096);
+
+ vmem_add_remap(mydir,src_phys,VMEM_COPY_PAGE,1,false);
+ vmem_add_remap(mydir,dst_phys,VMEM_COPY_PAGE+4096,1,false);
+
x86_invlpg(VMEM_COPY_PAGE); // refresh TLB
- memcpy(virt,VMEM_COPY_PAGE,4096);
+ x86_invlpg(VMEM_COPY_PAGE+4096); // refresh TLB
+
+ memcpy(VMEM_COPY_PAGE+4096,VMEM_COPY_PAGE,4096);
}
- virt+=4096;
+ virt+=4096;
}
-
}
else virt+=4096*1024;
}
- x86_set_page_directory(orig);
- x86_sti();
-
return dir;
}