diff options
| author | Franklin Wei <frankhwei536@gmail.com> | 2015-02-28 20:42:57 -0500 |
|---|---|---|
| committer | Franklin Wei <frankhwei536@gmail.com> | 2015-02-28 20:42:57 -0500 |
| commit | 2dc45e8cac33313e847f6097cbe2ba3bb3ceab2a (patch) | |
| tree | 973fa836d725659a6f0a8edfc108dd9e037430d0 /kernel/paging.c | |
| parent | d4a70e316e0991d788fb922e3e4eafae97fe950e (diff) | |
| download | kappa-2dc45e8cac33313e847f6097cbe2ba3bb3ceab2a.zip kappa-2dc45e8cac33313e847f6097cbe2ba3bb3ceab2a.tar.gz kappa-2dc45e8cac33313e847f6097cbe2ba3bb3ceab2a.tar.bz2 kappa-2dc45e8cac33313e847f6097cbe2ba3bb3ceab2a.tar.xz | |
Implement paging
Diffstat (limited to 'kernel/paging.c')
| -rw-r--r-- | kernel/paging.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/kernel/paging.c b/kernel/paging.c new file mode 100644 index 0000000..408ced8 --- /dev/null +++ b/kernel/paging.c @@ -0,0 +1,65 @@ +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include "frame.h" +#include "heap.h" +#include "isr.h" +#include "paging.h" +#include "panic.h" + +uint32_t *current_directory; + +static void page_fault(struct regs_t *regs) +{ + volatile uint32_t fault_addr; + asm("mov %%cr2, %0" : "=r"(fault_addr)); + printf("=== Page Fault ===\n"); + printf("Faulting address: 0x%x\n", fault_addr); + /* dump the regs */ + printf("EAX: 0x%x EBX: 0x%x\n", regs->eax, regs->ebx); + printf("ECX: 0x%x EDX: 0x%x\n", regs->ecx, regs->edx); + printf("ESP: 0x%x EBP: 0x%x\n", regs->esp, regs->ebp); + printf("ESI: 0x%x EDI: 0x%x\n", regs->esi, regs->edi); + printf("EIP: 0x%x\n", regs->eip); + panic("Page fault!\n"); +} + + void paging_switch_directory(uint32_t *dir) +{ + current_directory = dir; + extern void do_paging_enable(uint32_t); + do_paging_enable((uint32_t)current_directory); +} + +static uint32_t *identity_map_table(uint32_t start, int flags) +{ + /* make a page table */ + uint32_t *table = kmalloc_a(0x1000); + /* identity map 4MB */ + for(uint32_t i = start; i < start + 1024; ++i) + { + table[i - start] = (i * PAGE_SIZE) | flags; + } + return table; +} + +void paging_init(void) +{ + uint32_t *kernel_directory = kmalloc_a(0x1000); + memset(kernel_directory, 0, 0x1000); + /* blank the kernel directory */ + for(int i = 0; i < 1024; ++i) + { + kernel_directory[i] = PAGE_RW; + } + + /* identity map all 4GB */ + for(int i=0; i < 1024; ++i) + kernel_directory[i] = (uint32_t)identity_map_table(i * 1024, PAGE_PRESENT | PAGE_RW) | + PAGE_PRESENT | PAGE_RW; + + set_interrupt_handler(14, page_fault); + + paging_switch_directory(kernel_directory); +} |