diff options
-rw-r--r-- | kernel/include/mm/virtual_mm.h | 17 | ||||
-rw-r--r-- | kernel/mm/virtual_mm/virtual_mm.c | 28 |
2 files changed, 37 insertions, 8 deletions
diff --git a/kernel/include/mm/virtual_mm.h b/kernel/include/mm/virtual_mm.h index 52eb92c..980e809 100644 --- a/kernel/include/mm/virtual_mm.h +++ b/kernel/include/mm/virtual_mm.h @@ -25,9 +25,6 @@ #define PAGE_DIRECTORY_SIZE 1024 #define PAGE_TABLE_SIZE 1024 -#define PAGE_DIRECTORY_INDEX(virtual_address) ((virtual_address >> 22) & 0x3ff) -#define PAGE_TABLE_INDEX(virtual_address) ((virtual_address >> 12) & 0x3ff) - #define PDE_PRESENT(x) x #define PDE_WRITABLE(x) ((x) << 1) #define PDE_USER(x) ((x) << 2) @@ -42,7 +39,9 @@ /* Page table address */ #define PDE_FRAME(x) ((x) &0xFFFFF000) -#define GET_PDE_FRAME(x) ((*x) >> 12) +#define PDE_IS_PRESENT(pd_entry) ((*pd_entry) & 1) +#define GET_PDE_FRAME(virtual_address) (((uint32_t) virtual_address) >> 22) +#define PDE_GET_TABLE(pd_entry) ((*pd_entry) & ~0xfff) #define PTE_PRESENT(x) x #define PTE_WRITABLE(x) ((x) << 1) @@ -58,8 +57,9 @@ /* Left shift by 12 because we only need the bits from the twelfth bit. */ #define PTE_FRAME(x) ((x) << 12) -#define PTE_IS_PRESENT(x) ((x) &1) -#define GET_PTE_FRAME(x) ((*x) >> 12) +#define PTE_IS_PRESENT(pt_entry) ((*pt_entry) & 1) +#define GET_PTE_FRAME(virtual_address) \ + ((((uint32_t) virtual_address) >> 12) & 0x3ff) #define ADD_ATTRIB(entry, attribute) (*entry |= (attribute)) @@ -78,4 +78,9 @@ bool virtual_mm_switch_page_directory(uint32_t *page_directory); */ void virtual_mm_initialize(void); +/* + * Map a physical address to a virtual address + */ +void virtual_mm_map_page(void *physical_address, void *virtual_address); + #endif diff --git a/kernel/mm/virtual_mm/virtual_mm.c b/kernel/mm/virtual_mm/virtual_mm.c index 9c8292e..c69d194 100644 --- a/kernel/mm/virtual_mm/virtual_mm.c +++ b/kernel/mm/virtual_mm/virtual_mm.c @@ -62,10 +62,9 @@ virtual_mm_initialize(void) uint32_t *table = physical_mm_allocate_block(); if (!table) ASSERT_NOT_REACHED(); - printk("debug", "Page table is at: 0x%x", table); for (uint32_t i = 0; i < 1024; i++) - table[i] = 0x2; + table[i] = 0; /* Identity map the first 4MiB, excluding the 4th MiB * (maps 4KiB 1024 times) */ @@ -86,3 +85,28 @@ virtual_mm_initialize(void) virtual_mm_switch_page_directory(page_directory); virtual_mm_enable_paging(); } + +void +virtual_mm_map_page(void *physical_address, void *virtual_address) +{ + uint32_t *pd_entry = ¤t_page_directory[GET_PDE_FRAME(virtual_address)]; + + uint32_t *table = 0; + /* If the pd_entry isn't present, allocate a block for it, zero the table, + * and set the pd_entry's frame to the table's address. */ + if (!PDE_IS_PRESENT(pd_entry)) { + table = physical_mm_allocate_block(); + if (!table) + ASSERT_NOT_REACHED(); + + for (uint32_t i = 0; i < 1024; i++) + table[i] = 0; + + *pd_entry = PDE_FRAME((uint32_t) table) | PDE_PRESENT(1) | PDE_WRITABLE(1); + } else + table = (uint32_t *) PDE_GET_TABLE(pd_entry); + + uint32_t *pt_entry = &table[GET_PTE_FRAME(virtual_address)]; + *pt_entry = PTE_FRAME((uint32_t) physical_address) | PTE_PRESENT(1) + | PTE_WRITABLE(1); +} |