More unfinished work on kernel API
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
noinst_PROGRAMS = quark-kernel
|
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_LDADD = -lgcc
|
||||||
quark_kernel_CPPFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -fno-exceptions -fno-rtti -ggdb
|
quark_kernel_CPPFLAGS = -ffreestanding -mgeneral-regs-only -O0 -Wall -fno-exceptions -fno-rtti -ggdb
|
||||||
quark_kernel_LDFLAGS = -nostdlib
|
quark_kernel_LDFLAGS = -nostdlib
|
||||||
@@ -14,3 +14,4 @@ quark_kernel_SOURCES += x86/mmap.cpp \
|
|||||||
quark_kernel_LDFLAGS += -T x86/linker.ld
|
quark_kernel_LDFLAGS += -T x86/linker.ld
|
||||||
quark_kernel_DEPENDENCIES = x86/linker.ld
|
quark_kernel_DEPENDENCIES = x86/linker.ld
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include "pageallocator.hpp"
|
#include "pageallocator.hpp"
|
||||||
#include "memorymanager.hpp"
|
#include "memorymanager.hpp"
|
||||||
#include "memorymap.hpp"
|
#include "memorymap.hpp"
|
||||||
#include "memoryblock.hpp"
|
#include "sharedblock.hpp"
|
||||||
#include "process.hpp"
|
#include "process.hpp"
|
||||||
#include "systypes.hpp"
|
#include "systypes.hpp"
|
||||||
|
|
||||||
@@ -14,6 +14,10 @@ class Kernel
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
void* malloc(size_t size);
|
||||||
|
|
||||||
|
void free(void* ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Maps a region of pages starting at virtual address 'page' with
|
* @brief Maps a region of pages starting at virtual address 'page' with
|
||||||
* length 'length'. Allocates each mapped frame and any necessary page
|
* length 'length'. Allocates each mapped frame and any necessary page
|
||||||
@@ -64,9 +68,30 @@ public:
|
|||||||
*/
|
*/
|
||||||
void unmapRegion(void* page, size_t length);
|
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);
|
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'
|
* @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,
|
* If it holds any shared blocks which are not held by any other process,
|
||||||
* those blocks will be freed.
|
* 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);
|
void terminateProcess(unsigned int pid);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
@@ -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
|
|
||||||
95
src/map.hpp
95
src/map.hpp
@@ -1,95 +0,0 @@
|
|||||||
#ifndef MAP_H
|
|
||||||
#define MAP_H
|
|
||||||
|
|
||||||
template<class Key, class Value>
|
|
||||||
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
|
|
||||||
@@ -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
|
|
||||||
@@ -12,7 +12,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @return the size in bytes of a single page
|
* @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
|
* Allocates space for a new top-level page table, and initializes it to
|
||||||
|
|||||||
@@ -2,129 +2,6 @@
|
|||||||
|
|
||||||
using namespace kernelns;
|
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()
|
MemoryMap::MemoryMap()
|
||||||
{
|
{
|
||||||
this->m_entries = 0;
|
this->m_entries = 0;
|
||||||
@@ -137,7 +14,7 @@ MemoryMap::MemoryMap(MemoryMap& copy)
|
|||||||
this->m_entries = copy.m_entries;
|
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];
|
return m_map[index];
|
||||||
}
|
}
|
||||||
@@ -147,76 +24,58 @@ size_t MemoryMap::size() const
|
|||||||
return m_entries;
|
return m_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryMap::insertEntry(physaddr_t location, size_t size, Type type)
|
size_t MemoryMap::totalMemory() const
|
||||||
{
|
{
|
||||||
Region newRegion(location, size, type);
|
size_t sum = 0;
|
||||||
unsigned int i = 0;
|
for(int i = 0; i < m_entries; i++)
|
||||||
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++)
|
|
||||||
{
|
{
|
||||||
if(m_map[i].overlaps(m_map[i+1]))
|
sum += m_map[i].getSize();
|
||||||
{
|
|
||||||
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--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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)
|
void MemoryMap::remove(unsigned int index)
|
||||||
@@ -226,4 +85,88 @@ void MemoryMap::remove(unsigned int index)
|
|||||||
m_map[i] = m_map[i+1];
|
m_map[i] = m_map[i+1];
|
||||||
}
|
}
|
||||||
m_entries--;
|
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;
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
#define MEMORYMAP_H
|
#define MEMORYMAP_H
|
||||||
|
|
||||||
#include "systypes.hpp"
|
#include "systypes.hpp"
|
||||||
|
#include "memoryregion.hpp"
|
||||||
|
|
||||||
namespace kernelns
|
namespace kernelns
|
||||||
{
|
{
|
||||||
@@ -9,90 +10,138 @@ namespace kernelns
|
|||||||
class MemoryMap
|
class MemoryMap
|
||||||
{
|
{
|
||||||
public:
|
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(MemoryMap& copy);
|
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;
|
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;
|
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:
|
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);
|
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;
|
static const unsigned int maxEntries = 16;
|
||||||
|
|
||||||
Region m_map[maxEntries];
|
static const unsigned int invalidIndex = 0xFFFF;
|
||||||
|
|
||||||
|
MemoryRegion m_map[maxEntries];
|
||||||
|
|
||||||
size_t m_entries;
|
size_t m_entries;
|
||||||
|
|
||||||
|
|||||||
128
src/memoryregion.cpp
Normal file
128
src/memoryregion.cpp
Normal file
@@ -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;
|
||||||
|
}
|
||||||
87
src/memoryregion.hpp
Normal file
87
src/memoryregion.hpp
Normal file
@@ -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
|
||||||
11
src/memorytype.hpp
Normal file
11
src/memorytype.hpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef MEMORYTYPE_H
|
||||||
|
#define MEMORYTYPE_H
|
||||||
|
|
||||||
|
enum class MemoryType
|
||||||
|
{
|
||||||
|
Available = 1,
|
||||||
|
Unavailable = 2,
|
||||||
|
Defective = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
38
src/message.cpp
Normal file
38
src/message.cpp
Normal file
@@ -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];
|
||||||
|
}
|
||||||
59
src/message.hpp
Normal file
59
src/message.hpp
Normal file
@@ -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
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
#ifndef MMGR_H
|
|
||||||
#define MMGR_H
|
|
||||||
|
|
||||||
#include "mmap.hpp"
|
|
||||||
#include "pageallocator.hpp"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "pageallocator.hpp"
|
#include "pageallocator.hpp"
|
||||||
#include "systypes.hpp"
|
#include "systypes.hpp"
|
||||||
#include "memorymap.hpp"
|
#include "memorymap.hpp"
|
||||||
|
#include "memorytype.hpp"
|
||||||
|
|
||||||
#define roundUp(n, m) ((n % m == 0) ? n : (n + m - (n % m)))
|
#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;
|
physaddr_t location = 0x100000;
|
||||||
for(size_t i = 0; i < memmap.size() && memmap[i].getSize() > 0; i++)
|
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;
|
continue;
|
||||||
if(memmap[i].getLocation() > location)
|
if(memmap[i].getLocation() > location)
|
||||||
location = roundUp(memmap[i].getLocation(), 4096);
|
location = roundUp(memmap[i].getLocation(), 4096);
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
#define PROCESS_H
|
#define PROCESS_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "map.hpp"
|
|
||||||
|
#include "message.hpp"
|
||||||
|
|
||||||
namespace kernelns
|
namespace kernelns
|
||||||
{
|
{
|
||||||
@@ -17,16 +18,35 @@ public:
|
|||||||
|
|
||||||
Process();
|
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 hasSharedBlock(unsigned int blockID) const;
|
||||||
|
|
||||||
bool hasPhysicalBlock(unsigned int blockID) const;
|
bool hasPhysicalBlock(unsigned int blockID) const;
|
||||||
|
|
||||||
|
void pushMessage(Message* message);
|
||||||
|
|
||||||
|
Message* popMessage();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Map<unsigned int, MemoryBlock&> m_sharedBlocks;
|
|
||||||
|
|
||||||
Map<unsigned int, MemoryBlock&> m_physicalBlocks;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/sharedblock.hpp
Normal file
18
src/sharedblock.hpp
Normal file
@@ -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
|
||||||
@@ -1,17 +1,28 @@
|
|||||||
#include "syscalls.hpp"
|
#include "syscalls.hpp"
|
||||||
#include "kernel.hpp"
|
#include "kernel.hpp"
|
||||||
|
#include "memorytype.hpp"
|
||||||
|
|
||||||
int mmap(void* location, size_t length, int flags)
|
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);
|
return kernel.allocateRegion(location, length, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
int munmap(void* location, size_t length)
|
int munmap(void* location, size_t length)
|
||||||
{
|
{
|
||||||
// TODO: check that the requested region does not overlap something important
|
if(kernel.getActiveProcess().unmap(location, length))
|
||||||
kernel.freeRegion(location, length);
|
{
|
||||||
return 0;
|
kernel.freeRegion(location, length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int createSharedBlock(void* location, size_t length, int flags)
|
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);
|
unsigned int blockID = kernel.createSharedBlock(length, flags);
|
||||||
if(blockID > 0)
|
if(blockID > 0)
|
||||||
{
|
{
|
||||||
const MemoryBlock& block = kernel.getSharedBlock(blockID);
|
const SharedBlock& block = kernel.getSharedBlock(blockID);
|
||||||
kernel.mapRegion(location, block.getLocation(), length, flags);
|
kernel.mapRegion(location, block.getLocation(), length, flags);
|
||||||
// TODO: add block to current process
|
// TODO: add block to current process
|
||||||
// TODO: perform safety checks
|
// 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)
|
int aquireSharedBlock(void* location, unsigned int id)
|
||||||
{
|
{
|
||||||
const MemoryBlock& block = kernel.getSharedBlock(id);
|
const SharedBlock& block = kernel.getSharedBlock(id);
|
||||||
kernel.mapRegion(location, block.getLocation(), block.getSize(), block.getAttributes());
|
kernel.mapRegion(location, block.getLocation(), block.getSize(), block.getFlags());
|
||||||
// TODO: (somehow) handle invalid ids -- possibly hard while using references
|
// TODO: (somehow) handle invalid ids -- possibly hard while using references
|
||||||
// TODO: add block to current process
|
// TODO: add block to current process
|
||||||
// TODO: perform safety checks
|
// TODO: perform safety checks
|
||||||
@@ -59,4 +70,24 @@ int aquirePhysicalBlock(void* location, physaddr_t physicalAddress, size_t lengt
|
|||||||
int releasePhysicalBlock(int id)
|
int releasePhysicalBlock(int id)
|
||||||
{
|
{
|
||||||
return 0;
|
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;
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "systypes.hpp"
|
#include "systypes.hpp"
|
||||||
|
#include "message.hpp"
|
||||||
|
|
||||||
int mmap(void* location, size_t length, int flags);
|
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 releasePhysicalBlock(int id);
|
||||||
|
|
||||||
|
int sendMessage(unsigned int recipient, const Message* message);
|
||||||
|
|
||||||
|
int receiveMessage(Message* buffer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#ifndef SYSTEMINFO_H
|
|
||||||
#define SYSTEMINFO_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
20
src/util.cpp
20
src/util.cpp
@@ -1,7 +1,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
#include "kernelstate.hpp"
|
#include "kernel.hpp"
|
||||||
|
|
||||||
void* memcpy(void* destination, const void* source, size_t num)
|
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)
|
void* malloc(size_t size)
|
||||||
{
|
{
|
||||||
return kernelns::State::allocator.allocate(size);
|
return kernel.malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* calloc(size_t count, size_t 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* realloc(void* ptr, size_t size)
|
||||||
{
|
{
|
||||||
void* n = kernelns::State::allocator.allocate(size);
|
void* n = kernel.malloc(size);
|
||||||
memmove(n, ptr, size);
|
if(n != nullptr)
|
||||||
free(ptr);
|
{
|
||||||
|
memmove(n, ptr, size);
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free(void* p)
|
void free(void* p)
|
||||||
{
|
{
|
||||||
kernelns::State::allocator.free(p);
|
kernel.free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __cxa_pure_virtual()
|
void __cxa_pure_virtual()
|
||||||
|
|||||||
@@ -1,30 +1,14 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "multiboot2.hpp"
|
#include "multiboot2.hpp"
|
||||||
#include "tty.hpp"
|
#include "tty.hpp"
|
||||||
#include "../kernelstate.hpp"
|
|
||||||
#include "../systeminfo.hpp"
|
|
||||||
#include "../mmap.hpp"
|
#include "../mmap.hpp"
|
||||||
#include "../util.hpp"
|
#include "../util.hpp"
|
||||||
|
#include "../memorytype.hpp"
|
||||||
|
|
||||||
using namespace kernelns;
|
using namespace kernelns;
|
||||||
|
|
||||||
extern int _kernelEnd;
|
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"
|
extern "C"
|
||||||
int startPaging(uint32_t* directory, uint32_t* table, uint32_t* identityTable)
|
int startPaging(uint32_t* directory, uint32_t* table, uint32_t* identityTable)
|
||||||
{
|
{
|
||||||
@@ -57,12 +41,12 @@ int initialize(void* multibootInfo)
|
|||||||
for(; heapSize > 1; log++)
|
for(; heapSize > 1; log++)
|
||||||
heapSize >>= 1;
|
heapSize >>= 1;
|
||||||
heapSize <<= log;
|
heapSize <<= log;
|
||||||
new(&State::allocator) Allocator((void*) (0xFFC00000 - heapSize), heapSize, 64);
|
//new(&State::allocator) Allocator((void*) (0xFFC00000 - heapSize), heapSize, 64);
|
||||||
Multiboot2Info bootInfo(multibootInfo);
|
Multiboot2Info bootInfo(multibootInfo);
|
||||||
if(!bootInfo.isValid())
|
if(!bootInfo.isValid())
|
||||||
return 1;
|
return 1;
|
||||||
bootInfo.getMemoryMap().insertEntry(0, 4 * 1024 * 1024, MemoryMap::UNAVAILABLE);
|
bootInfo.getMemoryMap().insertEntry(0, 4 * 1024 * 1024, (unsigned int) MemoryType::Unavailable);
|
||||||
new(&State::config) SystemInfo(bootInfo.getMemoryMap(), bootInfo.getCommandLine());
|
//new(&State::config) SystemInfo(bootInfo.getMemoryMap(), bootInfo.getCommandLine());
|
||||||
TTY tty((char*) 0xFF8B8000);
|
TTY tty((char*) 0xFF8B8000);
|
||||||
tty << "Type\t\tLocation\t\tSize\n";
|
tty << "Type\t\tLocation\t\tSize\n";
|
||||||
for(size_t i = 0; i < bootInfo.getMemoryMap().size() && bootInfo.getMemoryMap()[i].getSize() > 0; i++)
|
for(size_t i = 0; i < bootInfo.getMemoryMap().size() && bootInfo.getMemoryMap()[i].getSize() > 0; i++)
|
||||||
|
|||||||
31
src/x86/memorymanagerx86.cpp
Normal file
31
src/x86/memorymanagerx86.cpp
Normal file
@@ -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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
29
src/x86/memorymanagerx86.hpp
Normal file
29
src/x86/memorymanagerx86.hpp
Normal file
@@ -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
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "multiboot2.hpp"
|
#include "multiboot2.hpp"
|
||||||
|
#include "../memorytype.hpp"
|
||||||
|
|
||||||
using namespace kernelns;
|
using namespace kernelns;
|
||||||
|
|
||||||
@@ -11,31 +12,35 @@ Multiboot2Info::Multiboot2Info(void* tableLocation)
|
|||||||
ptr += 2;
|
ptr += 2;
|
||||||
while(*ptr != 0)
|
while(*ptr != 0)
|
||||||
{
|
{
|
||||||
if(*ptr == T_BootCommand)
|
if(*ptr == (uint32_t) Tag::BootCommand)
|
||||||
{
|
{
|
||||||
m_commandLine = &reinterpret_cast<TagString*>(ptr)->str;
|
m_commandLine = &reinterpret_cast<TagString*>(ptr)->str;
|
||||||
}
|
}
|
||||||
else if(*ptr == T_Bootloader)
|
else if(*ptr == (uint32_t) Tag::Bootloader)
|
||||||
{
|
{
|
||||||
m_bootloader = &reinterpret_cast<TagString*>(ptr)->str;
|
m_bootloader = &reinterpret_cast<TagString*>(ptr)->str;
|
||||||
}
|
}
|
||||||
else if(*ptr == T_MemoryMap)
|
else if(*ptr == (uint32_t) Tag::MemoryMap)
|
||||||
{
|
{
|
||||||
unsigned int tagSize = reinterpret_cast<TagMemoryMap*>(ptr)->size - 16;
|
unsigned int tagSize = reinterpret_cast<TagMemoryMap*>(ptr)->size - 16;
|
||||||
unsigned int entrySize = reinterpret_cast<TagMemoryMap*>(ptr)->entrySize;
|
unsigned int entrySize = reinterpret_cast<TagMemoryMap*>(ptr)->entrySize;
|
||||||
MemoryMapEntry* entry = &reinterpret_cast<TagMemoryMap*>(ptr)->entries;
|
MemoryMapEntry* entry = &reinterpret_cast<TagMemoryMap*>(ptr)->entries;
|
||||||
while(tagSize > 0)
|
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<char*>(entry) + entrySize);
|
entry = (MemoryMapEntry*) (reinterpret_cast<char*>(entry) + entrySize);
|
||||||
tagSize -= entrySize;
|
tagSize -= entrySize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(*ptr == T_Module)
|
else if(*ptr == (uint32_t) Tag::Module)
|
||||||
{
|
{
|
||||||
TagModule* moduleTag = reinterpret_cast<TagModule*>(ptr);
|
TagModule* moduleTag = reinterpret_cast<TagModule*>(ptr);
|
||||||
m_modules[m_moduleCount] = Module(moduleTag->start, moduleTag->end, &moduleTag->str);
|
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);
|
unsigned int size = (ptr[1] + 7) - ((ptr[1] + 7) % 8);
|
||||||
ptr += size / sizeof(uint32_t);
|
ptr += size / sizeof(uint32_t);
|
||||||
|
|||||||
@@ -11,29 +11,36 @@ class Multiboot2Info
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum TagType
|
enum class Tag
|
||||||
{
|
{
|
||||||
T_BootCommand = 1,
|
BootCommand = 1,
|
||||||
T_Bootloader = 2,
|
Bootloader = 2,
|
||||||
T_Module = 3,
|
Module = 3,
|
||||||
T_MemoryInfo = 4,
|
MemoryInfo = 4,
|
||||||
T_BIOSBootDevice = 5,
|
BIOSBootDevice = 5,
|
||||||
T_MemoryMap = 6,
|
MemoryMap = 6,
|
||||||
T_VBE = 7,
|
VBE = 7,
|
||||||
T_Framebuffer = 8,
|
Framebuffer = 8,
|
||||||
T_ELFSymbols = 9,
|
ELFSymbols = 9,
|
||||||
T_APM = 10,
|
APM = 10,
|
||||||
T_EFI32SystemTable = 11,
|
EFI32SystemTable = 11,
|
||||||
T_EFI64SystemTable = 12,
|
EFI64SystemTable = 12,
|
||||||
T_SMBIOS = 13,
|
SMBIOS = 13,
|
||||||
T_ACPI10RSDP = 14,
|
ACPI10RSDP = 14,
|
||||||
T_ACPT20RSDP = 15,
|
ACPT20RSDP = 15,
|
||||||
T_Network = 16,
|
Network = 16,
|
||||||
T_EFIMemoryMap = 17,
|
EFIMemoryMap = 17,
|
||||||
T_EFIBootServices = 18,
|
EFIBootServices = 18,
|
||||||
T_EFI32Image = 19,
|
EFI32Image = 19,
|
||||||
T_EFI64Image = 20,
|
EFI64Image = 20,
|
||||||
T_LoadAddress = 21
|
LoadAddress = 21
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Multiboot2MemoryType
|
||||||
|
{
|
||||||
|
Available = 1,
|
||||||
|
ACPI = 3,
|
||||||
|
Defective = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TagString
|
struct TagString
|
||||||
|
|||||||
132
src/x86/pagetableentry.cpp
Normal file
132
src/x86/pagetableentry.cpp
Normal file
@@ -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;
|
||||||
|
}
|
||||||
83
src/x86/pagetableentry.hpp
Normal file
83
src/x86/pagetableentry.hpp
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user