From aa25bfac399e32efda039eb833b2c4d74f1edba0 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 24 Jul 2026 17:25:23 +0200 Subject: kernel: restructure devices and drivers --- kernel/CMakeLists.txt | 5 +- kernel/kapi/devices.cpp | 4 +- kernel/kernel/devices/storage.cpp | 4 - kernel/kernel/devices/storage/ram_disk/driver.cpp | 158 --------------------- kernel/kernel/devices/storage/ram_disk/driver.hpp | 35 ----- kernel/kernel/drivers/init.cpp | 21 +++ kernel/kernel/drivers/init.hpp | 11 ++ kernel/kernel/drivers/storage/ram_disk.cpp | 158 +++++++++++++++++++++ kernel/kernel/drivers/storage/ram_disk.hpp | 33 +++++ kernel/kernel/filesystem/type_registry.cpp | 8 ++ kernel/kernel/main.cpp | 2 +- .../test_support/filesystem/type_registry.hpp | 10 ++ .../kernel/test_support/state_reset_listener.cpp | 18 ++- 13 files changed, 259 insertions(+), 208 deletions(-) delete mode 100644 kernel/kernel/devices/storage/ram_disk/driver.cpp delete mode 100644 kernel/kernel/devices/storage/ram_disk/driver.hpp create mode 100644 kernel/kernel/drivers/init.cpp create mode 100644 kernel/kernel/drivers/init.hpp create mode 100644 kernel/kernel/drivers/storage/ram_disk.cpp create mode 100644 kernel/kernel/drivers/storage/ram_disk.hpp create mode 100644 kernel/kernel/test_support/filesystem/type_registry.hpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 700cde8f..082cb7be 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -42,9 +42,12 @@ target_sources("kernel_lib" PRIVATE "kernel/devices/block_device_utils.cpp" "kernel/devices/root_bus.cpp" + # Driver Subsystem + "kernel/drivers/storage/ram_disk.cpp" + "kernel/drivers/init.cpp" + # Storage Device Subsystem "kernel/devices/storage.cpp" - "kernel/devices/storage/ram_disk/driver.cpp" # Filesystem Subsystem "kernel/filesystem/dentry.cpp" diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp index 267bfb4d..64e549f3 100644 --- a/kernel/kapi/devices.cpp +++ b/kernel/kapi/devices.cpp @@ -1,8 +1,8 @@ #include #include +#include -#include #include #include @@ -31,7 +31,7 @@ namespace kapi::devices } interface_registry::init(); - driver_registry::init(); + kernel::drivers::init(); root_bus = kstd::make_shared(); register_device(root_bus); diff --git a/kernel/kernel/devices/storage.cpp b/kernel/kernel/devices/storage.cpp index cfdf3ec2..1f74b9af 100644 --- a/kernel/kernel/devices/storage.cpp +++ b/kernel/kernel/devices/storage.cpp @@ -1,7 +1,5 @@ #include -#include - #include #include #include @@ -13,8 +11,6 @@ namespace kernel::devices::storage { auto init() -> void { - kapi::devices::driver_registry::get().add(kstd::make_shared()); - auto modules_bus = kstd::make_shared(&kapi::boot_modules::get_boot_module_registry()); kapi::devices::get_root_bus()->add_child(modules_bus); diff --git a/kernel/kernel/devices/storage/ram_disk/driver.cpp b/kernel/kernel/devices/storage/ram_disk/driver.cpp deleted file mode 100644 index 4aedf43b..00000000 --- a/kernel/kernel/devices/storage/ram_disk/driver.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace kstd::units_literals; - -namespace kernel::devices::storage::ram_disk -{ - - namespace - { - constexpr auto ram_disk_block_size = 512_B; - - struct block_device final : kapi::devices::block_device - { - explicit block_device(kapi::boot_modules::boot_module const & module) - : m_module(module) - {} - - auto read_block(std::size_t block_index, void * buffer) const -> kstd::result override - { - if (!buffer) - { - kapi::system::panic("[RAM DISK] read_block called with null buffer."); - } - - auto info = block_device_utils::calculate_transfer(*this, block_index); - - if (info.to_transfer > 0_B) - { - auto source = static_cast(m_module.start_address) + info.offset; - kstd::libc::memcpy(buffer, source, info.to_transfer.value); - } - - if (info.remainder > 0_B) - { - kstd::libc::memset(static_cast(buffer) + info.to_transfer, 0, info.remainder.value); - } - - return info.to_transfer; - } - - auto write_block(std::size_t block_index, void const * buffer) -> kstd::result override - { - if (buffer == nullptr) - { - kapi::system::panic("[RAM DISK] write_block called with null buffer."); - } - - auto const info = block_device_utils::calculate_transfer(*this, block_index); - - if (info.to_transfer > 0_B) - { - auto const dest = static_cast(m_module.start_address) + info.offset; - kstd::libc::memcpy(dest, buffer, info.to_transfer.value); - } - - return info.to_transfer; - } - - [[nodiscard]] auto block_size() const -> kstd::units::bytes override - { - return ram_disk_block_size; - } - - [[nodiscard]] auto capacity() const -> kstd::units::bytes override - { - return kstd::units::bytes{m_module.size}; - } - - private: - kapi::boot_modules::boot_module m_module; - }; - - } // namespace - - auto driver::probe(kapi::devices::device & device) -> kstd::result - { - auto interface = device.as(); - if (!interface) - { - return kstd::failure(make_error_code(kstd::errc::invalid_argument)); - } - - auto const & module = interface->module(); - if (module.start_address.raw() == 0 || module.size == 0) - { - return kstd::failure(make_error_code(kstd::errc::invalid_argument)); - } - - auto implementation = kstd::make_shared(module); - - auto next_index = std::ranges::count_if( - kapi::devices::interface_registry::get().all(kapi::devices::block_device::id), [this](auto const & published) { - auto published_device = published.device(); - return published_device && published_device->bound_driver() == this; - }); - auto name = kstd::format("ram{}", next_index); - - auto published = kapi::devices::publish_interface(device.shared_from_this(), name, - implementation.get()); - if (!published) - { - return published; - } - - device.set_driver_data(implementation); - - return kstd::success(); - } - - auto driver::unbind(kapi::devices::device & device) -> void - { - kapi::devices::interface_registry::get().unpublish(device, kapi::devices::block_device::id); - device.set_driver_data(nullptr); - } - - auto driver::claimed_parameter() const -> std::pair - { - return {"type", "ramdisk"}; - } - - auto driver::claimed_major() const -> std::optional - { - return kernel::filesystem::block_major_numbers::ram_disk; - } - - auto driver::query_interface(kapi::devices::interface interface) -> void * - { - if (interface == kapi::boot_modules::boot_module_driver_identification::id) - { - return static_cast(this); - } - - return kapi::devices::driver::query_interface(interface); - } - -} // namespace kernel::devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/kernel/devices/storage/ram_disk/driver.hpp b/kernel/kernel/devices/storage/ram_disk/driver.hpp deleted file mode 100644 index e079d832..00000000 --- a/kernel/kernel/devices/storage/ram_disk/driver.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_DRIVER_HPP -#define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_DRIVER_HPP - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -namespace kernel::devices::storage::ram_disk -{ - - struct driver final : kapi::devices::driver, kapi::boot_modules::boot_module_driver_identification - { - [[nodiscard]] auto probe(kapi::devices::device & device) -> kstd::result override; - - auto unbind(kapi::devices::device & device) -> void override; - - [[nodiscard]] auto claimed_parameter() const -> std::pair override; - - [[nodiscard]] auto claimed_major() const -> std::optional override; - - protected: - auto query_interface(kapi::devices::interface interface) -> void * override; - }; - -} // namespace kernel::devices::storage::ram_disk - -#endif \ No newline at end of file diff --git a/kernel/kernel/drivers/init.cpp b/kernel/kernel/drivers/init.cpp new file mode 100644 index 00000000..766011ef --- /dev/null +++ b/kernel/kernel/drivers/init.cpp @@ -0,0 +1,21 @@ +#include + +#include + +#include + +#include + +namespace kernel::drivers +{ + + auto init() -> void + { + kapi::devices::driver_registry::init(); + + auto & registry = kapi::devices::driver_registry::get(); + + registry.add(kstd::make_shared()); + } + +} // namespace kernel::drivers \ No newline at end of file diff --git a/kernel/kernel/drivers/init.hpp b/kernel/kernel/drivers/init.hpp new file mode 100644 index 00000000..73dfb9bc --- /dev/null +++ b/kernel/kernel/drivers/init.hpp @@ -0,0 +1,11 @@ +#ifndef TEACHOS_KERNEL_DRIVERS_INIT_HPP +#define TEACHOS_KERNEL_DRIVERS_INIT_HPP + +namespace kernel::drivers +{ + + auto init() -> void; + +} + +#endif \ No newline at end of file diff --git a/kernel/kernel/drivers/storage/ram_disk.cpp b/kernel/kernel/drivers/storage/ram_disk.cpp new file mode 100644 index 00000000..69256a56 --- /dev/null +++ b/kernel/kernel/drivers/storage/ram_disk.cpp @@ -0,0 +1,158 @@ +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace kstd::units_literals; + +namespace kernel::drivers::storage +{ + + namespace + { + constexpr auto default_block_size = 512_B; + + struct block_node final : kapi::devices::block_device + { + explicit block_node(kapi::boot_modules::boot_module const & module) + : m_module(module) + {} + + auto read_block(std::size_t block_index, void * buffer) const -> kstd::result override + { + if (!buffer) + { + kapi::system::panic("[RAM DISK] read_block called with null buffer."); + } + + auto info = devices::block_device_utils::calculate_transfer(*this, block_index); + + if (info.to_transfer > 0_B) + { + auto source = static_cast(m_module.start_address) + info.offset; + kstd::libc::memcpy(buffer, source, info.to_transfer.value); + } + + if (info.remainder > 0_B) + { + kstd::libc::memset(static_cast(buffer) + info.to_transfer, 0, info.remainder.value); + } + + return info.to_transfer; + } + + auto write_block(std::size_t block_index, void const * buffer) -> kstd::result override + { + if (buffer == nullptr) + { + kapi::system::panic("[RAM DISK] write_block called with null buffer."); + } + + auto const info = devices::block_device_utils::calculate_transfer(*this, block_index); + + if (info.to_transfer > 0_B) + { + auto const dest = static_cast(m_module.start_address) + info.offset; + kstd::libc::memcpy(dest, buffer, info.to_transfer.value); + } + + return info.to_transfer; + } + + [[nodiscard]] auto block_size() const -> kstd::units::bytes override + { + return default_block_size; + } + + [[nodiscard]] auto capacity() const -> kstd::units::bytes override + { + return kstd::units::bytes{m_module.size}; + } + + private: + kapi::boot_modules::boot_module m_module; + }; + + } // namespace + + auto ram_disk::probe(kapi::devices::device & device) -> kstd::result + { + auto interface = device.as(); + if (!interface) + { + return kstd::failure(make_error_code(kstd::errc::invalid_argument)); + } + + auto const & module = interface->module(); + if (module.start_address.raw() == 0 || module.size == 0) + { + return kstd::failure(make_error_code(kstd::errc::invalid_argument)); + } + + auto implementation = kstd::make_shared(module); + + auto next_index = std::ranges::count_if( + kapi::devices::interface_registry::get().all(kapi::devices::block_device::id), [this](auto const & published) { + auto published_device = published.device(); + return published_device && published_device->bound_driver() == this; + }); + auto name = kstd::format("ram{}", next_index); + + auto published = kapi::devices::publish_interface(device.shared_from_this(), name, + implementation.get()); + if (!published) + { + return published; + } + + device.set_driver_data(implementation); + + return kstd::success(); + } + + auto ram_disk::unbind(kapi::devices::device & device) -> void + { + kapi::devices::interface_registry::get().unpublish(device, kapi::devices::block_device::id); + device.set_driver_data(nullptr); + } + + auto ram_disk::claimed_parameter() const -> std::pair + { + return {"type", "ramdisk"}; + } + + auto ram_disk::claimed_major() const -> std::optional + { + return kernel::filesystem::block_major_numbers::ram_disk; + } + + auto ram_disk::query_interface(kapi::devices::interface interface) -> void * + { + if (interface == kapi::boot_modules::boot_module_driver_identification::id) + { + return static_cast(this); + } + + return kapi::devices::driver::query_interface(interface); + } + +} // namespace kernel::drivers::storage \ No newline at end of file diff --git a/kernel/kernel/drivers/storage/ram_disk.hpp b/kernel/kernel/drivers/storage/ram_disk.hpp new file mode 100644 index 00000000..973a9e45 --- /dev/null +++ b/kernel/kernel/drivers/storage/ram_disk.hpp @@ -0,0 +1,33 @@ +#ifndef TEACH_OS_KERNEL_DRIVERS_STORAGE_RAM_DISK_HPP +#define TEACH_OS_KERNEL_DRIVERS_STORAGE_RAM_DISK_HPP + +#include +#include + +#include + +#include +#include +#include +#include + +namespace kernel::drivers::storage +{ + + struct ram_disk final : kapi::devices::driver, kapi::boot_modules::boot_module_driver_identification + { + [[nodiscard]] auto probe(kapi::devices::device & device) -> kstd::result override; + + auto unbind(kapi::devices::device & device) -> void override; + + [[nodiscard]] auto claimed_parameter() const -> std::pair override; + + [[nodiscard]] auto claimed_major() const -> std::optional override; + + protected: + auto query_interface(kapi::devices::interface interface) -> void * override; + }; + +} // namespace kernel::drivers::storage + +#endif \ No newline at end of file diff --git a/kernel/kernel/filesystem/type_registry.cpp b/kernel/kernel/filesystem/type_registry.cpp index 6850090a..0b4cb7ea 100644 --- a/kernel/kernel/filesystem/type_registry.cpp +++ b/kernel/kernel/filesystem/type_registry.cpp @@ -74,3 +74,11 @@ namespace kernel::filesystem } } // namespace kernel::filesystem + +namespace kernel::tests::filesystem::type_registry +{ + auto deinit() -> void + { + kernel::filesystem::instance.reset(); + } +} // namespace kernel::tests::filesystem::type_registry \ No newline at end of file diff --git a/kernel/kernel/main.cpp b/kernel/kernel/main.cpp index bc1285c6..aa12df1a 100644 --- a/kernel/kernel/main.cpp +++ b/kernel/kernel/main.cpp @@ -156,7 +156,7 @@ auto main() -> int kstd::println("[OS] Memory subsystem initialized."); kapi::devices::init(); - kstd::println("[OS] System root bus initialized."); + kstd::println("[OS] Basic device and driver subsystem initialized."); kapi::devices::init_platform_drivers(); kstd::println("[OS] Platform drivers initialized."); diff --git a/kernel/kernel/test_support/filesystem/type_registry.hpp b/kernel/kernel/test_support/filesystem/type_registry.hpp new file mode 100644 index 00000000..8d5b6029 --- /dev/null +++ b/kernel/kernel/test_support/filesystem/type_registry.hpp @@ -0,0 +1,10 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_TYPE_REGISTRY_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_TYPE_REGISTRY_HPP + +namespace kernel::tests::filesystem::type_registry +{ + //! Deinitialize the FS type registry singleton. + auto deinit() -> void; +} // namespace kernel::tests::filesystem::type_registry + +#endif \ No newline at end of file diff --git a/kernel/kernel/test_support/state_reset_listener.cpp b/kernel/kernel/test_support/state_reset_listener.cpp index 1f2cb769..cc51d43f 100644 --- a/kernel/kernel/test_support/state_reset_listener.cpp +++ b/kernel/kernel/test_support/state_reset_listener.cpp @@ -1,10 +1,13 @@ -#include +#include #include +#include +#include #include #include #include #include #include +#include #include #include @@ -28,28 +31,29 @@ struct state_reset_listener : Catch::EventListenerBase void testCaseStarting(Catch::TestCaseInfo const &) override { - kernel::filesystem::open_file_table::init(); - kapi::cio::init(); kapi::cpu::init(); kapi::memory::init(); kapi::devices::init(); - kapi::devices::driver_registry::get().add(kstd::make_shared()); + kernel::filesystem::open_file_table::init(); + + kapi::devices::driver_registry::get().add(kstd::make_shared()); } void testCaseEnded(Catch::TestCaseStats const &) override { kernel::tests::filesystem::device_number_registry::deinit(); - kernel::tests::filesystem::open_file_table::deinit(); kernel::tests::filesystem::vfs::deinit(); + kernel::tests::filesystem::type_registry::deinit(); + kernel::tests::filesystem::open_file_table::deinit(); + kernel::tests::boot_modules::deinit(); + kapi::test_support::devices::deinit(); kernel::tests::memory::deinit(); kernel::tests::cpu::deinit(); kernel::tests::cio::deinit(); - - kapi::test_support::devices::deinit(); } }; -- cgit v1.2.3