From 9c5e1ad6f4c88b4db69e3906cc25b58e212d8dd6 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 24 Jul 2026 23:28:22 +0200 Subject: kapi: move block and character device --- kapi/kapi/devices.hpp | 2 - kapi/kapi/devices/block_device.hpp | 51 ---------------------- kapi/kapi/devices/character_device.hpp | 39 ----------------- kapi/kapi/filesystem.hpp | 8 ++-- kapi/kapi/filesystem/block_device.hpp | 51 ++++++++++++++++++++++ kapi/kapi/filesystem/character_device.hpp | 39 +++++++++++++++++ kernel/kernel/devices/block_device_utils.cpp | 19 ++++---- kernel/kernel/devices/block_device_utils.hpp | 8 ++-- kernel/kernel/devices/storage.cpp | 3 +- kernel/kernel/devices/storage.tests.cpp | 3 +- kernel/kernel/drivers/storage/ram_disk.cpp | 20 +++++---- kernel/kernel/filesystem/device_inode.cpp | 4 +- kernel/kernel/filesystem/device_inode.tests.cpp | 2 +- .../filesystem/device_number_registry.tests.cpp | 5 ++- kernel/kernel/filesystem/file_type_bindings.hpp | 3 +- .../kernel/test_support/devices/block_device.cpp | 5 ++- .../kernel/test_support/devices/block_device.hpp | 3 +- .../filesystem/storage_boot_module_fixture.cpp | 6 ++- 18 files changed, 141 insertions(+), 130 deletions(-) delete mode 100644 kapi/kapi/devices/block_device.hpp delete mode 100644 kapi/kapi/devices/character_device.hpp create mode 100644 kapi/kapi/filesystem/block_device.hpp create mode 100644 kapi/kapi/filesystem/character_device.hpp diff --git a/kapi/kapi/devices.hpp b/kapi/kapi/devices.hpp index c1e7e9f4..51f5129e 100644 --- a/kapi/kapi/devices.hpp +++ b/kapi/kapi/devices.hpp @@ -1,10 +1,8 @@ #ifndef TEACHOS_KAPI_DEVICES_HPP #define TEACHOS_KAPI_DEVICES_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 #include // IWYU pragma: export diff --git a/kapi/kapi/devices/block_device.hpp b/kapi/kapi/devices/block_device.hpp deleted file mode 100644 index e606188e..00000000 --- a/kapi/kapi/devices/block_device.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef TEACHOS_KAPI_DEVICES_BLOCK_DEVICE_HPP -#define TEACHOS_KAPI_DEVICES_BLOCK_DEVICE_HPP - -// IWYU pragma: private, include - -#include - -#include -#include - -#include - -namespace kapi::devices -{ - - struct block_device - { - constexpr auto static id = interface_id{"block"}; - - //! Virtual destructor to enable clean deletes through base pointers. - virtual ~block_device() = default; - - //! Read data from a block into a given buffer. - //! - //! If the selected block is smaller than the buffer, a partial read will occur. - //! - //! @param block_index The number of the block to read from. - //! @param buffer The buffer to read into. - //! @return The number of bytes read on success, an error otherwise. - [[nodiscard]] auto virtual read_block(size_t block_index, void * buffer) const - -> kstd::result = 0; - - //! Write data from a buffer into a block. - //! - //! If the buffer is larger than the selected block, a partial write will occur. - //! - //! @param block_index The number of the block to write to. - //! @param buffer The buffer to write from. - //! @return The number of bytes written on success, an error otherwise. - auto virtual write_block(std::size_t block_index, void const * buffer) -> kstd::result = 0; - - //! Get the block size in bytes. - [[nodiscard]] auto virtual block_size() const -> kstd::units::bytes = 0; - - //! Get the capacity of the associated device. - [[nodiscard]] auto virtual capacity() const -> kstd::units::bytes = 0; - }; - -} // namespace kapi::devices - -#endif \ No newline at end of file diff --git a/kapi/kapi/devices/character_device.hpp b/kapi/kapi/devices/character_device.hpp deleted file mode 100644 index 40921940..00000000 --- a/kapi/kapi/devices/character_device.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef TEACHOS_KAPI_DEVICES_CHARACTER_DEVICE_HPP -#define TEACHOS_KAPI_DEVICES_CHARACTER_DEVICE_HPP - -// IWYU pragma: private, include - -#include - -#include -#include - -#include -#include - -namespace kapi::devices -{ - - struct character_device - { - constexpr auto static id = interface_id{"char"}; - - //! Virtual destructor to enable clean deletes through base pointers. - virtual ~character_device() = default; - - //! Read data from the stream into a given buffer. - //! - //! @param buffer The buffer to read into. - //! @return The number of bytes read on success, an error otherwise. - [[nodiscard]] auto virtual read(std::span buffer) const -> kstd::result = 0; - - //! Write data from a buffer into the stream. - //! - //! @param buffer The buffer to write from. - //! @return The number of bytes written on success, an error otherwise. - auto virtual write_block(std::span buffer) -> kstd::result = 0; - }; - -} // namespace kapi::devices - -#endif \ No newline at end of file diff --git a/kapi/kapi/filesystem.hpp b/kapi/kapi/filesystem.hpp index 4b0971f6..6796532f 100644 --- a/kapi/kapi/filesystem.hpp +++ b/kapi/kapi/filesystem.hpp @@ -1,9 +1,11 @@ #ifndef TEACHOS_KAPI_FILESYSTEM_HPP #define TEACHOS_KAPI_FILESYSTEM_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 +#include // IWYU pragma: export +#include // IWYU pragma: export #include #include diff --git a/kapi/kapi/filesystem/block_device.hpp b/kapi/kapi/filesystem/block_device.hpp new file mode 100644 index 00000000..6d062b07 --- /dev/null +++ b/kapi/kapi/filesystem/block_device.hpp @@ -0,0 +1,51 @@ +#ifndef TEACHOS_KAPI_FILESYSTEM_BLOCK_DEVICE_HPP +#define TEACHOS_KAPI_FILESYSTEM_BLOCK_DEVICE_HPP + +// IWYU pragma: private, include + +#include + +#include +#include + +#include + +namespace kapi::filesystem +{ + + struct block_device + { + constexpr auto static id = kapi::devices::interface_id{"block"}; + + //! Virtual destructor to enable clean deletes through base pointers. + virtual ~block_device() = default; + + //! Read data from a block into a given buffer. + //! + //! If the selected block is smaller than the buffer, a partial read will occur. + //! + //! @param block_index The number of the block to read from. + //! @param buffer The buffer to read into. + //! @return The number of bytes read on success, an error otherwise. + [[nodiscard]] auto virtual read_block(size_t block_index, void * buffer) const + -> kstd::result = 0; + + //! Write data from a buffer into a block. + //! + //! If the buffer is larger than the selected block, a partial write will occur. + //! + //! @param block_index The number of the block to write to. + //! @param buffer The buffer to write from. + //! @return The number of bytes written on success, an error otherwise. + auto virtual write_block(std::size_t block_index, void const * buffer) -> kstd::result = 0; + + //! Get the block size in bytes. + [[nodiscard]] auto virtual block_size() const -> kstd::units::bytes = 0; + + //! Get the capacity of the associated device. + [[nodiscard]] auto virtual capacity() const -> kstd::units::bytes = 0; + }; + +} // namespace kapi::filesystem + +#endif \ No newline at end of file diff --git a/kapi/kapi/filesystem/character_device.hpp b/kapi/kapi/filesystem/character_device.hpp new file mode 100644 index 00000000..b839410d --- /dev/null +++ b/kapi/kapi/filesystem/character_device.hpp @@ -0,0 +1,39 @@ +#ifndef TEACHOS_KAPI_FILESYSTEM_CHARACTER_DEVICE_HPP +#define TEACHOS_KAPI_FILESYSTEM_CHARACTER_DEVICE_HPP + +// IWYU pragma: private, include + +#include + +#include +#include + +#include +#include + +namespace kapi::filesystem +{ + + struct character_device + { + constexpr auto static id = kapi::devices::interface_id{"char"}; + + //! Virtual destructor to enable clean deletes through base pointers. + virtual ~character_device() = default; + + //! Read data from the stream into a given buffer. + //! + //! @param buffer The buffer to read into. + //! @return The number of bytes read on success, an error otherwise. + [[nodiscard]] auto virtual read(std::span buffer) const -> kstd::result = 0; + + //! Write data from a buffer into the stream. + //! + //! @param buffer The buffer to write from. + //! @return The number of bytes written on success, an error otherwise. + auto virtual write_block(std::span buffer) -> kstd::result = 0; + }; + +} // namespace kapi::filesystem + +#endif \ No newline at end of file diff --git a/kernel/kernel/devices/block_device_utils.cpp b/kernel/kernel/devices/block_device_utils.cpp index a46e10ba..83bb8144 100644 --- a/kernel/kernel/devices/block_device_utils.cpp +++ b/kernel/kernel/devices/block_device_utils.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include @@ -19,10 +19,11 @@ namespace kernel::devices::block_device_utils namespace { using block_op = kstd::result (*)(size_t idx, kstd::units::bytes off, kstd::units::bytes len, - kstd::units::bytes done, kapi::devices::block_device & device, - std::byte * scratch, void * buffer); + kstd::units::bytes done, + kapi::filesystem::block_device & device, std::byte * scratch, + void * buffer); - auto process_blocks(kapi::devices::block_device & device, kstd::units::bytes offset, kstd::units::bytes size, + auto process_blocks(kapi::filesystem::block_device & device, kstd::units::bytes offset, kstd::units::bytes size, void * buffer, block_op op) -> kstd::result { if (buffer == nullptr) @@ -68,7 +69,7 @@ namespace kernel::devices::block_device_utils } } // namespace - auto calculate_transfer(kapi::devices::block_device const & device, size_t block_index) -> transfer_info + auto calculate_transfer(kapi::filesystem::block_device const & device, size_t block_index) -> transfer_info { auto const offset = block_index * device.block_size(); auto const limit = device.capacity(); @@ -79,12 +80,12 @@ namespace kernel::devices::block_device_utils return {offset, to_transfer, device.block_size() - to_transfer}; } - auto read(kapi::devices::block_device & device, void * buffer, kstd::units::bytes offset, kstd::units::bytes size) + auto read(kapi::filesystem::block_device & device, void * buffer, kstd::units::bytes offset, kstd::units::bytes size) -> kstd::result { return process_blocks(device, offset, size, buffer, [](size_t idx, kstd::units::bytes off, kstd::units::bytes len, kstd::units::bytes done, - kapi::devices::block_device & device, std::byte * scratch, void * buffer) { + kapi::filesystem::block_device & device, std::byte * scratch, void * buffer) { auto * out = static_cast(buffer); if (off == 0_B && len == device.block_size()) { @@ -102,12 +103,12 @@ namespace kernel::devices::block_device_utils }); } - auto write(kapi::devices::block_device & device, void const * buffer, kstd::units::bytes offset, + auto write(kapi::filesystem::block_device & device, void const * buffer, kstd::units::bytes offset, kstd::units::bytes size) -> kstd::result { return process_blocks(device, offset, size, const_cast(buffer), [](size_t idx, kstd::units::bytes off, kstd::units::bytes len, kstd::units::bytes done, - kapi::devices::block_device & device, std::byte * scratch, void * buffer) { + kapi::filesystem::block_device & device, std::byte * scratch, void * buffer) { auto const * in = static_cast(buffer); if (off == 0_B && len == device.block_size()) { diff --git a/kernel/kernel/devices/block_device_utils.hpp b/kernel/kernel/devices/block_device_utils.hpp index a3895259..240cb20d 100644 --- a/kernel/kernel/devices/block_device_utils.hpp +++ b/kernel/kernel/devices/block_device_utils.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_UTILS_HPP #define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_UTILS_HPP -#include +#include #include #include @@ -28,7 +28,7 @@ namespace kernel::devices::block_device_utils kstd::units::bytes remainder; }; - [[nodiscard]] auto calculate_transfer(kapi::devices::block_device const & device, size_t block_index) + [[nodiscard]] auto calculate_transfer(kapi::filesystem::block_device const & device, size_t block_index) -> transfer_info; /** @@ -40,7 +40,7 @@ namespace kernel::devices::block_device_utils @param size The number of bytes to read. @return The number of bytes actually read, which may be less than the requested size. */ - auto read(kapi::devices::block_device & device, void * buffer, kstd::units::bytes offset, kstd::units::bytes size) + auto read(kapi::filesystem::block_device & device, void * buffer, kstd::units::bytes offset, kstd::units::bytes size) -> kstd::result; /** @@ -52,7 +52,7 @@ namespace kernel::devices::block_device_utils @param size The number of bytes to write. @return The number of bytes actually written, which may be less than the requested size. */ - auto write(kapi::devices::block_device & device, void const * buffer, kstd::units::bytes offset, + auto write(kapi::filesystem::block_device & device, void const * buffer, kstd::units::bytes offset, kstd::units::bytes size) -> kstd::result; } // namespace kernel::devices::block_device_utils diff --git a/kernel/kernel/devices/storage.cpp b/kernel/kernel/devices/storage.cpp index a95b1840..12d5639c 100644 --- a/kernel/kernel/devices/storage.cpp +++ b/kernel/kernel/devices/storage.cpp @@ -3,6 +3,7 @@ #include #include +#include #include @@ -17,7 +18,7 @@ namespace kernel::devices::storage auto determine_boot_device() -> kstd::shared_ptr { - auto block_devices = kapi::devices::interface_registry::get().all(kapi::devices::block_device::id); + auto block_devices = kapi::devices::interface_registry::get().all(kapi::filesystem::block_device::id); if (block_devices.empty()) { return nullptr; diff --git a/kernel/kernel/devices/storage.tests.cpp b/kernel/kernel/devices/storage.tests.cpp index 2a06149a..754457b9 100644 --- a/kernel/kernel/devices/storage.tests.cpp +++ b/kernel/kernel/devices/storage.tests.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -28,7 +29,7 @@ TEST_CASE("Storage devices attached with init() are reachable from the root bus" bus->add_child(device); - auto block_devices = kapi::devices::interface_registry::get().all(kapi::devices::block_device::id); + auto block_devices = kapi::devices::interface_registry::get().all(kapi::filesystem::block_device::id); REQUIRE(block_devices.size() == 1); CHECK(block_devices[0].name() == "ram0"); diff --git a/kernel/kernel/drivers/storage/ram_disk.cpp b/kernel/kernel/drivers/storage/ram_disk.cpp index 8bf06b66..6c9bed0d 100644 --- a/kernel/kernel/drivers/storage/ram_disk.cpp +++ b/kernel/kernel/drivers/storage/ram_disk.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -30,7 +31,7 @@ namespace kernel::drivers::storage { constexpr auto default_block_size = 512_B; - struct block_node final : kapi::devices::block_device + struct block_node final : kapi::filesystem::block_device { explicit block_node(kapi::boot_modules::module const & module) : m_module(module) @@ -109,15 +110,16 @@ namespace kernel::drivers::storage 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 next_index = + std::ranges::count_if(kapi::devices::interface_registry::get().all(kapi::filesystem::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()); + auto published = kapi::devices::publish_interface(device.shared_from_this(), name, + implementation.get()); if (!published) { return published; @@ -130,7 +132,7 @@ namespace kernel::drivers::storage auto ram_disk::unbind(kapi::devices::device & device) -> void { - kapi::devices::interface_registry::get().unpublish(device, kapi::devices::block_device::id); + kapi::devices::interface_registry::get().unpublish(device, kapi::filesystem::block_device::id); device.set_driver_data(nullptr); } diff --git a/kernel/kernel/filesystem/device_inode.cpp b/kernel/kernel/filesystem/device_inode.cpp index b898c5eb..c68e8d8d 100644 --- a/kernel/kernel/filesystem/device_inode.cpp +++ b/kernel/kernel/filesystem/device_inode.cpp @@ -41,7 +41,7 @@ namespace kernel::filesystem auto device_inode::read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const -> kstd::result { - if (auto block_device = kapi::devices::interface_registry::get().resolve(*m_device)) + if (auto block_device = kapi::devices::interface_registry::get().resolve(*m_device)) { return devices::block_device_utils::read(*block_device, buffer, offset, size); } @@ -52,7 +52,7 @@ namespace kernel::filesystem auto device_inode::write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size) -> kstd::result { - if (auto block_device = kapi::devices::interface_registry::get().resolve(*m_device)) + if (auto block_device = kapi::devices::interface_registry::get().resolve(*m_device)) { return devices::block_device_utils::write(*block_device, buffer, offset, size); } diff --git a/kernel/kernel/filesystem/device_inode.tests.cpp b/kernel/kernel/filesystem/device_inode.tests.cpp index f36bb4dc..f859bb1a 100644 --- a/kernel/kernel/filesystem/device_inode.tests.cpp +++ b/kernel/kernel/filesystem/device_inode.tests.cpp @@ -172,7 +172,7 @@ SCENARIO("Device inode raw_device()", "[filesystem][device-inode]") CHECK(kernel::tests::devices::bind(*device, std::uint8_t{1})); - REQUIRE(kapi::devices::interface_registry::get().publish(device, "ram0")); + REQUIRE(kapi::devices::interface_registry::get().publish(device, "ram0")); auto inode = kernel::filesystem::device_inode{device}; diff --git a/kernel/kernel/filesystem/device_number_registry.tests.cpp b/kernel/kernel/filesystem/device_number_registry.tests.cpp index 906f330a..262330e3 100644 --- a/kernel/kernel/filesystem/device_number_registry.tests.cpp +++ b/kernel/kernel/filesystem/device_number_registry.tests.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -27,7 +28,7 @@ namespace { auto device = kstd::make_shared(name, block_size); [[maybe_unused]] auto driver = kernel::tests::devices::bind(*device, major); - if (!interfaces.publish(device, name)) + if (!interfaces.publish(device, name)) { throw std::runtime_error{"failed to publish block device!"}; } @@ -144,7 +145,7 @@ SCENARIO("Device number registry resolves and numbers published block devices", GIVEN("A published device with no bound driver at all") { auto device = kstd::make_shared("unbound0", 512_B); - CHECK(interfaces.publish(device, "unbound0")); + CHECK(interfaces.publish(device, "unbound0")); THEN("it is never numbered") { diff --git a/kernel/kernel/filesystem/file_type_bindings.hpp b/kernel/kernel/filesystem/file_type_bindings.hpp index 00651f4a..9ef4d77f 100644 --- a/kernel/kernel/filesystem/file_type_bindings.hpp +++ b/kernel/kernel/filesystem/file_type_bindings.hpp @@ -5,6 +5,7 @@ #include #include +#include #include @@ -22,7 +23,7 @@ namespace kernel::filesystem //! //! This array associates published interfaces with files types. constexpr auto inline file_type_bindings = std::array{ - file_type_binding{kapi::devices::block_device::id, file_type::block}, + file_type_binding{kapi::filesystem::block_device::id, file_type::block}, }; } // namespace kernel::filesystem diff --git a/kernel/kernel/test_support/devices/block_device.cpp b/kernel/kernel/test_support/devices/block_device.cpp index a91a9cfb..48414aae 100644 --- a/kernel/kernel/test_support/devices/block_device.cpp +++ b/kernel/kernel/test_support/devices/block_device.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -69,9 +70,9 @@ namespace kernel::tests::devices auto block_device::query_interface(kapi::devices::interface_id interface) -> void * { - if (interface == kapi::devices::block_device::id) + if (interface == kapi::filesystem::block_device::id) { - return static_cast(this); + return static_cast(this); } return kapi::devices::device::query_interface(interface); diff --git a/kernel/kernel/test_support/devices/block_device.hpp b/kernel/kernel/test_support/devices/block_device.hpp index a1c37688..fed7b2bd 100644 --- a/kernel/kernel/test_support/devices/block_device.hpp +++ b/kernel/kernel/test_support/devices/block_device.hpp @@ -2,6 +2,7 @@ #define TEACHOS_KERNEL_TEST_SUPPORT_DEVICES_BLOCK_DEVICE_HPP #include +#include #include #include @@ -14,7 +15,7 @@ namespace kernel::tests::devices { - struct block_device final : kapi::devices::device, kapi::devices::block_device + struct block_device final : kapi::devices::device, kapi::filesystem::block_device { block_device(kstd::string const & name, kstd::units::bytes block_size, kstd::units::bytes initial_size = {}); 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 644e38fe..79011450 100644 --- a/kernel/kernel/test_support/filesystem/storage_boot_module_fixture.cpp +++ b/kernel/kernel/test_support/filesystem/storage_boot_module_fixture.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -102,7 +103,7 @@ namespace kernel::tests::filesystem m_boot_module_bus->add_child(kstd::make_shared(i, module)); } - if (module_count > 0 && kapi::devices::interface_registry::get().all(kapi::devices::block_device::id).empty()) + if (module_count > 0 && kapi::devices::interface_registry::get().all(kapi::filesystem::block_device::id).empty()) { throw std::runtime_error{"No RAM disk driver bound to any of the test fixture's boot modules."}; } @@ -126,7 +127,8 @@ namespace kernel::tests::filesystem setup_module_from_img(i, module_names[i], img_paths[i]); } - if (!module_names.empty() && kapi::devices::interface_registry::get().all(kapi::devices::block_device::id).empty()) + if (!module_names.empty() && + kapi::devices::interface_registry::get().all(kapi::filesystem::block_device::id).empty()) { throw std::runtime_error{"No RAM disk driver bound to any of the test fixture's boot modules."}; } -- cgit v1.2.3