Kernel: Continue moving utilities to a separate subdirectory

This commit is contained in:
apio 2022-10-14 17:26:47 +02:00
parent 13a5c0e445
commit 1707739477
5 changed files with 41 additions and 35 deletions

View File

@ -1,30 +1,10 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
namespace Utilities namespace Utilities
{ {
inline uint64_t get_blocks_from_size(uint64_t blocksize, uint64_t size) inline uint64_t get_blocks_from_size(uint64_t blocksize, uint64_t size)
{ {
return (size + (blocksize - 1)) / blocksize; return (size + (blocksize - 1)) / blocksize;
} }
inline uint64_t get_top_of_stack(uint64_t bottom, uint64_t stack_pages)
{
return bottom + (stack_pages * PAGE_SIZE) - sizeof(uintptr_t);
}
inline uint64_t round_down_to_nearest_page(uint64_t addr)
{
return addr - (addr % PAGE_SIZE);
}
inline uint64_t round_up_to_nearest_page(uint64_t addr)
{
if (addr % PAGE_SIZE) return addr + (PAGE_SIZE - (addr % PAGE_SIZE));
return addr;
}
} }

View File

@ -0,0 +1,23 @@
#pragma once
#include <stdint.h>
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
inline uintptr_t get_top_of_stack(uintptr_t bottom, uintptr_t stack_pages)
{
return bottom + (stack_pages * PAGE_SIZE) - sizeof(uintptr_t);
}
inline uintptr_t round_down_to_nearest_page(uintptr_t addr)
{
return addr - (addr % PAGE_SIZE);
}
inline uintptr_t round_up_to_nearest_page(uintptr_t addr)
{
if (addr % PAGE_SIZE) return addr + (PAGE_SIZE - (addr % PAGE_SIZE));
return addr;
}

View File

