aboutsummaryrefslogtreecommitdiff
path: root/kernel/features
diff options
context:
space:
mode:
authorMarvin Borner2021-03-08 12:25:40 +0100
committerMarvin Borner2021-03-08 12:25:40 +0100
commit776f1da4686d57dfa1c398d3b875d174fe6082c6 (patch)
tree7b648e45a09a70037d9feef7887e5a26dd8cd2ef /kernel/features
parente6abffbca51c35f46911097def2a8ae03f450962 (diff)
im stoopid and i know it
Diffstat (limited to 'kernel/features')
-rw-r--r--kernel/features/mm.c461
1 files changed, 242 insertions, 219 deletions
diff --git a/kernel/features/mm.c b/kernel/features/mm.c
index b17d9fc..cde9a94 100644
--- a/kernel/features/mm.c
+++ b/kernel/features/mm.c
@@ -9,21 +9,24 @@
#include <print.h>
+static struct page_dir kernel_dir ALIGNED(PAGE_SIZE) = { 0 };
+static struct page_table kernel_tables[256] ALIGNED(PAGE_SIZE) = { 0 };
+
/**
- * Paging
+ * Lowlevel paging
*/
-void paging_disable(void)
+static void paging_disable(void)
{
cr0_set(cr0_get() | 0x7fffffff);
}
-void paging_enable(void)
+static void paging_enable(void)
{
cr0_set(cr0_get() | 0x80000000);
}
-void paging_switch_dir(u32 dir)
+static void paging_switch_dir(u32 dir)
{
assert(dir);
cr3_set(dir);
@@ -31,68 +34,131 @@ void paging_switch_dir(u32 dir)
extern void paging_invalidate_tlb(void);
+static void page_fault(struct regs *r)
+{
+ // Check error code
+ const char *type = (r->err_code & 4) ? "present" : "non-present";
+ const char *operation = (r->err_code & 2) ? "write" : "read";
+ const char *super = (r->err_code & 1) ? "User" : "Super";
+
+ // Check cr2 address
+ u32 vaddr;
+ __asm__ volatile("movl %%cr2, %%eax" : "=a"(vaddr));
+ struct proc *proc = proc_current();
+ struct page_dir *dir = NULL;
+ if (proc && proc->page_dir) {
+ dir = proc->page_dir;
+ printf("Stack is at %x, entry at %x\n", virtual_to_physical(dir, proc->regs.ebp),
+ virtual_to_physical(dir, proc->entry));
+ } else {
+ dir = &kernel_dir;
+ }
+ u32 paddr = virtual_to_physical(dir, vaddr);
+
+ // Print!
+ printf("%s process tried to %s a %s page at [vaddr=%x; paddr=%x]\n", super, operation, type,
+ vaddr, paddr);
+
+ isr_panic(r);
+}
+
/**
* Physical
*/
static u32 memory_used = 0;
static u32 memory_total = 0;
+static u32 best_bet = 0;
static u8 memory[PAGE_COUNT * PAGE_COUNT / 8] = { 0 };
-#define PHYSICAL_IS_USED(addr) \
- (memory[(u32)(addr) / PAGE_SIZE / 8] & (1 << ((u32)(addr) / PAGE_SIZE % 8)))
-#define PHYSICAL_SET_USED(addr) \
- (memory[(u32)(addr) / PAGE_SIZE / 8] |= (1 << ((u32)(addr) / PAGE_SIZE % 8)))
+static u8 physical_page_is_used(u32 addr)
+{
+ u32 page = addr / PAGE_SIZE;
+ return memory[page / 8] & (1 << (page % 8));
+}
+
+static void physical_page_set_used(u32 address)
+{
+ u32 page = address / PAGE_SIZE;
+
+ if (page == best_bet)
+ best_bet++;
-#define PHYSICAL_SET_FREE(addr) \
- (memory[(u32)(addr) / PAGE_SIZE / 8] &= ~(1 << ((u32)(addr) / PAGE_SIZE % 8)))
+ memory[page / 8] |= 1 << (page % 8);
+}
-u8 physical_is_used(u32 addr, u32 n)
+static void physical_page_set_free(u32 address)
{
- for (u32 i = 0; i < n; i++) {
- if (PHYSICAL_IS_USED(addr + (i * PAGE_SIZE)))
- return 1;
- }
- return 0;
+ u32 page = address / PAGE_SIZE;
+
+ if (page < best_bet)
+ best_bet = page;
+
+ memory[page / 8] &= ~(1 << (page % 8));
}
-void physical_set_used(u32 addr, u32 n)
+static void physical_set_used(struct memory_range range)
{
- for (u32 i = 0; i < n; i++) {
- if (!PHYSICAL_IS_USED(addr + (i * PAGE_SIZE))) {
+ assert(PAGE_ALIGNED(range.base) && PAGE_ALIGNED(range.size));
+
+ for (u32 i = 0; i < range.size / PAGE_SIZE; i++) {
+ u32 addr = range.base + i * PAGE_SIZE;
+ if (!physical_page_is_used(addr)) {
memory_used += PAGE_SIZE;
- PHYSICAL_SET_USED(addr + (i * PAGE_SIZE));
+ physical_page_set_used(addr);
}
}
}
-void physical_set_free(u32 addr, u32 n)
+static void physical_set_free(struct memory_range range)
{
- for (u32 i = 0; i < n; i++) {
- if (PHYSICAL_IS_USED(addr + (i * PAGE_SIZE))) {
+ assert(PAGE_ALIGNED(range.base) && PAGE_ALIGNED(range.size));
+
+ for (u32 i = 0; i < range.size / PAGE_SIZE; i++) {
+ u32 addr = range.base + i * PAGE_SIZE;
+
+ if (physical_page_is_used(addr)) {
memory_used -= PAGE_SIZE;
- PHYSICAL_SET_FREE(addr + (i * PAGE_SIZE));
+ physical_page_set_free(addr);
}
}
}
-u32 physical_alloc(u32 n)
+static u8 physical_is_used(struct memory_range range)
{
- for (u32 i = 0; i < (memory_total / PAGE_SIZE); i++) {
- u32 addr = i * PAGE_SIZE;
- if (!physical_is_used(addr, n)) {
- physical_set_used(addr, n);
- return addr;
+ assert(PAGE_ALIGNED(range.base) && PAGE_ALIGNED(range.size));
+
+ for (u32 i = 0; i < range.size / PAGE_SIZE; i++) {
+ u32 addr = range.base + i * PAGE_SIZE;
+
+ if (physical_page_is_used(addr))
+ return 1;
+ }
+
+ return 0;
+}
+
+static struct memory_range physical_alloc(u32 size)
+{
+ assert(PAGE_ALIGNED(size));
+
+ for (u32 i = best_bet; i < ((memory_total - size) / PAGE_SIZE); i++) {
+ struct memory_range range = memory_range(i * PAGE_SIZE, size);
+
+ if (!physical_is_used(range)) {
+ physical_set_used(range);
+ return range;
}
}
panic("Out of physical memory!\n");
- return 0;
+ return memory_range(0, 0);
}
-void physical_free(u32 addr, u32 n)
+static void physical_free(struct memory_range range)
{
- physical_set_free(addr, n);
+ assert(PAGE_ALIGNED(range.base) && PAGE_ALIGNED(range.size));
+ physical_set_free(range);
}
/**
@@ -102,9 +168,6 @@ void physical_free(u32 addr, u32 n)
#define PDI(vaddr) ((vaddr) >> 22)
#define PTI(vaddr) (((vaddr) >> 12) & 0x03ff)
-static struct page_dir kernel_dir ALIGNED(PAGE_SIZE) = { 0 };
-static struct page_table kernel_tables[256] ALIGNED(PAGE_SIZE) = { 0 };
-
u8 virtual_present(struct page_dir *dir, u32 vaddr)
{
u32 pdi = PDI(vaddr);
@@ -116,10 +179,8 @@ u8 virtual_present(struct page_dir *dir, u32 vaddr)
struct page_table *table = (struct page_table *)(dir_entry->bits.address * PAGE_SIZE);
union page_table_entry *table_entry = &table->entries[pti];
- if (!table_entry->bits.present)
- return 0;
- return 1;
+ return !table_entry->bits.present;
}
u32 virtual_to_physical(struct page_dir *dir, u32 vaddr)
@@ -139,10 +200,9 @@ u32 virtual_to_physical(struct page_dir *dir, u32 vaddr)
return (table_entry->bits.address * PAGE_SIZE) + (vaddr & (PAGE_SIZE - 1));
}
-void memory_alloc_identity(struct page_dir *dir, u32 flags, u32 *out);
-void virtual_map(struct page_dir *dir, u32 vaddr, u32 paddr, u32 n, u8 user)
+void virtual_map(struct page_dir *dir, struct memory_range prange, u32 vaddr, u32 flags)
{
- for (u32 i = 0; i < n; i++) {
+ for (u32 i = 0; i < prange.size / PAGE_SIZE; i++) {
u32 offset = i * PAGE_SIZE;
u32 pdi = PDI(vaddr + offset);
u32 pti = PTI(vaddr + offset);
@@ -150,41 +210,42 @@ void virtual_map(struct page_dir *dir, u32 vaddr, u32 paddr, u32 n, u8 user)
union page_dir_entry *dir_entry = &dir->entries[pdi];
struct page_table *table =
(struct page_table *)(dir_entry->bits.address * PAGE_SIZE);
- union page_table_entry *table_entry = &table->entries[pti];
if (!dir_entry->bits.present) {
- memory_alloc_identity(dir, MEMORY_CLEAR, (u32 *)&table);
+ table = memory_alloc_identity(dir, MEMORY_CLEAR);
dir_entry->bits.present = 1;
dir_entry->bits.writable = 1;
- dir_entry->bits.user = user;
- dir_entry->bits.address = (u32)table >> 12;
+ dir_entry->bits.user = 1;
+ dir_entry->bits.address = (u32)(table) >> 12;
}
+ union page_table_entry *table_entry = &table->entries[pti];
table_entry->bits.present = 1;
table_entry->bits.writable = 1;
- table_entry->bits.user = user;
- table_entry->bits.address = (paddr + offset) >> 12;
+ table_entry->bits.user = flags & MEMORY_USER;
+ table_entry->bits.address = (prange.base + offset) >> 12;
}
paging_invalidate_tlb();
}
-struct memory_range virtual_alloc(struct page_dir *dir, struct memory_range physical_range,
- u32 flags)
+struct memory_range virtual_alloc(struct page_dir *dir, struct memory_range prange, u32 flags)
{
- u8 is_user = flags & MEMORY_USER;
+ u8 user = flags & MEMORY_USER;
u32 vaddr = 0;
u32 size = 0;
- for (u32 i = (is_user ? 256 : 1) * PAGE_COUNT;
- i < (is_user ? PAGE_COUNT : 256) * PAGE_COUNT; i++) {
+
+ for (u32 i = (user ? 256 : 1) * PAGE_COUNT; i < (user ? PAGE_COUNT : 256) * PAGE_COUNT;
+ i++) {
u32 addr = i * PAGE_SIZE;
if (!virtual_present(dir, addr)) {
if (size == 0)
vaddr = addr;
+
size += PAGE_SIZE;
- if (size == physical_range.size) {
- virtual_map(dir, vaddr, physical_range.base,
- physical_range.size / PAGE_SIZE, is_user);
+
+ if (size == prange.size) {
+ virtual_map(dir, prange, vaddr, flags);
return memory_range(vaddr, size);
}
} else {
@@ -196,15 +257,18 @@ struct memory_range virtual_alloc(struct page_dir *dir, struct memory_range phys
return memory_range(0, 0);
}
-void virtual_free(struct page_dir *dir, struct memory_range virtual_range)
+void virtual_free(struct page_dir *dir, struct memory_range vrange)
{
- for (u32 i = 0; i < virtual_range.size / PAGE_SIZE; i++) {
+ for (u32 i = 0; i < vrange.size / PAGE_SIZE; i++) {
u32 offset = i * PAGE_SIZE;
- u32 pdi = PDI(virtual_range.base + offset);
- u32 pti = PTI(virtual_range.base + offset);
+ u32 pdi = PDI(vrange.base + offset);
+ u32 pti = PTI(vrange.base + offset);
union page_dir_entry *dir_entry = &dir->entries[pdi];
+ if (!dir_entry->bits.present)
+ continue;
+
struct page_table *table =
(struct page_table *)(dir_entry->bits.address * PAGE_SIZE);
union page_table_entry *table_entry = &table->entries[pti];
@@ -216,181 +280,165 @@ void virtual_free(struct page_dir *dir, struct memory_range virtual_range)
paging_invalidate_tlb();
}
-/**
- * Memory wrapper
- */
-
-extern u32 kernel_start;
-extern u32 kernel_end;
-
-struct memory_range memory_range_from_address(u32 base, u32 size)
+struct page_dir *virtual_create_dir(void)
{
- u32 align = PAGE_SIZE - base % PAGE_SIZE;
+ struct page_dir *dir = memory_alloc(&kernel_dir, sizeof(*dir), MEMORY_CLEAR);
- if (base % PAGE_SIZE == 0) {
- align = 0;
- }
+ for (u32 i = 0; i < 256; i++) {
+ union page_dir_entry *dir_entry = &dir->entries[i];
- base += align;
- size -= align;
+ dir_entry->bits.user = 0;
+ dir_entry->bits.writable = 1;
+ dir_entry->bits.present = 1;
+ dir_entry->bits.address = (u32)&kernel_tables[i] / PAGE_SIZE;
+ }
- size -= size % PAGE_SIZE;
+ return dir;
+}
- return memory_range(base, size);
+struct page_dir *virtual_kernel_dir(void)
+{
+ return &kernel_dir;
}
-struct memory_range memory_range_around_address(u32 base, u32 size)
+void virtual_destroy_dir(struct page_dir *dir)
{
- u32 align = base % PAGE_SIZE;
+ assert(dir != &kernel_dir);
- base -= align;
- size += align;
+ for (u32 i = 256; i < PAGE_COUNT; i++) {
+ union page_dir_entry *dir_entry = &dir->entries[i];
+ if (dir_entry->bits.present) {
+ struct page_table *table =
+ (struct page_table *)(dir_entry->bits.address * PAGE_SIZE);
+ for (u32 j = 0; j < PAGE_COUNT; j++) {
+ union page_table_entry *table_entry = &table->entries[j];
+ if (table_entry->bits.present) {
+ u32 paddr = table_entry->bits.address * PAGE_SIZE;
+ physical_free(memory_range(paddr, PAGE_SIZE));
+ }
+ }
- size += PAGE_SIZE - size % PAGE_SIZE;
+ memory_free(&kernel_dir, memory_range((u32)table, sizeof(*table)));
+ }
+ }
- return memory_range(base, size);
+ memory_free(&kernel_dir, memory_range((u32)dir, sizeof(*dir)));
}
-static struct memory_range kernel_memory_range(void)
-{
- return memory_range_around_address((u32)&kernel_start,
- (u32)&kernel_end - (u32)&kernel_start);
-}
+/**
+ * Memory wrappers
+ */
-void memory_map_identity(struct page_dir *dir, struct memory_range range, u32 flags)
+void *memory_alloc(struct page_dir *dir, u32 size, u32 flags)
{
- assert(PAGE_ALIGNED(range.base) && PAGE_ALIGNED(range.size));
+ assert(PAGE_ALIGNED(size));
- u32 page_count = range.size / PAGE_SIZE;
- physical_set_used(range.base, page_count);
- virtual_map(dir, range.base, range.base, page_count, flags & MEMORY_USER);
-
- if (flags & MEMORY_CLEAR)
- memset((void *)range.base, 0, range.size);
-}
+ if (!size)
+ return 0;
-void memory_map(struct page_dir *dir, struct memory_range range, u32 flags)
-{
- assert(PAGE_ALIGNED(range.base) && PAGE_ALIGNED(range.size));
+ struct memory_range prange = physical_alloc(size);
+ if (prange.size == 0)
+ return 0;
- for (u32 i = 0; i < range.size / PAGE_SIZE; i++) {
- u32 vaddr = range.base + i * PAGE_SIZE;
- if (!virtual_present(dir, vaddr)) {
- u32 paddr = physical_alloc(1);
- virtual_map(dir, vaddr, paddr, 1, flags & MEMORY_USER);
- }
+ u32 vaddr = virtual_alloc(dir, prange, flags).base;
+ if (!vaddr) {
+ physical_free(prange);
+ return 0;
}
if (flags & MEMORY_CLEAR)
- memset((void *)range.base, 0, range.size);
+ memset((void *)vaddr, 0, size);
+
+ return (void *)vaddr;
}
-void memory_alloc_identity(struct page_dir *dir, u32 flags, u32 *out)
+void *memory_alloc_identity(struct page_dir *dir, u32 flags)
{
for (u32 i = 1; i < 256 * PAGE_COUNT; i++) {
- u32 addr = i * PAGE_SIZE;
- if (!virtual_present(dir, addr) && !physical_is_used(addr, 1)) {
- physical_set_used(addr, 1);
- virtual_map(dir, addr, addr, 1, flags & MEMORY_USER);
+ struct memory_range range = memory_range(i * PAGE_SIZE, PAGE_SIZE);
+ if (!virtual_present(dir, range.base) && !physical_is_used(range)) {
+ physical_set_used(range);
+ virtual_map(dir, range, range.base, flags);
if (flags & MEMORY_CLEAR)
- memset((void *)addr, 0, PAGE_SIZE);
-
- *out = addr;
-
- return;
+ memset((void *)range.base, 0, PAGE_SIZE);
+ return (void *)range.base;
}
}
- *out = 0;
- panic("Out of memory!\n");
-}
-
-void memory_alloc(struct page_dir *dir, u32 size, u32 flags, u32 *out)
-{
- assert(size && PAGE_ALIGNED(size));
- *out = 0;
-
- u32 page_count = size / PAGE_SIZE;
- u32 paddr = physical_alloc(page_count);
- assert(paddr);
- u32 vaddr = virtual_alloc(dir, memory_range(paddr, size), flags).base;
- assert(vaddr);
- if (flags & MEMORY_CLEAR)
- memset((void *)vaddr, 0, page_count * PAGE_SIZE);
- *out = vaddr;
+ return 0;
}
-void memory_free(struct page_dir *dir, struct memory_range range)
+void memory_free(struct page_dir *dir, struct memory_range vrange)
{
- assert(PAGE_ALIGNED(range.base) && PAGE_ALIGNED(range.size));
+ assert(PAGE_ALIGNED(vrange.base) && PAGE_ALIGNED(vrange.size));
- for (u32 i = 0; i < range.size / PAGE_SIZE; i++) {
- u32 vaddr = range.base + i * PAGE_SIZE;
+ for (u32 i = 0; i < vrange.size / PAGE_SIZE; i++) {
+ u32 vaddr = vrange.base + i * PAGE_SIZE;
if (virtual_present(dir, vaddr)) {
- physical_free(virtual_to_physical(dir, vaddr), 1);
- virtual_free(dir, memory_range(vaddr, PAGE_SIZE));
+ struct memory_range page_prange =
+ memory_range(virtual_to_physical(dir, vaddr), PAGE_SIZE);
+ struct memory_range page_vrange = memory_range(vaddr, PAGE_SIZE);
+ physical_free(page_prange);
+ virtual_free(dir, page_vrange);
}
}
}
-struct page_dir *memory_dir_create(void)
+void memory_map_identity(struct page_dir *dir, struct memory_range prange, u32 flags)
{
- struct page_dir *dir = NULL;
- memory_alloc(&kernel_dir, sizeof(*dir), MEMORY_CLEAR, (u32 *)&dir);
- memset(dir, 0, sizeof(*dir));
+ assert(PAGE_ALIGNED(prange.base) && PAGE_ALIGNED(prange.size));
- for (u32 i = 0; i < 256; i++) {
- union page_dir_entry *entry = &dir->entries[i];
- entry->bits.present = 1;
- entry->bits.writable = 1;
- entry->bits.user = 0;
- entry->bits.address = (u32)&kernel_tables[i] / PAGE_SIZE;
- }
+ physical_set_used(prange);
+ virtual_map(dir, prange, prange.base, flags);
+ if (flags & MEMORY_CLEAR)
+ memset((void *)prange.base, 0, prange.size);
+}
- return dir;
+void memory_switch_dir(struct page_dir *dir)
+{
+ paging_switch_dir(virtual_to_physical(&kernel_dir, (u32)dir));
}
-void memory_dir_destroy(struct page_dir *dir)
+struct memory_range memory_range_from(u32 base, u32 size)
{
- for (u32 i = 256; i < PAGE_COUNT; i++) {
- union page_dir_entry *dir_entry = &dir->entries[i];
- if (dir_entry->bits.present) {
- struct page_table *table =
- (struct page_table *)(dir_entry->bits.address * PAGE_SIZE);
- for (u32 j = 0; j < PAGE_COUNT; j++) {
- union page_table_entry *table_entry = &table->entries[j];
- if (table_entry->bits.present)
- physical_free(table_entry->bits.address * PAGE_SIZE, 1);
- }
+ u32 align = PAGE_SIZE - base % PAGE_SIZE;
- memory_free(&kernel_dir, memory_range((u32)table, sizeof(*table)));
- }
+ if (base % PAGE_SIZE == 0) {
+ align = 0;
}
- memory_free(&kernel_dir, memory_range((u32)dir, sizeof(*dir)));
+
+ base += align;
+ size -= align;
+
+ size -= size % PAGE_SIZE;
+
+ return memory_range(base, size);
}
-void memory_dir_switch(struct page_dir *dir)
+struct memory_range memory_range_around(u32 base, u32 size)
{
- paging_switch_dir(virtual_to_physical(&kernel_dir, (u32)dir));
+ u32 align = base % PAGE_SIZE;
+
+ base -= align;
+ size += align;
+
+ size += PAGE_SIZE - size % PAGE_SIZE;
+
+ return memory_range(base, size);
}
-struct page_dir *memory_kernel_dir(void)
+extern u32 kernel_start;
+extern u32 kernel_end;
+static struct memory_range kernel_memory_range(void)
{
- return &kernel_dir;
+ return memory_range_around((u32)&kernel_start, (u32)&kernel_end - (u32)&kernel_start);
}
-void memory_initialize(struct mem_info *mem_info)
+void memory_install(struct mem_info *mem_info)
{
- for (u32 i = 0; i < 256; i++) {
- union page_dir_entry *entry = &kernel_dir.entries[i];
- entry->bits.present = 1;
- entry->bits.writable = 1;
- entry->bits.user = 0;
- entry->bits.address = (u32)&kernel_tables[i] / PAGE_SIZE;
- }
+ heap_init(HEAP_START);
- // Detect memory using E820 memory map
for (struct mmap_boot *p = mem_info->start; (u32)(p - mem_info->start) < mem_info->size;
p++) {
if (p->hbase || !p->acpi || !p->type)
@@ -402,13 +450,21 @@ void memory_initialize(struct mem_info *mem_info)
/* printf("Memory region: %x-%x\n", p->lbase, p->lbase + size); */
if (p->type == MEMORY_AVAILABLE) {
- physical_set_free(p->lbase, size / PAGE_SIZE);
+ physical_set_free(memory_range_around(p->lbase, size / PAGE_SIZE));
memory_total += size;
} else if (p->type == MEMORY_DEFECT) {
printf("Defect memory at 0x%x-0x%x!\n", p->lbase, p->lbase + size);
}
}
+ for (u32 i = 0; i < 256; i++) {
+ union page_dir_entry *dir_entry = &kernel_dir.entries[i];
+ dir_entry->bits.present = 1;
+ dir_entry->bits.writable = 1;
+ dir_entry->bits.user = 0;
+ dir_entry->bits.address = (u32)&kernel_tables[i] / PAGE_SIZE;
+ }
+
memory_used = 0;
printf("Detected memory: %dKiB (%dMiB)\n", memory_total >> 10, memory_total >> 20);
@@ -416,56 +472,23 @@ void memory_initialize(struct mem_info *mem_info)
memory_map_identity(&kernel_dir, kernel_memory_range(), MEMORY_NONE);
// Map kernel stack
- memory_map_identity(&kernel_dir,
- memory_range_around_address(STACK_START - STACK_SIZE, STACK_SIZE),
+ memory_map_identity(&kernel_dir, memory_range_around(STACK_START - STACK_SIZE, STACK_SIZE),
MEMORY_NONE);
// Map kernel heap
- memory_map_identity(&kernel_dir, memory_range_around_address(HEAP_START, HEAP_INIT_SIZE),
+ memory_map_identity(&kernel_dir, memory_range_around(HEAP_START, HEAP_INIT_SIZE),
MEMORY_NONE);
// TODO: Triple fault prevention? Probably bootloader stuff or something
- memory_map_identity(&kernel_dir, memory_range_around_address(0x7000, 0x1000), MEMORY_NONE);
+ memory_map_identity(&kernel_dir, memory_range_around(0x7000, 0x1000), MEMORY_NONE);
// Unmap NULL byte/page
- virtual_free(&kernel_dir, memory_range(0, PAGE_SIZE));
- physical_set_used(0, 1);
+ struct memory_range zero = memory_range(0, PAGE_SIZE);
+ virtual_free(&kernel_dir, zero);
+ physical_set_used(zero);
- memory_dir_switch(&kernel_dir);
+ memory_switch_dir(&kernel_dir);
paging_enable();
-}
-static void page_fault(struct regs *r)
-{
- // Check error code
- const char *type = (r->err_code & 4) ? "present" : "non-present";
- const char *operation = (r->err_code & 2) ? "write" : "read";
- const char *super = (r->err_code & 1) ? "User" : "Super";
-
- // Check cr2 address
- u32 vaddr;
- __asm__ volatile("movl %%cr2, %%eax" : "=a"(vaddr));
- struct proc *proc = proc_current();
- struct page_dir *dir = NULL;
- if (proc && proc->page_dir) {
- dir = proc->page_dir;
- printf("Stack is at %x, entry at %x\n", virtual_to_physical(dir, proc->regs.ebp),
- virtual_to_physical(dir, proc->entry));
- } else {
- dir = &kernel_dir;
- }
- u32 paddr = virtual_to_physical(dir, vaddr);
-
- // Print!
- printf("%s process tried to %s a %s page at [vaddr=%x; paddr=%x]\n", super, operation, type,
- vaddr, paddr);
-
- isr_panic(r);
-}
-
-void paging_install(struct mem_info *mem_info)
-{
- memory_initialize(mem_info);
- heap_init(HEAP_START);
isr_install_handler(14, page_fault);
}