summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/i386/include/kernel/asm.h12
-rw-r--r--arch/i386/include/kernel/paging.h14
-rw-r--r--arch/i386/include/kernel/vmem.h17
-rw-r--r--arch/i386/kernel/paging.c122
4 files changed, 88 insertions, 77 deletions
diff --git a/arch/i386/include/kernel/asm.h b/arch/i386/include/kernel/asm.h
index a002a44..d692917 100644
--- a/arch/i386/include/kernel/asm.h
+++ b/arch/i386/include/kernel/asm.h
@@ -4,13 +4,6 @@
#include <kernel/gdt.h>
#include <stdint.h>
-extern uintptr_t _kernel_start;
-extern uintptr_t _kernel_end;
-#define KSTART ((uintptr_t)&_kernel_start)
-#define KEND ((uintptr_t)&_kernel_end - 0xC0000000)
-
-#define PAGE_SIZE 4096
-
#define PCI_CONFIG_ADDR 0xCF8
#define PCI_CONFIG_DATA 0xCFC
@@ -108,7 +101,6 @@ void aquire_lock(int *lock);
void release_lock(int *lock);
void enable_paging(uint32_t new_cr3);
-
void flush_gdt(void);
static inline void outb(uint16_t port, uint8_t value) {
@@ -153,6 +145,10 @@ static inline void flush_tss(void) {
__asm__ volatile("movw $0x28, %ax; ltr %ax");
}
+static inline void flush_tlb(void) {
+ __asm__ volatile("movl %cr3, %eax; movl %eax, %cr3");
+}
+
static inline void invlpg(void *addr) {
__asm__ volatile("invlpg (%0)" : : "b"(addr) : "memory");
}
diff --git a/arch/i386/include/kernel/paging.h b/arch/i386/include/kernel/paging.h
index 5999986..d8bb8f3 100644
--- a/arch/i386/include/kernel/paging.h
+++ b/arch/i386/include/kernel/paging.h
@@ -5,6 +5,8 @@
#include <kernel/multiboot.h>
#include <stdint.h>
+#define PAGE_SIZE 4096
+
#define PD_PRES 0x0001
#define PD_RW 0x0002
#define PD_USR 0x0004
@@ -28,14 +30,16 @@
#define GET_PADDR(x) (((uint32_t)(x)) - 0xC0000000)
#define GET_VADDR(x) (((uint32_t)(x)) + 0xC0000000)
-#define GET_PDX(x) (((uintptr_t)(x) >> 22) & 0x3FF)
-#define GET_PTX(x) (((uintptr_t)(x) >> 12) & 0x3FF)
+#define GET_PDX(x) ((uintptr_t)(x) >> 22)
+#define GET_PTX(x) (((uintptr_t)(x) >> 12) & 0x03FF)
+
+uintptr_t get_physaddr(void *vaddr);
-uintptr_t* init_page_table(void);
void paging_init(void);
-void map_page(uint32_t *pd, uintptr_t paddr, uintptr_t vaddr, uint32_t flags);
-void unmap_page(uint32_t *pd, uintptr_t vaddr);
+uintptr_t init_page_directory(void);
+void map_page(uintptr_t paddr, uintptr_t vaddr, uint32_t flags);
+void unmap_page(uintptr_t vaddr);
void page_fault_handler(struct isr_frame *frame);
diff --git a/arch/i386/include/kernel/vmem.h b/arch/i386/include/kernel/vmem.h
new file mode 100644
index 0000000..94aa32d
--- /dev/null
+++ b/arch/i386/include/kernel/vmem.h
@@ -0,0 +1,17 @@
+#ifndef I386_VMEM_H
+#define I386_VMEM_H
+
+extern uintptr_t _kernel_start;
+extern uintptr_t _kernel_end;
+
+#define KSTART ((uintptr_t)&_kernel_start)
+#define KEND ((uintptr_t)&_kernel_end - 0xC0000000)
+
+#define KHEAP_START (GET_VADDR(KEND) + 0x2000)
+#define KHEAP_STOP 0xFF7FF000
+
+#define PAGE_DIR_MAP 0xFFFFF000
+#define PAGE_TAB_MAP 0xFFC00000
+#define PAGE_TMP_MAP 0xFFBFF000
+
+#endif
diff --git a/arch/i386/kernel/paging.c b/arch/i386/kernel/paging.c
index 96ad2ce..b8e00af 100644
--- a/arch/i386/kernel/paging.c
+++ b/arch/i386/kernel/paging.c
@@ -1,96 +1,88 @@
#include <kernel/paging.h>
#include <kernel/asm.h>
+#include <kernel/vmem.h>
#include <kernel/pmem.h>
#include <kernel/panic.h>
#include <kernel/syscall.h>
#include <libk/io.h>
#include <libk/string.h>
-uintptr_t *kpgdir = NULL;
-
-static uintptr_t kernel_pd[1024] __attribute__((aligned(PAGE_SIZE)));
-static uintptr_t kernel_pt[1024] __attribute__((aligned(PAGE_SIZE)));
-static uintptr_t accnt_pt[1024] __attribute__((aligned(PAGE_SIZE)));
static int paging_enabled = 0;
-void _copy_kernel_maps(uintptr_t *new_pd) {
- int pdx = GET_PDX(GET_VADDR(KSTART));
- new_pd[pdx] = GET_PADDR(kernel_pt) | PD_PRES | PD_RW;
- new_pd[832] = GET_PADDR(accnt_pt) | PD_PRES | PD_RW;
-}
-
-uintptr_t* init_page_table(void) {
- uintptr_t *ret = (uintptr_t*)pfa_alloc();
- if ((uintptr_t)ret == PFA_ALLOC_ERR)
- return NULL;
-
- uintptr_t *temp_map = (uintptr_t*)0xD0001000;
- map_page(NULL, (uintptr_t)ret, (uintptr_t)temp_map, PD_PRES | PD_RW);
- memset((char*)temp_map, 0, PAGE_SIZE);
- unmap_page(NULL, (uintptr_t)temp_map);
- return ret;
-}
-
-uintptr_t* init_page_directory(void) {
- uintptr_t *ret = (uintptr_t*)pfa_alloc();
- if ((uintptr_t)ret == PFA_ALLOC_ERR)
- return NULL;
-
- map_page(NULL, (uintptr_t)ret, (uintptr_t)ret, PD_PRES | PD_RW);
- memset(ret, 0, PAGE_SIZE);
- _copy_kernel_maps(ret);
- unmap_page(NULL, (uintptr_t)ret);
-
- return ret;
-}
-
void paging_init(void) {
if (paging_enabled == 1)
return;
-
- _copy_kernel_maps(kernel_pd);
+
+ uintptr_t phys_pt = pfa_alloc(1);
+ map_page(phys_pt, PAGE_TMP_MAP, PD_PRES | PD_RW);
+ uintptr_t *pt = (uintptr_t*)PAGE_TMP_MAP;
for (uintptr_t i = KSTART; i < KEND; i += PAGE_SIZE)
- map_page(kernel_pd, i, GET_VADDR(i), PD_PRES);
+ pt[GET_PTX(GET_VADDR(i))] = i | PD_PRES;
+ unmap_page(PAGE_TMP_MAP);
- map_page(kernel_pd, 0xB8000, 0xC03FF000, PD_PRES | PD_RW);
- kpgdir = kernel_pd;
- enable_paging(GET_PADDR(kpgdir));
+ uintptr_t phys_pd = pfa_alloc(1);
+ map_page(phys_pd, PAGE_TMP_MAP, PD_PRES | PD_RW);
+ uintptr_t *pd = (uintptr_t*)PAGE_TMP_MAP;
+ pd[GET_PDX(GET_VADDR(KSTART))] = phys_pt | PD_PRES | PD_RW;
+ pd[1023] = phys_pd | PD_PRES | PD_RW;
+ unmap_page(PAGE_TMP_MAP);
+
+ enable_paging(phys_pd);
paging_enabled = 1;
return;
}
-void map_page(uint32_t *pd, uintptr_t paddr, uintptr_t vaddr, uint32_t flags) {
- if (pd == NULL)
- pd = kpgdir;
+void init_page_table(int pdindex, uint32_t flags) {
+ uintptr_t *pd = (uintptr_t*)PAGE_DIR_MAP;
+ if ((pd[pdindex] & PD_PRES) != 0)
+ return;
+
+ uintptr_t paddr = pfa_alloc(1);
+ pd[pdindex] = paddr | PD_PRES | PD_RW | flags;
+
+ uintptr_t *pt = ((uintptr_t*)PAGE_TAB_MAP) + (pdindex << 12);
+ pd[GET_PDX(pt)] = paddr | PD_PRES | PD_RW;
+}
+
+uintptr_t init_page_directory(void) {
+ uintptr_t ret = pfa_alloc(1);
+ map_page(ret, PAGE_TMP_MAP, PD_RW);
+
+ uintptr_t *new_pd = (uintptr_t*)PAGE_TMP_MAP;
+ uintptr_t *cur_pd = (uintptr_t*)PAGE_DIR_MAP;
+ int kernel_pdx = GET_PDX(GET_VADDR(KSTART));
+ new_pd[kernel_pdx] = cur_pd[kernel_pdx];
+ unmap_page(PAGE_TMP_MAP);
+ return ret;
+}
+
+void map_page(uintptr_t paddr, uintptr_t vaddr, uint32_t flags) {
paddr = PGROUNDDN(paddr);
vaddr = PGROUNDDN(vaddr);
- uintptr_t pdindex = GET_PDX(vaddr);
- uintptr_t ptindex = GET_PTX(vaddr);
+ int pdindex = GET_PDX(vaddr);
+ int ptindex = GET_PTX(vaddr);
- uintptr_t *pt = (uintptr_t*)(GET_VADDR(pd[pdindex]) & 0xFFFFF000);
- if (pd[pdindex] == 0)
- pd[pdindex] = (uintptr_t)init_page_table();
+ uintptr_t *pd = (uintptr_t*)PAGE_DIR_MAP;
+ if ((pd[pdindex] & PD_PRES) == 0)
+ init_page_table(pdindex, 0);
- uintptr_t *pte = (uintptr_t*)(&pt[ptindex]);
- *pte |= paddr | (flags & 0xFFF) | 0x01;
+ uintptr_t *pt = (uintptr_t*)(PAGE_TAB_MAP + (pdindex << 12));
+ pt[ptindex] = paddr | PD_PRES | flags;
invlpg((void*)vaddr);
}
-void unmap_page(uint32_t *pd, uintptr_t vaddr) {
- if (pd == NULL)
- pd = kpgdir;
-
+void unmap_page(uintptr_t vaddr) {
uintptr_t pdindex = GET_PDX(vaddr);
uintptr_t ptindex = GET_PTX(vaddr);
- uintptr_t *pt = (uintptr_t*)(GET_VADDR(pd[pdindex]) & 0xFFFFF000);
- if (pd[pdindex] == 0)
+ uintptr_t *pd = (uintptr_t*)PAGE_DIR_MAP;
+ if ((pd[pdindex] & PD_PRES) == 0)
return;
- uintptr_t *pte = (uintptr_t*)(&pt[ptindex]);
- *pte &= 0;
+ uintptr_t *pt = (uintptr_t*)(PAGE_TAB_MAP + (pdindex << 12));
+ pt[ptindex] = 0;
invlpg((void*)vaddr);
}
@@ -98,28 +90,30 @@ void page_fault_handler(struct isr_frame *frame) {
uintptr_t fault_addr;
__asm__ volatile("movl %%cr2, %0" : "=r"(fault_addr));
+ kprintf("Faulting address: %x\n", fault_addr);
+ panic("Page fault not operational");
switch (frame->isr_err) {
case 0:
- map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES);
+ //map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES);
break;
case 1:
panic("Kernel process caused protection fault on read\n");
break;
case 2:
- map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES | PD_RW);
+ //map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES | PD_RW);
break;
case 3:
panic("Kernel process caused protection fault on write\n");
break;
case 4:
- map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES | PD_USR);
+ //map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES | PD_USR);
break;
case 5:
// TODO: instead of panicking, kill process
panic("User process caused protection fault on read\n");
break;
case 6:
- map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES | PD_RW | PD_USR);
+ //map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES | PD_RW | PD_USR);
break;
case 7:
// TODO: see case 101