From 3d09b0bd2c35740b34b87c1400e0a3d93647a5d2 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 24 Jul 2026 19:27:20 +0200 Subject: kapi: extract real boot module registry singleton --- arch/x86_64/kapi/boot_modules.cpp | 22 +--- kapi/kapi/boot_modules.hpp | 18 +-- kapi/kapi/boot_modules/boot_module_registry.hpp | 109 ----------------- kapi/kapi/boot_modules/bus.hpp | 6 +- kapi/kapi/boot_modules/registry.hpp | 76 ++++++++++++ kapi/kapi/test_support/boot_modules.hpp | 17 +++ kernel/CMakeLists.txt | 2 +- kernel/kapi/boot_module/bus.cpp | 2 +- kernel/kapi/boot_module/registry.cpp | 131 +++++++++++++++++++++ kernel/kapi/boot_modules.cpp | 41 ------- kernel/kernel/devices/storage.cpp | 3 +- kernel/kernel/devices/storage.tests.cpp | 11 +- kernel/kernel/test_support/boot_modules.hpp | 10 -- .../filesystem/storage_boot_module_fixture.cpp | 28 +++-- .../filesystem/storage_boot_module_fixture.hpp | 2 +- .../kernel/test_support/state_reset_listener.cpp | 5 +- 16 files changed, 261 insertions(+), 222 deletions(-) delete mode 100644 kapi/kapi/boot_modules/boot_module_registry.hpp create mode 100644 kapi/kapi/boot_modules/registry.hpp create mode 100644 kapi/kapi/test_support/boot_modules.hpp create mode 100644 kernel/kapi/boot_module/registry.cpp delete mode 100644 kernel/kapi/boot_modules.cpp delete mode 100644 kernel/kernel/test_support/boot_modules.hpp diff --git a/arch/x86_64/kapi/boot_modules.cpp b/arch/x86_64/kapi/boot_modules.cpp index f910bdbc..361a155a 100644 --- a/arch/x86_64/kapi/boot_modules.cpp +++ b/arch/x86_64/kapi/boot_modules.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include @@ -14,40 +14,26 @@ #include #include -#include #include #include -#include namespace kapi::boot_modules { - namespace - { - auto constinit registry = std::optional{}; - } // 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::init(); - registry.emplace(kapi::boot_modules::boot_module_registry{}); + kstd::println("[x86_64:BOOT_MODULES] Registering boot modules."); auto modules = boot::bootstrap_information.mbi->modules(); std::ranges::for_each(modules, [](auto const & module) { - registry->add_boot_module(kapi::boot_modules::boot_module{ + registry::get().add(kapi::boot_modules::boot_module{ .name = module.string(), .start_address = memory::linear_address{module.start_address + std::bit_cast(&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/kapi/boot_modules.hpp b/kapi/kapi/boot_modules.hpp index 18995303..49a83ef5 100644 --- a/kapi/kapi/boot_modules.hpp +++ b/kapi/kapi/boot_modules.hpp @@ -1,9 +1,9 @@ #ifndef TEACHOS_KAPI_BOOT_MODULES_HPP #define TEACHOS_KAPI_BOOT_MODULES_HPP -#include // IWYU pragma: export -#include // IWYU pragma: export -#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export namespace kapi::boot_modules { @@ -17,17 +17,5 @@ namespace kapi::boot_modules //! 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; - - //! @qualifier kernel-defined - //! Get the boot module registry. - //! - //! @returns The boot module registry. - auto get_boot_module_registry() -> boot_module_registry const &; - } // namespace kapi::boot_modules #endif \ No newline at end of file diff --git a/kapi/kapi/boot_modules/boot_module_registry.hpp b/kapi/kapi/boot_modules/boot_module_registry.hpp deleted file mode 100644 index 7f490ae3..00000000 --- a/kapi/kapi/boot_modules/boot_module_registry.hpp +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef TEACHOS_KAPI_BOOT_MODULES_BOOT_MODULE_REGISTRY_HPP -#define TEACHOS_KAPI_BOOT_MODULES_BOOT_MODULE_REGISTRY_HPP - -// IWYU pragma: private, include - -#include - -#include - -#include - -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 = kstd::vector; - 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; - - [[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.push_back(module); - } - - private: - range_type m_modules{}; - }; -} // namespace kapi::boot_modules - -#endif \ No newline at end of file diff --git a/kapi/kapi/boot_modules/bus.hpp b/kapi/kapi/boot_modules/bus.hpp index 9cab7edb..7e3c773c 100644 --- a/kapi/kapi/boot_modules/bus.hpp +++ b/kapi/kapi/boot_modules/bus.hpp @@ -4,7 +4,7 @@ // IWYU pragma: private, include #include -#include +#include #include #include @@ -53,7 +53,7 @@ namespace kapi::boot_modules struct boot_module_bus final : kapi::devices::bus, kapi::devices::bus_protocol { - explicit boot_module_bus(boot_module_registry const * registry); + explicit boot_module_bus(registry const * registry); auto enumerate(kapi::devices::bus & self) -> void override; @@ -63,7 +63,7 @@ namespace kapi::boot_modules [[nodiscard]] auto protocol() -> kapi::devices::bus_protocol * override; private: - boot_module_registry const * m_registry; + registry const * m_registry; }; } // namespace kapi::boot_modules diff --git a/kapi/kapi/boot_modules/registry.hpp b/kapi/kapi/boot_modules/registry.hpp new file mode 100644 index 00000000..4c659fa4 --- /dev/null +++ b/kapi/kapi/boot_modules/registry.hpp @@ -0,0 +1,76 @@ +#ifndef TEACHOS_KAPI_BOOT_MODULES_REGISTRY_HPP +#define TEACHOS_KAPI_BOOT_MODULES_REGISTRY_HPP + +// IWYU pragma: private, include + +#include + +#include + +#include + +namespace kapi::boot_modules +{ + + //! @addtogroup kapi-boot_modules-kernel-defined + //! @{ + + //! 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 registry + { + using container = kstd::vector; + using value_type = container::value_type; + using const_reference = container::const_reference; + + using const_iterator = container::const_iterator; + using const_reverse_iterator = container::const_reverse_iterator; + using size_type = container::size_type; + + auto static init() -> void; + + auto static get() -> registry &; + + registry() = default; + + [[nodiscard]] auto begin() const noexcept -> const_iterator; + + [[nodiscard]] auto end() const noexcept -> const_iterator; + + [[nodiscard]] auto cbegin() const noexcept -> const_iterator; + + [[nodiscard]] auto cend() const noexcept -> const_iterator; + + [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator; + + [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator; + + [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator; + + [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator; + + [[nodiscard]] auto front() const noexcept -> const_reference; + + [[nodiscard]] auto back() const noexcept -> const_reference; + + [[nodiscard]] auto size() const noexcept -> std::size_t; + + [[nodiscard]] auto empty() const noexcept -> bool; + + [[nodiscard]] auto at(std::size_t index) const -> const_reference; + + [[nodiscard]] auto operator[](std::size_t index) const noexcept -> const_reference; + + auto add(boot_module module) -> void; + + private: + container m_modules{}; + }; + + //! @} + +} // namespace kapi::boot_modules + +#endif \ No newline at end of file diff --git a/kapi/kapi/test_support/boot_modules.hpp b/kapi/kapi/test_support/boot_modules.hpp new file mode 100644 index 00000000..86a81307 --- /dev/null +++ b/kapi/kapi/test_support/boot_modules.hpp @@ -0,0 +1,17 @@ +#ifndef KAPI_TEST_SUPPORT_BOOT_MODULES_HPP +#define KAPI_TEST_SUPPORT_BOOT_MODULES_HPP + +#include + +#include + +namespace kapi::test_support::boot_modules +{ + + auto deinit_registry() -> void; + + auto inject_registry(kapi::boot_modules::registry && registry) -> std::optional; + +} // namespace kapi::test_support::boot_modules + +#endif diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index f4d0d3b3..5a0b42a8 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -9,7 +9,7 @@ target_sources("kernel_lib" PRIVATE # Kernel-defined KAPI Implementation "kapi/acpi.cpp" "kapi/boot_module/bus.cpp" - "kapi/boot_modules.cpp" + "kapi/boot_module/registry.cpp" "kapi/cio.cpp" "kapi/cpu.cpp" "kapi/devices.cpp" diff --git a/kernel/kapi/boot_module/bus.cpp b/kernel/kapi/boot_module/bus.cpp index aab1403b..88f2cda3 100644 --- a/kernel/kapi/boot_module/bus.cpp +++ b/kernel/kapi/boot_module/bus.cpp @@ -53,7 +53,7 @@ namespace kapi::boot_modules return kapi::devices::device::query_interface(interface); } - boot_module_bus::boot_module_bus(boot_module_registry const * registry) + boot_module_bus::boot_module_bus(registry const * registry) : kapi::devices::bus{"boot_modules"} , m_registry(registry) {} diff --git a/kernel/kapi/boot_module/registry.cpp b/kernel/kapi/boot_module/registry.cpp new file mode 100644 index 00000000..80c76129 --- /dev/null +++ b/kernel/kapi/boot_module/registry.cpp @@ -0,0 +1,131 @@ +#include + +#include +#include +#include + +#include +#include +#include + +namespace kapi::boot_modules +{ + + namespace + { + constinit auto instance = std::optional{}; + } + + auto registry::init() -> void + { + if (instance) + { + system::panic("[OS] Boot module registry has already been initialized."); + } + + instance.emplace(); + } + + auto registry::get() -> registry & + { + if (!instance) + { + system::panic("[OS] Boot module registry has not been initialized."); + } + + return *instance; + } + + auto registry::begin() const noexcept -> const_iterator + { + return m_modules.begin(); + } + + auto registry::end() const noexcept -> const_iterator + { + return m_modules.end(); + } + + auto registry::cbegin() const noexcept -> const_iterator + { + return m_modules.cbegin(); + } + + auto registry::cend() const noexcept -> const_iterator + { + return m_modules.cend(); + } + + auto registry::rbegin() const noexcept -> const_reverse_iterator + { + return m_modules.rbegin(); + } + + auto registry::rend() const noexcept -> const_reverse_iterator + { + return m_modules.rend(); + } + + auto registry::crbegin() const noexcept -> const_reverse_iterator + { + return m_modules.crbegin(); + } + + auto registry::crend() const noexcept -> const_reverse_iterator + { + return m_modules.crend(); + } + + auto registry::front() const noexcept -> const_reference + { + return m_modules.front(); + } + + auto registry::back() const noexcept -> const_reference + { + return m_modules.back(); + } + + auto registry::size() const noexcept -> std::size_t + { + return m_modules.size(); + } + + auto registry::empty() const noexcept -> bool + { + return m_modules.empty(); + } + + auto registry::at(std::size_t index) const -> const_reference + { + return m_modules.at(index); + } + + auto registry::operator[](std::size_t index) const noexcept -> const_reference + { + return m_modules[index]; + } + + auto registry::add(boot_module module) -> void + { + m_modules.push_back(module); + } + +} // namespace kapi::boot_modules + +namespace kapi::test_support::boot_modules +{ + + auto deinit_registry() -> void + { + kapi::boot_modules::instance.reset(); + } + + auto inject_registry(kapi::boot_modules::registry && registry) -> std::optional + { + auto old = std::move(kapi::boot_modules::instance); + kapi::boot_modules::instance.emplace(std::move(registry)); + return old; + } + +} // namespace kapi::test_support::boot_modules diff --git a/kernel/kapi/boot_modules.cpp b/kernel/kapi/boot_modules.cpp deleted file mode 100644 index 5629b77f..00000000 --- a/kernel/kapi/boot_modules.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include - -#include - -#include - -namespace -{ - constinit auto static registry = std::optional{}; -} // namespace - -namespace kapi::boot_modules -{ - auto set_boot_module_registry(boot_module_registry & new_registry) -> void - { - if (registry) - { - system::panic("[x86_64] Boot module registry has already been set."); - } - - registry = new_registry; - } - - auto get_boot_module_registry() -> boot_module_registry const & - { - if (!registry) - { - system::panic("[x86_64] Boot module registry has not been initialized."); - } - - return *registry; - } -} // namespace kapi::boot_modules - -namespace kernel::tests::boot_modules -{ - auto deinit() -> void - { - registry.reset(); - } -} // namespace kernel::tests::boot_modules diff --git a/kernel/kernel/devices/storage.cpp b/kernel/kernel/devices/storage.cpp index 28f96de2..cbd350ce 100644 --- a/kernel/kernel/devices/storage.cpp +++ b/kernel/kernel/devices/storage.cpp @@ -9,8 +9,7 @@ namespace kernel::devices::storage { auto init() -> void { - auto modules_bus = - kstd::make_shared(&kapi::boot_modules::get_boot_module_registry()); + auto modules_bus = kstd::make_shared(&kapi::boot_modules::registry::get()); kapi::devices::get_root_bus()->add_child(modules_bus); modules_bus->enumerate(*modules_bus); } diff --git a/kernel/kernel/devices/storage.tests.cpp b/kernel/kernel/devices/storage.tests.cpp index a51b6996..30cafe4a 100644 --- a/kernel/kernel/devices/storage.tests.cpp +++ b/kernel/kernel/devices/storage.tests.cpp @@ -1,10 +1,9 @@ #include -#include - #include #include #include +#include #include @@ -14,15 +13,15 @@ TEST_CASE("Storage devices attached with init() are reachable from the root bus", "[devices][storage]") { auto storage = std::vector{4096, std::byte{}}; - auto registry = kapi::boot_modules::boot_module_registry{}; + auto registry = kapi::boot_modules::registry{}; - registry.add_boot_module({ + registry.add({ .name = "test_module type=ramdisk", .start_address = kapi::memory::linear_address{storage.data()}, .size = storage.size(), }); - kapi::boot_modules::set_boot_module_registry(registry); + kapi::test_support::boot_modules::inject_registry(std::move(registry)); kernel::devices::storage::init(); @@ -47,5 +46,5 @@ TEST_CASE("Storage devices attached with init() are reachable from the root bus" CHECK(boot_device->state() == kapi::devices::state::bound); CHECK(boot_device->bound_driver() != nullptr); - kernel::tests::boot_modules::deinit(); + kapi::test_support::boot_modules::deinit_registry(); } \ No newline at end of file diff --git a/kernel/kernel/test_support/boot_modules.hpp b/kernel/kernel/test_support/boot_modules.hpp deleted file mode 100644 index 2343a104..00000000 --- a/kernel/kernel/test_support/boot_modules.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef TEACHOS_KERNEL_TEST_SUPPORT_BOOT_MODULES_HPP -#define TEACHOS_KERNEL_TEST_SUPPORT_BOOT_MODULES_HPP - -namespace kernel::tests::boot_modules -{ - //! Deinitialize the boot module registry. - auto deinit() -> void; -} // namespace kernel::tests::boot_modules - -#endif \ No newline at end of file diff --git a/kernel/kernel/test_support/filesystem/storage_boot_module_fixture.cpp b/kernel/kernel/test_support/filesystem/storage_boot_module_fixture.cpp index 5bddd956..75b25011 100644 --- a/kernel/kernel/test_support/filesystem/storage_boot_module_fixture.cpp +++ b/kernel/kernel/test_support/filesystem/storage_boot_module_fixture.cpp @@ -1,11 +1,11 @@ #include #include -#include #include #include #include +#include #include @@ -78,7 +78,7 @@ namespace kernel::tests::filesystem storage_boot_module_fixture::~storage_boot_module_fixture() { - kernel::tests::boot_modules::deinit(); + kapi::test_support::boot_modules::deinit_registry(); } auto storage_boot_module_fixture::setup_modules(std::size_t module_count, std::size_t module_size) -> void @@ -98,14 +98,16 @@ namespace kernel::tests::filesystem for (std::size_t i = 0; i < module_count; ++i) { - m_registry.add_boot_module(kapi::boot_modules::boot_module{ - m_module_names[i].c_str(), kapi::memory::linear_address{m_module_data[i].data()}, m_module_data[i].size()}); + m_registry.add({ + .name = m_module_names[i].c_str(), + .start_address = kapi::memory::linear_address{m_module_data[i].data()}, + .size = m_module_data[i].size(), + }); } - kapi::boot_modules::set_boot_module_registry(m_registry); + kapi::test_support::boot_modules::inject_registry(std::move(m_registry)); - m_boot_module_bus = - kstd::make_shared(&kapi::boot_modules::get_boot_module_registry()); + m_boot_module_bus = kstd::make_shared(&kapi::boot_modules::registry::get()); m_boot_module_bus->enumerate(*m_boot_module_bus); if (module_count > 0 && kapi::devices::interface_registry::get().all(kapi::devices::block_device::id).empty()) @@ -131,10 +133,9 @@ namespace kernel::tests::filesystem setup_module_from_img(module_names[i], img_paths[i]); } - kapi::boot_modules::set_boot_module_registry(m_registry); + kapi::test_support::boot_modules::inject_registry(std::move(m_registry)); - m_boot_module_bus = - kstd::make_shared(&kapi::boot_modules::get_boot_module_registry()); + m_boot_module_bus = kstd::make_shared(&kapi::boot_modules::registry::get()); m_boot_module_bus->enumerate(*m_boot_module_bus); if (!module_names.empty() && kapi::devices::interface_registry::get().all(kapi::devices::block_device::id).empty()) @@ -149,7 +150,10 @@ namespace kernel::tests::filesystem m_module_names.push_back(module_name + " type=ramdisk"); auto & mapped_image = m_mapped_images.emplace_back(img_path); - m_registry.add_boot_module(kapi::boot_modules::boot_module{ - m_module_names.back().c_str(), kapi::memory::linear_address{mapped_image.mapping}, mapped_image.size}); + m_registry.add({ + .name = m_module_names.back().c_str(), + .start_address = kapi::memory::linear_address{mapped_image.mapping}, + .size = mapped_image.size, + }); } } // namespace kernel::tests::filesystem \ No newline at end of file diff --git a/kernel/kernel/test_support/filesystem/storage_boot_module_fixture.hpp b/kernel/kernel/test_support/filesystem/storage_boot_module_fixture.hpp index 663a8032..fdb50037 100644 --- a/kernel/kernel/test_support/filesystem/storage_boot_module_fixture.hpp +++ b/kernel/kernel/test_support/filesystem/storage_boot_module_fixture.hpp @@ -37,7 +37,7 @@ namespace kernel::tests::filesystem std::size_t size; }; - kapi::boot_modules::boot_module_registry m_registry{}; + kapi::boot_modules::registry m_registry{}; std::vector m_module_names{}; std::vector> m_module_data{}; std::vector m_mapped_images{}; diff --git a/kernel/kernel/test_support/state_reset_listener.cpp b/kernel/kernel/test_support/state_reset_listener.cpp index cc51d43f..45e8f5cb 100644 --- a/kernel/kernel/test_support/state_reset_listener.cpp +++ b/kernel/kernel/test_support/state_reset_listener.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -16,6 +15,7 @@ #include #include #include +#include #include #include @@ -48,8 +48,7 @@ struct state_reset_listener : Catch::EventListenerBase kernel::tests::filesystem::type_registry::deinit(); kernel::tests::filesystem::open_file_table::deinit(); - kernel::tests::boot_modules::deinit(); - + kapi::test_support::boot_modules::deinit_registry(); kapi::test_support::devices::deinit(); kernel::tests::memory::deinit(); kernel::tests::cpu::deinit(); -- cgit v1.2.3