diff options
| author | Miguel <m.i@gmx.at> | 2018-09-10 04:13:28 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-09-10 04:13:28 +0200 |
| commit | 65f5cca027af81e77b3e06da658b6d13f1861a03 (patch) | |
| tree | 4e1aa57b8d4dedb00beb649992054faf6f24ff40 /kernel/vmem.c | |
| parent | 67e7f93fc2ea9c6d04698f9af29be78d0123afb0 (diff) | |
fixing paging / per cpu pages
Diffstat (limited to 'kernel/vmem.c')
| -rw-r--r-- | kernel/vmem.c | 126 |
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); } - - |
