summaryrefslogtreecommitdiff
path: root/kernel/vmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/vmem.c')
-rw-r--r--kernel/vmem.c149
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;
}