aboutsummaryrefslogtreecommitdiff
path: root/kapi
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-03-13 22:28:50 +0100
committerFelix Morgner <felix.morgner@ost.ch>2026-03-13 23:51:38 +0100
commite284d574ed9237a215d994861cc502452fec11ce (patch)
tree716c9929ef4c0df2b89ab0166c615271aec2374c /kapi
parent7ba274d0838e5cd4e48e85f81557bbb837ed4349 (diff)
downloadteachos-e284d574ed9237a215d994861cc502452fec11ce.tar.xz
teachos-e284d574ed9237a215d994861cc502452fec11ce.zip
kernel/memory: implement basic bitmap allocator
Diffstat (limited to 'kapi')
-rw-r--r--kapi/include/kapi/memory.hpp15
-rw-r--r--kapi/include/kapi/memory/buffered_allocator.hpp5
-rw-r--r--kapi/include/kapi/memory/chunk.hpp37
-rw-r--r--kapi/include/kapi/memory/frame.hpp12
-rw-r--r--kapi/include/kapi/memory/frame_allocator.hpp3
-rw-r--r--kapi/include/kapi/memory/page.hpp10
6 files changed, 61 insertions, 21 deletions
diff --git a/kapi/include/kapi/memory.hpp b/kapi/include/kapi/memory.hpp
index 87268ff..3a8f42d 100644
--- a/kapi/include/kapi/memory.hpp
+++ b/kapi/include/kapi/memory.hpp
@@ -25,6 +25,21 @@ namespace kapi::memory
auto init() -> void;
//! @qualifier kernel-defined
+ //! Initialize the physical memory manager.
+ //!
+ //! This function initializes the kernel-wide physical memory manager. The function will invoke the handoff handler to
+ //! transfer the platform-specific frame allocation state to the physical memory manager.
+ //!
+ //! @param frame_count The number of frames present in the system.
+ //! @param handoff_handler A function to be invoked to transfer the platform-specific frame allocation state. The
+ //! allocator to hand off to is passed to the handler.
+ auto init_pmm(std::size_t frame_count, void (&handoff_handler)(frame_allocator &)) -> void;
+
+ //! @qualifier kernel-defined
+ //! Get the currently active frame allocator.
+ auto get_frame_allocator() -> frame_allocator &;
+
+ //! @qualifier kernel-defined
//! Set the currently active frame allocator.
//!
//! @param allocator A new frame allocator.
diff --git a/kapi/include/kapi/memory/buffered_allocator.hpp b/kapi/include/kapi/memory/buffered_allocator.hpp
index 49137c6..286c841 100644
--- a/kapi/include/kapi/memory/buffered_allocator.hpp
+++ b/kapi/include/kapi/memory/buffered_allocator.hpp
@@ -88,6 +88,11 @@ namespace kapi::memory
return m_underlying->allocate_many(count);
}
+ auto mark_used(kapi::memory::frame) -> void override
+ {
+ system::panic("[x86_64:MEM] Not implemented");
+ }
+
auto release_many(std::pair<kapi::memory::frame, std::size_t> frame_set) -> void override
{
if (m_free == BufferSize)
diff --git a/kapi/include/kapi/memory/chunk.hpp b/kapi/include/kapi/memory/chunk.hpp
index dd97a58..3d90326 100644
--- a/kapi/include/kapi/memory/chunk.hpp
+++ b/kapi/include/kapi/memory/chunk.hpp
@@ -12,9 +12,10 @@ namespace kapi::memory
//! @qualifier kernel-defined
//! A fixed-size unit of memory, indexed by a number.
//!
+ //! @tparam ChunkType The CRTP type of the deriving class
//! @tparam AddressType The type of addresses used to index this chunk
//! @tparam Size The size of this chunk.
- template<typename AddressType, std::size_t Size>
+ template<typename ChunkType, typename AddressType, std::size_t Size>
struct chunk
{
//! The type of addresses used to index this chunk
@@ -23,21 +24,13 @@ namespace kapi::memory
//! The size of this chunk
constexpr auto static size = Size;
- //! Construct a handle referencing the first chunk of the respective address space.
- constexpr chunk() noexcept = default;
-
- //! Construct a handle referencing the chunk of memory with the given number.
- explicit constexpr chunk(std::size_t number) noexcept
- : m_number{number}
- {}
-
//! Construct a new chunk handle for the chunk containing the given address.
//!
//! @param address An address contained by the desired chunk.
//! @return A handle to a chunk containing the given address.
- constexpr auto static containing(address_type address) noexcept -> chunk
+ constexpr auto static containing(address_type address) noexcept -> ChunkType
{
- return chunk{address.raw() / size};
+ return ChunkType{address.raw() / size};
}
//! Get the start address of the chunk referenced by this handle.
@@ -60,17 +53,17 @@ namespace kapi::memory
//!
//! @param n The positive offset to this chunk.
//! @return A handle referencing the chunk n chunks after the one referenced by this handle.
- constexpr auto operator+(std::size_t n) const noexcept -> chunk
+ constexpr auto operator+(std::size_t n) const noexcept -> ChunkType
{
- return chunk{m_number + n};
+ return ChunkType{m_number + n};
}
//! Let this handle reference the next chunk after the currently reference one.
//!
//! @return A handle referencing the same chunk as this handle did before the operation.
- constexpr auto operator++(int) noexcept -> chunk
+ constexpr auto operator++(int) noexcept -> ChunkType
{
- auto copy = *this;
+ auto copy = static_cast<ChunkType>(*this);
++*this;
return copy;
}
@@ -78,10 +71,10 @@ namespace kapi::memory
//! Let this handle reference the next chunk after the currently reference one.
//!
//! @return A reference to this handle.
- constexpr auto operator++() noexcept -> chunk &
+ constexpr auto operator++() noexcept -> ChunkType &
{
++m_number;
- return *this;
+ return static_cast<ChunkType &>(*this);
}
//! Check if this chunk handle reference the same chunk as another one.
@@ -95,6 +88,16 @@ namespace kapi::memory
constexpr auto operator<=>(chunk const & other) const noexcept -> std::strong_ordering = default;
private:
+ friend ChunkType;
+
+ //! Construct a handle referencing the first chunk of the respective address space.
+ constexpr chunk() noexcept = default;
+
+ //! Construct a handle referencing the chunk of memory with the given number.
+ explicit constexpr chunk(std::size_t number) noexcept
+ : m_number{number}
+ {}
+
//! The number of the currently referenced chunk.
std::size_t m_number{};
};
diff --git a/kapi/include/kapi/memory/frame.hpp b/kapi/include/kapi/memory/frame.hpp
index e7b0832..deab300 100644
--- a/kapi/include/kapi/memory/frame.hpp
+++ b/kapi/include/kapi/memory/frame.hpp
@@ -6,6 +6,8 @@
#include "kapi/memory/address.hpp"
#include "kapi/memory/chunk.hpp"
+#include <cstddef>
+
namespace kapi::memory
{
@@ -13,9 +15,15 @@ namespace kapi::memory
//! A handle to a frame of physical memory.
//!
//! @note Contrary to the address types, this type is modeled using inheritance to support future extensions.
- struct frame : chunk<physical_address, PLATFORM_FRAME_SIZE>
+ struct frame : chunk<frame, physical_address, PLATFORM_FRAME_SIZE>
{
- using chunk::chunk;
+ frame() = default;
+
+ frame(std::size_t number)
+ : chunk{number}
+ {}
+
+ using difference_type = std::ptrdiff_t;
//! @copydoc chunk::containing
//!
diff --git a/kapi/include/kapi/memory/frame_allocator.hpp b/kapi/include/kapi/memory/frame_allocator.hpp
index 6ed114c..cfa8a1c 100644
--- a/kapi/include/kapi/memory/frame_allocator.hpp
+++ b/kapi/include/kapi/memory/frame_allocator.hpp
@@ -34,6 +34,9 @@ namespace kapi::memory
return allocate_many(1).transform([](auto result) { return result.first; });
}
+ //! Mark the given frame as used
+ virtual auto mark_used(frame frame) -> void = 0;
+
//! Allocate multiple consecutive frames of physical memory.
//!
//! @param count The number of frames to allocate
diff --git a/kapi/include/kapi/memory/page.hpp b/kapi/include/kapi/memory/page.hpp
index 55d6e75..f209278 100644
--- a/kapi/include/kapi/memory/page.hpp
+++ b/kapi/include/kapi/memory/page.hpp
@@ -6,6 +6,8 @@
#include "kapi/memory/address.hpp"
#include "kapi/memory/chunk.hpp"
+#include <cstddef>
+
namespace kapi::memory
{
@@ -13,9 +15,13 @@ namespace kapi::memory
//! A handle to a page of virtual memory.
//!
//! @note Contrary to the address types, this type is modeled using inheritance to support future extensions.
- struct page : chunk<linear_address, PLATFORM_PAGE_SIZE>
+ struct page : chunk<page, linear_address, PLATFORM_PAGE_SIZE>
{
- using chunk::chunk;
+ page() = default;
+
+ page(std::size_t number)
+ : chunk{number}
+ {}
//! @copydoc chunk::containing
//!