Use a friendlier way of iterating over the memory map
This commit is contained in:
parent
5aa2d1fa18
commit
5f6c48bd12
@ -7,6 +7,7 @@ set(SOURCES
|
||||
src/video/TextConsole.cpp
|
||||
src/memory/MemoryManager.cpp
|
||||
src/memory/Heap.cpp
|
||||
src/memory/MemoryMap.cpp
|
||||
src/boot/Init.cpp
|
||||
src/arch/Serial.cpp
|
||||
src/arch/Timer.cpp
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "arch/CPU.h"
|
||||
#include "arch/MMU.h"
|
||||
#include "boot/bootboot.h"
|
||||
#include "memory/MemoryMap.h"
|
||||
#include <luna/Alignment.h>
|
||||
#include <luna/Bitmap.h>
|
||||
#include <luna/String.h>
|
||||
@ -29,22 +30,10 @@ static Bitmap g_frame_bitmap;
|
||||
|
||||
static usize get_physical_address_space_size()
|
||||
{
|
||||
MMapEnt* ptr = &bootboot.mmap;
|
||||
u64 biggest_ptr = 0;
|
||||
u64 biggest_ptr_size = 0;
|
||||
u64 mmap_entries = (bootboot.size - 128) / 16;
|
||||
for (u64 i = 0; i < mmap_entries; i++)
|
||||
{
|
||||
if (MMapEnt_Ptr(ptr) > biggest_ptr)
|
||||
{
|
||||
biggest_ptr = MMapEnt_Ptr(ptr);
|
||||
biggest_ptr_size = MMapEnt_Size(ptr);
|
||||
}
|
||||
MemoryMapIterator iter;
|
||||
MemoryMapEntry entry = iter.highest();
|
||||
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return biggest_ptr + biggest_ptr_size; // This would be the address at the end of the last entry, thus the whole
|
||||
return entry.ptr + entry.size; // This is the address at the end of the last (highest) entry, thus the whole
|
||||
// address space that was passed to us.
|
||||
}
|
||||
|
||||
@ -67,28 +56,15 @@ namespace MemoryManager
|
||||
{
|
||||
u64 total_mem = 0;
|
||||
|
||||
void* biggest_usable_memory_block = nullptr;
|
||||
u64 biggest_usable_memory_block_size = 0;
|
||||
MemoryMapIterator iter;
|
||||
|
||||
// walk the memory map
|
||||
MMapEnt* ptr = &bootboot.mmap;
|
||||
u64 mmap_entries = (bootboot.size - 128) / 16;
|
||||
for (u64 i = 0; i < mmap_entries; i++)
|
||||
{
|
||||
u64 size = MMapEnt_Size(ptr);
|
||||
total_mem += size;
|
||||
if (!MMapEnt_IsFree(ptr))
|
||||
{
|
||||
ptr++;
|
||||
continue;
|
||||
}
|
||||
if (size > biggest_usable_memory_block_size)
|
||||
{
|
||||
biggest_usable_memory_block = (void*)MMapEnt_Ptr(ptr);
|
||||
biggest_usable_memory_block_size = MMapEnt_Size(ptr);
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
MemoryMapEntry entry;
|
||||
while (iter.next().try_set_value(entry)) { total_mem += entry.size; }
|
||||
|
||||
auto largest_free = iter.largest_free();
|
||||
|
||||
void* biggest_usable_memory_block = (void*)largest_free.ptr;
|
||||
u64 biggest_usable_memory_block_size = largest_free.size;
|
||||
|
||||
// The entire physical address space. May contain inexistent memory holes, thus differs from total_mem which
|
||||
// only counts existent memory. Our bitmap needs to have space for all of the physical address space, since
|
||||
@ -110,18 +86,17 @@ namespace MemoryManager
|
||||
|
||||
g_frame_bitmap.clear(true); // Set all pages to used/reserved by default, then clear out the free ones
|
||||
|
||||
ptr = &bootboot.mmap;
|
||||
for (u64 i = 0; i < mmap_entries; i++)
|
||||
iter.rewind();
|
||||
while (iter.next().try_set_value(entry))
|
||||
{
|
||||
u64 index = MMapEnt_Ptr(ptr) / ARCH_PAGE_SIZE;
|
||||
u64 pages = MMapEnt_Size(ptr) / ARCH_PAGE_SIZE;
|
||||
if (!MMapEnt_IsFree(ptr)) { reserved_mem += MMapEnt_Size(ptr); }
|
||||
u64 index = entry.ptr / ARCH_PAGE_SIZE;
|
||||
u64 pages = entry.size / ARCH_PAGE_SIZE;
|
||||
if (!entry.free) { reserved_mem += entry.size; }
|
||||
else
|
||||
{
|
||||
free_mem += MMapEnt_Size(ptr);
|
||||
free_mem += entry.size;
|
||||
g_frame_bitmap.clear_region(index, pages, false);
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
|
||||
lock_frames((u64)frame_bitmap_addr, frame_bitmap_size / ARCH_PAGE_SIZE + 1);
|
||||
|
75
kernel/src/memory/MemoryMap.cpp
Normal file
75
kernel/src/memory/MemoryMap.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
#include "memory/MemoryMap.h"
|
||||
|
||||
extern BOOTBOOT bootboot;
|
||||
|
||||
static MemoryMapEntry memory_map_entry_from_mmapent(MMapEnt* ent)
|
||||
{
|
||||
MemoryMapEntry result;
|
||||
result.ptr = MMapEnt_Ptr(ent);
|
||||
result.size = MMapEnt_Size(ent);
|
||||
result.free = MMapEnt_IsFree(ent);
|
||||
return result;
|
||||
}
|
||||
|
||||
MemoryMapIterator::MemoryMapIterator()
|
||||
{
|
||||
m_mmap_entries = (bootboot.size - 128) / 16;
|
||||
m_base_ent = &bootboot.mmap;
|
||||
rewind();
|
||||
}
|
||||
|
||||
void MemoryMapIterator::rewind()
|
||||
{
|
||||
m_cur_ent = 0;
|
||||
}
|
||||
|
||||
Result<MemoryMapEntry> MemoryMapIterator::at(usize index)
|
||||
{
|
||||
if (index >= m_mmap_entries) return err(ERANGE);
|
||||
return memory_map_entry_from_mmapent(m_base_ent + index);
|
||||
}
|
||||
|
||||
Result<MemoryMapEntry> MemoryMapIterator::next()
|
||||
{
|
||||
return at(m_cur_ent++);
|
||||
}
|
||||
|
||||
MemoryMapEntry MemoryMapIterator::largest_free()
|
||||
{
|
||||
usize largest_size = 0;
|
||||
usize largest_index = 0;
|
||||
|
||||
rewind();
|
||||
|
||||
MemoryMapEntry entry;
|
||||
while (next().try_set_value(entry))
|
||||
{
|
||||
if (entry.free && entry.size > largest_size)
|
||||
{
|
||||
largest_size = entry.size;
|
||||
largest_index = m_cur_ent - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return at(largest_index).release_value();
|
||||
}
|
||||
|
||||
MemoryMapEntry MemoryMapIterator::highest()
|
||||
{
|
||||
usize highest_ptr = 0;
|
||||
usize highest_index = 0;
|
||||
|
||||
rewind();
|
||||
|
||||
MemoryMapEntry entry;
|
||||
while (next().try_set_value(entry))
|
||||
{
|
||||
if (entry.ptr > highest_ptr)
|
||||
{
|
||||
highest_ptr = entry.ptr;
|
||||
highest_index = m_cur_ent - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return at(highest_index).release_value();
|
||||
}
|
37
kernel/src/memory/MemoryMap.h
Normal file
37
kernel/src/memory/MemoryMap.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include "boot/bootboot.h"
|
||||
#include <luna/Result.h>
|
||||
#include <luna/Types.h>
|
||||
|
||||
struct MemoryMapEntry
|
||||
{
|
||||
u64 ptr;
|
||||
u64 size;
|
||||
bool free;
|
||||
};
|
||||
|
||||
class MemoryMapIterator
|
||||
{
|
||||
public:
|
||||
MemoryMapIterator();
|
||||
|
||||
void rewind();
|
||||
|
||||
Result<MemoryMapEntry> next();
|
||||
|
||||
MemoryMapEntry largest_free();
|
||||
|
||||
MemoryMapEntry highest();
|
||||
|
||||
Result<MemoryMapEntry> at(usize index);
|
||||
|
||||
usize entries()
|
||||
{
|
||||
return m_mmap_entries;
|
||||
}
|
||||
|
||||
private:
|
||||
usize m_mmap_entries;
|
||||
MMapEnt* m_base_ent;
|
||||
usize m_cur_ent;
|
||||
};
|
Loading…
Reference in New Issue
Block a user