aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/CMakeLists.txt1
-rw-r--r--arch/x86_64/kapi/boot_modules.cpp51
-rw-r--r--kapi/CMakeLists.txt3
-rw-r--r--kapi/include/kapi/boot_module/boot_module.hpp21
-rw-r--r--kapi/include/kapi/boot_module/boot_module_registry.hpp108
-rw-r--r--kapi/include/kapi/boot_modules.hpp25
-rw-r--r--kernel/CMakeLists.txt1
-rw-r--r--kernel/kapi/boot_modules.cpp21
-rw-r--r--kernel/src/main.cpp4
9 files changed, 235 insertions, 0 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt
index 41932c9..4ae09ff 100644
--- a/arch/x86_64/CMakeLists.txt
+++ b/arch/x86_64/CMakeLists.txt
@@ -12,6 +12,7 @@ target_link_libraries("x86_64" PUBLIC
target_sources("x86_64" PRIVATE
# Platform-dependent KAPI implementation
+ "kapi/boot_modules.cpp"
"kapi/cio.cpp"
"kapi/cpu.cpp"
"kapi/memory.cpp"
diff --git a/arch/x86_64/kapi/boot_modules.cpp b/arch/x86_64/kapi/boot_modules.cpp
new file mode 100644
index 0000000..5d06eb5
--- /dev/null
+++ b/arch/x86_64/kapi/boot_modules.cpp
@@ -0,0 +1,51 @@
+#include "kapi/boot_modules.hpp"
+
+#include "kapi/boot.hpp"
+#include "kapi/boot_module/boot_module.hpp"
+#include "kapi/boot_module/boot_module_registry.hpp"
+#include "kapi/system.hpp"
+
+#include "arch/boot/boot.hpp"
+#include "arch/boot/ld.hpp"
+
+#include <kstd/print>
+
+#include <multiboot2/information.hpp>
+
+#include <algorithm>
+#include <atomic>
+#include <bit>
+#include <cstdint>
+#include <optional>
+
+namespace kapi::boot_modules
+{
+ namespace
+ {
+ auto constinit registry = std::optional<kapi::boot_modules::boot_module_registry>{};
+ } // namespace
+
+ auto init() -> void
+ {
+ auto static constinit is_initialized = std::atomic_flag{};
+ if (is_initialized.test_and_set())
+ {
+ system::panic("[x86_64] Boot module registry has already been initialized.");
+ }
+
+ kstd::println("[x86_64:BOOT_MODULES] Initializing boot module registry.");
+
+ registry.emplace(kapi::boot_modules::boot_module_registry{});
+
+ auto modules = boot::bootstrap_information.mbi->modules();
+ std::ranges::for_each(modules, [](auto const & module) {
+ registry->add_boot_module(kapi::boot_modules::boot_module{
+ .name = module.string(),
+ .start_address = module.start_address + std::bit_cast<std::uintptr_t>(&arch::boot::TEACHOS_VMA),
+ .size = module.end_address - module.start_address,
+ });
+ });
+
+ set_boot_module_registry(*registry);
+ }
+} // namespace kapi::boot_modules \ No newline at end of file
diff --git a/kapi/CMakeLists.txt b/kapi/CMakeLists.txt
index 5e914bb..028cdbb 100644
--- a/kapi/CMakeLists.txt
+++ b/kapi/CMakeLists.txt
@@ -5,8 +5,11 @@ target_sources("kapi" PUBLIC
FILE_SET HEADERS
BASE_DIRS "include"
FILES
+ "include/kapi/boot_modules.hpp"
"include/kapi/boot.hpp"
"include/kapi/cio.hpp"
+ "include/kapi/boot_module/boot_module.hpp"
+ "include/kapi/boot_module/boot_module_registry.hpp"
"include/kapi/memory.hpp"
"include/kapi/memory/address.hpp"
"include/kapi/memory/frame_allocator.hpp"
diff --git a/kapi/include/kapi/boot_module/boot_module.hpp b/kapi/include/kapi/boot_module/boot_module.hpp
new file mode 100644
index 0000000..f2d97ae
--- /dev/null
+++ b/kapi/include/kapi/boot_module/boot_module.hpp
@@ -0,0 +1,21 @@
+#ifndef TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_HPP
+#define TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_HPP
+
+#include <cstddef>
+#include <string_view>
+
+namespace kapi::boot_modules
+{
+ // ! The boot module struct
+ // !
+ // ! The boot module struct represents a module loaded by the bootloader, and contains information about it, such as
+ // ! its name, virtual start address, and size.
+ struct boot_module
+ {
+ std::string_view name;
+ size_t start_address;
+ size_t size;
+ };
+} // namespace kapi::boot_modules
+
+#endif \ No newline at end of file
diff --git a/kapi/include/kapi/boot_module/boot_module_registry.hpp b/kapi/include/kapi/boot_module/boot_module_registry.hpp
new file mode 100644
index 0000000..3732a5f
--- /dev/null
+++ b/kapi/include/kapi/boot_module/boot_module_registry.hpp
@@ -0,0 +1,108 @@
+#ifndef TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_REGISTRY_HPP
+#define TEACHOS_KAPI_BOOT_MODULE_BOOT_MODULE_REGISTRY_HPP
+
+#include "kapi/boot_module/boot_module.hpp"
+
+#include <array>
+#include <cstddef>
+
+namespace kapi::boot_modules
+{
+
+ // ! The interface of the boot module registry
+ // !
+ // ! The boot module registry is responsible for keeping track of the modules loaded by the bootloader, and
+ // ! providing access to them for the rest of the kernel.
+ struct boot_module_registry
+ {
+ using range_type = std::array<boot_module, 32>; // TODO BA-FS26 use kstd::vector when available
+
+ using value_type = range_type::value_type;
+ using const_reference = range_type::const_reference;
+
+ using const_iterator = range_type::const_iterator;
+ using const_reverse_iterator = range_type::const_reverse_iterator;
+ using size_type = range_type::size_type;
+ using difference_type = range_type::difference_type;
+
+ [[nodiscard]] auto begin() const noexcept -> const_iterator
+ {
+ return m_modules.begin();
+ }
+
+ [[nodiscard]] auto end() const noexcept -> const_iterator
+ {
+ return m_modules.end();
+ }
+
+ [[nodiscard]] auto cbegin() const noexcept -> const_iterator
+ {
+ return begin();
+ }
+
+ [[nodiscard]] auto cend() const noexcept -> const_iterator
+ {
+ return end();
+ }
+
+ [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator
+ {
+ return m_modules.rbegin();
+ }
+
+ [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator
+ {
+ return m_modules.rend();
+ }
+
+ [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator
+ {
+ return rbegin();
+ }
+
+ [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator
+ {
+ return rend();
+ }
+
+ [[nodiscard]] auto front() const noexcept -> const_reference
+ {
+ return m_modules.front();
+ }
+
+ [[nodiscard]] auto back() const noexcept -> const_reference
+ {
+ return m_modules.back();
+ }
+
+ [[nodiscard]] auto size() const noexcept -> std::size_t
+ {
+ return m_modules.size();
+ }
+
+ [[nodiscard]] auto empty() const noexcept -> bool
+ {
+ return m_modules.empty();
+ }
+
+ [[nodiscard]] auto at(std::size_t index) const -> const_reference
+ {
+ return m_modules.at(index);
+ }
+
+ [[nodiscard]] auto operator[](std::size_t index) const noexcept -> const_reference
+ {
+ return m_modules[index];
+ }
+
+ auto add_boot_module(boot_module module) -> void
+ {
+ m_modules.at(0) = module; // TODO BA-FS26 push back when kstd::vector is available
+ }
+
+ private:
+ range_type m_modules{};
+ };
+} // namespace kapi::boot_modules
+
+#endif \ No newline at end of file
diff --git a/kapi/include/kapi/boot_modules.hpp b/kapi/include/kapi/boot_modules.hpp
new file mode 100644
index 0000000..752b070
--- /dev/null
+++ b/kapi/include/kapi/boot_modules.hpp
@@ -0,0 +1,25 @@
+#ifndef TEACHOS_KAPI_BOOT_MODULES_HPP
+#define TEACHOS_KAPI_BOOT_MODULES_HPP
+
+#include "kapi/boot_module/boot_module_registry.hpp" // IWYU pragma: export
+
+namespace kapi::boot_modules
+{
+
+ //! @qualifier platform-defined
+ //! Initialize the boot module registry.
+ //!
+ //! @note This function must be implemented by the target platform.
+ //!
+ //! This function initializes the boot module registry, which is responsible for keeping track of the modules loaded
+ //! by the bootloader, and providing access to them for the rest of the kernel.
+ auto init() -> void;
+
+ //! @qualifier kernel-defined
+ //! Set the boot module registry
+ //!
+ //! @param registry A new boot module registry.
+ auto set_boot_module_registry(boot_module_registry & registry) -> void;
+
+} // namespace kapi::boot_modules
+#endif \ No newline at end of file
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index 02e517c..b7b7c71 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -1,5 +1,6 @@
add_executable("kernel"
# Platform-independent KAPI implementation
+ "kapi/boot_modules.cpp"
"kapi/cio.cpp"
"kapi/memory.cpp"
"kapi/system.cpp"
diff --git a/kernel/kapi/boot_modules.cpp b/kernel/kapi/boot_modules.cpp
new file mode 100644
index 0000000..3f0f044
--- /dev/null
+++ b/kernel/kapi/boot_modules.cpp
@@ -0,0 +1,21 @@
+#include "kapi/boot_modules.hpp"
+
+#include "kapi/system.hpp"
+
+#include <optional>
+
+namespace kapi::boot_modules
+{
+
+ constinit auto static registry = std::optional<kapi::boot_modules::boot_module_registry>{};
+
+ auto set_boot_module_registry(boot_module_registry & registry) -> void
+ {
+ if (kapi::boot_modules::registry)
+ {
+ system::panic("[x86_64] Boot module registry has already been set.");
+ }
+
+ kapi::boot_modules::registry = registry;
+ }
+} // namespace kapi::boot_modules
diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp
index 01bcbb0..117a1d8 100644
--- a/kernel/src/main.cpp
+++ b/kernel/src/main.cpp
@@ -1,3 +1,4 @@
+#include "kapi/boot_modules.hpp"
#include "kapi/cio.hpp"
#include "kapi/memory.hpp"
#include "kapi/system.hpp"
@@ -16,5 +17,8 @@ auto main() -> int
kstd::println("[OS] Memory subsystem initialized.");
kapi::system::memory_initialized();
+ kapi::boot_modules::init();
+ kstd::println("[OS] Boot module registry initialized.");
+
kapi::system::panic("Returning from kernel main!");
}