From ec74cb650ce50947f7eb792bf6c165a7b30236b7 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 19 Mar 2016 12:01:01 -0400 Subject: [PATCH] Attempt to write an iterator for the multiboot memory map list --- src/Multiboot.cc | 95 ++++++++++++++++++++++++++++++++++++++++++++++++ src/Multiboot.hh | 51 ++++++++++++++++++++------ 2 files changed, 134 insertions(+), 12 deletions(-) diff --git a/src/Multiboot.cc b/src/Multiboot.cc index f8cc266..cda50be 100644 --- a/src/Multiboot.cc +++ b/src/Multiboot.cc @@ -52,6 +52,71 @@ Information::setInformation(Information *info) * Public */ +Information::MemoryMapIterator::MemoryMapIterator(uint32_t address, + uint32_t count) + : mCurrent(reinterpret_cast(address)), + mCount(count) +{ } + + +Information::MemoryMapIterator::MemoryMapIterator(const MemoryMapIterator& other) + : mCurrent(other.mCurrent), + mCount(other.mCount) +{ } + + +Information::MemoryMapIterator& +Information::MemoryMapIterator::operator++() +{ + if (mCount > 0) { + auto p = reinterpret_cast(mCurrent); + // The size of the current struct is stored at (mCurrent - 4) bytes. + mCurrent = (mCurrent + p[-1]); + mCount--; + } + return *this; +} + + +Information::MemoryMapIterator +Information::MemoryMapIterator::operator++(int) +{ + MemoryMapIterator tmp(reinterpret_cast(mCurrent), mCount); + operator++(); + return tmp; +} + + +MemoryChunk +Information::MemoryMapIterator::operator*() +{ + if (mCount == 0) { + return MemoryChunk{0, 0, 0}; + } + return *mCurrent; +} + + +bool +Information::MemoryMapIterator::operator==(const MemoryMapIterator& other) + const +{ + if (mCount == 0 && other.mCount == 0) { + // If both iterators have 0 counts, it doesn't matter what the mCurrent members point at. + return true; + } + return mCurrent == other.mCurrent && mCount == other.mCount; +} + + +bool +Information::MemoryMapIterator::operator!=(const MemoryMapIterator& other) + const +{ + return !(*this == other); +} + + uint32_t Information::lowerMemoryKB() const @@ -83,5 +148,35 @@ Information::commandLine() } return reinterpret_cast(mCommandLine); } + + +uint32_t +Information::memoryMapChunks() + const +{ + if ((mFlags & Present::MemoryMap) == 0) { + return 0; + } + return memoryMapCount; +} + + +Information::MemoryMapIterator +Information::memoryMapBegin() + const +{ + if ((mFlags & Present::MemoryMap) == 0) { + return memoryMapEnd(); + } + return MemoryMapIterator(memoryMapAddress, memoryMapCount); +} + + +Information::MemoryMapIterator +Information::memoryMapEnd() + const +{ + return {0, 0}; +} } /* namespace multiboot */ diff --git a/src/Multiboot.hh b/src/Multiboot.hh index 72b42d5..a9185cc 100644 --- a/src/Multiboot.hh +++ b/src/Multiboot.hh @@ -15,19 +15,51 @@ namespace multiboot { +struct PACKED MemoryChunk +{ + /** Base address of the chunk of memory. */ + uint64_t base; + /** Length of the chunk of memory, in bytes. */ + uint64_t length; + /** Type of address range. 1 indicates available; all other values indicate reserved memory. */ + uint32_t type; +}; + /** * The multiboot information struct. Defined by the multiboot spec. * See http://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Machine-state */ struct PACKED Information { + struct MemoryMapIterator + { + MemoryMapIterator(uint32_t address, uint32_t count); + MemoryMapIterator(const MemoryMapIterator& other); + + MemoryMapIterator& operator++(); + MemoryMapIterator operator++(int); + MemoryChunk operator*(); + + bool operator==(const MemoryMapIterator& other) const; + bool operator!=(const MemoryMapIterator& other) const; + + private: + MemoryChunk *mCurrent; + uint32_t mCount; + }; + static const Information *information(); static void setInformation(Information* info); uint32_t lowerMemoryKB() const; uint32_t upperMemoryKB() const; + const char* commandLine() const; + uint32_t memoryMapChunks() const; + MemoryMapIterator memoryMapBegin() const; + MemoryMapIterator memoryMapEnd() const; + private: /** * Bit field of flags. Fields below are only defined if the appropriate @@ -98,16 +130,16 @@ private: } symbols; /** + * @defgroup Memory Map * Points to a buffer containing a memory map of the machine provided by the * BIOS. Defined only if `memoryMapPresent == true`. + * @{ */ - struct PACKED - { - /** Number of memory map entries present. */ - uint32_t count; - /** Pointer to start of memory map entry array. */ - uint32_t address; - } memoryMap; + /** Number of memory map entries present. */ + uint32_t memoryMapCount; + /** Pointer to start of memory map entry array. */ + uint32_t memoryMapAddress; + /** @} */ /** * Points to a buffer containing a list of drive definitions provided by the @@ -152,11 +184,6 @@ struct PACKED Module uint32_t reserved; }; -// TODO: Define the MemoryMap struct -struct PACKED MemoryChunk -{ -}; - // TODO: Define the Drive struct struct PACKED Drive {