summaryrefslogtreecommitdiff
path: root/kernel/vmem.c
diff options
context:
space:
mode:
authorMiguel <m.i@gmx.at>2018-09-10 04:13:28 +0200
committerMiguel <m.i@gmx.at>2018-09-10 04:13:28 +0200
commit65f5cca027af81e77b3e06da658b6d13f1861a03 (patch)
tree4e1aa57b8d4dedb00beb649992054faf6f24ff40 /kernel/vmem.c
parent67e7f93fc2ea9c6d04698f9af29be78d0123afb0 (diff)
fixing paging / per cpu pages
Diffstat (limited to 'kernel/vmem.c')
-rw-r--r--kernel/vmem.c126
1 files changed, 109 insertions, 17 deletions
diff --git a/kernel/vmem.c b/kernel/vmem.c
index ff464ea..04f0354 100644
--- a/kernel/vmem.c
+++ b/kernel/vmem.c
@@ -40,6 +40,7 @@ typedef struct ptable_struct {
typedef struct pdirectory_struct {
pd_entry m_entries[PAGES_PER_DIR];
}pdirectory;
+
static uint32_t kernel_pages;
uint32_t fb_addr; // TODO!??!!? how can we share so ugly with vesa
static uint32_t apic_addr;
@@ -197,7 +198,7 @@ static pt_entry* vmmngr_ptable_lookup_entry (ptable* p, virtual_addr addr)
/// SHIT BELOW THIs LINE
void vmem_free_dir(pdirectory *dir)
{
- x86_paging_disable();
+ x86_paging_disable(); //TODO : do not disable this!
uint32_t virt_addr=0;
@@ -250,7 +251,110 @@ void vmem_free_dir(pdirectory *dir)
x86_paging_enable();
}
+static pdirectory* vmem_clean_dir()
+{
+ fixme("replace ALLL kballoc with getting the pages from mem/vmem");
+ pdirectory* dir = (pdirectory*) kballoc(1);
+ for(int i=0;i<1024;i++)dir->m_entries [i]=0; // zero all
+ klog("fresh page directory: 0x%X",dir);
+ return dir;
+}
+
+static void vmem_add_alloc(pdirectory* dir,uint32_t start,uint32_t pages)
+{
+ uint32_t virt_addr=start;
+ for(int j=0;j<2;j++)
+ {
+
+ ptable* table = (ptable*) kballoc (1);
+ pd_entry *oldentry=NULL;
+ ptable* oldtable=NULL;
+
+ for (int i=0, virt=virt_addr; i<1024; i++, virt+=4096)
+ {
+ //klog("i = %d",i);
+ uint32_t phys_addr=mem_alloc_block(); // get free space from the memory manager
+
+ 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;
+ }
+
+}
+
+static void vmem_add_identity(pdirectory* dir,uint32_t start,uint32_t pages)
+{
+ fixme("make sure the pages are marked as used in the physical mem manager");
+
+ uint32_t phys_addr=start;
+ uint32_t virt_addr=start;
+
+ while(pages>0)
+ {
+ // each table in our page directory maps 1024*4096 bytes
+ ptable* table;
+ table = (ptable*) kballoc(1);
+ for(int i=0;i<1024;i++)table->m_entries [i]=0; // zero all
+
+ //! 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;
+ pages--;
+ if(pages<=0)break;
+ }
+
+ 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_add_attrib (entry, I86_PDE_USER);
+ pd_entry_set_frame (entry, (physical_addr)table);
+
+ phys_addr+=1024*4096;
+ virt_addr+=1024*4096;
+ }
+}
+pdirectory* vmem_kernel_dir()
+{
+ fixme("remove user flags where appropriate");
+ fixme("do not waste soo many pages/page tables!");
+ fixme("align properly!! / merge page tables if required!");
+ pdirectory* dir = vmem_clean_dir();
+ vmem_add_identity(dir,0,1024*8);//first 32 megs
+ if(fb_addr>0x100000)vmem_add_identity(dir,fb_addr,1024*4);//16megs (?) TODO: dynamic
+ vmem_add_identity(dir,apic_addr,1024*2);
+ vmem_add_identity(dir,io_apic_addr,1024*2);
+ vmem_add_alloc(dir,0x8000000,1024*4);
+ return dir;
+}
//
// vmem init / also copies all the shit over for FORK
@@ -266,22 +370,14 @@ void vmem_free_dir(pdirectory *dir)
pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only)
{
- x86_paging_disable();
-
- //
- pdirectory* dir = (pdirectory*) kballoc(1);
-
- klog("new pdirectory: 0x%X",dir);
- if (!dir)kpanic("unable to alloc pdirectory");
+ x86_paging_disable(); //TODO: do not disable
- // first of all let's zero all the entries
- for(int i=0;i<1024;i++)dir->m_entries [i]=0;
+ pdirectory* dir = vmem_clean_dir();
// identity mapping for first blocks
uint32_t phys_addr=0;
uint32_t virt_addr=0;
-
- kernel_pages=8;
+ kernel_pages=8; //32megs
// first pages are identity mapped
for(int j=0;j<kernel_pages;j++)
@@ -619,14 +715,10 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only)
return dir;
}
-pdirectory* vmem_init(uint32_t kernel_blocks, uint32_t frameb_addr, uint32_t apic_ad, uint32_t ioapic_ad)
+void vmem_init(uint32_t kernel_blocks, uint32_t frameb_addr, uint32_t apic_ad, uint32_t ioapic_ad)
{
fixme("do not share fb_addr with syscalls like that!");
fb_addr=frameb_addr;
apic_addr=apic_ad;
io_apic_addr=ioapic_ad;
- kernel_pages=kernel_blocks/1024+1;
- return vmem_new_space_dir(NULL,false);
}
-
-