@ -6,6 +6,7 @@
#include "memory/PMM.h" #include "memory/PMM.h"
#include "misc/utils.h" #include "misc/utils.h"
#include "std/string.h" #include "std/string.h"
#include "utils/Addresses.h"
#include "utils/Registers.h" #include "utils/Registers.h"
// FIXME: There is a lot of duplicate code in this file. This should probably be refactored. // FIXME: There is a lot of duplicate code in this file. This should probably be refactored.
@ -19,7 +20,7 @@ void VMM::init()
void VMM::unmap(uint64_t vaddr) void VMM::unmap(uint64_t vaddr)
{ {
vaddr = Utilities::round_down_to_nearest_page(vaddr); vaddr = round_down_to_nearest_page(vaddr);
PageDirectoryEntry* pde = find_pde(PML4, vaddr); PageDirectoryEntry* pde = find_pde(PML4, vaddr);
if (!pde) return; // Already unmapped if (!pde) return; // Already unmapped
@ -30,7 +31,7 @@ void VMM::unmap(uint64_t vaddr)
uint64_t VMM::get_physical(uint64_t vaddr) uint64_t VMM::get_physical(uint64_t vaddr)
{ {
PageDirectoryEntry* pde = find_pde(PML4, Utilities::round_down_to_nearest_page(vaddr)); PageDirectoryEntry* pde = find_pde(PML4, round_down_to_nearest_page(vaddr));
if (!pde) return UINT64_MAX; // Not mapped if (!pde) return UINT64_MAX; // Not mapped
return pde->get_address() | (vaddr % PAGE_SIZE); return pde->get_address() | (vaddr % PAGE_SIZE);
@ -38,7 +39,7 @@ uint64_t VMM::get_physical(uint64_t vaddr)
uint64_t VMM::get_flags(uint64_t vaddr) uint64_t VMM::get_flags(uint64_t vaddr)
{ {
PageDirectoryEntry* pde = find_pde(PML4, Utilities::round_down_to_nearest_page(vaddr)); PageDirectoryEntry* pde = find_pde(PML4, round_down_to_nearest_page(vaddr));
if (!pde) return 0; // Not mapped if (!pde) return 0; // Not mapped
uint64_t flags = 0; uint64_t flags = 0;
@ -49,7 +50,7 @@ uint64_t VMM::get_flags(uint64_t vaddr)
void VMM::map(uint64_t vaddr, uint64_t paddr, int flags) void VMM::map(uint64_t vaddr, uint64_t paddr, int flags)
{ {
vaddr = Utilities::round_down_to_nearest_page(vaddr); vaddr = round_down_to_nearest_page(vaddr);
PageDirectoryEntry* pde = find_pde(PML4, vaddr); PageDirectoryEntry* pde = find_pde(PML4, vaddr);
bool will_flush_tlb = true; bool will_flush_tlb = true;
if (!pde) if (!pde)
@ -64,7 +65,7 @@ void VMM::map(uint64_t vaddr, uint64_t paddr, int flags)
will_flush_tlb = false; will_flush_tlb = false;
} }
pde->set_address(Utilities::round_down_to_nearest_page(paddr)); pde->set_address(round_down_to_nearest_page(paddr));
if (flags & User) propagate_user(PML4, vaddr); if (flags & User) propagate_user(PML4, vaddr);
if (flags & ReadWrite) propagate_read_write(PML4, vaddr); if (flags & ReadWrite) propagate_read_write(PML4, vaddr);
if (will_flush_tlb) flush_tlb(vaddr); if (will_flush_tlb) flush_tlb(vaddr);

View File

@ -12,6 +12,7 @@
#include "std/stdlib.h" #include "std/stdlib.h"
#include "std/string.h" #include "std/string.h"
#include "sys/elf/ELF.h" #include "sys/elf/ELF.h"
#include "utils/Addresses.h"
static const char* format_permissions(uint32_t flags) static const char* format_permissions(uint32_t flags)
{ {
@ -86,8 +87,8 @@ ELFImage* ELFLoader::load_elf_from_vfs(VFS::Node* node)
phdr.p_filesz, phdr.p_memsz, format_permissions(phdr.p_flags)); phdr.p_filesz, phdr.p_memsz, format_permissions(phdr.p_flags));
ASSERT(phdr.p_vaddr); ASSERT(phdr.p_vaddr);
uint64_t pages = Utilities::get_blocks_from_size(PAGE_SIZE, (phdr.p_vaddr % PAGE_SIZE) + phdr.p_memsz); uint64_t pages = Utilities::get_blocks_from_size(PAGE_SIZE, (phdr.p_vaddr % PAGE_SIZE) + phdr.p_memsz);
void* buffer = (void*)((uint64_t)MemoryManager::get_pages_at( void* buffer =
Utilities::round_down_to_nearest_page(phdr.p_vaddr), pages, (void*)((uint64_t)MemoryManager::get_pages_at(round_down_to_nearest_page(phdr.p_vaddr), pages,
phdr.p_flags & 2 ? MAP_READ_WRITE | MAP_USER : MAP_USER) + phdr.p_flags & 2 ? MAP_READ_WRITE | MAP_USER : MAP_USER) +
(phdr.p_vaddr % PAGE_SIZE)); (phdr.p_vaddr % PAGE_SIZE));
VFS::read(node, phdr.p_offset, phdr.p_filesz, (char*)buffer); VFS::read(node, phdr.p_offset, phdr.p_filesz, (char*)buffer);
@ -180,7 +181,7 @@ void ELFLoader::release_elf_image(ELFImage* image)
{ {
ELFSection& section = image->sections[i]; ELFSection& section = image->sections[i];
kdbgln("Freeing up section %lx, was using %ld pages", section.base, section.pages); kdbgln("Freeing up section %lx, was using %ld pages", section.base, section.pages);
MemoryManager::release_pages((void*)Utilities::round_down_to_nearest_page(section.base), section.pages); MemoryManager::release_pages((void*)round_down_to_nearest_page(section.base), section.pages);
} }
kfree(image); kfree(image);
} }

View File

@ -14,6 +14,7 @@
#include "sys/elf/ELFLoader.h" #include "sys/elf/ELFLoader.h"
#include "thread/PIT.h" #include "thread/PIT.h"
#include "thread/Task.h" #include "thread/Task.h"
#include "utils/Addresses.h"
#include "utils/Registers.h" #include "utils/Registers.h"
static uint64_t task_num = 0; static uint64_t task_num = 0;
@ -35,7 +36,7 @@ void Scheduler::init()
memset(&idle_task, 0, sizeof(Task)); memset(&idle_task, 0, sizeof(Task));
idle_task.id = free_tid++; idle_task.id = free_tid++;
idle_task.regs.rip = (uint64_t)idle_task_function; idle_task.regs.rip = (uint64_t)idle_task_function;
idle_task.regs.rsp = Utilities::get_top_of_stack((uint64_t)MemoryManager::get_page(), 1); idle_task.regs.rsp = get_top_of_stack((uint64_t)MemoryManager::get_page(), 1);
idle_task.regs.cs = 0x08; idle_task.regs.cs = 0x08;
idle_task.regs.ss = 0x10; idle_task.regs.ss = 0x10;
idle_task.regs.rflags = (1 << 21) | (1 << 9); idle_task.regs.rflags = (1 << 21) | (1 << 9);
@ -67,7 +68,7 @@ void Scheduler::add_kernel_task(void (*task)(void))
new_task->regs.rip = (uint64_t)task; new_task->regs.rip = (uint64_t)task;
new_task->allocated_stack = new_task->allocated_stack =
(uint64_t)MemoryManager::get_pages(TASK_PAGES_IN_STACK); // 16 KB is enough for everyone, right? (uint64_t)MemoryManager::get_pages(TASK_PAGES_IN_STACK); // 16 KB is enough for everyone, right?
new_task->regs.rsp = Utilities::get_top_of_stack(new_task->allocated_stack, TASK_PAGES_IN_STACK); new_task->regs.rsp = get_top_of_stack(new_task->allocated_stack, TASK_PAGES_IN_STACK);
new_task->regs.cs = 0x08; new_task->regs.cs = 0x08;
new_task->regs.ss = 0x10; new_task->regs.ss = 0x10;
new_task->regs.ds = 0x10; new_task->regs.ds = 0x10;
@ -96,7 +97,7 @@ void Scheduler::add_user_task(void* task)
new_task->regs.rip = (uint64_t)task; new_task->regs.rip = (uint64_t)task;
new_task->allocated_stack = (uint64_t)MemoryManager::get_pages( new_task->allocated_stack = (uint64_t)MemoryManager::get_pages(
TASK_PAGES_IN_STACK, MAP_READ_WRITE | MAP_USER); // 16 KB is enough for everyone, right? TASK_PAGES_IN_STACK, MAP_READ_WRITE | MAP_USER); // 16 KB is enough for everyone, right?
new_task->regs.rsp = Utilities::get_top_of_stack(new_task->allocated_stack, TASK_PAGES_IN_STACK); new_task->regs.rsp = get_top_of_stack(new_task->allocated_stack, TASK_PAGES_IN_STACK);
new_task->regs.cs = 0x18 | 0x03; new_task->regs.cs = 0x18 | 0x03;
new_task->regs.ss = 0x20 | 0x03; new_task->regs.ss = 0x20 | 0x03;
new_task->regs.ds = 0x20 | 0x03; new_task->regs.ds = 0x20 | 0x03;
@ -138,7 +139,7 @@ void Scheduler::load_user_task(const char* filename)
new_task->image = image; new_task->image = image;
new_task->allocated_stack = (uint64_t)MemoryManager::get_pages( new_task->allocated_stack = (uint64_t)MemoryManager::get_pages(
TASK_PAGES_IN_STACK, MAP_READ_WRITE | MAP_USER); // 16 KB is enough for everyone, right? TASK_PAGES_IN_STACK, MAP_READ_WRITE | MAP_USER); // 16 KB is enough for everyone, right?
new_task->regs.rsp = Utilities::get_top_of_stack(new_task->allocated_stack, TASK_PAGES_IN_STACK); new_task->regs.rsp = get_top_of_stack(new_task->allocated_stack, TASK_PAGES_IN_STACK);
new_task->regs.cs = 0x18 | 0x03; new_task->regs.cs = 0x18 | 0x03;
new_task->regs.ss = 0x20 | 0x03; new_task->regs.ss = 0x20 | 0x03;
new_task->regs.ds = 0x20 | 0x03; new_task->regs.ds = 0x20 | 0x03;
@ -164,7 +165,7 @@ void Scheduler::reset_task(Task* task, ELFImage* new_image)
task->state = task->Running; task->state = task->Running;
task->regs.rip = new_image->entry; task->regs.rip = new_image->entry;
task->image = new_image; task->image = new_image;
task->regs.rsp = Utilities::get_top_of_stack(task->allocated_stack, TASK_PAGES_IN_STACK); task->regs.rsp = get_top_of_stack(task->allocated_stack, TASK_PAGES_IN_STACK);
task->regs.cs = 0x18 | 0x03; task->regs.cs = 0x18 | 0x03;
task->regs.ss = 0x20 | 0x03; task->regs.ss = 0x20 | 0x03;
task->regs.ds = 0x20 | 0x03; task->regs.ds = 0x20 | 0x03;