feat: start of paging setup

This commit is contained in:
2022-05-14 17:01:10 +02:00
parent e850dabc8b
commit 6c32c430d0
7 changed files with 224 additions and 112 deletions

View File

@@ -13,7 +13,7 @@
#include <myke/libk/kprint.h>
#include <myke/libk/libk.h>
#include <myke/libk/syscall.h>
#include <myke/mem/mem.h>
#include <myke/mem/vmm.h>
#include <myke/util/init.h>
#include <myke/tasks/task.h>
@@ -21,15 +21,6 @@ const int version_major = 0,
version_minor = 0,
version_patch = 1;
void init_mmap(multiboot_info_t *multiboot_info) {
if (multiboot_info->flags & (1 << 6)) {
mmap_init_multiboot((struct multiboot_mmap_entry *) multiboot_info->mmap_addr,
multiboot_info->mmap_length / sizeof(struct multiboot_mmap_entry));
} else {
k_panics("mmap invalid!\n");
}
}
void init_pci_system() {
pci_scan();
pci_init_drivers();
@@ -38,6 +29,9 @@ void init_pci_system() {
void att_noreturn att_used kmain(multiboot_info_t *multiboot_info, uint32_t mb_name) {
// early init
isr_install();
// initialize memory management
vmm_init(multiboot_info);
// initialize early modules (kprint etc.)
init_execute_all(INIT_STAGE_EARLY_BOOT_0);
@@ -48,8 +42,6 @@ void att_noreturn att_used kmain(multiboot_info_t *multiboot_info, uint32_t mb_n
store_bootloader_info(multiboot_info);
// initialize memory management
init_mmap(multiboot_info);
// safe multiboot info for later use
debug_store_info(multiboot_info);

View File

@@ -2,58 +2,80 @@
// Created by rick on 21-02-21.
//
#include <attributes.h>
#include <stdbool.h>
#include <sys/types.h>
#include <attributes.h>
#include <myke/mem/paging.h>
#include <sys/param.h>
#define TABLE_ADDR_MASK 0xFFFFF000
#define DIRECTORY_SIZE 1024
#define PAGING_DIR_INDEX(virt) ((virt) >> 22)
#define PAGING_TABLE_INDEX(virt) ((virt) >> 12 & 0x03FF)
const uint32_t x = TABLE_ADDR_MASK;
typedef struct {
union {
struct {
bool present: 1;
bool read_write: 1;
bool user_mode: 1;
bool write_through: 1;
bool cache_disabled: 1;
bool accessed: 1;
char ignored: 1;
bool page_size: 1;
bool global: 1; // ignored
uint8_t avail: 3;
} att_packed;
uint32_t addr;
};
} att_packed page_directory_entry;
#define KERNEL_OFFSET 0xC0000000
typedef struct {
union {
struct {
bool present: 1;
bool read_write: 1;
bool user_supervisor: 1;
bool write_through: 1;
bool cache_disabled: 1;
bool accessed: 1;
bool dirty: 1;
char ignored: 1;
bool global: 1;
uint8_t available: 3;
} att_packed;
uint32_t addr;
};
} att_packed page_table_entry;
// One page table, only 4M
#define PAGING_STATE_EARLY 0
#define PAGING_STATE_FULL 60
page_directory_entry page_directory[DIRECTORY_SIZE] att_aligned(4096);
page_directory_entry att_aligned(4096) kernel_page_directory[DIRECTORY_SIZE] = {0};
void page_pre_init() {
for (int i = 0; i < DIRECTORY_SIZE; ++i) {
page_directory[i].read_write = true;
page_directory[i].user_mode = false;
page_directory[i].present = false;
int paging_state = PAGING_STATE_EARLY;
void paging_load_directory(uintptr_t physical_address) {
asm volatile("mov %%eax, %%cr3" : : "a" (physical_address));
}
uintptr_t paging_get_current_directory_physical() {
uintptr_t directory_address;
asm volatile("mov %%cr3, %%eax" : "=a" (directory_address));
return directory_address;
}
page_directory_entry *paging_get_current() {
return kernel_page_directory;
}
int paging_map_4m(uintptr_t physical_address, uintptr_t virtual_address, int count, int mode) {
if (virtual_address & ~PAGING_MASK_4M || physical_address & PAGING_MASK_4M) {
// address not 4M aligned
return PAGING_RESULT_ALIGN;
}
page_directory_entry *dir = paging_get_current();
for (int i = 0; i < count; ++i) {
page_directory_entry current_val = dir[PAGING_DIR_INDEX(virtual_address) + i];
if (current_val & DIRECTORY_PRESENT_MASK) {
return PAGING_RESULT_INUSE;
}
}
page_directory_entry mask = DIRECTORY_PAGE_SIZE_MASK;
if (mode & PAGING_MODE_RW) {
mask |= DIRECTORY_RW_MASK;
}
if (mode & PAGING_MODE_US) {
mask |= DIRECTORY_US_MASK;
}
for (int i = 0; i < count; ++i) {
dir[PAGING_DIR_INDEX(virtual_address) + i] = physical_address & mask;
}
paging_load_directory((uintptr_t) dir);
return PAGING_RESULT_OK;
}
int paging_map_memory(uintptr_t physical_address, uintptr_t virtual_address, int count, int mode) {
if (mode & PAGING_MODE_4M) {
return paging_map_4m(physical_address, virtual_address, count, mode);
}
if (paging_state < PAGING_STATE_FULL) {
// can't allocate 4K pages yet
if ((virtual_address & ~PAGING_MASK_4M) != (physical_address & ~PAGING_MASK_4M)) {
return PAGING_RESULT_ERR; // not in same pos in 4M page
}
int table_index = PAGING_TABLE_INDEX(virtual_address);
int pages = DIV_ROUND_UP(table_index + count, 1024);
return paging_map_4m(physical_address & PAGING_MASK_4M,
virtual_address & PAGING_MASK_4M,
pages,
mode | PAGING_MODE_4M);
}
return PAGING_RESULT_ERR;
}

24
kernel/mem/vmm.c Normal file
View File

@@ -0,0 +1,24 @@
//
// Created by rick on 17-10-21.
//
#include <sys/types.h>
#include <myke/libk/libk.h>
#include <myke/mem/mem.h>
#include <myke/mem/vmm.h>
void vmm_init(multiboot_info_t *multiboot_info) {
if (!(multiboot_info->flags & MULTIBOOT_INFO_MEM_MAP)) {
k_panics("No MMAP info available");
}
mmap_init_multiboot((struct multiboot_mmap_entry *) multiboot_info->mmap_addr,
multiboot_info->mmap_length / sizeof(struct multiboot_mmap_entry));
}
void* vmm_map_physical(uintptr_t physical) {
}
void* vmm_unmap_physical(uintptr_t physical) {
}
void* vmm_unmap_virtual(uintptr_t virtual) {
}