PageAllocator!

This commit is contained in:
Eryn Wells 2016-04-24 19:21:35 -04:00
parent 27dad4d3f5
commit cb78f4cfaa
3 changed files with 140 additions and 0 deletions

View file

@ -26,6 +26,7 @@ files = [
'memory/FrameAllocator.cc',
'memory/Memory.cc',
'memory/Pager.cc',
]
toolchain_bin = Dir(os.environ['POLKA_TOOLCHAIN']).Dir('bin')

102
src/memory/Pager.cc Normal file
View file

@ -0,0 +1,102 @@
/* Pager.cc
* vim: set tw=80:
* Eryn Wells <eryn@erynwells.me>
*/
/**
* Page tables 'n stuff.
*/
#include "Attributes.hh"
#include "Pager.hh"
#include "kstd/Bitmap.hh"
#include "memory/Memory.hh"
namespace kernel {
struct PageDirectoryEntry
{
PageDirectoryEntry();
/** Mark the whole entry not present. */
void setNotPresent();
bool isNotPresent() const;
void setAddress(void* address);
private:
static const u8 OneBit = 0;
static const u8 ReadWriteBit = 1;
static const u8 UserAccessBit = 2;
static const u8 PageWriteThroughBit = 3;
static const u8 PageCacheDisabledBit = 4;
static const u8 AccessedBit = 5;
static const u8 DirtyBit = 6;
static const u8 ZeroBit = 7;
static const u32 IgnoredMask = 0x00000F00;
static const u32 AddressMask = 0xFFFFF000;
static const u32 FlagMask = 0x00000FFF;
u32 mEntry;
void setRequiredBits();
};
PageDirectoryEntry::PageDirectoryEntry()
: mEntry(0)
{
static_assert(sizeof(PageDirectoryEntry) == 4, "PageDirectoryEntry must be 4 bytes long.");
}
bool
PageDirectoryEntry::isNotPresent()
const
{
return mEntry == 0;
}
void
PageDirectoryEntry::setNotPresent()
{
mEntry = 0;
}
void
PageDirectoryEntry::setAddress(void* address)
{
kstd::Bit::setMask(mEntry, memory::pageAlignDown(uptr(address)), AddressMask);
}
void
PageDirectoryEntry::setRequiredBits()
{
kstd::Bit::set(mEntry, OneBit);
kstd::Bit::clear(mEntry, ZeroBit);
kstd::Bit::clearMask(mEntry, IgnoredMask);
}
/*
* Public
*/
void
PageAllocator::initialize(const StartupInformation& startupInformation,
void* pageDirectory)
{
mPageDirectory = reinterpret_cast<PageDirectoryEntry*>(pageDirectory);
for (usize i = 0; i < NumberOfEntries; i++) {
mPageDirectory[i].setNotPresent();
}
}
/*
* Private
*/
const u16 PageAllocator::NumberOfEntries = 1024;
} /* namespace kernel */

37
src/memory/Pager.hh Normal file
View file

@ -0,0 +1,37 @@
/* Pager.hh
* vim: set tw=80:
* Eryn Wells <eryn@erynwells.me>
*/
/**
* Page tables 'n stuff.
*/
#ifndef __MEMORY_PAGE_HH__
#define __MEMORY_PAGE_HH__
#include "StartupInformation.hh"
#include "kstd/Types.hh"
namespace kernel {
struct PageDirectoryEntry;
/**
* Handles allocating pages
*/
struct PageAllocator
{
void initialize(const StartupInformation& startupInformation, void* pageDirectory);
// TODO: A method to install a page table into the system. For per-process page tables, I'll need a way to set the current page table so the system knows where to look.
private:
static const u16 NumberOfEntries;
/** The kernel's page directory. */
PageDirectoryEntry* mPageDirectory;
};
} /* namespace kernel */
#endif /* __MEMORY_PAGE_HH__ */