blob: d8f72a376f28ef8df5b63f921a670bfa726eaf69 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
#include <kernel/paging.h>
#include <kernel/io.h>
#include <kernel/syscall.h>
#include <kernel/string.h>
#include <kernel/alloc.h>
#include <stddef.h>
extern int halt_catch_fire();
extern uint32_t _kernel_start;
extern uint32_t _kernel_end;
static uint32_t *kstart = &_kernel_start;
static uint32_t *kend = (uint32_t)(&_kernel_end) - 0xC0000000;
static uint32_t page_directory[1024] __attribute__((aligned(PAGE_SIZE)));
static uint32_t first_page_table[1024] __attribute__((aligned(PAGE_SIZE)));
static int paging_enabled = 0;
void paging_init(void) {
for (int i = 0; i < 1024; i++)
page_directory[i] = 0x00000002;
page_directory[1023] = ((uint32_t)&page_directory - 0xC0000000) | 3;
page_directory[0] = ((uint32_t)&first_page_table - 0xC0000000) | 3;
page_directory[768] = ((uint32_t)&first_page_table - 0xC0000000) | 3;
for (uint32_t i = kstart; i < kend; i += 4096) {
map_page(i, get_vaddr(i), 0x003);
mark_bitmap(i, 1);
}
map_page(0xB8000, 0xC03FF000, 0x003);
mark_bitmap(0xB8000, 1);
load_page_dir(((uint32_t)&page_directory) - 0xC0000000);
enable_paging();
paging_enabled = 1;
return;
}
void page_fault_handler(struct isr_frame *frame) {
kprintf("Page fault detected\n");
uint32_t errno = frame->errno;
uint32_t fault_addr;
__asm__ volatile("movl %%cr2, %0" : "=r"(fault_addr));
kprintf("Fault occured at address %x\n", fault_addr);
uint32_t present = errno & ERR_PRESENT;
uint32_t rw = errno & ERR_RW;
uint32_t user = errno & ERR_USER;
uint32_t reserved = errno & ERR_RESERVED;
uint32_t ifetch = errno & ERR_INST;
kprintf("Possible causes:\n");
if (!present) kprintf("\tPage not present\n");
if (rw || user) kprintf("\tPage is read only\n");
if (reserved) kprintf("\tOverwrote reserved bits\n");
if (ifetch) kprintf("\tInstruction fetch\n");
halt_catch_fire(frame);
}
uint32_t get_paddr(uint32_t vaddr) {
uint32_t pdindex = vaddr >> 22;
uint32_t ptindex = vaddr >> 12 & 0x03FF;
uint32_t *page_table = (page_directory[pdindex] + 0xC0000000 & 0xFFFFF000);
return (page_table[ptindex] & 0xFFFFF000) | (vaddr & 0x00000FFF);
}
uint32_t get_vaddr(uint32_t paddr) {
return paddr + 0xC0000000;
}
void map_page(uint32_t paddr, uint32_t vaddr, uint32_t flags) {
uint32_t pdindex = vaddr >> 22;
uint32_t ptindex = vaddr >> 12 & 0x03FF;
uint32_t *page_table = (page_directory[pdindex] + 0xC0000000 & 0xFFFFF000);
uint32_t *pte = (uint32_t*)(&page_table[ptindex]);
*pte |= paddr | (flags & 0xFFF) | 0x01;
}
void unmap_page(uint32_t vaddr) {
uint32_t pdindex = vaddr >> 22;
uint32_t ptindex = vaddr >> 12 & 0x03FF;
uint32_t *page_table = (page_directory[pdindex] + 0xC0000000 & 0xFFFFF000);
uint32_t *pte = (uint32_t*)(&page_table[ptindex]);
*pte &= 0;
}
|