summaryrefslogtreecommitdiff
path: root/kernel/vmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/vmem.c')
-rw-r--r--kernel/vmem.c91
1 files changed, 60 insertions, 31 deletions
diff --git a/kernel/vmem.c b/kernel/vmem.c
index 53e33c4..0a9e4b1 100644
--- a/kernel/vmem.c
+++ b/kernel/vmem.c
@@ -85,7 +85,7 @@ typedef struct pdirectory_struct {
#define MAX_PAGEDIRS 10
pdirectory *page_dirs[MAX_PAGEDIRS];
-int last_page_dir=0;
+int next_page_dir=0;
int current_dir=0;
////
@@ -107,8 +107,6 @@ void pt_entry_set_frame (pt_entry* e , physical_addr addr)
}
physical_addr pt_entry_get_frame (pt_entry* e)
{
- // *e = (*e & ~I86_PTE_FRAME) | addr;
-
return *e&I86_PTE_FRAME;
}
@@ -140,6 +138,12 @@ void pd_entry_set_frame (pd_entry* e, physical_addr add)
{
*e|=I86_PDE_FRAME&add;
}
+physical_addr pd_entry_get_frame (pd_entry* e)
+{
+ return *e&I86_PDE_FRAME;
+
+}
+
bool pd_entry_is_present (pd_entry e)
{
return e&I86_PDE_PRESENT;
@@ -249,7 +253,8 @@ uint32_t vmem_alloc_block_at(uint32_t virt_addr)
}
*/
-int vmem_new_space_dir()
+// vmem init and also copies all the shit for FORK
+volatile int vmem_new_space_dir()
{
x86_paging_disable();
@@ -266,41 +271,58 @@ int vmem_new_space_dir()
for(int j=0;j<3;j++)
{
- ptable* table = (ptable*) pmmngr_alloc_block ();
- if (!table)panic(FOOLOS_MODULE_NAME,"unable to alloc table");
-// log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"table: 0x%X",table);
-
+ // this is the table for our page directory. It maps 1024*4096 bytes
+ ptable* table;
- //! idenitity mapping
- for (int i=0, frame=phys_addr, virt=virt_addr; i<1024; i++, frame+=4096, virt+=4096)
+ // create new tables on init
+ if(next_page_dir==0)
{
- //! create a new page
- pt_entry page=0;
- pt_entry_add_attrib (&page, I86_PTE_PRESENT);
- pt_entry_add_attrib (&page, I86_PTE_WRITABLE);
- pt_entry_set_frame (&page, frame);
+ // alloc space for our new table
+ table = (ptable*) pmmngr_alloc_block ();
+ if (!table)panic(FOOLOS_MODULE_NAME,"unable to alloc table");
+
+ //! idenitity mapping
+ for (int i=0, frame=phys_addr, virt=virt_addr; i<1024; i++, frame+=4096, virt+=4096)
+ {
+ //! create a new page
+ pt_entry page=0;
+ pt_entry_add_attrib (&page, I86_PTE_PRESENT);
+ pt_entry_add_attrib (&page, I86_PTE_WRITABLE);
+ pt_entry_set_frame (&page, frame);
+
+ //! ...and add it to the page table
+ table->m_entries [PAGE_TABLE_INDEX (virt) ] = page;
+ }
+
+ pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt_addr) ];
+ *entry=0;
+ pd_entry_add_attrib (entry, I86_PDE_PRESENT);
+ pd_entry_add_attrib (entry, I86_PDE_WRITABLE);
+ pd_entry_set_frame (entry, (physical_addr)table);
+
+ }
+ // otherwise simply take existing stuff from pdir 0
+ else
+ {
+ dir->m_entries[PAGE_DIRECTORY_INDEX(virt_addr)]=
+ page_dirs[0]->m_entries[PAGE_DIRECTORY_INDEX(virt_addr)];
- //! ...and add it to the page table
- table->m_entries [PAGE_TABLE_INDEX (virt) ] = page;
}
-
- pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt_addr) ];
- *entry=0;
- pd_entry_add_attrib (entry, I86_PDE_PRESENT);
- pd_entry_add_attrib (entry, I86_PDE_WRITABLE);
- pd_entry_set_frame (entry, (physical_addr)table);
phys_addr+=1024*4096;
virt_addr+=1024*4096;
-
}
- // programm space (for init)
+ // programm space
virt_addr=0x8048000;
for(int j=0;j<2;j++)
{
ptable* table = (ptable*) pmmngr_alloc_block ();
+ pd_entry *oldentry= &(page_dirs[0]->m_entries[PAGE_DIRECTORY_INDEX(virt_addr)]);
+ ptable* oldtable=pd_entry_get_frame(oldentry);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"oldtable at: 0x%08X",oldtable);
+
if (!table)panic(FOOLOS_MODULE_NAME,"unable to alloc table");
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"alloc table: %08X",table);
@@ -309,6 +331,16 @@ int vmem_new_space_dir()
phys_addr=pmmngr_alloc_block(); // get free space from the memory manager
if (!phys_addr)panic(FOOLOS_MODULE_NAME,"unable to alloc spce for frame");
+ // if this is not init , copy contents from current space!
+ if(next_page_dir!=0)
+ {
+ uint32_t addr_old=pt_entry_get_frame(&oldtable->m_entries[PAGE_TABLE_INDEX(virt)]);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"physical memcpy(0x%08X,0x%08X,4096)",phys_addr, addr_old);
+ memcpy(phys_addr,addr_old,4096);
+
+ }
+
+
int frame=phys_addr;
//! create a new page
@@ -331,19 +363,16 @@ int vmem_new_space_dir()
}
- page_dirs[last_page_dir]=dir;
- if(last_page_dir!=0)x86_paging_enable();
- return last_page_dir++;
+ page_dirs[next_page_dir]=dir;
+ if(next_page_dir!=0)x86_paging_enable();
+ return next_page_dir++;
}
void vmem_set_dir(int dir)
{
-// x86_paging_disable();
x86_set_pdbr(page_dirs[dir]);
- // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"set pagedir to %d (0x%08X)",dir,page_dirs[dir]);
current_dir=dir;
-// x86_paging_enable();
}