More work on Kernel class, syscalls

This commit is contained in:
Nathan Giddings
2020-12-11 09:19:29 -06:00
parent e8c3de4a63
commit 69c3c8a847
34 changed files with 390 additions and 121 deletions

View File

@@ -20,12 +20,12 @@ inline size_t ilog2(size_t n)
return count - (isPowerOfTwo ? 1 : 0); return count - (isPowerOfTwo ? 1 : 0);
} }
kernel::Allocator::Allocator() kernelns::Allocator::Allocator()
{ {
} }
kernel::Allocator::Allocator(void* base, size_t heapSize, size_t blockSize) kernelns::Allocator::Allocator(void* base, size_t heapSize, size_t blockSize)
{ {
this->base = (char*) base; this->base = (char*) base;
this->heapSize = heapSize; this->heapSize = heapSize;
@@ -54,7 +54,7 @@ kernel::Allocator::Allocator(void* base, size_t heapSize, size_t blockSize)
} }
} }
void* kernel::Allocator::allocate(size_t size) void* kernelns::Allocator::allocate(size_t size)
{ {
size += blockSize - 1; size += blockSize - 1;
size -= size % blockSize; size -= size % blockSize;
@@ -68,7 +68,7 @@ void* kernel::Allocator::allocate(size_t size)
return NULL; return NULL;
} }
void kernel::Allocator::free(void* location) void kernelns::Allocator::free(void* location)
{ {
size_t offset = (size_t) location - (size_t) base; size_t offset = (size_t) location - (size_t) base;
size_t index = (offset / blockSize) + (1 << treeHeight); size_t index = (offset / blockSize) + (1 << treeHeight);
@@ -82,7 +82,7 @@ void kernel::Allocator::free(void* location)
} }
} }
size_t kernel::Allocator::findFreeBlock(size_t height) size_t kernelns::Allocator::findFreeBlock(size_t height)
{ {
if(height > treeHeight) if(height > treeHeight)
return 0; return 0;

View File

@@ -3,7 +3,7 @@
#include <stddef.h> #include <stddef.h>
namespace kernel namespace kernelns
{ {
class Allocator class Allocator

View File

@@ -1,23 +1,23 @@
#include "elf.hpp" #include "elf.hpp"
#include "util.hpp" #include "util.hpp"
kernel::ELF::ELF() kernelns::ELF::ELF()
{ {
this->m_fileLocation = (void*) NULL; this->m_fileLocation = (void*) NULL;
} }
kernel::ELF::ELF(void* location) kernelns::ELF::ELF(void* location)
{ {
this->m_fileLocation = location; this->m_fileLocation = location;
} }
void* kernel::ELF::entry() void* kernelns::ELF::entry()
{ {
Header* fileHeader = (Header*) m_fileLocation; Header* fileHeader = (Header*) m_fileLocation;
return fileHeader->entry; return fileHeader->entry;
} }
int kernel::ELF::validate() int kernelns::ELF::validate()
{ {
Header* fileHeader = (Header*) m_fileLocation; Header* fileHeader = (Header*) m_fileLocation;
if(fileHeader->magic != 0x464c457f) if(fileHeader->magic != 0x464c457f)
@@ -29,7 +29,7 @@ int kernel::ELF::validate()
return 0; return 0;
} }
int kernel::ELF::load() int kernelns::ELF::load()
{ {
Header* fileHeader = (Header*) m_fileLocation; Header* fileHeader = (Header*) m_fileLocation;
ProgramHeader* programHeader = (ProgramHeader*) ((size_t) m_fileLocation + fileHeader->phoffset); ProgramHeader* programHeader = (ProgramHeader*) ((size_t) m_fileLocation + fileHeader->phoffset);

View File

@@ -3,7 +3,7 @@
#include "systypes.hpp" #include "systypes.hpp"
namespace kernel namespace kernelns
{ {
class ELF class ELF

View File

@@ -1,7 +1,7 @@
#ifndef INTERRUPTS_H #ifndef INTERRUPTS_H
#define INTERRUPTS_H #define INTERRUPTS_H
namespace kernel namespace kernelns
{ {
class Interrupts class Interrupts
{ {

31
src/kernel.cpp Normal file
View File

@@ -0,0 +1,31 @@
#include "kernel.hpp"
int Kernel::allocateRegion(void* page, size_t length, int flags)
{
char* ptr = (char*) page;
for(int i = (int) length; i > 0; i -= mmgr.getPageSize())
{
physaddr_t frame = pageAllocator.allocate(mmgr.getPageSize());
if(frame != 0)
mmgr.mapPage(page, reserveFrame(), flags);
else
return -1;
ptr += mmgr.getPageSize();
}
return 0;
}
void Kernel::freeRegion(void* page, size_t length)
{
char* ptr = (char*) page;
for(int i = (int) length; i > 0; i -= mmgr.getPageSize())
{
pageAllocator.free(mmgr.unmapPage((void*) ptr), mmgr.getPageSize());
ptr += mmgr.getPageSize();
}
}
int Kernel::mapRegion(void* page, physaddr_t frame, size_t length, int flags)
{
}

View File

@@ -1,17 +1,24 @@
#ifndef KERNEL_H #ifndef KERNEL_H
#define KERNEL_H #define KERNEL_H
#include "pageallocator.hpp"
#include "memorymanager.hpp"
#include "memoryblock.hpp"
#include "process.hpp"
#include "systypes.hpp" #include "systypes.hpp"
using namespace kernelns;
class Kernel class Kernel
{ {
public: public:
Kernel();
/** /**
* Maps a region of pages starting at the virtual address 'page', allocating * @brief Maps a region of pages starting at virtual address 'page' with
* each mapped frame and any necessary page tables. * length 'length'. Allocates each mapped frame and any necessary page
* tables. This method does not perform any checks before overwriting page
* tables; it is the responsibility of the caller to ensure that the
* operation is safe to perform.
* *
* @param page The virtual address of the first page to map * @param page The virtual address of the first page to map
* @param length The size in bytes of the region to map * @param length The size in bytes of the region to map
@@ -22,9 +29,21 @@ public:
int allocateRegion(void* page, size_t length, int flags); int allocateRegion(void* page, size_t length, int flags);
/** /**
* Maps a contiguous region of pages to a configuous region of frames, * @brief Unmaps and frees a region of mapped pages starting at virtual
* allocating new page tables as needed. All pages will share the same * address 'page' with length 'length'. Does not free any page tables
* flags. * that are made redundant by this operation. It is the responsibility
* of the caller to ensure that all pages in the specified region are
* mapped and should be returned to the page allocator.
*
* @param page The virtual address of the first page to free
* @param length The size in bytes of the region to free
*/
void freeRegion(void* page, size_t length);
/**
* @brief Maps a contiguous region of pages to a contiguous region of
* frames. Allocates new page tables as needed. All pages will share
* the same flags.
* *
* @param page The virtual address of the first page to map * @param page The virtual address of the first page to map
* @param frame The physical address of the first frame to map to * @param frame The physical address of the first frame to map to
@@ -36,33 +55,32 @@ public:
int mapRegion(void* page, physaddr_t frame, size_t length, int flags); int mapRegion(void* page, physaddr_t frame, size_t length, int flags);
/** /**
* Maps a single page to a single frame. Allocates a new page table if one * @brief Unmaps a region of pages; does not return them to the page
* does not exist for that frame. * allocator.
* *
* @param page the virtual address of the page to map * @param page The virtual address of the first page to unmap
* @param frame the physical address of the frame to map to * @param length The size in bytes of the region to unmap
* @param flags flags to apply to the entry
*
* @returns zero upon success, nonzero on failure
*/ */
int mapPage(void* page, physaddr_t frame, int flags); void unmapRegion(void* page, size_t length);
/** unsigned int createSharedBlock(size_t length, int flags);
* Reserve a single page frame.
*
* @returns the physical address of the reserved frame.
*/
physaddr_t reserveFrame();
/** void deleteSharedBlock(unsigned int id);
* Frees a single page frame.
*/ const MemoryBlock& getSharedBlock(unsigned int id);
void freeFrame(physaddr_t frame);
const Process& getActiveProcess();
const Process& switchProcess();
private: private:
PageAllocator& pageAllocator;
MemoryManager& mmgr;
}; };
extern Kernel kernel;
#endif #endif

View File

@@ -1,6 +1,6 @@
#include "kernelstate.hpp" #include "kernelstate.hpp"
using namespace kernel; using namespace kernelns;
BuddyAllocator State::pageAllocator; BuddyAllocator State::pageAllocator;
Allocator State::allocator; Allocator State::allocator;

View File

@@ -7,7 +7,7 @@
#include "scheduler.hpp" #include "scheduler.hpp"
#include "systeminfo.hpp" #include "systeminfo.hpp"
namespace kernel namespace kernelns
{ {
class State class State

95
src/map.hpp Normal file
View File

@@ -0,0 +1,95 @@
#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

34
src/memoryblock.hpp Normal file
View File

@@ -0,0 +1,34 @@
#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

View File

@@ -1,6 +1,6 @@
#include "memorymap.hpp" #include "memorymap.hpp"
using namespace kernel; using namespace kernelns;
MemoryMap::Region::Region() MemoryMap::Region::Region()
{ {

View File

@@ -3,7 +3,7 @@
#include "systypes.hpp" #include "systypes.hpp"
namespace kernel namespace kernelns
{ {
class MemoryMap class MemoryMap

View File

@@ -7,7 +7,7 @@
#define MMAP_EXEC 0x02 #define MMAP_EXEC 0x02
#define MMAP_SHARED 0x04 #define MMAP_SHARED 0x04
namespace kernel namespace kernelns
{ {
int mmap(void* start, size_t length, int flags); int mmap(void* start, size_t length, int flags);

View File

@@ -1,7 +1,7 @@
#include "module.hpp" #include "module.hpp"
#include "util.hpp" #include "util.hpp"
using namespace kernel; using namespace kernelns;
Module::Module() Module::Module()
{ {

View File

@@ -5,7 +5,7 @@
#include "systypes.hpp" #include "systypes.hpp"
namespace kernel namespace kernelns
{ {
class Module class Module

View File

@@ -21,12 +21,12 @@ uint32_t ilog2(uint32_t n, bool roundUp)
return count - (isPowerOfTwo ? 1 : (roundUp ? 0 : 1)); return count - (isPowerOfTwo ? 1 : (roundUp ? 0 : 1));
} }
kernel::BuddyAllocator::BuddyAllocator() kernelns::BuddyAllocator::BuddyAllocator()
{ {
} }
kernel::BuddyAllocator::BuddyAllocator(const kernel::MemoryMap& memmap, kernelns::BuddyAllocator::BuddyAllocator(const kernelns::MemoryMap& memmap,
char* bitmap, size_t blockCount, char* bitmap, size_t blockCount,
size_t treeHeight) size_t treeHeight)
{ {
@@ -44,7 +44,7 @@ kernel::BuddyAllocator::BuddyAllocator(const kernel::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() != kernel::MemoryMap::AVAILABLE) if(memmap[i].getType() != kernelns::MemoryMap::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);
@@ -58,7 +58,7 @@ kernel::BuddyAllocator::BuddyAllocator(const kernel::MemoryMap& memmap,
} }
} }
kernel::BuddyAllocator::BuddyAllocator(char* bitmap, size_t blockSize, kernelns::BuddyAllocator::BuddyAllocator(char* bitmap, size_t blockSize,
size_t blockCount, size_t treeHeight) size_t blockCount, size_t treeHeight)
{ {
this->bitmap = bitmap; this->bitmap = bitmap;
@@ -77,7 +77,7 @@ kernel::BuddyAllocator::BuddyAllocator(char* bitmap, size_t blockSize,
} }
} }
physaddr_t kernel::BuddyAllocator::allocate(size_t size) physaddr_t kernelns::BuddyAllocator::allocate(size_t size)
{ {
size_t height = ilog2(roundUp(size, blockSize) / blockSize, true); size_t height = ilog2(roundUp(size, blockSize) / blockSize, true);
if(height > treeHeight) // Requested block size is greater than maximum if(height > treeHeight) // Requested block size is greater than maximum
@@ -99,7 +99,7 @@ physaddr_t kernel::BuddyAllocator::allocate(size_t size)
} }
} }
void kernel::BuddyAllocator::free(physaddr_t location, size_t size) void kernelns::BuddyAllocator::free(physaddr_t location, size_t size)
{ {
size_t height = ilog2(roundUp(size, blockSize) / blockSize, true); size_t height = ilog2(roundUp(size, blockSize) / blockSize, true);
if(height <= treeHeight) if(height <= treeHeight)
@@ -113,7 +113,7 @@ void kernel::BuddyAllocator::free(physaddr_t location, size_t size)
} }
} }
size_t kernel::BuddyAllocator::freeBlocks() const size_t kernelns::BuddyAllocator::freeBlocks() const
{ {
size_t count = 0; size_t count = 0;
for(size_t j = 0; j < blockCount; j++) for(size_t j = 0; j < blockCount; j++)
@@ -126,7 +126,7 @@ size_t kernel::BuddyAllocator::freeBlocks() const
return count; return count;
} }
size_t kernel::BuddyAllocator::maxAllocationSize() const size_t kernelns::BuddyAllocator::maxAllocationSize() const
{ {
for(size_t i = treeHeight; i >= 0; i--) for(size_t i = treeHeight; i >= 0; i--)
{ {
@@ -141,17 +141,17 @@ size_t kernel::BuddyAllocator::maxAllocationSize() const
return 0; return 0;
} }
size_t kernel::BuddyAllocator::getBlockSize() const size_t kernelns::BuddyAllocator::getBlockSize() const
{ {
return blockSize; return blockSize;
} }
size_t kernel::BuddyAllocator::getMemorySize() const size_t kernelns::BuddyAllocator::getMemorySize() const
{ {
return blockCount; return blockCount;
} }
size_t kernel::BuddyAllocator::findFreeBlock(size_t height) size_t kernelns::BuddyAllocator::findFreeBlock(size_t height)
{ {
for(size_t i = 0; i < (blockCount >> height); i++) for(size_t i = 0; i < (blockCount >> height); i++)
{ {
@@ -171,7 +171,7 @@ size_t kernel::BuddyAllocator::findFreeBlock(size_t height)
return INVALID; return INVALID;
} }
size_t kernel::BuddyAllocator::split(size_t height, size_t index) size_t kernelns::BuddyAllocator::split(size_t height, size_t index)
{ {
if(height > 0 && isFree(height, index)) if(height > 0 && isFree(height, index))
{ {
@@ -186,7 +186,7 @@ size_t kernel::BuddyAllocator::split(size_t height, size_t index)
} }
} }
size_t kernel::BuddyAllocator::merge(size_t height, size_t index) size_t kernelns::BuddyAllocator::merge(size_t height, size_t index)
{ {
if(isFree(height, index) && isFree(height, getBuddy(index)) && height < treeHeight) if(isFree(height, index) && isFree(height, getBuddy(index)) && height < treeHeight)
{ {
@@ -209,34 +209,34 @@ size_t kernel::BuddyAllocator::merge(size_t height, size_t index)
} }
} }
size_t kernel::BuddyAllocator::getBuddy(size_t index) size_t kernelns::BuddyAllocator::getBuddy(size_t index)
{ {
return index ^ 1; return index ^ 1;
} }
size_t kernel::BuddyAllocator::getParent(size_t index) size_t kernelns::BuddyAllocator::getParent(size_t index)
{ {
return index / 2; return index / 2;
} }
size_t kernel::BuddyAllocator::getChild(size_t index) size_t kernelns::BuddyAllocator::getChild(size_t index)
{ {
return index * 2; return index * 2;
} }
physaddr_t kernel::BuddyAllocator::nodeToAddress(size_t height, size_t index) physaddr_t kernelns::BuddyAllocator::nodeToAddress(size_t height, size_t index)
const const
{ {
return index * (blockSize << height); return index * (blockSize << height);
} }
size_t kernel::BuddyAllocator::addressToNode(size_t height, size_t kernelns::BuddyAllocator::addressToNode(size_t height,
physaddr_t location) const physaddr_t location) const
{ {
return location / (blockSize << height); return location / (blockSize << height);
} }
void kernel::BuddyAllocator::reserveNode(size_t height, size_t index) void kernelns::BuddyAllocator::reserveNode(size_t height, size_t index)
{ {
size_t bit = (height == 0) ? 0 size_t bit = (height == 0) ? 0
: ((blockCount * 2) - (blockCount >> (height - 1))); : ((blockCount * 2) - (blockCount >> (height - 1)));
@@ -244,7 +244,7 @@ void kernel::BuddyAllocator::reserveNode(size_t height, size_t index)
bitmap[bit / 8] |= 1 << (bit % 8); bitmap[bit / 8] |= 1 << (bit % 8);
} }
void kernel::BuddyAllocator::freeNode(size_t height, size_t index) void kernelns::BuddyAllocator::freeNode(size_t height, size_t index)
{ {
size_t bit = (height == 0) ? 0 size_t bit = (height == 0) ? 0
: ((blockCount * 2) - (blockCount >> (height - 1))); : ((blockCount * 2) - (blockCount >> (height - 1)));
@@ -252,7 +252,7 @@ void kernel::BuddyAllocator::freeNode(size_t height, size_t index)
bitmap[bit / 8] &= ~(1 << (bit % 8)); bitmap[bit / 8] &= ~(1 << (bit % 8));
} }
bool kernel::BuddyAllocator::isFree(size_t height, size_t index) const bool kernelns::BuddyAllocator::isFree(size_t height, size_t index) const
{ {
size_t bit = (height == 0) ? 0 size_t bit = (height == 0) ? 0
: ((blockCount * 2) - (blockCount >> (height - 1))); : ((blockCount * 2) - (blockCount >> (height - 1)));

View File

@@ -5,7 +5,7 @@
#include "systypes.hpp" #include "systypes.hpp"
#include "memorymap.hpp" #include "memorymap.hpp"
namespace kernel namespace kernelns
{ {
/** /**

View File

@@ -2,20 +2,27 @@
#define PROCESS_H #define PROCESS_H
#include <stddef.h> #include <stddef.h>
#include "map.hpp"
namespace kernel namespace kernelns
{ {
class Process class Process
{ {
public: public:
Process();
size_t priority; size_t priority;
void* stack; void* stack;
Process();
bool hasSharedBlock(unsigned int blockID) const;
private:
Map<unsigned int, MemoryBlock&> m_sharedBlocks;
}; };
} }

View File

@@ -1,17 +1,17 @@
#include "scheduler.hpp" #include "scheduler.hpp"
kernel::ProcessQueue::ProcessQueue() kernelns::ProcessQueue::ProcessQueue()
{ {
} }
kernel::ProcessQueue::ProcessQueue(Process** array) kernelns::ProcessQueue::ProcessQueue(Process** array)
{ {
m_array = array; m_array = array;
m_size = 0; m_size = 0;
} }
kernel::Process* kernel::ProcessQueue::extractMin() kernelns::Process* kernelns::ProcessQueue::extractMin()
{ {
if(m_size == 0) if(m_size == 0)
return NULL; return NULL;
@@ -22,7 +22,7 @@ kernel::Process* kernel::ProcessQueue::extractMin()
return p; return p;
} }
void kernel::ProcessQueue::insert(Process* n) void kernelns::ProcessQueue::insert(Process* n)
{ {
size_t i = m_size; size_t i = m_size;
m_size++; m_size++;
@@ -33,7 +33,7 @@ void kernel::ProcessQueue::insert(Process* n)
m_array[i] = n; m_array[i] = n;
} }
void kernel::ProcessQueue::remove(Process* n) void kernelns::ProcessQueue::remove(Process* n)
{ {
for(size_t i = 0; i < m_size; i++) for(size_t i = 0; i < m_size; i++)
{ {
@@ -47,7 +47,7 @@ void kernel::ProcessQueue::remove(Process* n)
} }
} }
void kernel::ProcessQueue::heapify(size_t i) void kernelns::ProcessQueue::heapify(size_t i)
{ {
if(i * 2 + 1 >= m_size) if(i * 2 + 1 >= m_size)
return; return;

View File

@@ -5,7 +5,7 @@
#include "process.hpp" #include "process.hpp"
namespace kernel namespace kernelns
{ {
class ProcessQueue class ProcessQueue

62
src/syscalls.cpp Normal file
View File

@@ -0,0 +1,62 @@
#include "syscalls.hpp"
#include "kernel.hpp"
int mmap(void* location, size_t length, int flags)
{
// TODO: check that the requested region does not overlap something important
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;
}
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);
kernel.mapRegion(location, block.getLocation(), length, flags);
// TODO: add block to current process
// TODO: perform safety checks
}
return blockID;
}
int aquireSharedBlock(void* location, unsigned int id)
{
const MemoryBlock& block = kernel.getSharedBlock(id);
kernel.mapRegion(location, block.getLocation(), block.getSize(), block.getAttributes());
// TODO: (somehow) handle invalid ids -- possibly hard while using references
// TODO: add block to current process
// TODO: perform safety checks
return 0;
}
int releaseSharedBlock(int id)
{
// (0) Check that process actually posesses block
// (1) Get virtual address of block
// (2) Unmap block
// (3) Delete block if no one posesses it anymore
return 0;
}
int querySharedBlock(void* info, int id)
{
// TODO: define struct for block info
}
int aquirePhysicalBlock(void* location, physaddr_t physicalAddress, size_t length)
{
return 0;
}
int releasePhysicalBlock(int id)
{
return 0;
}

23
src/syscalls.hpp Normal file
View File

@@ -0,0 +1,23 @@
#ifndef SYSCALLS_H
#define SYSCALLS_H
#include <stddef.h>
#include "systypes.hpp"
int mmap(void* location, size_t length, int flags);
int munmap(void* location, size_t length);
unsigned int createSharedBlock(void* location, size_t length, int flags);
int aquireSharedBlock(void* location, unsigned int id);
int releaseSharedBlock(int id);
int querySharedBlock(void* info, int id);
int aquirePhysicalBlock(void* location, physaddr_t physicalAddress, size_t length);
int releasePhysicalBlock(int id);
#endif

View File

@@ -1,7 +1,7 @@
#include "systeminfo.hpp" #include "systeminfo.hpp"
#include "util.hpp" #include "util.hpp"
using namespace kernel; using namespace kernelns;
SystemInfo::SystemInfo() SystemInfo::SystemInfo()
{ {

View File

@@ -6,7 +6,7 @@
#include "systypes.hpp" #include "systypes.hpp"
#include "memorymap.hpp" #include "memorymap.hpp"
namespace kernel namespace kernelns
{ {
class SystemInfo class SystemInfo

View File

@@ -17,17 +17,6 @@ void* memcpy(void* destination, const void* source, size_t num)
return destination; return destination;
} }
/*
* There are four distinct cases here:
* 1. destination and source blocks do not overlap
* 2. destination and source are the same
* 3. destination and source do overlap; destination starts before source
* 4. destination and source do overlap; destination starts after source
*
* Memcpy results in expected behavior in all cases except for case 4. In that
* case, copying must be done backwards to avoid reading from bytes that have
* already been overwritten.
*/
void* memmove(void* destination, const void* source, size_t num) void* memmove(void* destination, const void* source, size_t num)
{ {
if(num > 0) if(num > 0)
@@ -123,7 +112,7 @@ char* strcpy(char* destination, const char* source)
void* malloc(size_t size) void* malloc(size_t size)
{ {
return kernel::State::allocator.allocate(size); return kernelns::State::allocator.allocate(size);
} }
void* calloc(size_t count, size_t size) void* calloc(size_t count, size_t size)
@@ -131,9 +120,17 @@ void* calloc(size_t count, size_t size)
return memset(malloc(count * size), 0, count * size); return memset(malloc(count * size), 0, count * size);
} }
void* realloc(void* ptr, size_t size)
{
void* n = kernelns::State::allocator.allocate(size);
memmove(n, ptr, size);
free(ptr);
return n;
}
void free(void* p) void free(void* p)
{ {
kernel::State::allocator.free(p); kernelns::State::allocator.free(p);
} }
void __cxa_pure_virtual() void __cxa_pure_virtual()

View File

@@ -19,6 +19,8 @@ extern "C" void* malloc(size_t size);
extern "C" void* calloc(size_t count, size_t size); extern "C" void* calloc(size_t count, size_t size);
extern "C" void* realloc(void* ptr, size_t size);
extern "C" void free(void* p); extern "C" void free(void* p);
extern "C" void __cxa_pure_virtual(); extern "C" void __cxa_pure_virtual();

View File

@@ -6,7 +6,7 @@
#include "../mmap.hpp" #include "../mmap.hpp"
#include "../util.hpp" #include "../util.hpp"
using namespace kernel; using namespace kernelns;
extern int _kernelEnd; extern int _kernelEnd;

View File

@@ -140,7 +140,7 @@ void syscallHandler(void* frame)
} }
kernel::Interrupts::Interrupts() kernelns::Interrupts::Interrupts()
{ {
for(unsigned int i = 0; i <= MAX_SYSCALL_ID; i++) for(unsigned int i = 0; i <= MAX_SYSCALL_ID; i++)
syscalls[i] = (void*) NULL; syscalls[i] = (void*) NULL;
@@ -152,17 +152,17 @@ kernel::Interrupts::Interrupts()
lidt(); lidt();
} }
void kernel::Interrupts::enable() void kernelns::Interrupts::enable()
{ {
asm("sti"); asm("sti");
} }
void kernel::Interrupts::disable() void kernelns::Interrupts::disable()
{ {
asm("cli"); asm("cli");
} }
void kernel::Interrupts::addSyscall(unsigned int id, void* function) void kernelns::Interrupts::addSyscall(unsigned int id, void* function)
{ {
if(id <= MAX_SYSCALL_ID) if(id <= MAX_SYSCALL_ID)
syscalls[id] = function; syscalls[id] = function;

View File

@@ -150,7 +150,7 @@ private:
uint32_t physicalAddress : 20; uint32_t physicalAddress : 20;
}; };
int kernel::mmap(void* start, size_t length, int flags) int kernelns::mmap(void* start, size_t length, int flags)
{ {
if((size_t) start % 4096 != 0) if((size_t) start % 4096 != 0)
return -1; return -1;
@@ -184,7 +184,7 @@ int kernel::mmap(void* start, size_t length, int flags)
return 0; return 0;
} }
int kernel::mmap(void* start, physaddr_t p_start, size_t length, int flags) int kernelns::mmap(void* start, physaddr_t p_start, size_t length, int flags)
{ {
if((size_t) start % 4096 != 0 || p_start % 4096 != 0) if((size_t) start % 4096 != 0 || p_start % 4096 != 0)
return -1; return -1;
@@ -198,7 +198,7 @@ int kernel::mmap(void* start, physaddr_t p_start, size_t length, int flags)
return 0; return 0;
} }
int kernel::mapPage(void* start, physaddr_t p_start, int flags) int kernelns::mapPage(void* start, physaddr_t p_start, int flags)
{ {
if((size_t) start % 4096 != 0 || p_start % 4096 != 0) if((size_t) start % 4096 != 0 || p_start % 4096 != 0)
return -1; return -1;
@@ -228,7 +228,7 @@ int kernel::mapPage(void* start, physaddr_t p_start, int flags)
return 0; return 0;
} }
int kernel::munmap(void* start, size_t length) int kernelns::munmap(void* start, size_t length)
{ {
if((size_t) start % 4096 != 0) if((size_t) start % 4096 != 0)
return -1; return -1;
@@ -250,7 +250,7 @@ int kernel::munmap(void* start, size_t length)
return 0; return 0;
} }
bool kernel::isMapped(void* addr) bool kernelns::isMapped(void* addr)
{ {
PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000; PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000;
size_t tableIndex = (size_t) addr / 4096; size_t tableIndex = (size_t) addr / 4096;
@@ -263,14 +263,14 @@ bool kernel::isMapped(void* addr)
return false; return false;
} }
physaddr_t kernel::getPhysicalAddress(void* addr) physaddr_t kernelns::getPhysicalAddress(void* addr)
{ {
PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000; PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000;
size_t tableIndex = (size_t) addr / 4096; size_t tableIndex = (size_t) addr / 4096;
return pageTables[tableIndex].getPhysicalAddress() + ((size_t) addr & 0xFFF); return pageTables[tableIndex].getPhysicalAddress() + ((size_t) addr & 0xFFF);
} }
int kernel::createAddressSpace(void* table) int kernelns::createAddressSpace(void* table)
{ {
if(((size_t) table & 0xFFF) != 0) if(((size_t) table & 0xFFF) != 0)
return -1; return -1;
@@ -281,7 +281,7 @@ int kernel::createAddressSpace(void* table)
return 0; return 0;
} }
int kernel::loadAddressSpace(physaddr_t table) int kernelns::loadAddressSpace(physaddr_t table)
{ {
if((table & 0xFFF) != 0) if((table & 0xFFF) != 0)
return -1; return -1;

View File

@@ -1,6 +1,6 @@
#include "multiboot2.hpp" #include "multiboot2.hpp"
using namespace kernel; using namespace kernelns;
Multiboot2Info::Multiboot2Info(void* tableLocation) Multiboot2Info::Multiboot2Info(void* tableLocation)
{ {

View File

@@ -4,7 +4,7 @@
#include "../memorymap.hpp" #include "../memorymap.hpp"
#include "../module.hpp" #include "../module.hpp"
namespace kernel namespace kernelns
{ {
class Multiboot2Info class Multiboot2Info

View File

@@ -1,7 +1,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "tty.hpp" #include "tty.hpp"
kernel::TTY::TTY(char* vga) kernelns::TTY::TTY(char* vga)
{ {
this->vga = vga; this->vga = vga;
this->cursor = 0; this->cursor = 0;
@@ -9,7 +9,7 @@ kernel::TTY::TTY(char* vga)
this->base = 10; this->base = 10;
} }
kernel::TTY& kernel::TTY::operator<<(kernel::TTY::Format fmt) kernelns::TTY& kernelns::TTY::operator<<(kernelns::TTY::Format fmt)
{ {
switch(fmt) switch(fmt)
{ {
@@ -25,42 +25,42 @@ kernel::TTY& kernel::TTY::operator<<(kernel::TTY::Format fmt)
} }
} }
kernel::TTY& kernel::TTY::operator<<(const char* str) kernelns::TTY& kernelns::TTY::operator<<(const char* str)
{ {
return printString(str); return printString(str);
} }
kernel::TTY& kernel::TTY::operator<<(unsigned int n) kernelns::TTY& kernelns::TTY::operator<<(unsigned int n)
{ {
return printNumber(n, base, width); return printNumber(n, base, width);
} }
kernel::TTY& kernel::TTY::operator<<(int n) kernelns::TTY& kernelns::TTY::operator<<(int n)
{ {
return printNumber((unsigned int) n, base, width); return printNumber((unsigned int) n, base, width);
} }
kernel::TTY& kernel::TTY::operator<<(void* n) kernelns::TTY& kernelns::TTY::operator<<(void* n)
{ {
return printNumber((unsigned int) n, 16, 8); return printNumber((unsigned int) n, 16, 8);
} }
kernel::TTY& kernel::TTY::operator<<(char c) kernelns::TTY& kernelns::TTY::operator<<(char c)
{ {
return putChar(c); return putChar(c);
} }
void kernel::TTY::setWidth(size_t width) void kernelns::TTY::setWidth(size_t width)
{ {
this->width = width; this->width = width;
} }
size_t kernel::TTY::getWidth() size_t kernelns::TTY::getWidth()
{ {
return width; return width;
} }
void kernel::TTY::clear() void kernelns::TTY::clear()
{ {
for(int i = 0; i < 80*25; i++) for(int i = 0; i < 80*25; i++)
{ {
@@ -69,7 +69,7 @@ void kernel::TTY::clear()
cursor = 0; cursor = 0;
} }
kernel::TTY& kernel::TTY::printNumber(unsigned int n, size_t base, kernelns::TTY& kernelns::TTY::printNumber(unsigned int n, size_t base,
size_t width) size_t width)
{ {
const char* digits = "0123456789ABCDEF"; const char* digits = "0123456789ABCDEF";
@@ -94,7 +94,7 @@ kernel::TTY& kernel::TTY::printNumber(unsigned int n, size_t base,
return *this; return *this;
} }
kernel::TTY& kernel::TTY::printString(const char* str) kernelns::TTY& kernelns::TTY::printString(const char* str)
{ {
while(*str) while(*str)
{ {
@@ -104,7 +104,7 @@ kernel::TTY& kernel::TTY::printString(const char* str)
return *this; return *this;
} }
kernel::TTY& kernel::TTY::putChar(char c) kernelns::TTY& kernelns::TTY::putChar(char c)
{ {
switch(c) switch(c)
{ {

View File

@@ -3,7 +3,7 @@
#include <stddef.h> #include <stddef.h>
namespace kernel namespace kernelns
{ {
class TTY class TTY