From d8331335ff1720ce28eba45afe1a02814b38b033 Mon Sep 17 00:00:00 2001 From: Michal Idziorek Date: Mon, 1 Dec 2014 21:49:22 +0100 Subject: finally implemented fork() syscall --- kernel/vmem.c | 91 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 31 deletions(-) (limited to 'kernel/vmem.c') 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(); } -- cgit v1.2.3