Allocate space for a frame bitmap

Basically there, but still some kinks to work out...
This commit is contained in:
Eryn Wells 2016-04-13 00:24:33 -04:00
parent 764297de59
commit 109ea7ce2e
2 changed files with 64 additions and 8 deletions

View file

@ -10,6 +10,7 @@
#include "kstd/Memory.hh"
#include "kstd/PrintFormat.hh"
#include "memory/FrameAllocator.hh"
#include "memory/Memory.hh"
namespace kernel {
@ -23,16 +24,68 @@ void
FrameAllocator::initialize(const StartupInformation& startupInformation)
{
// Page frame bitmap starts immediately after the kernel.
mBitmap = reinterpret_cast<u8*>(startupInformation.kernelEnd);
mBitmap = reinterpret_cast<Bitmap*>(startupInformation.kernelEnd);
const u32 pageSize = startupInformation.pageSize;
const u32 numberOfPages = startupInformation.multibootInformation->memoryKB() * 1024 / pageSize;
mBitmapSize = numberOfPages / (sizeof(FrameBitmap) * 8);
const u32 numberOfPages = startupInformation.memorySize() / memory::pageSize;
const u32 pagesPerBitmap = Bitmap::length;
mBitmapSize = numberOfPages / pagesPerBitmap;
if ((numberOfPages % pagesPerBitmap) != 0) {
// Add an extra bitmap for the last few pages.
mBitmapSize++;
}
kstd::printFormat("Allocated bitmap of %ld bytes for %ld pages at 0x%08lX\n", mBitmapSize, numberOfPages, u32(mBitmap));
// TODO: Before modifying this memory, maybe make sure none of the multiboot information is hanging out there?
kstd::Memory::zero(mBitmap, mBitmapSize);
// Lower 1 MB is always allocated.
reserveRange(0, 0x100000);
// Kernel image (including this frame bitmap) is always allocated.
reserveRange(startupInformation.kernelStart, startupInformation.kernelSize() + mBitmapSize);
}
void
FrameAllocator::reserveRange(u32 start,
u32 length)
{
// TODO: `start` and `length` validation.
const u32 pagesPerBitmap = Bitmap::length;
const u32 startPage = memory::pageAlignDown(start) / memory::pageSize;
const u32 endPage = memory::pageAlignUp(start + length) / memory::pageSize;
// Iterators
u32 page = startPage;
u32 bitmapIndex = start / pagesPerBitmap;
u8 bitmapOffset = start % pagesPerBitmap;
kstd::printFormat("Reserving %ld pages for memory addresses between 0x%08lX and 0x%08lX\n", endPage - startPage, start, start + length);
// Fill in any entries that aren't aligned to pagesPerBitmap at the beginning.
while (bitmapOffset != 0) {
mBitmap[bitmapIndex].set(bitmapOffset);
bitmapOffset = (bitmapOffset + 1) % 8;
page++;
if (bitmapOffset == 0) {
bitmapIndex++;
}
}
// Fill in entries in `pagesPerBitmap` sized chunks.
while ((endPage - page) > pagesPerBitmap) {
mBitmap[bitmapIndex++].fill();
page += pagesPerBitmap;
}
// Fill in any entries that aren't aligned to `pagesPerBitmap` at the end of the range.
while ((endPage - page) > 0) {
mBitmap[bitmapIndex].set(bitmapOffset);
bitmapOffset = (bitmapOffset + 1) % 8;
page++;
}
}
} /* namespace kernel */

View file

@ -10,9 +10,9 @@
#define __MEMORY_FRAMEALLOCATOR_HH__
#include "StartupInformation.hh"
#include "kstd/Bitmap.hh"
#include "kstd/Types.hh"
namespace kernel {
struct FrameAllocator
@ -22,12 +22,15 @@ struct FrameAllocator
void initialize(const StartupInformation& startupInformation);
private:
typedef u8 FrameBitmap;
typedef kstd::Bitmap<u8> Bitmap;
/** Starting address of the frame allocation bitmap. */
FrameBitmap* mBitmap;
/** Size of the bitmap in bytes. */
Bitmap* mBitmap;
/** Size of the bitmap in `sizeof(Bitmap)` units. */
u32 mBitmapSize;
/** Reserve a range of memory. */
void reserveRange(u32 start, u32 length);
};
} /* namespace */