Skip to content
Snippets Groups Projects
Verified Commit 4440cd93 authored by iliya.saroukha's avatar iliya.saroukha :first_quarter_moon:
Browse files

feat: paging seemingly fully working now

parent 8afd6ea3
Branches
No related tags found
No related merge requests found
#include "paging.h"
#include "boot/multiboot.h"
#include "boot/multiboot_structs.h"
#include "common/mem.h"
#include "common/types.h"
#include "drivers/display.h"
#include "frame.h"
#include "x86.h"
extern void ld_stack_start();
uint_t stack_start = (uint_t)&ld_stack_start;
static PDE_t kernel_pagedir[PAGETABLES_IN_PD]
__attribute__((aligned(PAGE_SIZE)));
......@@ -12,21 +20,128 @@ static PDE_t kernel_pagedir[PAGETABLES_IN_PD]
// table if one was just allocated, otherwise returns 0.
static PTE_t *mmap_page(PDE_t *pagedir, uint32_t virt_addr, uint32_t phys_addr,
enum privilege_t privilege, enum access_t access) {
// TODO
uint_t pde_idx = ADDR_TO_PDE(virt_addr);
PTE_t *page_table = NULL;
if (!pagedir[pde_idx].present) {
page_table = frame_alloc();
if (page_table == FRAME_ALLOC_ERR) {
return FRAME_ALLOC_ERR;
}
pagedir[pde_idx].present = 1;
pagedir[pde_idx].rw = access;
pagedir[pde_idx].user = privilege;
pagedir[pde_idx].page_sz = 0;
pagedir[pde_idx].pagetable_frame_number = ADDR_TO_FRAME_NB(page_table);
uint_t pte_idx = (virt_addr >> 12) & 0x3FF;
page_table[pte_idx].present = 1;
page_table[pte_idx].user = privilege;
page_table[pte_idx].rw = access;
page_table[pte_idx].frame_number = ADDR_TO_FRAME_NB(phys_addr);
return page_table;
}
page_table =
(PTE_t *)FRAME_NB_TO_ADDR(pagedir[pde_idx].pagetable_frame_number);
uint_t pte_idx = (virt_addr >> 12) & 0x3FF;
page_table[pte_idx].present = 1;
page_table[pte_idx].user = privilege;
page_table[pte_idx].rw = access;
page_table[pte_idx].frame_number = ADDR_TO_FRAME_NB(phys_addr);
return 0;
}
void paging_mmap(PDE_t *pagedir, uint32_t virt_addr, uint32_t phys_addr,
uint32_t size, enum privilege_t privilege,
enum access_t access) {
// TODO
struct terminal_t term;
if (term_init(&term) != 0) {
return;
}
uint_t va_aligned = ALIGN_TO_PAGE_SIZE(virt_addr);
uint_t pa_aligned = ALIGN_TO_PAGE_SIZE(phys_addr);
uint_t end_addr = va_aligned + size;
// i actually hate myself for this `if` block, ugliest stuff ever
uint_t to_mmap;
if (end_addr < PAGE_SIZE) {
to_mmap = PAGE_SIZE;
} else {
to_mmap = ALIGN_TO_PAGE_SIZE(end_addr);
}
/*uint_t to_mmap = ALIGN_TO_PAGE_SIZE(va_aligned + size);*/
for (uint_t i = va_aligned, j = pa_aligned; i < to_mmap;
i += PAGE_SIZE, j += FRAME_SIZE) {
PTE_t *pt = mmap_page(pagedir, i, j, privilege, access);
if (pt == FRAME_ALLOC_ERR) {
/*kprintf(&term,*/
/* "New page table allocated at 0x%x pointing to 0x%x\n",
* pt,*/
/* FRAME_NB_TO_ADDR(pt->frame_number));*/
kprintf(&term, "Shit happened\n");
}
}
}
static void unmap_page(PDE_t *pagedir, uint32_t virt_addr) {
// TODO
uint_t pde_idx = ADDR_TO_PDE(virt_addr);
PDE_t *dir_entry = &pagedir[pde_idx];
PTE_t *page_table =
(PTE_t *)FRAME_NB_TO_ADDR(dir_entry->pagetable_frame_number);
uint_t pte_idx = (virt_addr >> 12) & 0x3FF;
frame_free((void *)FRAME_NB_TO_ADDR(page_table[pte_idx].frame_number));
memset(&page_table[pte_idx], 0, sizeof(PTE_t));
for (uint_t i = 0; i < PAGES_IN_PT; i++) {
if (!is_frame_free(page_table[i].frame_number)) {
return;
}
}
frame_free((void *)FRAME_NB_TO_ADDR(dir_entry->pagetable_frame_number));
memset(dir_entry, 0, sizeof(PDE_t));
}
void paging_init(uint_t RAM_in_KB) {
// TODO
if (!RAM_in_KB) {
return;
}
paging_mmap(kernel_pagedir, 0, 0, RAM_in_KB * 1024, PRIVILEGE_KERNEL,
ACCESS_READWRITE);
multiboot_info_t *mbi = multiboot_get_info();
uint_t fb_size = mbi->framebuffer_pitch *
(mbi->framebuffer_height * (mbi->framebuffer_bpp / 8));
// Identity mapping of the framebuffer
paging_mmap(kernel_pagedir, mbi->framebuffer_addr, mbi->framebuffer_addr,
fb_size, PRIVILEGE_KERNEL, ACCESS_READWRITE);
// Second mapping of the VBE framebuffer to VA 3GB (3 * (1 << 30))
uint_t va_framebuffer = 3 * (1UL << 30);
paging_mmap(kernel_pagedir, va_framebuffer, mbi->framebuffer_addr, fb_size,
PRIVILEGE_KERNEL, ACCESS_READWRITE);
unmap_page(kernel_pagedir, 0);
// unmapping the stack guard page
unmap_page(kernel_pagedir, stack_start);
paging_load_pagedir(kernel_pagedir);
paging_enable();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment