diff options
Diffstat (limited to 'kernel/vmem.c')
| -rw-r--r-- | kernel/vmem.c | 149 |
1 files changed, 72 insertions, 77 deletions
diff --git a/kernel/vmem.c b/kernel/vmem.c index b12b3b8..3cbda9a 100644 --- a/kernel/vmem.c +++ b/kernel/vmem.c @@ -42,8 +42,8 @@ typedef struct pdirectory_struct { }pdirectory; static uint32_t kernel_pages; -uint32_t fb_addr; // TODO!??!!? how can we share so ugly with vesa -static uint32_t apic_addr; +static uint32_t fb_addr; +static uint32_t local_apic_addr; static uint32_t io_apic_addr; // TODO : why is the frame not 0xfffff?? @@ -260,87 +260,76 @@ static pdirectory* vmem_clean_dir() return dir; } -static void vmem_add_alloc(pdirectory* dir,uint32_t start,uint32_t pages) +// 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) { - uint32_t virt_addr=start; - for(int j=0;j<2;j++) - { + fixme("make sure the pages are marked as used in the physical mem manager, really?"); - 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 + //force align + phys/=4096; + phys*=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; - } - -} - -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; + //force align + virt/=4096; + virt*=4096; while(pages>0) { - // each table in our page directory maps 1024*4096 bytes + pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt) ]; 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); + if(*entry==0){ + // no pagetable here yet. + table = (ptable*) kballoc(1); + for(int i=0;i<1024;i++)table->m_entries [i]=0; // zero all - //! ...and add it to the page table - table->m_entries [PAGE_TABLE_INDEX (virt) ] = page; - pages--; - if(pages<=0)break; + 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, table); + } + else{ + // add to existing one. + table= pd_entry_get_frame (entry); } - 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); + if(alloc) + { + phys=mem_alloc_block(); // get free space from the memory manager + klog("allocated physical at 0x%08X",phys); + } - phys_addr+=1024*4096; - virt_addr+=1024*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, phys); + + //and add it to the page table + uint32_t old=table->m_entries [PAGE_TABLE_INDEX (virt) ]; + if(old!=0&&old!=page)kpanic("overwriting existing page data!"); + table->m_entries [PAGE_TABLE_INDEX (virt) ] = page; + + virt+=4096; + phys+=4096; + + pages--; } } +static void vmem_add_alloc(pdirectory* dir,uint32_t addr,uint32_t pages) +{ + vmem_add_generic(dir,addr,addr,pages, true); +} + +static void vmem_add_remap(pdirectory* dir,uint32_t phys,uint32_t virt,uint32_t pages) +{ + vmem_add_generic(dir,phys,virt,pages, false); +} +static void vmem_add_identity(pdirectory* dir,uint32_t addr,uint32_t pages) +{ + vmem_add_generic(dir,addr,addr,pages, false); +} pdirectory* vmem_kernel_dir() { @@ -348,12 +337,18 @@ pdirectory* vmem_kernel_dir() fixme("do not waste soo many pages/page tables!"); fixme("align properly!! / merge page tables if required!"); fixme("Is ioapic/lapic really on one page?"); + fixme("kernelspace: kernel/lapic/framebuffer/ext2-ramimage"); + 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); // we do not nee this (ioapic never accessed after paging enabled) - vmem_add_alloc(dir,0x8000000,1024*4); + + vmem_add_identity(dir,0,1024*8);//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_alloc(dir,VMEM_CPU_PRIVATE,2); + return dir; } @@ -483,8 +478,8 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only) } // 2 pages for apic ( in case on boundary??) - phys_addr=apic_addr; - virt_addr=apic_addr; + phys_addr=local_apic_addr; + virt_addr=local_apic_addr; for(int j=0;j<2;j++) { @@ -720,6 +715,6 @@ void vmem_init(multiboot_information *cfg_multiboot, acpi_information *cfg_acpi) { fixme("do not share fb_addr with syscalls like that!"); fb_addr=cfg_multiboot->framebuffer_addr; - apic_addr=cfg_acpi->local_apic_address; + local_apic_addr=cfg_acpi->local_apic_address; io_apic_addr=cfg_acpi->io_apic_address; } |
