diff options
| -rw-r--r-- | arch/x86_64/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | arch/x86_64/kapi/boot_modules.cpp | 51 | ||||
| -rw-r--r-- | kapi/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | kapi/include/kapi/boot_module/boot_module.hpp | 21 | ||||
| -rw-r--r-- | kapi/include/kapi/boot_module/boot_module_registry.hpp | 108 | ||||
| -rw-r--r-- | kapi/include/kapi/boot_modules.hpp | 25 | ||||
| -rw-r--r-- | kernel/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | kernel/kapi/boot_modules.cpp | 21 | ||||
| -rw-r--r-- | kernel/src/main.cpp | 4 |
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!"); } |
