diff --git a/memory/Makefile b/memory/Makefile index 270fd73..574a39e 100644 --- a/memory/Makefile +++ b/memory/Makefile @@ -3,14 +3,14 @@ MEM = memory.a PMM_SRC = pmm/pmm.c PMM_OBJ = pmm/pmm.o -VMM_SRC = vmm/vmm.c vmm/paging.s -VMM_OBJ = vmm/vmm.o vmm/paging.o +VMM_SRC = vmm/vmm.c vmm/paging.s vmm/pdt.c +VMM_OBJ = vmm/vmm.o vmm/paging.o vmm/pdt.o AR = ../gcc_kfs/bin/i386-elf-ar rcs CC = ../gcc_kfs/bin/i386-elf-gcc FLAGS = -ffreestanding \ -g \ - -O2 \ + -O0 \ -nostdlib all: $(MEM) diff --git a/memory/pmm/pmm.c b/memory/pmm/pmm.c index 6806ced..a8ef769 100644 --- a/memory/pmm/pmm.c +++ b/memory/pmm/pmm.c @@ -5,15 +5,15 @@ uint32_t _memory_used_blocks = 0; uint32_t _memory_max_blocks = 0; uint32_t* _memory_map = NULL; -inline void mmap_set(int bit) { +void mmap_set(int bit) { _memory_map[bit / 32] |= (1 << (bit % 32)); } -inline void mmap_unset(int bit) { +void mmap_unset(int bit) { _memory_map[bit / 32] &= ~(1 << (bit % 32)); } -inline int mmap_test(int bit) { +int mmap_test(int bit) { return _memory_map[bit / 32] & (1 << (bit % 32)); } diff --git a/memory/vmm/paging.s b/memory/vmm/paging.s index 3b591d6..b806786 100644 --- a/memory/vmm/paging.s +++ b/memory/vmm/paging.s @@ -11,7 +11,8 @@ enable_paging: ret switch_dir: - mov %eax, %cr3 + movl 4(%esp), %eax + movl %eax, %cr3 ret flush_tlb_entry: diff --git a/memory/vmm/pdt.c b/memory/vmm/pdt.c new file mode 100644 index 0000000..c8658b5 --- /dev/null +++ b/memory/vmm/pdt.c @@ -0,0 +1,57 @@ +#include "pdt.h" + +inline void pt_entry_add_attrib (pt_entry* e, uint32_t attrib) { + *e |= attrib; +} + +inline void pt_entry_del_attrib (pt_entry* e, uint32_t attrib) { + *e &= ~attrib; +} + +inline void pt_entry_set_frame (pt_entry* e, uint32_t addr) { + *e = (*e & ~I86_PTE_FRAME) | addr; +} + +inline int pt_entry_is_present (pt_entry e) { + return e & I86_PTE_PRESENT; +} + +inline int pt_entry_is_writable (pt_entry e) { + return e & I86_PTE_WRITABLE; +} + +inline uint32_t pt_entry_pfn (pt_entry e) { + return e & I86_PTE_FRAME; +} + +inline void pd_entry_add_attrib (pd_entry* e, uint32_t attrib) { + *e |= attrib; +} + +inline void pd_entry_del_attrib (pd_entry* e, uint32_t attrib) { + *e &= ~attrib; +} + +inline void pd_entry_set_frame (pd_entry* e, uint32_t addr) { + *e = (*e & ~I86_PDE_FRAME) | addr; +} + +inline int pd_entry_is_present (pd_entry e) { + return e & I86_PDE_PRESENT; +} + +inline int pd_entry_is_writable (pd_entry e) { + return e & I86_PDE_WRITABLE; +} + +inline uint32_t pd_entry_pfn (pd_entry e) { + return e & I86_PDE_FRAME; +} + +inline int pd_entry_is_user (pd_entry e) { + return e & I86_PDE_USER; +} + +inline int pd_entry_is_4mb (pd_entry e) { + return e & I86_PDE_4MB; +} diff --git a/memory/vmm/pdt.h b/memory/vmm/pdt.h index 42379d7..d236897 100644 --- a/memory/vmm/pdt.h +++ b/memory/vmm/pdt.h @@ -21,13 +21,6 @@ enum PAGE_PTE_FLAGS { typedef uint32_t pt_entry; -#define PT_ENTRY_ADD_ATTRIB(ENTRY, ATTRIB) ((ENTRY) = (uint32_t)(ENTRY) | (1 << ATTRIB)) -#define PT_ENTRY_DEL_ATTRIB(ENTRY, ATTRIB) ((ENTRY) = (uint32_t)(ENTRY) & ~(1 << ATTRIB)) -#define PT_ENTRY_SET_FRAME(ENTRY, PHYS_ADDR) ((ENTRY) = (void *)(((uint32_t)ENTRY & ~I86_PTE_FRAME) | ((uint32_t)PHYS_ADDR & I86_PTE_FRAME))) -#define PT_ENTRY_IS_PRESENT(ENTRY) ((uint32_t)(ENTRY) & I86_PTE_PRESENT) -#define PT_ENTRY_IS_WRITABLE(ENTRY) ((uint32_t)(ENTRY) & I86_PTE_WRITABLE) -#define PT_ENTRY_PFN(ENTRY) ((uint32_t)(ENTRY) & I86_PTE_FRAME) - // PAGE DIRECTORY ENTRY enum PAGE_PDE_FLAGS { @@ -46,15 +39,49 @@ enum PAGE_PDE_FLAGS { }; typedef uint32_t pd_entry; +//! sets a flag in the page table entry +extern void pd_entry_add_attrib (pd_entry* e, uint32_t attrib); + +//! clears a flag in the page table entry +extern void pd_entry_del_attrib (pd_entry* e, uint32_t attrib); + +//! sets a frame to page table entry +extern void pd_entry_set_frame (pd_entry*, uint32_t); + +//! test if page is present +extern int pd_entry_is_present (pd_entry e); + +//! test if directory is user mode +extern int pd_entry_is_user (pd_entry); + +//! test if directory contains 4mb pages +extern int pd_entry_is_4mb (pd_entry); + +//! test if page is writable +extern int pd_entry_is_writable (pd_entry e); + +//! get page table entry frame address +extern uint32_t pd_entry_pfn (pd_entry e); + +//! enable global pages +extern void pd_entry_enable_global (pd_entry e); + +//! sets a flag in the page table entry +extern void pt_entry_add_attrib (pt_entry* e, uint32_t attrib); + +//! clears a flag in the page table entry +extern void pt_entry_del_attrib (pt_entry* e, uint32_t attrib); + +//! sets a frame to page table entry +extern void pt_entry_set_frame (pt_entry*, uint32_t); + +//! test if page is present +extern int pt_entry_is_present (pt_entry e); + +//! test if page is writable +extern int pt_entry_is_writable (pt_entry e); -#define PD_ENTRY_ADD_ATTRIB(ENTRY, ATTRIB) ((ENTRY) = (uint32_t)(ENTRY) | (1 << ATTRIB)) -#define PD_ENTRY_DEL_ATTRIB(ENTRY, ATTRIB) ((ENTRY) = (uint32_t)(ENTRY) & ~(1 << ATTRIB)) -#define PD_ENTRY_SET_FRAME(ENTRY, PHYS_ADDR) ((ENTRY) = (void*)(((uint32_t)ENTRY & ~I86_PDE_FRAME) | ((uint32_t)PHYS_ADDR & I86_PDE_FRAME))) -#define PD_ENTRY_IS_PRESENT(ENTRY) ((uint32_t)(ENTRY) & I86_PDE_PRESENT) -#define PD_ENTRY_IS_USER(ENTRY) ((uint32_t)(ENTRY) & I86_PDE_USER) -#define PD_ENTRY_IS_4MB(ENTRY) ((uint32_t)(ENTRY) & I86_PDE_4MB) -#define PD_ENTRY_IS_WRITABLE(ENTRY) ((uint32_t)(ENTRY) & I86_PDE_WRITABLE) -#define PD_ENTRY_PFN(ENTRY) ((uint32_t)(ENTRY) & I86_PDE_FRAME) -#define PD_ENTRY_ENABLE_GLOBAL(ENTRY) ((ENTRY) = (uint32_t)(ENTRY) | I86_PDE_CPU_GLOBAL) +//! get page table entry frame address +extern uint32_t pt_entry_pfn (pt_entry e); #endif diff --git a/memory/vmm/vmm.c b/memory/vmm/vmm.c index 4e14ca7..b2a0c20 100644 --- a/memory/vmm/vmm.c +++ b/memory/vmm/vmm.c @@ -9,38 +9,31 @@ extern void flush_tlb_entry(uint32_t addr); int vmm_alloc_page(pt_entry* entry) { void* p = pmm_alloc_block(); if (!p) return 0; - PT_ENTRY_SET_FRAME(entry, p); - PT_ENTRY_ADD_ATTRIB(entry, I86_PTE_PRESENT); + pt_entry_set_frame(entry, (uint32_t)p); + pt_entry_add_attrib(entry, I86_PTE_PRESENT); return 1; } void vmm_free_page(pt_entry* entry) { - void* p = (void*)PT_ENTRY_PFN(entry); + void* p = (void*)pt_entry_pfn(entry); if (p) pmm_free_block(p); - PT_ENTRY_ADD_ATTRIB(entry, I86_PTE_PRESENT); + pt_entry_add_attrib(entry, I86_PTE_PRESENT); } -inline pt_entry* vmm_ptable_lookup_entry(p_table* p, uint32_t addr) { +pt_entry* vmm_ptable_lookup_entry(p_table* p, uint32_t addr) { if (p) return &p->m_entries[PAGE_TAB_INDEX(addr)]; return 0; } -inline pd_entry* vmm_pdir_lookup_entry(p_dir* p, uint32_t addr) { +pd_entry* vmm_pdir_lookup_entry(p_dir* p, uint32_t addr) { if (p) return &p->m_entries[PAGE_TAB_INDEX(addr)]; return 0; } -inline int vmm_switch_pdir(p_dir* dir) { +int vmm_switch_pdir(p_dir* dir) { if (!dir) return 0; _current_dir = dir; - asm volatile ( - "mov %0, %%cr3\n" - : - : "r" (_cur_pdbr) - : "memory" - ); - //switch_dir(_cur_pdbr); - return 1; + switch_dir(_cur_pdbr); } p_dir* vmm_get_dir() { return _current_dir; } @@ -53,14 +46,14 @@ void vmm_map_page(void* phys, void* virt) { if (!table) return; memset(table, 0, sizeof(p_table)); pd_entry* entry = &page_dir->m_entries[PAGE_DIR_INDEX((uint32_t)virt)]; - PD_ENTRY_ADD_ATTRIB(entry, I86_PDE_PRESENT); - PD_ENTRY_ADD_ATTRIB(entry, I86_PDE_WRITABLE); - PD_ENTRY_SET_FRAME(entry, (uint32_t)table); + pd_entry_add_attrib(entry, I86_PDE_PRESENT); + pd_entry_add_attrib(entry, I86_PDE_WRITABLE); + pd_entry_set_frame(entry, (uint32_t)table); } p_table* table = (p_table*)PAGE_PHYS_ADDR(e); pt_entry* page = &table->m_entries[PAGE_TAB_INDEX((uint32_t)virt)]; - PT_ENTRY_SET_FRAME(page, (uint32_t)phys); - PT_ENTRY_ADD_ATTRIB(page, I86_PTE_PRESENT); + pt_entry_set_frame(page, (uint32_t)phys); + pt_entry_add_attrib(page, I86_PTE_PRESENT); } void vmm_init() { @@ -68,27 +61,28 @@ void vmm_init() { if (!table) return; p_table* table2 = (p_table*)pmm_alloc_block(); if (!table2) return; - memset(table, 0, sizeof(p_table)); + memset(table, 0, sizeof(p_table)); + memset(table2, 0, sizeof(p_table)); //! 1st 4mb are idenitity mapped - for (int i=0, frame=0x0, virt=0x00000000; i<1024; i++, frame+=4096, virt+=4096) { + for (int i=0, frame=0x0, virt=0x00000000; im_entries [PAGE_TAB_INDEX(virt) ] = page; } //! map 1mb to 3gb (where we are at) - for (int i=0, frame=0x100000, virt=0xc0000000; i<1024; i++, frame+=4096, virt+=4096) { + for (int i=0, frame=0x100000, virt=0xc0000000; im_entries [PAGE_TAB_INDEX (virt) ] = page; @@ -100,18 +94,18 @@ void vmm_init() { //! clear directory table and set it as current memset (dir, 0, sizeof (p_dir)); pd_entry* entry = &dir->m_entries [PAGE_DIR_INDEX (0xc0000000) ]; - PD_ENTRY_ADD_ATTRIB (entry, I86_PDE_PRESENT); - PD_ENTRY_ADD_ATTRIB (entry, I86_PDE_WRITABLE); - PD_ENTRY_SET_FRAME (entry, table); + pd_entry_add_attrib (entry, I86_PDE_PRESENT); + pd_entry_add_attrib (entry, I86_PDE_WRITABLE); + pd_entry_set_frame (entry, (uint32_t)table); pd_entry* entry2 = &dir->m_entries [PAGE_DIR_INDEX (0x00000000) ]; - PD_ENTRY_ADD_ATTRIB (entry2, I86_PDE_PRESENT); - PD_ENTRY_ADD_ATTRIB (entry2, I86_PDE_WRITABLE); - PD_ENTRY_SET_FRAME (entry2, table2); + pd_entry_add_attrib (entry2, I86_PDE_PRESENT); + pd_entry_add_attrib (entry2, I86_PDE_WRITABLE); + pd_entry_set_frame (entry2, (uint32_t)table2); //! store current PDBR _cur_pdbr = (uint32_t) &dir->m_entries; //! switch to our page directory vmm_switch_pdir(dir); - enable_paging(); + //enable_paging(); } diff --git a/memory/vmm/vmm.h b/memory/vmm/vmm.h index a48f8a4..2e1be37 100644 --- a/memory/vmm/vmm.h +++ b/memory/vmm/vmm.h @@ -7,14 +7,14 @@ #define PAGES_PER_TABLE 1024 #define PAGES_PER_DIR 1024 -#define PAGE_DIR_INDEX(ADDR) ((ADDR) >> 22) & 0x3FF -#define PAGE_TAB_INDEX(ADDR) ((ADDR) >> 12) & 0x3FF +#define PAGE_DIR_INDEX(ADDR) (((ADDR) >> 22) & 0x3FF) +#define PAGE_TAB_INDEX(ADDR) (((ADDR) >> 12) & 0x3FF) #define PAGE_PHYS_ADDR(ADDR) ((*ADDR) & ~0xFFF) #define PTABLE_ADDR_SPACE_SIZE 0x400000 // 4MB #define DTABLE_ADDR_SPACE_SIZE 0x100000000 // 4GB -#define PAGE_SIZE 0x1000 +#define PAGE_SIZE 0x1000 // 4KB typedef struct { pt_entry m_entries[PAGES_PER_TABLE];