mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
Implement first-pass simple virtual memory manager
This commit is contained in:
@@ -54,6 +54,10 @@ kernel_main(popcorn_data *header)
|
|||||||
header->memory_map_length,
|
header->memory_map_length,
|
||||||
header->memory_map_desc_size);
|
header->memory_map_desc_size);
|
||||||
|
|
||||||
|
size_t n = 5000;
|
||||||
|
void *p = kalloc(n);
|
||||||
|
g_console.printf("kalloc'd %d bytes at %lx\n", n, p);
|
||||||
|
|
||||||
interrupts_init();
|
interrupts_init();
|
||||||
interrupts_enable();
|
interrupts_enable();
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,50 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "memory_pages.h"
|
#include "memory_pages.h"
|
||||||
|
|
||||||
memory_manager g_memory_manager;
|
memory_manager g_kernel_memory_manager;
|
||||||
|
|
||||||
memory_manager::memory_manager()
|
struct memory_allocation_header
|
||||||
|
{
|
||||||
|
uint64_t pages;
|
||||||
|
uint64_t reserved;
|
||||||
|
uint8_t data[0];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
memory_manager::memory_manager() :
|
||||||
|
m_start(nullptr),
|
||||||
|
m_length(0)
|
||||||
{
|
{
|
||||||
kassert(this == &g_memory_manager, "Attempt to create another memory_manager.");
|
}
|
||||||
|
|
||||||
|
memory_manager::memory_manager(void *start, size_t length) :
|
||||||
|
m_start(start),
|
||||||
|
m_length(length)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
memory_manager::allocate(size_t length)
|
||||||
|
{
|
||||||
|
length = page_align(length + sizeof(memory_allocation_header));
|
||||||
|
|
||||||
|
if (length > m_length) return nullptr;
|
||||||
|
|
||||||
|
m_length -= length;
|
||||||
|
memory_allocation_header *header =
|
||||||
|
reinterpret_cast<memory_allocation_header *>(m_start);
|
||||||
|
m_start = reinterpret_cast<uint8_t *>(m_start) + length;
|
||||||
|
|
||||||
|
size_t pages = length / page_manager::page_size;
|
||||||
|
g_page_manager.map_pages(
|
||||||
|
reinterpret_cast<page_manager::addr_t>(header),
|
||||||
|
pages);
|
||||||
|
|
||||||
|
header->pages = pages;
|
||||||
|
return &header->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
memory_manager::free(void *p)
|
||||||
|
{
|
||||||
|
// In this simple version, we don't care about freed pointers
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,21 +3,44 @@
|
|||||||
/// The block memory manager and related definitions.
|
/// The block memory manager and related definitions.
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct memory_block_node;
|
||||||
|
|
||||||
/// Manager for allocation of virtual memory.
|
/// Manager for allocation of virtual memory.
|
||||||
class memory_manager
|
class memory_manager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
memory_manager();
|
memory_manager();
|
||||||
|
memory_manager(void *start, size_t length);
|
||||||
|
|
||||||
memory_manager(const memory_manager &) = delete;
|
/// Allocate memory from the area managed.
|
||||||
|
/// \arg length The amount of memory to allocate, in bytes
|
||||||
|
/// \returns A pointer to the allocated memory, or nullptr if
|
||||||
|
/// allocation failed.
|
||||||
|
void * allocate(size_t length);
|
||||||
|
|
||||||
|
/// Free a previous allocation.
|
||||||
|
/// \arg p A pointer previously retuned by allocate()
|
||||||
|
void free(void *p);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class page_manager;
|
friend class page_manager;
|
||||||
|
|
||||||
|
// Simple incrementing pointer.
|
||||||
|
void *m_start;
|
||||||
|
size_t m_length;
|
||||||
|
|
||||||
|
memory_manager(const memory_manager &) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern memory_manager g_memory_manager;
|
extern memory_manager g_kernel_memory_manager;
|
||||||
|
|
||||||
/// Bootstrap the memory managers.
|
/// Bootstrap the memory managers.
|
||||||
void memory_initialize_managers(const void *memory_map, size_t map_length, size_t desc_length);
|
void memory_initialize_managers(const void *memory_map, size_t map_length, size_t desc_length);
|
||||||
|
|
||||||
|
/// Allocate kernel space memory.
|
||||||
|
/// \arg length The amount of memory to allocate, in bytes
|
||||||
|
/// \returns A pointer to the allocated memory, or nullptr if
|
||||||
|
/// allocation failed.
|
||||||
|
inline void * kalloc(size_t length) { return g_kernel_memory_manager.allocate(length); }
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
#include "memory.h"
|
||||||
#include "memory_pages.h"
|
#include "memory_pages.h"
|
||||||
|
|
||||||
page_manager g_page_manager;
|
page_manager g_page_manager;
|
||||||
@@ -224,6 +225,18 @@ page_manager::init(
|
|||||||
page_block::dump(m_used, "used", true);
|
page_block::dump(m_used, "used", true);
|
||||||
page_block::dump(m_free, "free", true);
|
page_block::dump(m_free, "free", true);
|
||||||
|
|
||||||
|
// Initialize the kernel memory manager
|
||||||
|
addr_t end = 0;
|
||||||
|
for (page_block *b = m_used; b; b = b->next) {
|
||||||
|
if (b->virtual_address < page_offset)
|
||||||
|
end = b->virtual_end();
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
new (&g_kernel_memory_manager) memory_manager(
|
||||||
|
reinterpret_cast<void *>(end),
|
||||||
|
page_offset - end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
Reference in New Issue
Block a user