Add a WIP VMM

As of now the VMM (pretty much a doubly linked list of regions) supports allocating and demand paging. still no deallocation though so if you allocate something you can't free it yet :')
This commit is contained in:
Matheus
2022-07-27 00:39:55 -03:00
parent 4ea2880817
commit f1d3126990
11 changed files with 564 additions and 21 deletions
+3 -1
View File
@@ -3,10 +3,11 @@
#include <stdint.h>
cls_t bspcls;
vmm_context initialvmmcontext;
void arch_setcls(cls_t* addr){
wrmsr(MSR_GSBASE, (uint64_t)addr);
wrmsr(MSR_KERNELGSBASE, (uint64_t)addr);
}
cls_t* arch_getcls(){
@@ -15,4 +16,5 @@ cls_t* arch_getcls(){
void bsp_setcls(){
arch_setcls(&bspcls);
bspcls.context = &initialvmmcontext;
}
+2
View File
@@ -34,6 +34,8 @@ void idt_bspinit(){
idt_setentry(&idt[i], asmisr_except, 0x28, FLAGS_PRESENT | FLAGS_TYPE_TRAP, 0);
}
idt_setentry(&idt[VECTOR_PF], asmisr_pagefault, 0x28, FLAGS_PRESENT | FLAGS_TYPE_TRAP, 0);
idt_reload();
}
+15
View File
@@ -8,6 +8,21 @@
#define FLAGS_TYPE_INTERRUPT (0xE << 8)
#define FLAGS_TYPE_TRAP (0xF << 8)
#define VECTOR_DIV 0
#define VECTOR_DEBUG 1
#define VECTOR_NMI 2
#define VECTOR_BREAKPOINT 3
#define VECTOR_OVERFLOW 4
#define VECTOR_BOUNDRANGE 5
#define VECTOR_INVALIDOPCODE 6
#define VECTOR_DEVUNAVAILABLE 7
#define VECTOR_DOUBLEFAULT 8
#define VECTOR_COPROCESSOR 9
#define VECTOR_INVALIDTSS 10
#define VECTOR_SEGMENTNOTPRESENT 11
#define VECTOR_STACK 12
#define VECTOR_GPF 13
#define VECTOR_PF 14
typedef struct{
+1 -1
View File
@@ -5,7 +5,7 @@
extern void asmisr_general(arch_regsnoerror*);
extern void asmisr_except(arch_regserror*);
extern void asmisr_pagefault(arch_regserror*);
#endif
+5 -5
View File
@@ -6,11 +6,11 @@
#define PAGE_SIZE 4096
#define ARCH_MMU_MAP_READ (1 << 0)
#define ARCH_MMU_MAP_WRITE (1 << 1)
#define ARCH_MMU_MAP_USER (1 << 2)
#define ARCH_MMU_MAP_NOEXEC (1 << 63)
#define ARCH_MMU_MAP_PAGESIZE (1 << 7)
#define ARCH_MMU_MAP_READ (uint64_t)(1 << 0)
#define ARCH_MMU_MAP_WRITE (uint64_t)(1 << 1)
#define ARCH_MMU_MAP_USER (uint64_t)(1 << 2)
#define ARCH_MMU_MAP_NOEXEC (uint64_t)(1 << 63)
#define ARCH_MMU_MAP_PAGESIZE (uint64_t)(1 << 7)
typedef uint64_t* arch_mmu_tableptr;
+17 -3
View File
@@ -2,6 +2,8 @@ section .text
%macro pushregs 0
push rbp
push rsi
push rdi
@@ -27,6 +29,11 @@ section .text
mov rax, gs
push rax
cmp rax,0x30
jmp .noswapgs
swapgs
.noswapgs:
mov rdi,cr2
push rdi
@@ -36,8 +43,10 @@ section .text
%macro popregs 0
add rsp, 8 ; cr2
pop rax
cmp rax,0x30
je .dontpopsegs
mov gs,rax
pop rax
mov fs,rax
@@ -45,7 +54,12 @@ section .text
mov es,rax
pop rax
mov ds,rax
swapgs
jmp .poprest
.dontpopsegs:
add rsp,24
.poprest:
pop rax
pop rbx
pop rcx
@@ -89,7 +103,7 @@ section .text
%macro except 2
global %1
%1:
+5 -1
View File
@@ -1,5 +1,6 @@
#include <arch/isr.h>
#include <arch/panic.h>
#include <kernel/vmm.h>
void isr_general(arch_regsnoerror *reg){
_panic("Unhandled interrupt", 0);
@@ -11,6 +12,9 @@ void isr_except(arch_regserror *reg){
asm("hlt;");
}
void isr_pagefault(void*){
void isr_pagefault(arch_regserror *reg){
if(!vmm_dealwithrequest(reg->cr2))
_panic("Page fault!\n", 0);
}
+3 -2
View File
@@ -4,6 +4,7 @@
#include <arch/idt.h>
#include <arch/cls.h>
#include <kernel/pmm.h>
#include <kernel/vmm.h>
static volatile struct limine_terminal_request liminettyr = {
.id = LIMINE_TERMINAL_REQUEST,
@@ -40,8 +41,8 @@ void kmain(){
arch_mmu_init();
vmm_init();
}
+10 -8
View File
@@ -44,6 +44,7 @@ static bool setpage(arch_mmu_tableptr context, void* vaddr, uint64_t entry){
// TODO unallocate in case of failure
if(!pdptaddr){
pdptaddr = pmm_alloc(1);
changeentry(&context[pdpt], pdptaddr, PTR_FLAGS);
@@ -53,7 +54,7 @@ static bool setpage(arch_mmu_tableptr context, void* vaddr, uint64_t entry){
pdptaddr = (void*)pdptaddr + (size_t)limine_hhdm_offset;
uint64_t* pdaddr = pdptaddr[pd] & ~0xFFF;
if(!pdaddr){
pdaddr = pmm_alloc(1);
changeentry(&pdptaddr[pd], pdaddr, PTR_FLAGS);
@@ -64,8 +65,6 @@ static bool setpage(arch_mmu_tableptr context, void* vaddr, uint64_t entry){
uint64_t* ptaddr = pdaddr[pt]& ~0xFFF;
if(!ptaddr){
ptaddr = pmm_alloc(1);
changeentry(&pdaddr[pt], ptaddr, PTR_FLAGS);
@@ -87,7 +86,8 @@ int arch_mmu_map(arch_mmu_tableptr context, void* paddr, void* vaddr, size_t fla
changeentry(&entry, paddr, flags);
int ret = setpage(context, vaddr, entry);
if(ret) invalidate(vaddr);
return ret;
@@ -128,13 +128,13 @@ void arch_mmu_init(){
for(size_t entry = 0; entry < count; ++entry){
void* addr = entries[entry]->base;
for(size_t offset = 0; offset < entries[entry]->length; offset += PAGE_SIZE){
for(size_t pageoffset = 0; pageoffset < entries[entry]->length / PAGE_SIZE; ++pageoffset){
uint64_t entry;
changeentry(&entry, addr + offset, ARCH_MMU_MAP_READ | ARCH_MMU_MAP_WRITE);
changeentry(&entry, addr + pageoffset*PAGE_SIZE, ARCH_MMU_MAP_READ | ARCH_MMU_MAP_WRITE);
setpage(context, addr + offset, entry);
setpage(context, addr + offset + (size_t)limine_hhdm_offset, entry);
setpage(context, addr + pageoffset*PAGE_SIZE, entry);
setpage(context, addr + pageoffset*PAGE_SIZE + (size_t)limine_hhdm_offset, entry);
}
@@ -190,6 +190,8 @@ void arch_mmu_init(){
switchcontext(context);
arch_getcls()->context->context = context;
printf("In bootstrap context\n");
}