diff options
| author | Michal Idziorek <m.i@gmx.at> | 2014-08-29 19:56:40 +0200 |
|---|---|---|
| committer | Michal Idziorek <m.i@gmx.at> | 2014-08-29 19:56:40 +0200 |
| commit | 47d22a238a6c5d60c6abfac724e6ad91885cdd67 (patch) | |
| tree | bd3893777b58aac7c94d68fe2a4ba57cfbdb38ec /kernel/vmem.c | |
| parent | 659f1f1ae057c82a154a1fd32cc9dca040979daa (diff) | |
added paging support
Diffstat (limited to 'kernel/vmem.c')
| -rw-r--r-- | kernel/vmem.c | 146 |
1 files changed, 127 insertions, 19 deletions
diff --git a/kernel/vmem.c b/kernel/vmem.c index 9d34810..b1ecfa1 100644 --- a/kernel/vmem.c +++ b/kernel/vmem.c @@ -1,5 +1,12 @@ +// http://www.brokenthorn.com/Resources/OSDev18.html + #include "kernel.h" +#include "x86.h" +#include "../lib/logger/log.h" // logger facilities +#define FOOLOS_MODULE_NAME "vmem" + +// TODO : why is the frame not 0xfffff?? enum PAGE_PTE_FLAGS { I86_PTE_PRESENT = 1, //0000000000000000000000000000001 @@ -12,7 +19,7 @@ enum PAGE_PTE_FLAGS { I86_PTE_PAT = 0x80, //0000000000000000000000010000000 I86_PTE_CPU_GLOBAL = 0x100, //0000000000000000000000100000000 I86_PTE_LV4_GLOBAL = 0x200, //0000000000000000000001000000000 - I86_PTE_FRAME = 0x7FFFF000 //1111111111111111111000000000000 + I86_PTE_FRAME = 0xFFFFF000 //1111111111111111111000000000000 }; enum PAGE_PDE_FLAGS { @@ -27,7 +34,7 @@ enum PAGE_PDE_FLAGS { I86_PDE_4MB = 0x80, //0000000000000000000000010000000 I86_PDE_CPU_GLOBAL = 0x100, //0000000000000000000000100000000 I86_PDE_LV4_GLOBAL = 0x200, //0000000000000000000001000000000 - I86_PDE_FRAME = 0x7FFFF000 //1111111111111111111000000000000 + I86_PDE_FRAME = 0xFFFFF000 //1111111111111111111000000000000 }; //! page table entry @@ -62,53 +69,65 @@ typedef uint8_t bool; #define PAGE_SIZE 4096 //! page table -struct ptable { +typedef struct ptable_struct { pt_entry m_entries[PAGES_PER_TABLE]; -}; +}ptable ; //! page directory -struct pdirectory { +typedef struct pdirectory_struct { pd_entry m_entries[PAGES_PER_DIR]; -}; +}pdirectory; -void pt_entry_add_attrib (pt_entry* e, uint32_t attrib) +void pt_entry_add_attrib (pt_entry* e, uint32_t attrib) { + *e|=attrib; } -void pt_entry_del_attrib (pt_entry* e, uint32_t attrib) +void pt_entry_del_attrib (pt_entry* e, uint32_t attrib) { + *e&=~attrib; } -void pt_entry_set_frame (pt_entry* e , physical_addr addr) +void pt_entry_set_frame (pt_entry* e , physical_addr addr) { + // *e = (*e & ~I86_PTE_FRAME) | addr; + + *e|=I86_PTE_FRAME&addr; + } -bool pt_entry_is_present (pt_entry e) +bool pt_entry_is_present (pt_entry e) { - return 1; + return e&I86_PTE_PRESENT; } -bool pt_entry_is_writable (pt_entry e) + +bool pt_entry_is_writable (pt_entry e) { - return 1; + return e&I86_PTE_WRITABLE; } -physical_addr pt_entry_pfn (pt_entry e) + +physical_addr pt_entry_pfn (pt_entry e) { - return 1; + return e&I86_PTE_FRAME; } void pd_entry_add_attrib (pd_entry* e, uint32_t attrib) { + *e|=attrib; } void pd_entry_del_attrib (pd_entry* e, uint32_t attrib) { + *e&=~attrib; } void pd_entry_set_frame (pd_entry* e, physical_addr add) { + *e|=I86_PDE_FRAME&add; } bool pd_entry_is_present (pd_entry e) { - return 1; + return e&I86_PDE_PRESENT; } +/* bool pd_entry_is_user (pd_entry e) { return 1; @@ -118,20 +137,23 @@ bool pd_entry_is_4mb (pd_entry e) { return 1; } +*/ bool pd_entry_is_writable (pd_entry e) { - return 1; + return e&I86_PDE_WRITABLE; } physical_addr pd_entry_pfn (pd_entry e) { - return 1; + return e&I86_PDE_FRAME; } +/* void pd_entry_enable_global (pd_entry e) { } +*/ uint8_t vmmngr_alloc_page (pt_entry* e) { @@ -148,8 +170,94 @@ uint8_t vmmngr_alloc_page (pt_entry* e) return 1; } -void vmem_init() +void vmmngr_free_page (pt_entry* e) +{ + void* p = (void*)pt_entry_pfn (*e); + if (p) + pmmngr_free_block (p); + + pt_entry_del_attrib (e, I86_PTE_PRESENT); +} + +pt_entry* vmmngr_ptable_lookup_entry (ptable* p, virtual_addr addr) +{ + + if (p) + return &p->m_entries[ PAGE_TABLE_INDEX (addr) ]; + + return 0; +} + +// TODO !? http://www.brokenthorn.com/Resources/OSDev18.html +void vmmngr_map_page (void* phys, void* virt) +{ + +} + +void vmem_init(uint32_t vesa_physbase) { + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"init paging (vesa base: 0x%08x)",vesa_physbase); + + ptable* table1 = (ptable*) pmmngr_alloc_block (); + + if (!table1)panic(FOOLOS_MODULE_NAME,"unable to alloc table1"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"table1: 0x%X",table1); + + ptable* table2 = (ptable*) pmmngr_alloc_block (); + + if (!table1)panic(FOOLOS_MODULE_NAME,"unable to alloc table2"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"table2: 0x%X",table2); + + // TODO: 3blocks? + pdirectory* dir = (pdirectory*) pmmngr_alloc_block (); + if (!dir)panic(FOOLOS_MODULE_NAME,"unable to alloc pdirectory"); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"pdirectory: 0x%X",dir); + + //! map 1mb to 3gb (where we are at) + for (int i=0, frame=vesa_physbase, virt=vesa_physbase; 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_set_frame (&page, frame); + + //! ...and add it to the page table + table1->m_entries [PAGE_TABLE_INDEX (virt) ] = page; + } + + //! 1st 4mb are idenitity mapped + for (int i=0, frame=0x0, virt=0x00000000; 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_set_frame (&page, frame); + + //! ...and add it to the page table + table2->m_entries [PAGE_TABLE_INDEX (virt) ] = page; + } + + + pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (vesa_physbase) ]; + *entry=0; + pd_entry_add_attrib (entry, I86_PDE_PRESENT); + pd_entry_add_attrib (entry, I86_PDE_WRITABLE); + pd_entry_set_frame (entry, (physical_addr)table1); + + + pd_entry* entry2 = &dir->m_entries [PAGE_DIRECTORY_INDEX (0x00000000) ]; + *entry2=0; + pd_entry_add_attrib (entry2, I86_PDE_PRESENT); + pd_entry_add_attrib (entry2, I86_PDE_WRITABLE); + pd_entry_set_frame (entry2, (physical_addr)table2); + + + x86_set_pdbr(dir); + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"enabling paging..."); + x86_paging_enable(); + } |
