From f2e09e98a7d48bd5653665adf48c4e77d435dfdb Mon Sep 17 00:00:00 2001 From: Xnoe Date: Mon, 25 Oct 2021 01:13:29 +0100 Subject: [PATCH] Started work on Allocator class. Update PageMap --- src/kernel/kernel.cpp | 2 +- src/kernel/memory.cpp | 99 +++++++++++++++++++++++++++++++++++++++++++ src/kernel/memory.h | 36 +++++++++++----- 3 files changed, 125 insertions(+), 12 deletions(-) diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 63b945a..fcbc318 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -16,7 +16,7 @@ int main() { PageDirectory kernel_pd = PageDirectory(0xc0100000, 0x120000, 0xbffe0000); kernel_pd.select(); kernel_pd.map(0x0, 0x400000); - //kernel_pd.unmap(0x8000); + kernel_pd.unmap(0x8000); init_idt(); init_term(); diff --git a/src/kernel/memory.cpp b/src/kernel/memory.cpp index 9fc62c8..bd03369 100644 --- a/src/kernel/memory.cpp +++ b/src/kernel/memory.cpp @@ -10,6 +10,67 @@ void memcpy(uint8_t* src, uint8_t* dst, uint32_t count) { dst[i] = src[i]; } +void PageMap::set_bit(uint32_t index) { + uint32_t offset = index % 8; + uint32_t i = index / 8; + + pagemap[i] |= 1<<(7-offset); +} + +void PageMap::unset_bit(uint32_t index) { + uint32_t offset = index % 8; + uint32_t i = index / 8; + + pagemap[i] &= 255 - (1<<(7-offset)); +} + +bool PageMap::bit_set(uint32_t index) { + uint32_t offset = index % 8; + uint32_t i = index / 8; + + return pagemap[i] & 1<<(7-offset); +} + +void PageMap::mark_unavailable(uint32_t address) { + unset_bit(address >> 12); +} + +void PageMap::mark_unavailable(uint32_t address, uint32_t count) { + for (int i=0; i> 12) + i); +} + +void PageMap::mark_available(uint32_t address) { + set_bit(address >> 12); +} + +void PageMap::mark_available(uint32_t address, uint32_t count) { + for (int i=0; i> 12) + i); +} + +bool PageMap::available(uint32_t address) { + return bit_set(address >> 4096); +} + +uint32_t PageMap::find_next_available_from(uint32_t address) { + while (!available(address)) address += 4096; + + return address; +} + +uint32_t PageMap::find_next_available_from(uint32_t address, uint32_t count) { + while (1) { + while (!available(address)) address += 4096; + + for (int a=address, i=0; ipage_directory = page_directory; this->phys_addr = phys_addr; @@ -86,6 +151,40 @@ void PageDirectory::unmap(uint32_t virt) { page_tables[split->pd_index].unmap_table(split->pt_index); } +uint32_t PageDirectory::virtual_to_physical(uint32_t virt) { + split_addr* split = (split_addr*)&virt; + return page_tables[split->pd_index].get_physical_address(split->pt_index); +} + void PageDirectory::select() { asm volatile("mov %0, %%eax; mov %%eax, %%cr3" : : "m" (phys_addr)); +} + +PageMap* Allocator::phys; + +Allocator::Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt) { + PD = page_directory; + phys = phys; + virt = virt; + + remaining = 0; +} + +void* Allocator::allocate() { + uint32_t phys_addr = phys->find_next_available_from(0); + uint32_t virt_addr = virt->find_next_available_from(virt_alloc_base); + + phys->mark_unavailable(phys_addr); + virt->mark_unavailable(virt_addr); + + PD->map(phys, virt); +} + +void Allocator::deallocate(uint32_t virt_addr) { + uint32_t phys_addr = PD->virtual_to_physical(virt_addr); + + PD->unmap(virt_addr); + + phys->mark_available(phys_addr); + virt->mark_unavailable(virt_addr); } \ No newline at end of file diff --git a/src/kernel/memory.h b/src/kernel/memory.h index b81c7e1..d3317f3 100644 --- a/src/kernel/memory.h +++ b/src/kernel/memory.h @@ -16,11 +16,21 @@ private: void set_bit(uint32_t index); void unset_bit(uint32_t index); + bool bit_set(uint32_t index); + public: PageMap(uint8_t* map); - void mark_unavailble(uint32_t page); - void mark_available(uint32_t page); + void mark_unavailable(uint32_t address); + void mark_unavailable(uint32_t address, uint32_t count); + + void mark_available(uint32_t address); + void mark_available(uint32_t address, uint32_t count); + + bool available(uint32_t address); + + uint32_t find_next_available_from(uint32_t address); + uint32_t find_next_available_from(uint32_t address, uint32_t count); }; struct PageTable { @@ -34,6 +44,8 @@ struct PageTable { void map_table(uint32_t index, uint32_t addr); void unmap_table(uint32_t index); + + uint32_t get_physical_address(uint32_t index); }; class PageDirectory { @@ -47,26 +59,28 @@ public: PageDirectory(PDE* page_directories, uint32_t phys_addr, uint32_t offset); void map(uint32_t phys, uint32_t virt); - void unmap(uint32_t virt); + uint32_t virtual_to_physical(uint32_t virt); + void select(); }; class Allocator { protected: - static PageMap phys; - PageMap virt; + static PageMap* phys; + PageMap* virt; - PageDirectory PD; + PageDirectory* PD; - uint32_t current_page_index; + uint32_t current_alloc_address; uint32_t remaining; + + uint32_t virt_alloc_base; public: - Allocator(); - Allocator(PageDirectory page_directory, PageMap phys, PageMap virt); - void* allocate(); - void deallocate(); + Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt); + virtual void* allocate(); + virtual void deallocate(uint32_t virt_addr); }; class Process : protected Allocator {