From f4395ab6b5074b3d5cb464827bcc7b11e9a1a9b8 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Fri, 18 Dec 2020 14:12:00 -0600 Subject: [PATCH] More unfinished work on kernel API --- src/Makefile.am | 3 +- src/kernel.hpp | 31 +++- src/kernelstate.cpp | 9 - src/kernelstate.hpp | 33 ---- src/map.hpp | 95 ---------- src/memoryblock.hpp | 34 ---- src/memorymanager.hpp | 2 +- src/memorymap.cpp | 325 +++++++++++++++-------------------- src/memorymap.hpp | 183 ++++++++++++-------- src/memoryregion.cpp | 128 ++++++++++++++ src/memoryregion.hpp | 87 ++++++++++ src/memorytype.hpp | 11 ++ src/message.cpp | 38 ++++ src/message.hpp | 59 +++++++ src/mmgr.hpp | 7 - src/pageallocator.cpp | 3 +- src/process.hpp | 30 +++- src/sharedblock.hpp | 18 ++ src/syscalls.cpp | 45 ++++- src/syscalls.hpp | 5 + src/systeminfo.cpp | 25 --- src/systeminfo.hpp | 34 ---- src/util.cpp | 20 ++- src/x86/initialize.cpp | 24 +-- src/x86/memorymanagerx86.cpp | 31 ++++ src/x86/memorymanagerx86.hpp | 29 ++++ src/x86/multiboot2.cpp | 17 +- src/x86/multiboot2.hpp | 51 +++--- src/x86/pagetableentry.cpp | 132 ++++++++++++++ src/x86/pagetableentry.hpp | 83 +++++++++ 30 files changed, 1024 insertions(+), 568 deletions(-) delete mode 100644 src/kernelstate.cpp delete mode 100644 src/kernelstate.hpp delete mode 100644 src/map.hpp delete mode 100644 src/memoryblock.hpp create mode 100644 src/memoryregion.cpp create mode 100644 src/memoryregion.hpp create mode 100644 src/memorytype.hpp create mode 100644 src/message.cpp create mode 100644 src/message.hpp delete mode 100644 src/mmgr.hpp create mode 100644 src/sharedblock.hpp delete mode 100644 src/systeminfo.cpp delete mode 100644 src/systeminfo.hpp create mode 100644 src/x86/memorymanagerx86.cpp create mode 100644 src/x86/memorymanagerx86.hpp create mode 100644 src/x86/pagetableentry.cpp create mode 100644 src/x86/pagetableentry.hpp diff --git a/src/Makefile.am b/src/Makefile.am index aad19a1..b4709fc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ noinst_PROGRAMS = quark-kernel -quark_kernel_SOURCES = kernelstate.cpp module.cpp systeminfo.cpp util.cpp memorymap.cpp pageallocator.cpp allocator.cpp scheduler.cpp +quark_kernel_SOURCES = module.cpp util.cpp memorymap.cpp memoryregion.cpp pageallocator.cpp allocator.cpp scheduler.cpp quark_kernel_LDADD = -lgcc quark_kernel_CPPFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -fno-exceptions -fno-rtti -ggdb quark_kernel_LDFLAGS = -nostdlib @@ -14,3 +14,4 @@ quark_kernel_SOURCES += x86/mmap.cpp \ quark_kernel_LDFLAGS += -T x86/linker.ld quark_kernel_DEPENDENCIES = x86/linker.ld endif + diff --git a/src/kernel.hpp b/src/kernel.hpp index a8b5ef7..700989a 100644 --- a/src/kernel.hpp +++ b/src/kernel.hpp @@ -4,7 +4,7 @@ #include "pageallocator.hpp" #include "memorymanager.hpp" #include "memorymap.hpp" -#include "memoryblock.hpp" +#include "sharedblock.hpp" #include "process.hpp" #include "systypes.hpp" @@ -14,6 +14,10 @@ class Kernel { public: + void* malloc(size_t size); + + void free(void* ptr); + /** * @brief Maps a region of pages starting at virtual address 'page' with * length 'length'. Allocates each mapped frame and any necessary page @@ -64,9 +68,30 @@ public: */ void unmapRegion(void* page, size_t length); + /** + * @brief Create a Shared Block object + * + * @param length + * @param flags + * @returns The ID of the + */ unsigned int createSharedBlock(size_t length, int flags); - const MemoryBlock& getSharedBlock(unsigned int id); + /** + * @brief Get the shared memory block referred to by 'id' + * + * @param id + * @returns a reference + */ + const SharedBlock& getSharedBlock(unsigned int id); + + /** + * @brief Create a new process + * + * @param imageBlockID + * @return Process& + */ + Process& createProcess(unsigned int imageBlockID); /** * @brief Get the process object corresponsing to 'pid' @@ -112,7 +137,7 @@ public: * If it holds any shared blocks which are not held by any other process, * those blocks will be freed. * - * @param pid pid of the process to terminate + * @param pid id of the process to terminate */ void terminateProcess(unsigned int pid); diff --git a/src/kernelstate.cpp b/src/kernelstate.cpp deleted file mode 100644 index 89e3301..0000000 --- a/src/kernelstate.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "kernelstate.hpp" - -using namespace kernelns; - -BuddyAllocator State::pageAllocator; -Allocator State::allocator; -Interrupts State::interrupts; -ProcessQueue State::processQueue; -SystemInfo State::config; \ No newline at end of file diff --git a/src/kernelstate.hpp b/src/kernelstate.hpp deleted file mode 100644 index ecb8b63..0000000 --- a/src/kernelstate.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef KERNELSTATE_H -#define KERNELSTATE_H - -#include "pageallocator.hpp" -#include "allocator.hpp" -#include "interrupts.hpp" -#include "scheduler.hpp" -#include "systeminfo.hpp" - -namespace kernelns -{ - -class State -{ -public: - - static const unsigned int MAX_PROCESSES = 2048; - - static BuddyAllocator pageAllocator; - - static Allocator allocator; - - static Interrupts interrupts; - - static ProcessQueue processQueue; - - static SystemInfo config; - -}; - -} - -#endif \ No newline at end of file diff --git a/src/map.hpp b/src/map.hpp deleted file mode 100644 index e33ea38..0000000 --- a/src/map.hpp +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef MAP_H -#define MAP_H - -template -class Map -{ -public: - - Map(); - - bool contains(const Key& key) const - { - if(m_tree == nullptr) - return false; - else if(m_tree->search(key) == nullptr) - return false; - return true; - } - - Value& get(const Key& key) - { - if(m_tree = nullptr) - return (Value&) *nullptr; - Node* node = m_tree->search(key); - if(node == nullptr) - return (Value&) *nullptr; - else - return node->m_value; - } - - void insert(const Value& value); - - void remove(const Key& key); - - unsigned int size() const; - -private: - - class Node - { - public: - - enum class Color - { - Black, - Red - } - - Key m_key; - - Value& m_value; - - Node *left, *right, *parent; - - Color color; - - Node(); - - Node* uncle() - { - if(parent != nullptr && parent->parent != nullptr) - { - if(parent == parent->parent->left) - return parent->parent->right; - return parent->parent->left; - } - return nullptr; - } - - Node* search(const Key& key) - { - if(key == m_key) - return this; - if(left != nullptr) - { - Node* lsearch = left->search(key); - if(lsearch != nullptr) - return lsearch; - } - if(right != nullptr) - { - Node* rsearch = right->search(key); - if(rsearch != nullptr) - return rsearch; - } - return nullptr; - } - - }; - - Node *m_tree; - -}; - -#endif \ No newline at end of file diff --git a/src/memoryblock.hpp b/src/memoryblock.hpp deleted file mode 100644 index 2df0625..0000000 --- a/src/memoryblock.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef MEMORYBLOCK_H -#define MEMORYBLOCK_H - -#include "systypes.hpp" - -class MemoryBlock -{ -public: - - physaddr_t getLocation() const; - - physaddr_t getEnd() const; - - size_t getSize() const; - - int getAttributes() const; - - unsigned int getOwners() const; - - void decrementOwners(); - -private: - - physaddr_t m_location; - - size_t m_size; - - int m_attributes; - - unsigned int m_owners; - -}; - -#endif \ No newline at end of file diff --git a/src/memorymanager.hpp b/src/memorymanager.hpp index f8259ff..72d8237 100644 --- a/src/memorymanager.hpp +++ b/src/memorymanager.hpp @@ -12,7 +12,7 @@ public: * * @return the size in bytes of a single page */ - virtual unsigned int pageSize() const = 0; + virtual unsigned int getPageSize() const = 0; /** * Allocates space for a new top-level page table, and initializes it to diff --git a/src/memorymap.cpp b/src/memorymap.cpp index d5e58e6..e1b21e9 100644 --- a/src/memorymap.cpp +++ b/src/memorymap.cpp @@ -2,129 +2,6 @@ using namespace kernelns; -MemoryMap::Region::Region() -{ - m_location = 0; - m_size = 0; - m_type = (Type) 0; -} - -MemoryMap::Region::Region(Region& copy) -{ - m_location = copy.m_location; - m_size = copy.m_size; - m_type = copy.m_type; -} - -MemoryMap::Region::Region(physaddr_t location, size_t size, Type type) -{ - m_location = location; - m_size = size; - m_type = (size_t) type; -} - -const MemoryMap::Region& MemoryMap::Region::operator=(const MemoryMap::Region& rhs) -{ - m_location = rhs.m_location; - m_size = rhs.m_size; - m_type = rhs.m_type; - return rhs; -} - -const bool MemoryMap::Region::operator==(const MemoryMap::Region& rhs) const -{ - return (m_location == rhs.m_location) && (m_size == rhs.m_size); -} - -const bool MemoryMap::Region::operator<(const MemoryMap::Region& rhs) const -{ - return (m_location < rhs.m_location) || ((m_location == rhs.m_location) && (m_size < rhs.m_size)); -} - -const bool MemoryMap::Region::operator>(const MemoryMap::Region& rhs) const -{ - return (m_location > rhs.m_location) || ((m_location == rhs.m_location) && (m_size > rhs.m_size)); -} - -const bool MemoryMap::Region::operator<=(const MemoryMap::Region& rhs) const -{ - return (m_location < rhs.m_location) || ((m_location == rhs.m_location) && (m_size <= rhs.m_size)); -} - -const bool MemoryMap::Region::operator>=(const MemoryMap::Region& rhs) const -{ - return (m_location > rhs.m_location) || ((m_location == rhs.m_location) && (m_size >= rhs.m_size)); -} - -physaddr_t MemoryMap::Region::getLocation() const -{ - return m_location; -} - -size_t MemoryMap::Region::getSize() const -{ - return m_size; -} - -MemoryMap::Type MemoryMap::Region::getType() const -{ - return (Type) m_type; -} - -physaddr_t MemoryMap::Region::getEnd() const -{ - return m_location + m_size; -} - -bool MemoryMap::Region::contains(const MemoryMap::Region& r) const -{ - return contains(r.m_location, r.m_size); -} - -bool MemoryMap::Region::contains(physaddr_t location, size_t size) const -{ - return (location >= m_location) && - (location + size <= m_location + m_size); -} - -bool MemoryMap::Region::overlaps(const MemoryMap::Region& r) const -{ - if(r.m_location < m_location) - { - return r.m_location + r.m_size < m_location; - } - else - { - return r.m_location >= m_location && r.m_location < m_location + m_size; - } -} - -bool MemoryMap::Region::bordersLeft(const MemoryMap::Region& right) const -{ - return m_location + m_size == right.m_location; -} - -bool MemoryMap::Region::bordersRight(const MemoryMap::Region& left) const -{ - return m_location == left.m_location + left.m_size; -} - -bool MemoryMap::Region::borders(const MemoryMap::Region& r) const -{ - return bordersLeft(r) || bordersRight(r); -} - -void MemoryMap::Region::truncateLeft(physaddr_t left) -{ - m_size = getEnd() - left; - m_location = left; -} - -void MemoryMap::Region::truncateRight(physaddr_t right) -{ - m_size = right - m_location; -} - MemoryMap::MemoryMap() { this->m_entries = 0; @@ -137,7 +14,7 @@ MemoryMap::MemoryMap(MemoryMap& copy) this->m_entries = copy.m_entries; } -const MemoryMap::Region& MemoryMap::operator[](size_t index) const +const MemoryRegion& MemoryMap::operator[](size_t index) const { return m_map[index]; } @@ -147,76 +24,58 @@ size_t MemoryMap::size() const return m_entries; } -void MemoryMap::insertEntry(physaddr_t location, size_t size, Type type) +size_t MemoryMap::totalMemory() const { - Region newRegion(location, size, type); - unsigned int i = 0; - while(i < m_entries) - { - if(newRegion < m_map[i]) - { - Region buffer = newRegion; - newRegion = m_map[i]; - m_map[i] = buffer; - } - i++; - } - m_map[i] = newRegion; - m_entries++; - for(i = 0; i < (m_entries - 1); i++) + size_t sum = 0; + for(int i = 0; i < m_entries; i++) { - if(m_map[i].overlaps(m_map[i+1])) - { - if(m_map[i].getType() == m_map[i+1].getType()) - { - m_map[i] = Region(m_map[i].getLocation(), - (m_map[i+1].getEnd() > m_map[i].getEnd() ? m_map[i+1].getEnd() : m_map[i].getEnd()) - m_map[i].getLocation(), - m_map[i].getType()); - remove(i + 1); - i--; - } - else if(m_map[i].getType() == AVAILABLE) - { - if(m_map[i+1].contains(m_map[i])) - { - remove(i); - i--; - } - else if(m_map[i].getEnd() <= m_map[i+1].getEnd()) - { - m_map[i].truncateRight(m_map[i+1].getLocation()); - } - else - { - unsigned int end = m_map[i].getEnd(); - m_map[i].truncateRight(m_map[i+1].getLocation()); - insertEntry(m_map[i+1].getEnd(), end - m_map[i+1].getEnd(), AVAILABLE); - } - } - else if(m_map[i+1].getType() == AVAILABLE) - { - if(m_map[i].contains(m_map[i + 1])) - { - remove(i + 1); - i--; - } - else - { - m_map[i+1].truncateLeft(m_map[i].getEnd()); - } - } - else - { - // two overlapping unavailable regions - } - } - else if(m_map[i].bordersLeft(m_map[i+1]) && m_map[i].getType() == m_map[i+1].getType()) - { - m_map[i] = Region(m_map[i].getLocation(), m_map[i+1].getEnd() - m_map[i].getLocation(), m_map[i].getType()); - remove(i + 1); - i--; - } + sum += m_map[i].getSize(); } + return sum; +} + +size_t MemoryMap::totalMemory(unsigned int type) const +{ + size_t sum = 0; + for(int i = 0; i < m_entries; i++) + { + if(m_map[i].getType() == type) + sum += m_map[i].getSize(); + } + return sum; +} + +bool MemoryMap::overlaps(const MemoryRegion& region) const +{ + for(int i = 0; i < m_entries; i++) + { + if(m_map[i].overlaps(region)) + return true; + } + return false; +} + +bool MemoryMap::contains(const MemoryRegion& region) const +{ + for(int i = 0; i < m_entries; i++) + { + if(m_map[i].contains(region) && m_map[i].getType() == region.getType()) + return true; + } + return false; +} + +void MemoryMap::insertEntry(const MemoryRegion& region) +{ + simpleInsert(region); + unsigned int i = 0; + while(i != invalidIndex) + i = trim(i); +} + +void MemoryMap::insertEntry(physaddr_t location, size_t size, unsigned int type) +{ + insertEntry(MemoryRegion(location, size, type)); } void MemoryMap::remove(unsigned int index) @@ -226,4 +85,88 @@ void MemoryMap::remove(unsigned int index) m_map[i] = m_map[i+1]; } m_entries--; +} + +void MemoryMap::simpleInsert(const MemoryRegion& region) +{ + MemoryRegion newRegion(region); + unsigned int i = 0; + while(i < m_entries) + { + if(newRegion < m_map[i]) + { + MemoryRegion buffer = newRegion; + newRegion = m_map[i]; + m_map[i] = buffer; + } + i++; + } + m_map[i] = newRegion; + m_entries++; +} + +void MemoryMap::simpleInsert(physaddr_t location, size_t size, unsigned int type) +{ + simpleInsert(MemoryRegion(location, size, type)); +} + +unsigned int MemoryMap::trim(unsigned int index) +{ + if(index + 1 >= m_entries) + return invalidIndex; + MemoryRegion& left = m_map[index]; + MemoryRegion& right = m_map[index+1]; + if(left.overlaps(right)) + { + if(left.getType() == right.getType()) + { + left = MemoryRegion(left.getLocation(), + (right.getEnd() > left.getEnd() ? right.getEnd() : left.getEnd()) - left.getLocation(), + left.getType()); + remove(index + 1); + return index; + } + else if(left.getType() < right.getType()) + { + if(right.contains(left)) + { + remove(index); + return index; + } + else if(left.getEnd() <= right.getEnd()) + { + left.truncateRight(right.getLocation()); + return index + 1; + } + else + { + MemoryRegion newRight(right.getEnd(), left.getEnd() - right.getEnd(), left.getType()); + left.truncateRight(right.getLocation()); + if(left.getSize() == 0) + remove(index); + simpleInsert(newRight); + return index + 2; + } + } + else + { + if(left.contains(right)) + { + remove(index + 1); + return index; + } + else + { + right.truncateLeft(left.getEnd()); + return index + 1; + } + } + } + else if(left.bordersLeft(right) && left.getType() == right.getType()) + { + left = MemoryRegion(left.getLocation(), right.getEnd() - left.getLocation(), left.getType()); + remove(index + 1); + return index; + } + return index + 1; } \ No newline at end of file diff --git a/src/memorymap.hpp b/src/memorymap.hpp index 58aa1d0..6c428af 100644 --- a/src/memorymap.hpp +++ b/src/memorymap.hpp @@ -2,6 +2,7 @@ #define MEMORYMAP_H #include "systypes.hpp" +#include "memoryregion.hpp" namespace kernelns { @@ -9,90 +10,138 @@ namespace kernelns class MemoryMap { public: - - enum Type - { - AVAILABLE = 1, - UNAVAILABLE = 2, - ACPI = 3, - DEFECTIVE = 5 - }; - - class Region - { - public: - - Region(); - - Region(Region& copy); - - Region(physaddr_t location, size_t size, Type type); - - const Region& operator=(const Region& rhs); - - const bool operator==(const Region& rhs) const; - - const bool operator<(const Region& rhs) const; - - const bool operator>(const Region& rhs) const; - - const bool operator<=(const Region& rhs) const; - - const bool operator>=(const Region& rhs) const; - - physaddr_t getLocation() const; - - size_t getSize() const; - - Type getType() const; - - physaddr_t getEnd() const; - - bool contains(const Region& r) const; - - bool contains(physaddr_t location, size_t size) const; - - bool overlaps(const Region& r) const; - - bool bordersLeft(const Region& right) const; - - bool bordersRight(const Region& left) const; - - bool borders(const Region& r) const; - - void truncateLeft(physaddr_t left); - - void truncateRight(physaddr_t right); - - private: - - physaddr_t m_location; - - size_t m_size; - - size_t m_type; - - }; MemoryMap(); MemoryMap(MemoryMap& copy); - const Region& operator[](size_t index) const; + const MemoryRegion& operator[](size_t index) const; + /** + * @return The number of memory regions described by this object + */ size_t size() const; + /** + * @brief Get the total amount of memory described by this memory map. + * Since no two regions may overlap, this is equivalent to the sum of the + * size of each memory region stored in this object. + * + * @return The total amount of memory described by this memory map. + */ size_t totalMemory() const; - void insertEntry(physaddr_t location, size_t size, Type type); + /** + * @brief Get the total amount of memory of a specified type described by + * this memory map. Since no two regions overlap, this is equivalent to the + * sum of the size of each memory region stored in this object whose type + * is equal to `type`. + * + * @param type The type of memory region to count + * @return The total amount of memory of the specified type + */ + size_t totalMemory(unsigned int type) const; + + /** + * @brief Checks if `region` overlaps any memory region contained in this + * memory map. + * + * @param region + * @return true if, for any region `k` in this map, `k.overlaps(region)`. + * @return false if there is no region in this map where `k.overlaps(region)`. + */ + bool overlaps(const MemoryRegion& region) const; + + /** + * @brief Checks if `region` is contained an any memory region in this map + * with the same type as `region`. + * + * @param region + * @return true if, for any region `k` in this map, `k.contains(region) + * && k.getType() == region.getType()`. + * @return false if the condition above is not true + */ + bool contains(const MemoryRegion& region) const; + + /** + * @brief Adds `region` into the memory map. Adjusts the map as necessary + * so that no regions overlap. Regions of higher type take precedence over + * regions with lower types; therefore, the lower typed regions are trimmed + * or deleted where they overlap with higher typed regions. Adjacent or + * overlapping regions with identical types are merged. + * + * @param region The memory region to insert + */ + void insertEntry(const MemoryRegion& region); + + /** + * @brief Overload of `insertEntry()`. @see insertRegion(const MemoryRegion&). + * + * @param location + * @param size + * @param type + */ + void insertEntry(physaddr_t location, size_t size, unsigned int type); private: + /** + * @brief Removes the element at `index` in `m_map`. All objects located + * after that index are moved accordingly. + * + * @param index Locatation of the object to delete + */ void remove(unsigned int index); + /** + * @brief Inserts a copy of `region` into `m_map`. The new element is + * inserted such that `m_map` is sorted in ascending order. Overlapping + * elements are not trimmed. + * + * @param region The memory region to insert + */ + void simpleInsert(const MemoryRegion& region); + + /** + * @brief Overload of `simpleInsert(const MemoryRegion& region)`. + * + * @param location + * @param size + * @param type + */ + void simpleInsert(physaddr_t location, size_t size, unsigned int type); + + /** + * @brief If `m_map[index].overlaps(m_map[index+1])`, the two elements are + * modified so that they no longer overlap. The following rules apply: + * + * 1. This memory map will describe the same set of locations before and + * after performing this operation. + * + * 2. Adjacent regions of the same type are merged into a single region. + * + * 3. Where two regions of differing types overlap, the higher type takes + * precedence. The region of the lower type is truncated, split, or deleted + * so as to not overlap the region of the higher type. + * + * 4. This operation is local: only `m_map[index]` and `m_map[index+1]` are + * modified (although if a region must be split, a new region will be + * inserted at the location `index+2`). + * + * This function has no effect if `index+1 >= m_entries`, or if + * `m_map[index]` does not overlap the `m_map[index+1]`. + * + * @param index The location of the region to trim. + * + * @return The index of the rightmost region affected. + */ + unsigned int trim(unsigned int index); + static const unsigned int maxEntries = 16; - Region m_map[maxEntries]; + static const unsigned int invalidIndex = 0xFFFF; + + MemoryRegion m_map[maxEntries]; size_t m_entries; diff --git a/src/memoryregion.cpp b/src/memoryregion.cpp new file mode 100644 index 0000000..d0eeb15 --- /dev/null +++ b/src/memoryregion.cpp @@ -0,0 +1,128 @@ +#include "memoryregion.hpp" + +MemoryRegion::MemoryRegion() +{ + m_location = 0; + m_size = 0; + m_type = 0; +} + +MemoryRegion::MemoryRegion(const MemoryRegion& copy) +{ + m_location = copy.m_location; + m_size = copy.m_size; + m_type = copy.m_type; +} + +MemoryRegion::MemoryRegion(physaddr_t location, size_t size, unsigned int type) +{ + m_location = location; + m_size = size; + m_type = (size_t) type; +} + +const MemoryRegion& MemoryRegion::operator=(const MemoryRegion& rhs) +{ + m_location = rhs.m_location; + m_size = rhs.m_size; + m_type = rhs.m_type; + return rhs; +} + +bool MemoryRegion::operator==(const MemoryRegion& rhs) const +{ + return (m_location == rhs.m_location) && (m_size == rhs.m_size); +} + +bool MemoryRegion::operator!=(const MemoryRegion& rhs) const +{ + return (m_location != rhs.m_location) || (m_size != rhs.m_size); +} + +bool MemoryRegion::operator<(const MemoryRegion& rhs) const +{ + return (m_location < rhs.m_location) || ((m_location == rhs.m_location) && (m_size < rhs.m_size)); +} + +bool MemoryRegion::operator>(const MemoryRegion& rhs) const +{ + return (m_location > rhs.m_location) || ((m_location == rhs.m_location) && (m_size > rhs.m_size)); +} + +bool MemoryRegion::operator<=(const MemoryRegion& rhs) const +{ + return (m_location < rhs.m_location) || ((m_location == rhs.m_location) && (m_size <= rhs.m_size)); +} + +bool MemoryRegion::operator>=(const MemoryRegion& rhs) const +{ + return (m_location > rhs.m_location) || ((m_location == rhs.m_location) && (m_size >= rhs.m_size)); +} + +physaddr_t MemoryRegion::getLocation() const +{ + return m_location; +} + +size_t MemoryRegion::getSize() const +{ + return m_size; +} + +unsigned int MemoryRegion::getType() const +{ + return m_type; +} + +physaddr_t MemoryRegion::getEnd() const +{ + return m_location + m_size; +} + +bool MemoryRegion::contains(const MemoryRegion& r) const +{ + return contains(r.m_location, r.m_size); +} + +bool MemoryRegion::contains(physaddr_t location, size_t size) const +{ + return (location >= m_location) && + (location + size <= m_location + m_size); +} + +bool MemoryRegion::overlaps(const MemoryRegion& r) const +{ + if(r.m_location < m_location) + return r.m_location + r.m_size > m_location; + else + return r.m_location < getEnd(); +} + +bool MemoryRegion::bordersLeft(const MemoryRegion& right) const +{ + return getEnd() == right.m_location; +} + +bool MemoryRegion::bordersRight(const MemoryRegion& left) const +{ + return m_location == left.m_location + left.m_size; +} + +bool MemoryRegion::borders(const MemoryRegion& r) const +{ + return bordersLeft(r) || bordersRight(r); +} + +void MemoryRegion::truncateLeft(physaddr_t left) +{ + m_size = getEnd() - left; + m_location = left; +} + +void MemoryRegion::truncateRight(physaddr_t right) +{ + if(right > m_location) + m_size = right - m_location; + else + m_size = 0; +} \ No newline at end of file diff --git a/src/memoryregion.hpp b/src/memoryregion.hpp new file mode 100644 index 0000000..35e57e8 --- /dev/null +++ b/src/memoryregion.hpp @@ -0,0 +1,87 @@ +#ifndef MEMORYBLOCK_H +#define MEMORYBLOCK_H + +#include "systypes.hpp" + +class MemoryRegion +{ +public: + + MemoryRegion(); + + MemoryRegion(const MemoryRegion& copy); + + MemoryRegion(physaddr_t location, size_t size, unsigned int type); + + const MemoryRegion& operator=(const MemoryRegion& rhs); + + /** + * @brief Tests whether this object describes the same region of memory + * as rhs, irrespective of type. + * + * @param rhs The object to compare to + * @return true if and only if the location and size of the two regions are equal + * @return false if the two regions have differing locations or differing sizes + */ + bool operator==(const MemoryRegion& rhs) const; + + /** + * @brief Tests whether this object describes a different region of memory + * than rhs, irrespective of type. + * + * @param rhs The object to compare to + * @return true if the two regions have differing locations or differing sizes + * @return false if and only if the location and size of the two regions are equal + */ + bool operator!=(const MemoryRegion& rhs) const; + + /** + * @brief + * + * @param rhs + * @return true + * @return false + */ + bool operator<(const MemoryRegion& rhs) const; + + bool operator>(const MemoryRegion& rhs) const; + + bool operator<=(const MemoryRegion& rhs) const; + + bool operator>=(const MemoryRegion& rhs) const; + + physaddr_t getLocation() const; + + size_t getSize() const; + + unsigned int getType() const; + + physaddr_t getEnd() const; + + bool contains(const MemoryRegion& r) const; + + bool contains(physaddr_t location, size_t size) const; + + bool overlaps(const MemoryRegion& r) const; + + bool bordersLeft(const MemoryRegion& right) const; + + bool bordersRight(const MemoryRegion& left) const; + + bool borders(const MemoryRegion& r) const; + + void truncateLeft(physaddr_t left); + + void truncateRight(physaddr_t right); + +private: + + physaddr_t m_location; + + size_t m_size; + + unsigned int m_type; + +}; + +#endif \ No newline at end of file diff --git a/src/memorytype.hpp b/src/memorytype.hpp new file mode 100644 index 0000000..99ea80b --- /dev/null +++ b/src/memorytype.hpp @@ -0,0 +1,11 @@ +#ifndef MEMORYTYPE_H +#define MEMORYTYPE_H + +enum class MemoryType +{ + Available = 1, + Unavailable = 2, + Defective = 3 +}; + +#endif \ No newline at end of file diff --git a/src/message.cpp b/src/message.cpp new file mode 100644 index 0000000..2f503d5 --- /dev/null +++ b/src/message.cpp @@ -0,0 +1,38 @@ +#include "message.hpp" + +Message::Message() +{ + m_sender = 0; + m_type = 0; + m_args[0] = 0; + m_args[1] = 0; + m_args[2] = 0; +} + +Message::Message(const Message& copy) +{ + m_sender = copy.m_sender; + m_type = copy.m_type; + m_args[0] = copy.m_args[0]; + m_args[1] = copy.m_args[1]; + m_args[2] = copy.m_args[2]; +} + +Message::Message(unsigned int sender, unsigned int type, + unsigned long arg1, unsigned long arg2, unsigned long arg3) +{ + m_sender = sender; + m_type = type; + m_args[0] = arg1; + m_args[1] = arg2; + m_args[2] = arg3; +} + +Message& Message::operator=(const Message& rhs) +{ + m_sender = rhs.m_sender; + m_type = rhs.m_type; + m_args[0] = rhs.m_args[0]; + m_args[1] = rhs.m_args[1]; + m_args[2] = rhs.m_args[2]; +} \ No newline at end of file diff --git a/src/message.hpp b/src/message.hpp new file mode 100644 index 0000000..0702b1e --- /dev/null +++ b/src/message.hpp @@ -0,0 +1,59 @@ +#ifndef MESSAGE_H +#define MESSAGE_H + +struct Message +{ + + /** + * @brief Default constructor. Initializes all members to 0. + * + */ + Message(); + + /** + * @brief Copy constructor. + * + * @param copy + */ + Message(const Message& copy); + + /** + * @brief Construct a new Message object. + * + * @param sender + * @param type + * @param arg1 + * @param arg2 + * @param arg3 + */ + Message(unsigned int sender, unsigned int type, + unsigned long arg1, unsigned long arg2, unsigned long arg3); + + /** + * @brief Copy the contents of `rhs` to this object. + * + * @param rhs + * @return Message& + */ + Message& operator=(const Message& rhs); + + /** + * @brief PID of the process that generated this message. + */ + unsigned int m_sender; + + /** + * @brief Context-specific parameter which indicates to the receiver how + * the arguments are to be interpreted. + */ + unsigned int m_type; + + /** + * @brief Arguments of this message. The meaning of these values depend on + * context, as well as the values of `m_sender` and `m_type`. + */ + unsigned long m_args[3]; + +}; + +#endif \ No newline at end of file diff --git a/src/mmgr.hpp b/src/mmgr.hpp deleted file mode 100644 index e39cb6e..0000000 --- a/src/mmgr.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef MMGR_H -#define MMGR_H - -#include "mmap.hpp" -#include "pageallocator.hpp" - -#endif \ No newline at end of file diff --git a/src/pageallocator.cpp b/src/pageallocator.cpp index 08b6892..43ea72b 100755 --- a/src/pageallocator.cpp +++ b/src/pageallocator.cpp @@ -1,6 +1,7 @@ #include "pageallocator.hpp" #include "systypes.hpp" #include "memorymap.hpp" +#include "memorytype.hpp" #define roundUp(n, m) ((n % m == 0) ? n : (n + m - (n % m))) @@ -44,7 +45,7 @@ kernelns::BuddyAllocator::BuddyAllocator(const kernelns::MemoryMap& memmap, physaddr_t location = 0x100000; for(size_t i = 0; i < memmap.size() && memmap[i].getSize() > 0; i++) { - if(memmap[i].getType() != kernelns::MemoryMap::AVAILABLE) + if(memmap[i].getType() != (unsigned int) MemoryType::Available) continue; if(memmap[i].getLocation() > location) location = roundUp(memmap[i].getLocation(), 4096); diff --git a/src/process.hpp b/src/process.hpp index e84ef97..b25238f 100644 --- a/src/process.hpp +++ b/src/process.hpp @@ -2,7 +2,8 @@ #define PROCESS_H #include -#include "map.hpp" + +#include "message.hpp" namespace kernelns { @@ -17,16 +18,35 @@ public: Process(); + unsigned int getID() const; + + bool map(void* location, size_t size); + + /** + * @brief If the specified region is mapped and does not overlap a shared + * or private block, or the kernel, removes that region from the process's + * internal memory map. If the specified region overlaps an unmapped region, + * a shared or private block, or the kernel, the object goes unmodified. + * This method does not affect the page tables in any way, only the process's + * internal bookkeeping. + * + * @param location + * @param size + * @return true if the memory map was sucessfully updated + * @return false if the memory map was not modified + */ + bool unmap(void* location, size_t size); + bool hasSharedBlock(unsigned int blockID) const; bool hasPhysicalBlock(unsigned int blockID) const; + void pushMessage(Message* message); + + Message* popMessage(); + private: - Map m_sharedBlocks; - - Map m_physicalBlocks; - }; } diff --git a/src/sharedblock.hpp b/src/sharedblock.hpp new file mode 100644 index 0000000..e9fe3d6 --- /dev/null +++ b/src/sharedblock.hpp @@ -0,0 +1,18 @@ +#ifndef SHAREDBLOCK_H +#define SHAREDBLOCK_H + +#include "memoryregion.hpp" + +class SharedBlock : public MemoryRegion +{ +public: + + unsigned int getFlags() const; + +private: + + unsigned int m_flags; + +}; + +#endif \ No newline at end of file diff --git a/src/syscalls.cpp b/src/syscalls.cpp index 8255d15..30e3918 100644 --- a/src/syscalls.cpp +++ b/src/syscalls.cpp @@ -1,17 +1,28 @@ #include "syscalls.hpp" #include "kernel.hpp" +#include "memorytype.hpp" int mmap(void* location, size_t length, int flags) { - // TODO: check that the requested region does not overlap something important + if(kernel.getActiveProcess().map(location, length)) + { + if(kernel.allocateRegion(location, length, flags)) + return 0; + else if(kernel.getActiveProcess().unmap(location, length)) + return 1; + kernel.terminateActiveProcess(); + } return kernel.allocateRegion(location, length, flags); } int munmap(void* location, size_t length) { - // TODO: check that the requested region does not overlap something important - kernel.freeRegion(location, length); - return 0; + if(kernel.getActiveProcess().unmap(location, length)) + { + kernel.freeRegion(location, length); + return 0; + } + return 1; } unsigned int createSharedBlock(void* location, size_t length, int flags) @@ -19,7 +30,7 @@ unsigned int createSharedBlock(void* location, size_t length, int flags) unsigned int blockID = kernel.createSharedBlock(length, flags); if(blockID > 0) { - const MemoryBlock& block = kernel.getSharedBlock(blockID); + const SharedBlock& block = kernel.getSharedBlock(blockID); kernel.mapRegion(location, block.getLocation(), length, flags); // TODO: add block to current process // TODO: perform safety checks @@ -29,8 +40,8 @@ unsigned int createSharedBlock(void* location, size_t length, int flags) int aquireSharedBlock(void* location, unsigned int id) { - const MemoryBlock& block = kernel.getSharedBlock(id); - kernel.mapRegion(location, block.getLocation(), block.getSize(), block.getAttributes()); + const SharedBlock& block = kernel.getSharedBlock(id); + kernel.mapRegion(location, block.getLocation(), block.getSize(), block.getFlags()); // TODO: (somehow) handle invalid ids -- possibly hard while using references // TODO: add block to current process // TODO: perform safety checks @@ -59,4 +70,24 @@ int aquirePhysicalBlock(void* location, physaddr_t physicalAddress, size_t lengt int releasePhysicalBlock(int id) { return 0; +} + +int sendMessage(unsigned int recipient, const Message* message) +{ + Message* copy = new Message(*message); + copy->m_sender = kernel.getActiveProcess().getID(); + kernel.getProcess(recipient).pushMessage(copy); + return 0; +} + +int receiveMessage(Message* buffer) +{ + if(buffer == nullptr) + return 1; + Message* message = kernel.getActiveProcess().popMessage(); + if(message == nullptr) + return 1; + *buffer = *message; + delete message; + return 0; } \ No newline at end of file diff --git a/src/syscalls.hpp b/src/syscalls.hpp index 3971369..5364426 100644 --- a/src/syscalls.hpp +++ b/src/syscalls.hpp @@ -3,6 +3,7 @@ #include #include "systypes.hpp" +#include "message.hpp" int mmap(void* location, size_t length, int flags); @@ -20,4 +21,8 @@ int aquirePhysicalBlock(void* location, physaddr_t physicalAddress, size_t lengt int releasePhysicalBlock(int id); +int sendMessage(unsigned int recipient, const Message* message); + +int receiveMessage(Message* buffer); + #endif \ No newline at end of file diff --git a/src/systeminfo.cpp b/src/systeminfo.cpp deleted file mode 100644 index a7ceb84..0000000 --- a/src/systeminfo.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "systeminfo.hpp" -#include "util.hpp" - -using namespace kernelns; - -SystemInfo::SystemInfo() -{ - -} - -SystemInfo::SystemInfo(MemoryMap& memoryMap, const char* commandLine) - : m_memmap(memoryMap) -{ - strcpy(this->commandLine, commandLine); -} - -const MemoryMap& SystemInfo::getMemoryMap() const -{ - return m_memmap; -} - -const char* SystemInfo::getCommandLine() const -{ - return commandLine; -} diff --git a/src/systeminfo.hpp b/src/systeminfo.hpp deleted file mode 100644 index caff548..0000000 --- a/src/systeminfo.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef SYSTEMINFO_H -#define SYSTEMINFO_H - -#include - -#include "systypes.hpp" -#include "memorymap.hpp" - -namespace kernelns -{ - -class SystemInfo -{ -public: - - SystemInfo(); - - SystemInfo(MemoryMap& memoryMap, const char* commandLine); - - const MemoryMap& getMemoryMap() const; - - const char* getCommandLine() const; - -private: - - MemoryMap m_memmap; - - char commandLine[128]; - -}; - -} - -#endif diff --git a/src/util.cpp b/src/util.cpp index 89c2958..1256dbc 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,7 +1,7 @@ #include #include "util.hpp" -#include "kernelstate.hpp" +#include "kernel.hpp" void* memcpy(void* destination, const void* source, size_t num) { @@ -112,25 +112,31 @@ char* strcpy(char* destination, const char* source) void* malloc(size_t size) { - return kernelns::State::allocator.allocate(size); + return kernel.malloc(size); } void* calloc(size_t count, size_t size) { - return memset(malloc(count * size), 0, count * size); + void* ptr = malloc(count * size); + if(ptr != nullptr) + memset(malloc(count * size), 0, count * size); + return ptr; } void* realloc(void* ptr, size_t size) { - void* n = kernelns::State::allocator.allocate(size); - memmove(n, ptr, size); - free(ptr); + void* n = kernel.malloc(size); + if(n != nullptr) + { + memmove(n, ptr, size); + free(ptr); + } return n; } void free(void* p) { - kernelns::State::allocator.free(p); + kernel.free(p); } void __cxa_pure_virtual() diff --git a/src/x86/initialize.cpp b/src/x86/initialize.cpp index 57255fb..361cd4f 100644 --- a/src/x86/initialize.cpp +++ b/src/x86/initialize.cpp @@ -1,30 +1,14 @@ #include #include "multiboot2.hpp" #include "tty.hpp" -#include "../kernelstate.hpp" -#include "../systeminfo.hpp" #include "../mmap.hpp" #include "../util.hpp" +#include "../memorytype.hpp" using namespace kernelns; extern int _kernelEnd; -enum BootInfoType -{ - Terminate = 0, - CommandLine = 1, - BootLoader = 2, - Module = 3, - MemoryInfo = 4, - BootDevice = 5, - MMap = 6, - VBEInfo = 7, - FramebufferInfo = 8, - ELFSymbols = 9, - APMTable = 10 -}; - extern "C" int startPaging(uint32_t* directory, uint32_t* table, uint32_t* identityTable) { @@ -57,12 +41,12 @@ int initialize(void* multibootInfo) for(; heapSize > 1; log++) heapSize >>= 1; heapSize <<= log; - new(&State::allocator) Allocator((void*) (0xFFC00000 - heapSize), heapSize, 64); + //new(&State::allocator) Allocator((void*) (0xFFC00000 - heapSize), heapSize, 64); Multiboot2Info bootInfo(multibootInfo); if(!bootInfo.isValid()) return 1; - bootInfo.getMemoryMap().insertEntry(0, 4 * 1024 * 1024, MemoryMap::UNAVAILABLE); - new(&State::config) SystemInfo(bootInfo.getMemoryMap(), bootInfo.getCommandLine()); + bootInfo.getMemoryMap().insertEntry(0, 4 * 1024 * 1024, (unsigned int) MemoryType::Unavailable); + //new(&State::config) SystemInfo(bootInfo.getMemoryMap(), bootInfo.getCommandLine()); TTY tty((char*) 0xFF8B8000); tty << "Type\t\tLocation\t\tSize\n"; for(size_t i = 0; i < bootInfo.getMemoryMap().size() && bootInfo.getMemoryMap()[i].getSize() > 0; i++) diff --git a/src/x86/memorymanagerx86.cpp b/src/x86/memorymanagerx86.cpp new file mode 100644 index 0000000..b4aaefc --- /dev/null +++ b/src/x86/memorymanagerx86.cpp @@ -0,0 +1,31 @@ +#include "memorymanagerx86.hpp" + +unsigned int MemoryManagerx86::getPageSize() const +{ + return pageSize; +} + +physaddr_t MemoryManagerx86::createAddressSpace() +{ + if(((size_t) table & 0xFFF) != 0) + return -1; + PageTableEntry* newDirectory = (PageTableEntry*) table; + newDirectory[1022] = m_pageDirectory[1022]; + newDirectory[1023] = m_pageDirectory[1023]; + return 0; +} + +void MemoryManagerx86::loadAddressSpace(physaddr_t table) +{ + +} + +int MemoryManagerx86::mapPage(void *page, physaddr_t frame, int flags) +{ + +} + +physaddr_t MemoryManagerx86::unmapPage(void *page) +{ + +} \ No newline at end of file diff --git a/src/x86/memorymanagerx86.hpp b/src/x86/memorymanagerx86.hpp new file mode 100644 index 0000000..ed3273e --- /dev/null +++ b/src/x86/memorymanagerx86.hpp @@ -0,0 +1,29 @@ +#ifndef MEMORYMANAGERX86_H +#define MEMORYMANAGERX86_H + +#include "../memorymanager.hpp" +#include "pagetableentry.hpp" + +class MemoryManagerx86 : public MemoryManager +{ +public: + + virtual unsigned int getPageSize() const; + + virtual physaddr_t createAddressSpace(); + + virtual void loadAddressSpace(physaddr_t table); + + virtual int mapPage(void* page, physaddr_t frame, int flags); + + virtual physaddr_t unmapPage(void* page); + +private: + + static const unsigned int pageSize = 4096; + + PageTableEntry *m_pageTables, *m_pageDirectory; + +}; + +#endif \ No newline at end of file diff --git a/src/x86/multiboot2.cpp b/src/x86/multiboot2.cpp index b1569f4..ba745b5 100644 --- a/src/x86/multiboot2.cpp +++ b/src/x86/multiboot2.cpp @@ -1,4 +1,5 @@ #include "multiboot2.hpp" +#include "../memorytype.hpp" using namespace kernelns; @@ -11,31 +12,35 @@ Multiboot2Info::Multiboot2Info(void* tableLocation) ptr += 2; while(*ptr != 0) { - if(*ptr == T_BootCommand) + if(*ptr == (uint32_t) Tag::BootCommand) { m_commandLine = &reinterpret_cast(ptr)->str; } - else if(*ptr == T_Bootloader) + else if(*ptr == (uint32_t) Tag::Bootloader) { m_bootloader = &reinterpret_cast(ptr)->str; } - else if(*ptr == T_MemoryMap) + else if(*ptr == (uint32_t) Tag::MemoryMap) { unsigned int tagSize = reinterpret_cast(ptr)->size - 16; unsigned int entrySize = reinterpret_cast(ptr)->entrySize; MemoryMapEntry* entry = &reinterpret_cast(ptr)->entries; while(tagSize > 0) { - m_memmap.insertEntry(entry->base, entry->length, (MemoryMap::Type) entry->type); + unsigned int regionType = + (entry->type == (unsigned int) Multiboot2MemoryType::Available) ? (unsigned int) MemoryType::Available + : ((entry->type == (unsigned int) Multiboot2MemoryType::Defective) ? (unsigned int) MemoryType::Defective + : (unsigned int) MemoryType::Unavailable); + m_memmap.insertEntry(entry->base, entry->length, entry->type); entry = (MemoryMapEntry*) (reinterpret_cast(entry) + entrySize); tagSize -= entrySize; } } - else if(*ptr == T_Module) + else if(*ptr == (uint32_t) Tag::Module) { TagModule* moduleTag = reinterpret_cast(ptr); m_modules[m_moduleCount] = Module(moduleTag->start, moduleTag->end, &moduleTag->str); - m_memmap.insertEntry(moduleTag->start, moduleTag->end - moduleTag->start, MemoryMap::UNAVAILABLE); + m_memmap.insertEntry(moduleTag->start, moduleTag->end - moduleTag->start, (unsigned int) MemoryType::Unavailable); } unsigned int size = (ptr[1] + 7) - ((ptr[1] + 7) % 8); ptr += size / sizeof(uint32_t); diff --git a/src/x86/multiboot2.hpp b/src/x86/multiboot2.hpp index 6fcaf37..73962e1 100644 --- a/src/x86/multiboot2.hpp +++ b/src/x86/multiboot2.hpp @@ -11,29 +11,36 @@ class Multiboot2Info { public: - enum TagType + enum class Tag { - T_BootCommand = 1, - T_Bootloader = 2, - T_Module = 3, - T_MemoryInfo = 4, - T_BIOSBootDevice = 5, - T_MemoryMap = 6, - T_VBE = 7, - T_Framebuffer = 8, - T_ELFSymbols = 9, - T_APM = 10, - T_EFI32SystemTable = 11, - T_EFI64SystemTable = 12, - T_SMBIOS = 13, - T_ACPI10RSDP = 14, - T_ACPT20RSDP = 15, - T_Network = 16, - T_EFIMemoryMap = 17, - T_EFIBootServices = 18, - T_EFI32Image = 19, - T_EFI64Image = 20, - T_LoadAddress = 21 + BootCommand = 1, + Bootloader = 2, + Module = 3, + MemoryInfo = 4, + BIOSBootDevice = 5, + MemoryMap = 6, + VBE = 7, + Framebuffer = 8, + ELFSymbols = 9, + APM = 10, + EFI32SystemTable = 11, + EFI64SystemTable = 12, + SMBIOS = 13, + ACPI10RSDP = 14, + ACPT20RSDP = 15, + Network = 16, + EFIMemoryMap = 17, + EFIBootServices = 18, + EFI32Image = 19, + EFI64Image = 20, + LoadAddress = 21 + }; + + enum class Multiboot2MemoryType + { + Available = 1, + ACPI = 3, + Defective = 5 }; struct TagString diff --git a/src/x86/pagetableentry.cpp b/src/x86/pagetableentry.cpp new file mode 100644 index 0000000..5e50799 --- /dev/null +++ b/src/x86/pagetableentry.cpp @@ -0,0 +1,132 @@ +#include "pagetableentry.hpp" + +PageTableEntry::PageTableEntry() +{ + this->present = 0; + this->rw = 0; + this->usermode = 0; + this->writeThrough = 0; + this->cacheDisable = 0; + this->accessed = 0; + this->dirty = 0; + this->pat = 0; + this->global = 0; + this->shared = 0; + this->ignored = 0; + this->physicalAddress = 0; +} + +bool PageTableEntry::getAccessed() const +{ + return accessed == 1; +} + +bool PageTableEntry::getCacheDisable() const +{ + return cacheDisable == 1; +} + +void PageTableEntry::setCacheDisable(bool cacheDisable) +{ + this->cacheDisable = cacheDisable ? 1 : 0; +} + +bool PageTableEntry::getDirty() const +{ + return dirty == 1; +} + +bool PageTableEntry::getGlobal() const +{ + return global == 1; +} + +void PageTableEntry::setGlobal(bool global) +{ + this->global = global ? 1 : 0; +} + +bool PageTableEntry::getPat() const +{ + return pat == 1; +} + +void PageTableEntry::setPat(bool pat) +{ + this->pat = pat ? 1 : 0; +} + +physaddr_t PageTableEntry::getPhysicalAddress() const +{ + physaddr_t physicalAddress = this->physicalAddress; + return physicalAddress << 12; +} + +physaddr_t PageTableEntry::setPhysicalAddress(physaddr_t physicalAddress) +{ + this->physicalAddress = physicalAddress >> 12; + return this->physicalAddress << 12; +} + +bool PageTableEntry::getPresent() const +{ + return present == 1; +} + +void PageTableEntry::setPresent(bool present) +{ + this->present = present ? 1 : 0; +} + +bool PageTableEntry::getRw() const +{ + return rw == 1; +} + +void PageTableEntry::setRw(bool rw) +{ + this->rw = rw ? 1 : 0; +} + +bool PageTableEntry::getShared() const +{ + return shared == 1; +} + +void PageTableEntry::setShared(bool shared) +{ + this->shared = shared ? 1 : 0; +} + +bool PageTableEntry::getUsermode() const +{ + return usermode == 1; +} + +void PageTableEntry::setUsermode(bool usermode) +{ + this->usermode = usermode ? 1 : 0; +} + +bool PageTableEntry::getWriteThrough() const +{ + return writeThrough == 1; +} + +void PageTableEntry::setWriteThrough(bool writeThrough) +{ + this->writeThrough = writeThrough ? 1 : 0; +} + +physaddr_t PageTableEntry::operator=(physaddr_t rhs) +{ + return setPhysicalAddress(rhs); +} + +PageTableEntry PageTableEntry::operator=(PageTableEntry rhs) +{ + uint32_t *iThis = (uint32_t *)this; + uint32_t *iThat = (uint32_t *)&rhs; + *iThis = *iThat; + return rhs; +} \ No newline at end of file diff --git a/src/x86/pagetableentry.hpp b/src/x86/pagetableentry.hpp new file mode 100644 index 0000000..1a5381c --- /dev/null +++ b/src/x86/pagetableentry.hpp @@ -0,0 +1,83 @@ +#ifndef PAGETABLEENTRY_H +#define PAGETABLEENTRY_H + +#include "../systypes.hpp" + +class PageTableEntry { +public: + + PageTableEntry(); + + bool getAccessed() const; + + bool getCacheDisable() const; + + void setCacheDisable(bool cacheDisable); + + bool getDirty() const; + + bool getGlobal() const; + + void setGlobal(bool global); + + bool getPat() const; + + void setPat(bool pat); + + physaddr_t getPhysicalAddress() const; + + physaddr_t setPhysicalAddress(physaddr_t physicalAddress); + + bool getPresent() const; + + void setPresent(bool present); + + bool getRw() const; + + void setRw(bool rw); + + bool getShared() const; + + void setShared(bool shared); + + bool getUsermode() const; + + void setUsermode(bool usermode); + + bool getWriteThrough() const; + + void setWriteThrough(bool writeThrough); + + physaddr_t operator=(physaddr_t rhs); + + PageTableEntry operator=(PageTableEntry rhs); + +private: + + uint32_t present : 1; + + uint32_t rw : 1; + + uint32_t usermode : 1; + + uint32_t writeThrough : 1; + + uint32_t cacheDisable : 1; + + uint32_t accessed : 1; + + uint32_t dirty : 1; + + uint32_t pat : 1; + + uint32_t global : 1; + + uint32_t shared : 1; + + uint32_t ignored : 2; + + uint32_t physicalAddress : 20; + +}; + +#endif \ No newline at end of file