summaryrefslogtreecommitdiff
path: root/kernel/vmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/vmem.c')
-rw-r--r--kernel/vmem.c478
1 files changed, 36 insertions, 442 deletions
diff --git a/kernel/vmem.c b/kernel/vmem.c
index c004f9e..3752725 100644
--- a/kernel/vmem.c
+++ b/kernel/vmem.c
@@ -143,17 +143,10 @@ static bool pd_entry_is_present (pd_entry e)
return e&I86_PDE_PRESENT;
}
-/*
-bool pd_entry_is_user (pd_entry e)
-{
- return 1;
-}
-
-bool pd_entry_is_4mb (pd_entry e)
+bool pt_entry_is_user (pt_entry e)
{
- return 1;
+ return e&I86_PTE_USER;
}
-*/
static bool pd_entry_is_writable (pd_entry e)
{
@@ -208,7 +201,7 @@ static pdirectory* vmem_clean_dir()
}
// addresses need to be page aligned. (or will be forced down)
-static void vmem_add_generic(pdirectory* dir,uint32_t phys,uint32_t virt,uint32_t pages, bool alloc)
+static void vmem_add_generic(pdirectory* dir,uint32_t phys,uint32_t virt,uint32_t pages, bool alloc, bool user)
{
fixme("make sure the pages are marked as used in the physical mem manager, really?");
@@ -232,7 +225,7 @@ static void vmem_add_generic(pdirectory* dir,uint32_t phys,uint32_t virt,uint32_
pd_entry_add_attrib (entry, I86_PDE_PRESENT);
pd_entry_add_attrib (entry, I86_PDE_WRITABLE);
- pd_entry_add_attrib (entry, I86_PDE_USER);
+ if(user)pd_entry_add_attrib (entry, I86_PDE_USER);
pd_entry_set_frame (entry, table);
}
else{
@@ -250,7 +243,7 @@ static void vmem_add_generic(pdirectory* dir,uint32_t phys,uint32_t virt,uint32_
pt_entry page=0;
pt_entry_add_attrib (&page, I86_PTE_PRESENT);
pt_entry_add_attrib (&page, I86_PTE_WRITABLE);
- pt_entry_add_attrib (&page, I86_PTE_USER);
+ if(user)pt_entry_add_attrib (&page, I86_PTE_USER);
pt_entry_set_frame (&page, phys);
//and add it to the page table
@@ -264,18 +257,18 @@ static void vmem_add_generic(pdirectory* dir,uint32_t phys,uint32_t virt,uint32_
pages--;
}
}
-static void vmem_add_alloc(pdirectory* dir,uint32_t addr,uint32_t pages)
+static void vmem_add_alloc(pdirectory* dir,uint32_t addr,uint32_t pages,bool user)
{
- vmem_add_generic(dir,addr,addr,pages, true);
+ vmem_add_generic(dir,addr,addr,pages, true,user);
}
-static void vmem_add_remap(pdirectory* dir,uint32_t phys,uint32_t virt,uint32_t pages)
+static void vmem_add_remap(pdirectory* dir,uint32_t phys,uint32_t virt,uint32_t pages,bool user)
{
- vmem_add_generic(dir,phys,virt,pages, false);
+ vmem_add_generic(dir,phys,virt,pages, false,user);
}
-static void vmem_add_identity(pdirectory* dir,uint32_t addr,uint32_t pages)
+static void vmem_add_identity(pdirectory* dir,uint32_t addr,uint32_t pages, bool user)
{
- vmem_add_generic(dir,addr,addr,pages, false);
+ vmem_add_generic(dir,addr,addr,pages, false,user);
}
pdirectory* vmem_kernel_dir()
@@ -289,18 +282,34 @@ pdirectory* vmem_kernel_dir()
pdirectory* dir = vmem_clean_dir();
- vmem_add_identity(dir,0,1024*8);//identity map first 32 megs...
+ vmem_add_identity(dir,0,1024*8,false);//identity map first 32 megs...
- vmem_add_remap(dir,fb_addr,VMEM_FRAMEBUFFER,1024*8);//32megs should be enough for 4k (think about pitch)
- vmem_add_remap(dir,local_apic_addr,VMEM_LAPIC,1); //apic addr should be at pagestart, right? TODO: check.
- vmem_add_remap(dir,io_apic_addr,VMEM_IOAPIC,1);
- vmem_add_remap(dir,mod_start,VMEM_EXT2_RAMIMAGE,1024*8);//32megs for ramimage: TODO: check if enough?
+ vmem_add_remap(dir,fb_addr,VMEM_FRAMEBUFFER,1024*8,false);//32megs should be enough for 4k (think about pitch)
+ vmem_add_remap(dir,local_apic_addr,VMEM_LAPIC,1,false); //apic addr should be at pagestart, right? TODO: check.
+ vmem_add_remap(dir,io_apic_addr,VMEM_IOAPIC,1,false);
+ vmem_add_remap(dir,mod_start,VMEM_EXT2_RAMIMAGE,1024*8,false);//32megs for ramimage: TODO: check if enough?
- vmem_add_alloc(dir,VMEM_CPU_PRIVATE,4);
- vmem_add_alloc(dir,VMEM_CPU_STACK_TOP-4096*4,4);
+ vmem_add_alloc(dir,VMEM_CPU_PRIVATE,4,false);
+ vmem_add_alloc(dir,VMEM_CPU_STACK_TOP-4096*4,4,false);
- vmem_add_alloc(dir,VMEM_USER_PROG,1024*2);
- vmem_add_alloc(dir,VMEM_USER_STACK_TOP-4096*4,4);
+ vmem_add_alloc(dir,VMEM_USER_PROG,1024*2,true);
+ vmem_add_alloc(dir,VMEM_USER_STACK_TOP-4096*4,4,true);
+
+ return dir;
+}
+
+pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only)
+{
+ pdirectory* dir = vmem_clean_dir();
+ //copy non-user pages.
+ for(int i=0;i<1024;i++)
+ {
+ uint32_t src_pt=copy_dir->m_entries [i];
+ if(!pt_entry_is_user(src_pt))dir->m_entries [i]=src_pt;
+ }
+
+ vmem_add_alloc(dir,VMEM_USER_PROG,1024*2,true);
+ vmem_add_alloc(dir,VMEM_USER_STACK_TOP-4096*4,4,true);
return dir;
}
@@ -317,418 +326,3 @@ void vmem_init(multiboot_information *cfg_multiboot, acpi_information *cfg_acpi)
}
-///////////////////////////////////////////////////////////////////////
-
-/// SHIT BELOW THIs LINE
-void vmem_free_dir(pdirectory *dir)
-{
- x86_paging_disable(); //TODO : do not disable this!
-
- uint32_t virt_addr=0;
-
- // first pages are identity mapped (kernel space) just remove links
- for(int j=0;j<3;j++)
- {
- pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt_addr) ];
- virt_addr+=1024*4096;
- }
-
- // programm space
- virt_addr=0x8000000;
- for(int j=0;j<2;j++)
- {
-
- pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt_addr) ];
- ptable *table=pd_entry_get_frame(entry);
-
- for (int i=0, virt=virt_addr; i<1024; i++, virt+=4096)
- {
- pt_entry pte=&table->m_entries [PAGE_TABLE_INDEX (virt) ];
- mem_free_block(pt_entry_get_frame(pte)); // get free space from the memory manager
- }
-
- mem_free_block(pd_entry_get_frame (entry));
- virt_addr+=1024*4096;
-
- }
-
- // stack
- virt_addr=0x8c00000;
- for(int j=0;j<1;j++)
- {
-
- pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt_addr) ];
- ptable *table=pd_entry_get_frame(entry);
-
- for (int i=0, virt=virt_addr; i<1024; i++, virt+=4096)
- {
- pt_entry pte=&table->m_entries [PAGE_TABLE_INDEX (virt) ];
- mem_free_block(pt_entry_get_frame(pte)); // get free space from the memory manager
- }
-
- mem_free_block(pd_entry_get_frame (entry));
- virt_addr+=1024*4096;
-
- }
- mem_free_block(dir);
-
- x86_paging_enable();
-}
-//
-// vmem init / also copies all the shit over for FORK
-// if copy_dir==NULL creates brandnew dir
-// otherwise copies kernel pages and copies
-// programm pages procreates new programmspace
-//
-// TODO: FIX
-// KERNEL SPACE `kernel_pages` first 8 PAGES = 32megs
-// FRAMEBUFER WE GET ON INIT
-// PROGRAMM SPACE HARDCODED TO 0x8000000+2 pages and 0x8c00000+1 pages
-//
-
-pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only)
-{
- x86_paging_disable(); //TODO: do not disable
-
- pdirectory* dir = vmem_clean_dir();
-
- // identity mapping for first blocks
- uint32_t phys_addr=0;
- uint32_t virt_addr=0;
- kernel_pages=8; //32megs
-
- // first pages are identity mapped
- for(int j=0;j<kernel_pages;j++)
- {
-
- // this is the table for our page directory. It maps 1024*4096 bytes
- ptable* table;
-
- // create new tables on init
- if(copy_dir==NULL)
- {
- // alloc space for our new table
- table = (ptable*) kballoc(1);
- if (!table)kpanic("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_add_attrib (&page, I86_PTE_USER);
- 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);
- pt_entry_add_attrib (entry, I86_PTE_USER);
- 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)]=
- copy_dir->m_entries[PAGE_DIRECTORY_INDEX(virt_addr)];
-
- }
-
- phys_addr+=1024*4096;
- virt_addr+=1024*4096;
- }
-
- // FRAMEBUFFER IDENTITY MAP (4pages enought? )
- phys_addr=fb_addr;
- virt_addr=fb_addr;
-
- if(fb_addr>0x100000)
- for(int j=0;j<4;j++)
- {
-
- // this is the table for our page directory. It maps 1024*4096 bytes
- ptable* table;
-
- // create new tables on init
- if(copy_dir==NULL)
- {
- // alloc space for our new table
- table = (ptable*) kballoc(1);
- if (!table)kpanic("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_add_attrib (&page, I86_PTE_USER);
- 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);
- pt_entry_add_attrib (entry, I86_PTE_USER);
- 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)]=
- copy_dir->m_entries[PAGE_DIRECTORY_INDEX(virt_addr)];
-
- }
-
- phys_addr+=1024*4096;
- virt_addr+=1024*4096;
- }
-
- // 2 pages for apic ( in case on boundary??)
- phys_addr=local_apic_addr;
- virt_addr=local_apic_addr;
-
- for(int j=0;j<2;j++)
- {
-
- // this is the table for our page directory. It maps 1024*4096 bytes
- ptable* table;
-
- // create new tables on init
- if(copy_dir==NULL)
- {
- // alloc space for our new table
- table = (ptable*) kballoc(1);
- if (!table)kpanic("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_add_attrib (&page, I86_PTE_USER);
- 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);
- pt_entry_add_attrib (entry, I86_PTE_USER);
- 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)]=
- copy_dir->m_entries[PAGE_DIRECTORY_INDEX(virt_addr)];
-
- }
-
- phys_addr+=1024*4096;
- virt_addr+=1024*4096;
- }
- // 2 pages for ioapic ( in case on boundary??)
- phys_addr=io_apic_addr;
- virt_addr=io_apic_addr;
-
- for(int j=0;j<2;j++)
- {
-
- // this is the table for our page directory. It maps 1024*4096 bytes
- ptable* table;
-
- // create new tables on init
- if(copy_dir==NULL)
- {
- // alloc space for our new table
- table = (ptable*) kballoc(1);
- if (!table)kpanic("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_add_attrib (&page, I86_PTE_USER);
- 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);
- pt_entry_add_attrib (entry, I86_PTE_USER);
- 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)]=
- copy_dir->m_entries[PAGE_DIRECTORY_INDEX(virt_addr)];
-
- }
-
- phys_addr+=1024*4096;
- virt_addr+=1024*4096;
- }
- // programm space
- virt_addr=0x8000000;
- for(int j=0;j<2;j++)
- {
- if(stack_only)
- {
- dir->m_entries[PAGE_DIRECTORY_INDEX(virt_addr)]=
- copy_dir->m_entries[PAGE_DIRECTORY_INDEX(virt_addr)];
- virt_addr+=1024*4096;
- continue;
- }
-
- ptable* table = (ptable*) kballoc (1);
- pd_entry *oldentry=NULL;
- ptable* oldtable=NULL;
-
- if(copy_dir!=NULL)
- {
- oldentry=&(copy_dir->m_entries[PAGE_DIRECTORY_INDEX(virt_addr)]);
- oldtable=pd_entry_get_frame(oldentry);
- }
-
- klog("oldtable at: 0x%08X",oldtable);
-
- if (!table)kpanic("unable to alloc table");
- klog("alloc table: %08X",table);
-
- for (int i=0, virt=virt_addr; i<1024; i++, virt+=4096)
- {
- //klog("i = %d",i);
- phys_addr=mem_alloc_block(); // get free space from the memory manager
- if (!phys_addr)kpanic("unable to alloc spce for frame");
-
- // if this is not init , copy contents from current space!
- if(copy_dir!=NULL)
- {
- uint32_t addr_old=pt_entry_get_frame(&oldtable->m_entries[PAGE_TABLE_INDEX(virt)]);
- //klog("physical memcpy(0x%08X,0x%08X,4096)",phys_addr, addr_old);
- memcpy(phys_addr,addr_old,4096);
-
- }
-
- uint32_t frame=phys_addr;
-
- //! 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_add_attrib (&page, I86_PTE_USER);
- 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);
- pt_entry_add_attrib (entry, I86_PTE_USER);
- pd_entry_set_frame (entry, (physical_addr)table);
-
- virt_addr+=1024*4096;
- }
-
- // programm space : stack?
- virt_addr=0x8c00000;
- for(int j=0;j<1;j++)
- {
-
- ptable* table = (ptable*) kballoc (1);
- pd_entry *oldentry=NULL;
- ptable* oldtable=NULL;
-
- if(copy_dir!=NULL)
- {
- oldentry=&(copy_dir->m_entries[PAGE_DIRECTORY_INDEX(virt_addr)]);
- oldtable=pd_entry_get_frame(oldentry);
- }
- klog("oldtable at: 0x%08X",oldtable);
-
- if (!table)kpanic("unable to alloc table");
- klog("alloc table: %08X",table);
-
- for (int i=0, virt=virt_addr; i<1024; i++, virt+=4096)
- {
- phys_addr=mem_alloc_block(); // get free space from the memory manager
- if (!phys_addr)kpanic("unable to alloc spce for frame");
-
- // if this is not init , copy contents from current space!
- if(copy_dir!=NULL)
- {
- uint32_t addr_old=pt_entry_get_frame(&oldtable->m_entries[PAGE_TABLE_INDEX(virt)]);
- //klog("physical memcpy(0x%08X,0x%08X,4096)",phys_addr, addr_old);
- memcpy(phys_addr,addr_old,4096);
-
- }
-
- uint32_t frame=phys_addr;
-
- //! 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_add_attrib (&page, I86_PTE_USER);
- 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);
- pt_entry_add_attrib (entry, I86_PTE_USER);
- pd_entry_set_frame (entry, (physical_addr)table);
-
- virt_addr+=1024*4096;
-
- }
-
- if(copy_dir==NULL) // this happens only on init
- {
- klog("initializing virtual memory (paging)");
- x86_set_page_directory(dir);
- }
-
- x86_paging_enable();
- return dir;
-}