forked from PoliEcho-holding-org/kern
vmm bullshit
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
#ifndef _VMM_H
|
||||||
|
#define _VMM_H
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#define CANONICAL_MASK_KERNEL 0xFFFF800000000000
|
||||||
|
#define CANONICAL_MASK_USER 0x00007FFFFFFFFFF000
|
||||||
|
|
||||||
|
int vmm_alloc(void** vaddr, uint64_t count, uint64_t flags);
|
||||||
|
#endif
|
||||||
+47
-17
@@ -1,23 +1,28 @@
|
|||||||
|
#include "errno.h"
|
||||||
|
#include "types.h"
|
||||||
#include <bootloader.h>
|
#include <bootloader.h>
|
||||||
#include <kernel.h>
|
|
||||||
#include <paging.h>
|
|
||||||
#include <serial.h>
|
|
||||||
#include <random.h>
|
|
||||||
#include <splash.h>
|
|
||||||
#include <system.h>
|
|
||||||
#include <gdt.h>
|
#include <gdt.h>
|
||||||
#include <isr.h>
|
#include <isr.h>
|
||||||
|
#include <kernel.h>
|
||||||
|
#include <paging.h>
|
||||||
#include <pmm.h>
|
#include <pmm.h>
|
||||||
|
#include <random.h>
|
||||||
|
#include <serial.h>
|
||||||
|
#include <splash.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <system.h>
|
||||||
|
#include <vmm.h>
|
||||||
|
|
||||||
__noreturn
|
__noreturn void _start(void) {
|
||||||
void _start(void) {
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
// Serial console for debugging
|
// Serial console for debugging
|
||||||
if ((err = serial_init(COM1)) < 0) panic(NULL, "Failed to initialize Serial driver. (%d)", err);
|
if ((err = serial_init(COM1)) < 0)
|
||||||
|
panic(NULL, "Failed to initialize Serial driver. (%d)", err);
|
||||||
|
|
||||||
// Load structures from bootloader
|
// Load structures from bootloader
|
||||||
if ((err = boot_init()) < 0) panic(NULL, "Failed to parse bootloader structures. (%d)", err);
|
if ((err = boot_init()) < 0)
|
||||||
|
panic(NULL, "Failed to parse bootloader structures. (%d)", err);
|
||||||
|
|
||||||
// CPUID thingy :p
|
// CPUID thingy :p
|
||||||
uint32_t eax = 0;
|
uint32_t eax = 0;
|
||||||
@@ -26,26 +31,51 @@ void _start(void) {
|
|||||||
pr_info("[kernel] CPUID_GETVENDORID: %s\n", s);
|
pr_info("[kernel] CPUID_GETVENDORID: %s\n", s);
|
||||||
|
|
||||||
// System init
|
// System init
|
||||||
if ((err = gdt_init()) < 0) panic(NULL, "Failed to initalize GDT. (%d)", err);
|
if ((err = gdt_init()) < 0)
|
||||||
if ((err = isr_init()) < 0) panic(NULL, "Failed to initalize ISRs. (%d)", err);
|
panic(NULL, "Failed to initalize GDT. (%d)", err);
|
||||||
|
if ((err = isr_init()) < 0)
|
||||||
|
panic(NULL, "Failed to initalize ISRs. (%d)", err);
|
||||||
|
|
||||||
// Memory management
|
// Memory management
|
||||||
if ((err = pmm_init()) < 0) panic(NULL, "Failed to initalize Physical Memory Manager. (%d)", err);
|
if ((err = pmm_init()) < 0)
|
||||||
if ((err = pag_init()) < 0) panic(NULL, "Failed to initalize Paging. (%d)", err);
|
panic(NULL, "Failed to initalize Physical Memory Manager. (%d)",
|
||||||
|
err);
|
||||||
|
if ((err = pag_init()) < 0)
|
||||||
|
panic(NULL, "Failed to initalize Paging. (%d)", err);
|
||||||
|
|
||||||
// random number generation
|
// random number generation
|
||||||
rand_init();
|
rand_init();
|
||||||
// test random number generation
|
// test random number generation
|
||||||
printk("Random number generation test:\n");
|
printk("Random number generation test:\n");
|
||||||
for (uint8_t i = 0; i <= 16; i++) {
|
for (uint8_t i = 0; i <= 16; i++) {
|
||||||
printk("%d: %lu\n",i,get_random_number());
|
printk("%d: %lu\n", i, get_random_number());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test VMM
|
||||||
|
{
|
||||||
|
void* vaddr;
|
||||||
|
int ret = vmm_alloc(&vaddr, 2, 0);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
panic(NULL, "vmm_alloc returned %d", ret);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
uint64_t* pml4 = pag_get_pml4();
|
||||||
|
uint64_t* pte = pag_get_pte(pml4, vaddr);
|
||||||
|
if (!IS_ERR(pte) && (*pte & PTE_FLAG_PRESENT)) {
|
||||||
|
printk("page allocated\n");
|
||||||
|
} else {
|
||||||
|
printk("page not allocated\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memset(vaddr, 69, 2 * PAGE_SIZE);
|
||||||
|
*(char*)((vaddr + (2 * PAGE_SIZE)) - 1) = 0;
|
||||||
|
printk("read back:\n%s\n", (char*)vaddr);
|
||||||
|
}
|
||||||
|
|
||||||
// The most important function in the world.
|
// The most important function in the world.
|
||||||
splash();
|
splash();
|
||||||
|
|
||||||
// Patiently wait for things to do :)
|
// Patiently wait for things to do :)
|
||||||
while (1);
|
while (1)
|
||||||
|
;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+37
-9
@@ -1,9 +1,11 @@
|
|||||||
|
#include "vmm.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <isr.h>
|
#include <isr.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <paging.h>
|
#include <paging.h>
|
||||||
#include <pmm.h>
|
#include <pmm.h>
|
||||||
|
#include <random.h>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
// allocates set number of pages at address provided
|
// allocates set number of pages at address provided
|
||||||
@@ -12,27 +14,53 @@ int vmm_alloc(void** vaddr, uint64_t count, uint64_t flags) {
|
|||||||
if (flags == 0) {
|
if (flags == 0) {
|
||||||
flags = PTE_FLAG_PRESENT | PTE_FLAG_WRITE | PTE_FLAG_NOEXEC;
|
flags = PTE_FLAG_PRESENT | PTE_FLAG_WRITE | PTE_FLAG_NOEXEC;
|
||||||
}
|
}
|
||||||
|
bool random_vaddr = *vaddr ? false : true;
|
||||||
|
|
||||||
uint64_t* pml4 = pag_get_pml4();
|
uint64_t* pml4 = pag_get_pml4();
|
||||||
for (uint64_t i = 0; i < count; i++) {
|
{
|
||||||
uint64_t* pte = pag_get_pte(pml4, vaddr);
|
uint8_t limit_counter = 0;
|
||||||
if (!IS_ERR(pte) && (*pte & PTE_FLAG_PRESENT)) {
|
while (true) {
|
||||||
// TODO actualy handle conflict
|
if (random_vaddr) {
|
||||||
return EEXIST;
|
retry_selection:
|
||||||
|
*vaddr = (void*)ALIGN_DOWN(get_random_number(),
|
||||||
|
PAGE_SIZE);
|
||||||
|
|
||||||
|
*vaddr = (void*)((uint64_t)(*vaddr) &
|
||||||
|
CANONICAL_MASK_USER);
|
||||||
|
if (!(flags & PTE_FLAG_USER)) {
|
||||||
|
*vaddr = (void*)((uint64_t)(*vaddr) |
|
||||||
|
CANONICAL_MASK_KERNEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (uint64_t i = 0; i < count; i++) {
|
||||||
|
uint64_t* pte =
|
||||||
|
pag_get_pte(pml4, *vaddr + (i * PAGE_SIZE));
|
||||||
|
if (!IS_ERR(pte) && (*pte & PTE_FLAG_PRESENT)) {
|
||||||
|
if (!random_vaddr) {
|
||||||
|
return -EEXIST;
|
||||||
|
} else {
|
||||||
|
if (limit_counter < UINT8_MAX) {
|
||||||
|
goto retry_selection;
|
||||||
|
} else {
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint64_t i = 0; i < count; i++) {
|
for (uint64_t i = 0; i < count; i++) {
|
||||||
void* paddr = pmm_alloc();
|
void* paddr = pmm_alloc();
|
||||||
int pag_map_ret =
|
int pag_map_ret =
|
||||||
pag_map(pml4, (void*)(((size_t)vaddr) * i * PAGE_SIZE),
|
pag_map(pml4, *vaddr + (i * PAGE_SIZE), paddr, flags);
|
||||||
paddr, flags);
|
|
||||||
if (pag_map_ret != SUCCESS) {
|
if (pag_map_ret != SUCCESS) {
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
for (i -= 1; i != UINT64_MAX; i--) {
|
for (i -= 1; i != UINT64_MAX; i--) {
|
||||||
if (pag_unmap(pml4,
|
if (pag_unmap(pml4,
|
||||||
(void*)(((size_t)vaddr) *
|
*vaddr +
|
||||||
i * PAGE_SIZE)) !=
|
(i * PAGE_SIZE)) !=
|
||||||
SUCCESS) {
|
SUCCESS) {
|
||||||
panic(NULL,
|
panic(NULL,
|
||||||
"failed to unmap "
|
"failed to unmap "
|
||||||
|
|||||||
Reference in New Issue
Block a user