From 3ace886a9e9f044cd48de51f0a15aceb02bfa9b2 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Tue, 17 Mar 2026 19:36:20 +0100 Subject: Clean up project folder structure --- kernel/src/devices/block_device.cpp | 42 +++++++++++ kernel/src/devices/device.cpp | 28 +++++++ .../storage/ram_disk/ram_disk_controller.cpp | 28 +++++++ .../devices/storage/ram_disk/ram_disk_device.cpp | 77 ++++++++++++++++++++ kernel/src/devices/storage/storage_controller.cpp | 44 +++++++++++ kernel/src/devices/storage/storage_management.cpp | 85 ++++++++++++++++++++++ 6 files changed, 304 insertions(+) create mode 100644 kernel/src/devices/block_device.cpp create mode 100644 kernel/src/devices/device.cpp create mode 100644 kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp create mode 100644 kernel/src/devices/storage/ram_disk/ram_disk_device.cpp create mode 100644 kernel/src/devices/storage/storage_controller.cpp create mode 100644 kernel/src/devices/storage/storage_management.cpp (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/block_device.cpp b/kernel/src/devices/block_device.cpp new file mode 100644 index 0000000..d12251b --- /dev/null +++ b/kernel/src/devices/block_device.cpp @@ -0,0 +1,42 @@ +#include "kernel/devices/block_device.hpp" + +#include "kapi/system.hpp" + +#include "kernel/devices/device.hpp" + +#include +#include + +namespace devices +{ + block_device::block_device(size_t major, size_t minor, std::string_view name, size_t block_size) + : device(major, minor, name) + , m_block_size(block_size) + { + if (m_block_size == 0) + { + kapi::system::panic("[DEVICES] block_device constructed with zero block size."); + } + } + + auto block_device::calculate_transfer(size_t block_index) const -> transfer_info + { + size_t const offset = block_index * m_block_size; + size_t const limit = size(); + + size_t const available = (offset < limit) ? (limit - offset) : 0; + size_t const to_transfer = (available < m_block_size) ? available : m_block_size; + + return {offset, to_transfer, m_block_size - to_transfer}; + } + + auto block_device::block_size() const -> size_t + { + return m_block_size; + } + + auto block_device::capacity() const -> size_t + { + return size(); + } +} // namespace devices \ No newline at end of file diff --git a/kernel/src/devices/device.cpp b/kernel/src/devices/device.cpp new file mode 100644 index 0000000..29498fa --- /dev/null +++ b/kernel/src/devices/device.cpp @@ -0,0 +1,28 @@ +#include "kernel/devices/device.hpp" + +#include +#include + +namespace devices +{ + device::device(size_t major, size_t minor, std::string_view name) + : m_major(major) + , m_minor(minor) + , m_name(name) + {} + + auto device::major() const -> size_t + { + return m_major; + } + + auto device::minor() const -> size_t + { + return m_minor; + } + + auto device::name() const -> std::string_view + { + return m_name; + } +} // namespace devices \ No newline at end of file diff --git a/kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp b/kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp new file mode 100644 index 0000000..efb6256 --- /dev/null +++ b/kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp @@ -0,0 +1,28 @@ +#include "kernel/devices/storage/ram_disk/ram_disk_controller.hpp" + +#include "kapi/boot_module/boot_module_registry.hpp" + +#include "kernel/devices/storage/ram_disk/ram_disk_device.hpp" + +#include +#include + +#include +#include + +namespace devices::storage::ram_disk +{ + ram_disk_controller::ram_disk_controller(kapi::boot_modules::boot_module_registry const * registry) + : m_boot_module_registry(registry) + {} + + auto ram_disk_controller::probe() -> void + { + size_t current_device_index = 0; + + std::ranges::for_each(*m_boot_module_registry, [this, ¤t_device_index](auto const & module) { + auto const minor = current_device_index++ * m_minors_per_device; + m_devices.push_back(kstd::make_shared(module, m_major, minor)); + }); + } +} // namespace devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/src/devices/storage/ram_disk/ram_disk_device.cpp b/kernel/src/devices/storage/ram_disk/ram_disk_device.cpp new file mode 100644 index 0000000..650a151 --- /dev/null +++ b/kernel/src/devices/storage/ram_disk/ram_disk_device.cpp @@ -0,0 +1,77 @@ +#include "kernel/devices/storage/ram_disk/ram_disk_device.hpp" + +#include "kapi/boot_module/boot_module.hpp" +#include "kapi/system.hpp" + +#include "kernel/devices/block_device.hpp" + +#include + +#include +#include +#include + +namespace devices::storage::ram_disk +{ + namespace + { + constexpr size_t RAM_DISK_BLOCK_SIZE = 512uz; + + // TODO BA-FS26 @Felix + // TODO BA-FS26 currently only names for 9 minor devices + constinit std::array name = {'r', 'a', 'm', '0', '\0'}; + + auto determine_device_name(size_t minor) -> std::string_view + { + name[3] = '0' + minor; + return std::string_view{name}; + } + } // namespace + + ram_disk_device::ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor) + : block_device(major, minor, determine_device_name(minor), RAM_DISK_BLOCK_SIZE) + , m_boot_module(module) + {} + + auto ram_disk_device::read_block(size_t block_index, void * buffer) const -> void + { + if (buffer == nullptr) + { + kapi::system::panic("[RAM DISK DEVICE] read_block called with null buffer."); + } + + auto const info = calculate_transfer(block_index); + + if (info.to_transfer > 0) + { + auto const src = static_cast(m_boot_module.start_address) + info.offset; + kstd::libc::memcpy(buffer, src, info.to_transfer); + } + + if (info.remainder > 0) + { + kstd::libc::memset(static_cast(buffer) + info.to_transfer, 0, info.remainder); + } + } + + auto ram_disk_device::write_block(size_t block_index, void const * buffer) -> void + { + if (buffer == nullptr) + { + kapi::system::panic("[RAM DISK DEVICE] write_block called with null buffer."); + } + + auto const info = calculate_transfer(block_index); + + if (info.to_transfer > 0) + { + auto const dest = static_cast(m_boot_module.start_address) + info.offset; + kstd::libc::memcpy(dest, buffer, info.to_transfer); + } + } + + auto ram_disk_device::size() const -> size_t + { + return m_boot_module.size; + } +} // namespace devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/src/devices/storage/storage_controller.cpp b/kernel/src/devices/storage/storage_controller.cpp new file mode 100644 index 0000000..e415436 --- /dev/null +++ b/kernel/src/devices/storage/storage_controller.cpp @@ -0,0 +1,44 @@ +#include "kernel/devices/storage/storage_controller.hpp" + +#include "kernel/devices/device.hpp" + +#include +#include + +#include +#include + +namespace devices::storage +{ + auto storage_controller::set_ids(size_t major, size_t minors_per_dev) -> void + { + m_major = major; + m_minors_per_device = minors_per_dev; + } + + auto storage_controller::major() const -> size_t + { + return m_major; + } + + auto storage_controller::device_by_minor(size_t minor) const -> kstd::shared_ptr + { + auto it = std::ranges::find_if(m_devices, [minor](auto const & device) { return device->minor() == minor; }); + + if (it != m_devices.end()) + { + return *it; + } + return nullptr; + } + + auto storage_controller::devices_count() const -> size_t + { + return m_devices.size(); + } + + auto storage_controller::all_devices() const -> kstd::vector> const & + { + return m_devices; + } +} // namespace devices::storage \ No newline at end of file diff --git a/kernel/src/devices/storage/storage_management.cpp b/kernel/src/devices/storage/storage_management.cpp new file mode 100644 index 0000000..56216b0 --- /dev/null +++ b/kernel/src/devices/storage/storage_management.cpp @@ -0,0 +1,85 @@ +#include "kernel/devices/storage/storage_management.hpp" + +#include "kapi/boot_modules.hpp" +#include "kapi/system.hpp" + +#include "kernel/devices/device.hpp" +#include "kernel/devices/storage/ram_disk/ram_disk_controller.hpp" +#include "kernel/devices/storage/storage_controller.hpp" + +#include +#include + +#include +#include +#include + +namespace devices::storage +{ + namespace + { + constexpr size_t static MINORS_PER_DEVICE = 16; + constexpr size_t static START_MAJOR = 1; + constinit size_t static next_free_major = START_MAJOR; + + constinit auto static active_storage_management = std::optional{}; + } // namespace + + auto storage_management::init() -> void + { + if (active_storage_management) + { + kapi::system::panic("[DEVICES] Storage management has already been initialized."); + } + active_storage_management.emplace(storage_management{}); + + auto current_ram_disk_controller = + kstd::make_shared(&kapi::boot_modules::get_boot_module_registry()); + active_storage_management->add_controller(current_ram_disk_controller); + + std::ranges::for_each(active_storage_management->m_controllers, [](auto controller) { controller->probe(); }); + } + + auto storage_management::get() -> storage_management & + { + if (!active_storage_management) + { + kapi::system::panic("[DEVICES] Storage management has not been initialized."); + } + + return *active_storage_management; + } + + auto storage_management::add_controller(kstd::shared_ptr const & controller) -> void + { + controller->set_ids(next_free_major++, MINORS_PER_DEVICE); + m_controllers.push_back(controller); + } + + auto storage_management::all_controllers() const -> kstd::vector> const & + { + return m_controllers; + } + + auto storage_management::device_by_major_minor(size_t major, size_t minor) -> kstd::shared_ptr + { + kstd::shared_ptr found = nullptr; + + std::ranges::find_if(m_controllers, [&](auto const & controller) { + if (controller != nullptr && controller->major() == major) + { + found = controller->device_by_minor(minor); + return found != nullptr; + } + return false; + }); + + return found; + } + + auto storage_management::determine_boot_device() -> kstd::shared_ptr + { + return device_by_major_minor(START_MAJOR, 0); + } + +} // namespace devices::storage \ No newline at end of file -- cgit v1.2.3 From 8c502bc3423a6b3597ffbebb06a3fa3e17a6e4b0 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 18 Mar 2026 09:21:11 +0100 Subject: fix clang-tidy warnings --- kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp b/kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp index efb6256..f3e9f70 100644 --- a/kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp +++ b/kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp @@ -5,7 +5,6 @@ #include "kernel/devices/storage/ram_disk/ram_disk_device.hpp" #include -#include #include #include -- cgit v1.2.3 From ac3510bb9f696869f059ecd4ece2c6970fa63b6c Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 21 Mar 2026 23:57:49 +0100 Subject: implement device names with kstd::string --- kernel/src/devices/block_device.cpp | 5 +++-- kernel/src/devices/device.cpp | 7 ++++--- kernel/src/devices/storage/ram_disk/ram_disk_device.cpp | 15 ++------------- 3 files changed, 9 insertions(+), 18 deletions(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/block_device.cpp b/kernel/src/devices/block_device.cpp index d12251b..3402814 100644 --- a/kernel/src/devices/block_device.cpp +++ b/kernel/src/devices/block_device.cpp @@ -4,12 +4,13 @@ #include "kernel/devices/device.hpp" +#include + #include -#include namespace devices { - block_device::block_device(size_t major, size_t minor, std::string_view name, size_t block_size) + block_device::block_device(size_t major, size_t minor, kstd::string const & name, size_t block_size) : device(major, minor, name) , m_block_size(block_size) { diff --git a/kernel/src/devices/device.cpp b/kernel/src/devices/device.cpp index 29498fa..287f14b 100644 --- a/kernel/src/devices/device.cpp +++ b/kernel/src/devices/device.cpp @@ -1,11 +1,12 @@ #include "kernel/devices/device.hpp" +#include + #include -#include namespace devices { - device::device(size_t major, size_t minor, std::string_view name) + device::device(size_t major, size_t minor, kstd::string const & name) : m_major(major) , m_minor(minor) , m_name(name) @@ -21,7 +22,7 @@ namespace devices return m_minor; } - auto device::name() const -> std::string_view + auto device::name() const -> kstd::string const & { return m_name; } diff --git a/kernel/src/devices/storage/ram_disk/ram_disk_device.cpp b/kernel/src/devices/storage/ram_disk/ram_disk_device.cpp index 650a151..bf329cb 100644 --- a/kernel/src/devices/storage/ram_disk/ram_disk_device.cpp +++ b/kernel/src/devices/storage/ram_disk/ram_disk_device.cpp @@ -6,30 +6,19 @@ #include "kernel/devices/block_device.hpp" #include +#include -#include #include -#include namespace devices::storage::ram_disk { namespace { constexpr size_t RAM_DISK_BLOCK_SIZE = 512uz; - - // TODO BA-FS26 @Felix - // TODO BA-FS26 currently only names for 9 minor devices - constinit std::array name = {'r', 'a', 'm', '0', '\0'}; - - auto determine_device_name(size_t minor) -> std::string_view - { - name[3] = '0' + minor; - return std::string_view{name}; - } } // namespace ram_disk_device::ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor) - : block_device(major, minor, determine_device_name(minor), RAM_DISK_BLOCK_SIZE) + : block_device(major, minor, "ram" + kstd::to_string(minor), RAM_DISK_BLOCK_SIZE) , m_boot_module(module) {} -- cgit v1.2.3 From 9c602f2cf8fd87f55adc31c085e469e72b7cbbfa Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sun, 29 Mar 2026 20:49:03 +0200 Subject: Move block device offset and size-to-blocks calculation to block_device_utils --- kernel/src/devices/block_device_utils.cpp | 103 ++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 kernel/src/devices/block_device_utils.cpp (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/block_device_utils.cpp b/kernel/src/devices/block_device_utils.cpp new file mode 100644 index 0000000..9d3af1b --- /dev/null +++ b/kernel/src/devices/block_device_utils.cpp @@ -0,0 +1,103 @@ +#include "kernel/devices/block_device_utils.hpp" + +#include "kapi/system.hpp" + +#include "kernel/devices/block_device.hpp" +#include "kernel/devices/device.hpp" + +#include +#include +#include + +#include +#include + +namespace devices::block_device_utils +{ + + using block_op = void (*)(size_t idx, size_t off, size_t len, size_t done, devices::block_device * device, + std::byte * scratch, void * buffer); + + auto process_blocks(kstd::shared_ptr const & device, size_t offset, size_t size, void * buffer, + block_op op) -> size_t + { + if (buffer == nullptr) + { + kapi::system::panic("[FILESYSTEM] device_file::process_blocks called with null buffer."); + } + + if (size == 0) + { + return 0; + } + + auto * block_dev = static_cast(device.get()); + if (block_dev == nullptr) + { + kapi::system::panic("[FILESYSTEM] device_file: expected block_device."); + } + + size_t const block_size = block_dev->block_size(); + size_t const capacity = block_dev->capacity(); + + if (offset >= capacity) + return 0; + size_t const total_to_process = std::min(size, capacity - offset); + + kstd::vector scratch_buffer{block_size}; + auto processed = 0uz; + + while (processed < total_to_process) + { + size_t const absolute_offset = offset + processed; + size_t const block_index = absolute_offset / block_size; + size_t const in_block_offset = absolute_offset % block_size; + size_t const chunk_size = std::min(total_to_process - processed, block_size - in_block_offset); + + op(block_index, in_block_offset, chunk_size, processed, block_dev, scratch_buffer.data(), buffer); + + processed += chunk_size; + } + + return processed; + } + + auto read(kstd::shared_ptr const & device, void * buffer, size_t offset, size_t size) -> size_t + { + return process_blocks(device, offset, size, buffer, + [](size_t idx, size_t off, size_t len, size_t done, devices::block_device * device, + std::byte * scratch, void * buffer) { + auto * out = static_cast(buffer); + if (off == 0 && len == device->block_size()) + { + device->read_block(idx, out + done); + } + else + { + device->read_block(idx, scratch); + kstd::libc::memcpy(out + done, scratch + off, len); + } + }); + } + + auto write(kstd::shared_ptr const & device, void const * buffer, size_t offset, size_t size) + -> size_t + { + return process_blocks(device, offset, size, const_cast(buffer), + [](size_t idx, size_t off, size_t len, size_t done, devices::block_device * device, + std::byte * scratch, void * buffer) { + auto const * in = static_cast(buffer); + if (off == 0 && len == device->block_size()) + { + device->write_block(idx, in + done); + } + else + { + device->read_block(idx, scratch); + kstd::libc::memcpy(scratch + off, in + done, len); + device->write_block(idx, scratch); + } + }); + } + +} // namespace devices::block_device_utils \ No newline at end of file -- cgit v1.2.3 From 5603c7ec2b07dbc772fe2c20a9e9e176c5465c57 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Mon, 30 Mar 2026 21:22:22 +0200 Subject: Move everything in kernel into kernel namespace --- kernel/src/devices/block_device.cpp | 4 ++-- kernel/src/devices/block_device_utils.cpp | 4 ++-- kernel/src/devices/device.cpp | 4 ++-- kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp | 4 ++-- kernel/src/devices/storage/ram_disk/ram_disk_device.cpp | 4 ++-- kernel/src/devices/storage/storage_controller.cpp | 4 ++-- kernel/src/devices/storage/storage_management.cpp | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/block_device.cpp b/kernel/src/devices/block_device.cpp index 3402814..cfe2eb2 100644 --- a/kernel/src/devices/block_device.cpp +++ b/kernel/src/devices/block_device.cpp @@ -8,7 +8,7 @@ #include -namespace devices +namespace kernel::devices { block_device::block_device(size_t major, size_t minor, kstd::string const & name, size_t block_size) : device(major, minor, name) @@ -40,4 +40,4 @@ namespace devices { return size(); } -} // namespace devices \ No newline at end of file +} // namespace kernel::devices \ No newline at end of file diff --git a/kernel/src/devices/block_device_utils.cpp b/kernel/src/devices/block_device_utils.cpp index 9d3af1b..5469087 100644 --- a/kernel/src/devices/block_device_utils.cpp +++ b/kernel/src/devices/block_device_utils.cpp @@ -12,7 +12,7 @@ #include #include -namespace devices::block_device_utils +namespace kernel::devices::block_device_utils { using block_op = void (*)(size_t idx, size_t off, size_t len, size_t done, devices::block_device * device, @@ -100,4 +100,4 @@ namespace devices::block_device_utils }); } -} // namespace devices::block_device_utils \ No newline at end of file +} // namespace kernel::devices::block_device_utils \ No newline at end of file diff --git a/kernel/src/devices/device.cpp b/kernel/src/devices/device.cpp index 287f14b..1e7589e 100644 --- a/kernel/src/devices/device.cpp +++ b/kernel/src/devices/device.cpp @@ -4,7 +4,7 @@ #include -namespace devices +namespace kernel::devices { device::device(size_t major, size_t minor, kstd::string const & name) : m_major(major) @@ -26,4 +26,4 @@ namespace devices { return m_name; } -} // namespace devices \ No newline at end of file +} // namespace kernel::devices \ No newline at end of file diff --git a/kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp b/kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp index f3e9f70..26eb10b 100644 --- a/kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp +++ b/kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp @@ -9,7 +9,7 @@ #include #include -namespace devices::storage::ram_disk +namespace kernel::devices::storage::ram_disk { ram_disk_controller::ram_disk_controller(kapi::boot_modules::boot_module_registry const * registry) : m_boot_module_registry(registry) @@ -24,4 +24,4 @@ namespace devices::storage::ram_disk m_devices.push_back(kstd::make_shared(module, m_major, minor)); }); } -} // namespace devices::storage::ram_disk \ No newline at end of file +} // namespace kernel::devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/src/devices/storage/ram_disk/ram_disk_device.cpp b/kernel/src/devices/storage/ram_disk/ram_disk_device.cpp index bf329cb..72e8025 100644 --- a/kernel/src/devices/storage/ram_disk/ram_disk_device.cpp +++ b/kernel/src/devices/storage/ram_disk/ram_disk_device.cpp @@ -10,7 +10,7 @@ #include -namespace devices::storage::ram_disk +namespace kernel::devices::storage::ram_disk { namespace { @@ -63,4 +63,4 @@ namespace devices::storage::ram_disk { return m_boot_module.size; } -} // namespace devices::storage::ram_disk \ No newline at end of file +} // namespace kernel::devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/src/devices/storage/storage_controller.cpp b/kernel/src/devices/storage/storage_controller.cpp index e415436..3d13b66 100644 --- a/kernel/src/devices/storage/storage_controller.cpp +++ b/kernel/src/devices/storage/storage_controller.cpp @@ -8,7 +8,7 @@ #include #include -namespace devices::storage +namespace kernel::devices::storage { auto storage_controller::set_ids(size_t major, size_t minors_per_dev) -> void { @@ -41,4 +41,4 @@ namespace devices::storage { return m_devices; } -} // namespace devices::storage \ No newline at end of file +} // namespace kernel::devices::storage \ No newline at end of file diff --git a/kernel/src/devices/storage/storage_management.cpp b/kernel/src/devices/storage/storage_management.cpp index 56216b0..2bc57c4 100644 --- a/kernel/src/devices/storage/storage_management.cpp +++ b/kernel/src/devices/storage/storage_management.cpp @@ -14,7 +14,7 @@ #include #include -namespace devices::storage +namespace kernel::devices::storage { namespace { @@ -82,4 +82,4 @@ namespace devices::storage return device_by_major_minor(START_MAJOR, 0); } -} // namespace devices::storage \ No newline at end of file +} // namespace kernel::devices::storage \ No newline at end of file -- cgit v1.2.3 From 846135ba5cdfa545124b97c74182f5eada9a403a Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Mon, 30 Mar 2026 21:20:25 +0200 Subject: Rename ram_disk and storage files --- kernel/src/devices/storage/controller.cpp | 44 +++++++++++ kernel/src/devices/storage/management.cpp | 85 ++++++++++++++++++++++ kernel/src/devices/storage/ram_disk/controller.cpp | 27 +++++++ kernel/src/devices/storage/ram_disk/device.cpp | 65 +++++++++++++++++ .../storage/ram_disk/ram_disk_controller.cpp | 27 ------- .../devices/storage/ram_disk/ram_disk_device.cpp | 66 ----------------- kernel/src/devices/storage/storage_controller.cpp | 44 ----------- kernel/src/devices/storage/storage_management.cpp | 85 ---------------------- 8 files changed, 221 insertions(+), 222 deletions(-) create mode 100644 kernel/src/devices/storage/controller.cpp create mode 100644 kernel/src/devices/storage/management.cpp create mode 100644 kernel/src/devices/storage/ram_disk/controller.cpp create mode 100644 kernel/src/devices/storage/ram_disk/device.cpp delete mode 100644 kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp delete mode 100644 kernel/src/devices/storage/ram_disk/ram_disk_device.cpp delete mode 100644 kernel/src/devices/storage/storage_controller.cpp delete mode 100644 kernel/src/devices/storage/storage_management.cpp (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/storage/controller.cpp b/kernel/src/devices/storage/controller.cpp new file mode 100644 index 0000000..46c45e4 --- /dev/null +++ b/kernel/src/devices/storage/controller.cpp @@ -0,0 +1,44 @@ +#include "kernel/devices/storage/controller.hpp" + +#include "kernel/devices/device.hpp" + +#include +#include + +#include +#include + +namespace kernel::devices::storage +{ + auto controller::set_ids(size_t major, size_t minors_per_dev) -> void + { + m_major = major; + m_minors_per_device = minors_per_dev; + } + + auto controller::major() const -> size_t + { + return m_major; + } + + auto controller::device_by_minor(size_t minor) const -> kstd::shared_ptr + { + auto it = std::ranges::find_if(m_devices, [minor](auto const & device) { return device->minor() == minor; }); + + if (it != m_devices.end()) + { + return *it; + } + return nullptr; + } + + auto controller::devices_count() const -> size_t + { + return m_devices.size(); + } + + auto controller::all_devices() const -> kstd::vector> const & + { + return m_devices; + } +} // namespace kernel::devices::storage \ No newline at end of file diff --git a/kernel/src/devices/storage/management.cpp b/kernel/src/devices/storage/management.cpp new file mode 100644 index 0000000..62c0ce4 --- /dev/null +++ b/kernel/src/devices/storage/management.cpp @@ -0,0 +1,85 @@ +#include "kernel/devices/storage/management.hpp" + +#include "kapi/boot_modules.hpp" +#include "kapi/system.hpp" + +#include "kernel/devices/device.hpp" +#include "kernel/devices/storage/controller.hpp" +#include "kernel/devices/storage/ram_disk/controller.hpp" + +#include +#include + +#include +#include +#include + +namespace kernel::devices::storage +{ + namespace + { + constexpr size_t static MINORS_PER_DEVICE = 16; + constexpr size_t static START_MAJOR = 1; + constinit size_t static next_free_major = START_MAJOR; + + constinit auto static active_storage_management = std::optional{}; + } // namespace + + auto management::init() -> void + { + if (active_storage_management) + { + kapi::system::panic("[DEVICES] Storage management has already been initialized."); + } + active_storage_management.emplace(management{}); + + auto current_ram_disk_controller = + kstd::make_shared(&kapi::boot_modules::get_boot_module_registry()); + active_storage_management->add_controller(current_ram_disk_controller); + + std::ranges::for_each(active_storage_management->m_controllers, [](auto controller) { controller->probe(); }); + } + + auto management::get() -> management & + { + if (!active_storage_management) + { + kapi::system::panic("[DEVICES] Storage management has not been initialized."); + } + + return *active_storage_management; + } + + auto management::add_controller(kstd::shared_ptr const & controller) -> void + { + controller->set_ids(next_free_major++, MINORS_PER_DEVICE); + m_controllers.push_back(controller); + } + + auto management::all_controllers() const -> kstd::vector> const & + { + return m_controllers; + } + + auto management::device_by_major_minor(size_t major, size_t minor) -> kstd::shared_ptr + { + kstd::shared_ptr found = nullptr; + + std::ranges::find_if(m_controllers, [&](auto const & controller) { + if (controller != nullptr && controller->major() == major) + { + found = controller->device_by_minor(minor); + return found != nullptr; + } + return false; + }); + + return found; + } + + auto management::determine_boot_device() -> kstd::shared_ptr + { + return device_by_major_minor(START_MAJOR, 0); + } + +} // namespace kernel::devices::storage \ No newline at end of file diff --git a/kernel/src/devices/storage/ram_disk/controller.cpp b/kernel/src/devices/storage/ram_disk/controller.cpp new file mode 100644 index 0000000..040e61f --- /dev/null +++ b/kernel/src/devices/storage/ram_disk/controller.cpp @@ -0,0 +1,27 @@ +#include "kernel/devices/storage/ram_disk/controller.hpp" + +#include "kapi/boot_module/boot_module_registry.hpp" + +#include "kernel/devices/storage/ram_disk/device.hpp" + +#include + +#include +#include + +namespace kernel::devices::storage::ram_disk +{ + controller::controller(kapi::boot_modules::boot_module_registry const * registry) + : m_boot_module_registry(registry) + {} + + auto controller::probe() -> void + { + size_t current_device_index = 0; + + std::ranges::for_each(*m_boot_module_registry, [this, ¤t_device_index](auto const & module) { + auto const minor = current_device_index++ * m_minors_per_device; + m_devices.push_back(kstd::make_shared(module, m_major, minor)); + }); + } +} // namespace kernel::devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/src/devices/storage/ram_disk/device.cpp b/kernel/src/devices/storage/ram_disk/device.cpp new file mode 100644 index 0000000..5116c93 --- /dev/null +++ b/kernel/src/devices/storage/ram_disk/device.cpp @@ -0,0 +1,65 @@ +#include "kapi/boot_module/boot_module.hpp" +#include "kapi/system.hpp" + +#include "kernel/devices/block_device.hpp" +#include "kernel/devices/storage/ram_disk/device.hpp" + +#include +#include + +#include + +namespace kernel::devices::storage::ram_disk +{ + namespace + { + constexpr size_t RAM_DISK_BLOCK_SIZE = 512uz; + } // namespace + + device::device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor) + : block_device(major, minor, "ram" + kstd::to_string(minor), RAM_DISK_BLOCK_SIZE) + , m_boot_module(module) + {} + + auto device::read_block(size_t block_index, void * buffer) const -> void + { + if (buffer == nullptr) + { + kapi::system::panic("[RAM DISK DEVICE] read_block called with null buffer."); + } + + auto const info = calculate_transfer(block_index); + + if (info.to_transfer > 0) + { + auto const src = static_cast(m_boot_module.start_address) + info.offset; + kstd::libc::memcpy(buffer, src, info.to_transfer); + } + + if (info.remainder > 0) + { + kstd::libc::memset(static_cast(buffer) + info.to_transfer, 0, info.remainder); + } + } + + auto device::write_block(size_t block_index, void const * buffer) -> void + { + if (buffer == nullptr) + { + kapi::system::panic("[RAM DISK DEVICE] write_block called with null buffer."); + } + + auto const info = calculate_transfer(block_index); + + if (info.to_transfer > 0) + { + auto const dest = static_cast(m_boot_module.start_address) + info.offset; + kstd::libc::memcpy(dest, buffer, info.to_transfer); + } + } + + auto device::size() const -> size_t + { + return m_boot_module.size; + } +} // namespace kernel::devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp b/kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp deleted file mode 100644 index 26eb10b..0000000 --- a/kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "kernel/devices/storage/ram_disk/ram_disk_controller.hpp" - -#include "kapi/boot_module/boot_module_registry.hpp" - -#include "kernel/devices/storage/ram_disk/ram_disk_device.hpp" - -#include - -#include -#include - -namespace kernel::devices::storage::ram_disk -{ - ram_disk_controller::ram_disk_controller(kapi::boot_modules::boot_module_registry const * registry) - : m_boot_module_registry(registry) - {} - - auto ram_disk_controller::probe() -> void - { - size_t current_device_index = 0; - - std::ranges::for_each(*m_boot_module_registry, [this, ¤t_device_index](auto const & module) { - auto const minor = current_device_index++ * m_minors_per_device; - m_devices.push_back(kstd::make_shared(module, m_major, minor)); - }); - } -} // namespace kernel::devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/src/devices/storage/ram_disk/ram_disk_device.cpp b/kernel/src/devices/storage/ram_disk/ram_disk_device.cpp deleted file mode 100644 index 72e8025..0000000 --- a/kernel/src/devices/storage/ram_disk/ram_disk_device.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "kernel/devices/storage/ram_disk/ram_disk_device.hpp" - -#include "kapi/boot_module/boot_module.hpp" -#include "kapi/system.hpp" - -#include "kernel/devices/block_device.hpp" - -#include -#include - -#include - -namespace kernel::devices::storage::ram_disk -{ - namespace - { - constexpr size_t RAM_DISK_BLOCK_SIZE = 512uz; - } // namespace - - ram_disk_device::ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor) - : block_device(major, minor, "ram" + kstd::to_string(minor), RAM_DISK_BLOCK_SIZE) - , m_boot_module(module) - {} - - auto ram_disk_device::read_block(size_t block_index, void * buffer) const -> void - { - if (buffer == nullptr) - { - kapi::system::panic("[RAM DISK DEVICE] read_block called with null buffer."); - } - - auto const info = calculate_transfer(block_index); - - if (info.to_transfer > 0) - { - auto const src = static_cast(m_boot_module.start_address) + info.offset; - kstd::libc::memcpy(buffer, src, info.to_transfer); - } - - if (info.remainder > 0) - { - kstd::libc::memset(static_cast(buffer) + info.to_transfer, 0, info.remainder); - } - } - - auto ram_disk_device::write_block(size_t block_index, void const * buffer) -> void - { - if (buffer == nullptr) - { - kapi::system::panic("[RAM DISK DEVICE] write_block called with null buffer."); - } - - auto const info = calculate_transfer(block_index); - - if (info.to_transfer > 0) - { - auto const dest = static_cast(m_boot_module.start_address) + info.offset; - kstd::libc::memcpy(dest, buffer, info.to_transfer); - } - } - - auto ram_disk_device::size() const -> size_t - { - return m_boot_module.size; - } -} // namespace kernel::devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/src/devices/storage/storage_controller.cpp b/kernel/src/devices/storage/storage_controller.cpp deleted file mode 100644 index 3d13b66..0000000 --- a/kernel/src/devices/storage/storage_controller.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "kernel/devices/storage/storage_controller.hpp" - -#include "kernel/devices/device.hpp" - -#include -#include - -#include -#include - -namespace kernel::devices::storage -{ - auto storage_controller::set_ids(size_t major, size_t minors_per_dev) -> void - { - m_major = major; - m_minors_per_device = minors_per_dev; - } - - auto storage_controller::major() const -> size_t - { - return m_major; - } - - auto storage_controller::device_by_minor(size_t minor) const -> kstd::shared_ptr - { - auto it = std::ranges::find_if(m_devices, [minor](auto const & device) { return device->minor() == minor; }); - - if (it != m_devices.end()) - { - return *it; - } - return nullptr; - } - - auto storage_controller::devices_count() const -> size_t - { - return m_devices.size(); - } - - auto storage_controller::all_devices() const -> kstd::vector> const & - { - return m_devices; - } -} // namespace kernel::devices::storage \ No newline at end of file diff --git a/kernel/src/devices/storage/storage_management.cpp b/kernel/src/devices/storage/storage_management.cpp deleted file mode 100644 index 2bc57c4..0000000 --- a/kernel/src/devices/storage/storage_management.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "kernel/devices/storage/storage_management.hpp" - -#include "kapi/boot_modules.hpp" -#include "kapi/system.hpp" - -#include "kernel/devices/device.hpp" -#include "kernel/devices/storage/ram_disk/ram_disk_controller.hpp" -#include "kernel/devices/storage/storage_controller.hpp" - -#include -#include - -#include -#include -#include - -namespace kernel::devices::storage -{ - namespace - { - constexpr size_t static MINORS_PER_DEVICE = 16; - constexpr size_t static START_MAJOR = 1; - constinit size_t static next_free_major = START_MAJOR; - - constinit auto static active_storage_management = std::optional{}; - } // namespace - - auto storage_management::init() -> void - { - if (active_storage_management) - { - kapi::system::panic("[DEVICES] Storage management has already been initialized."); - } - active_storage_management.emplace(storage_management{}); - - auto current_ram_disk_controller = - kstd::make_shared(&kapi::boot_modules::get_boot_module_registry()); - active_storage_management->add_controller(current_ram_disk_controller); - - std::ranges::for_each(active_storage_management->m_controllers, [](auto controller) { controller->probe(); }); - } - - auto storage_management::get() -> storage_management & - { - if (!active_storage_management) - { - kapi::system::panic("[DEVICES] Storage management has not been initialized."); - } - - return *active_storage_management; - } - - auto storage_management::add_controller(kstd::shared_ptr const & controller) -> void - { - controller->set_ids(next_free_major++, MINORS_PER_DEVICE); - m_controllers.push_back(controller); - } - - auto storage_management::all_controllers() const -> kstd::vector> const & - { - return m_controllers; - } - - auto storage_management::device_by_major_minor(size_t major, size_t minor) -> kstd::shared_ptr - { - kstd::shared_ptr found = nullptr; - - std::ranges::find_if(m_controllers, [&](auto const & controller) { - if (controller != nullptr && controller->major() == major) - { - found = controller->device_by_minor(minor); - return found != nullptr; - } - return false; - }); - - return found; - } - - auto storage_management::determine_boot_device() -> kstd::shared_ptr - { - return device_by_major_minor(START_MAJOR, 0); - } - -} // namespace kernel::devices::storage \ No newline at end of file -- cgit v1.2.3 From 9e85f9d1f34d08213a918d9c1b0845c179e323af Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 31 Mar 2026 08:56:17 +0200 Subject: move device into kapi --- kernel/src/devices/block_device.cpp | 4 ++-- kernel/src/devices/block_device_utils.cpp | 8 +++---- kernel/src/devices/device.cpp | 29 -------------------------- kernel/src/devices/storage/controller.cpp | 6 +++--- kernel/src/devices/storage/management.cpp | 8 +++---- kernel/src/devices/storage/ram_disk/device.cpp | 8 ++++++- 6 files changed, 20 insertions(+), 43 deletions(-) delete mode 100644 kernel/src/devices/device.cpp (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/block_device.cpp b/kernel/src/devices/block_device.cpp index cfe2eb2..c006198 100644 --- a/kernel/src/devices/block_device.cpp +++ b/kernel/src/devices/block_device.cpp @@ -2,7 +2,7 @@ #include "kapi/system.hpp" -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include @@ -11,7 +11,7 @@ namespace kernel::devices { block_device::block_device(size_t major, size_t minor, kstd::string const & name, size_t block_size) - : device(major, minor, name) + : kapi::devices::device(major, minor, name) , m_block_size(block_size) { if (m_block_size == 0) diff --git a/kernel/src/devices/block_device_utils.cpp b/kernel/src/devices/block_device_utils.cpp index 5469087..6fe89fe 100644 --- a/kernel/src/devices/block_device_utils.cpp +++ b/kernel/src/devices/block_device_utils.cpp @@ -3,7 +3,7 @@ #include "kapi/system.hpp" #include "kernel/devices/block_device.hpp" -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include #include @@ -18,7 +18,7 @@ namespace kernel::devices::block_device_utils using block_op = void (*)(size_t idx, size_t off, size_t len, size_t done, devices::block_device * device, std::byte * scratch, void * buffer); - auto process_blocks(kstd::shared_ptr const & device, size_t offset, size_t size, void * buffer, + auto process_blocks(kstd::shared_ptr const & device, size_t offset, size_t size, void * buffer, block_op op) -> size_t { if (buffer == nullptr) @@ -62,7 +62,7 @@ namespace kernel::devices::block_device_utils return processed; } - auto read(kstd::shared_ptr const & device, void * buffer, size_t offset, size_t size) -> size_t + auto read(kstd::shared_ptr const & device, void * buffer, size_t offset, size_t size) -> size_t { return process_blocks(device, offset, size, buffer, [](size_t idx, size_t off, size_t len, size_t done, devices::block_device * device, @@ -80,7 +80,7 @@ namespace kernel::devices::block_device_utils }); } - auto write(kstd::shared_ptr const & device, void const * buffer, size_t offset, size_t size) + auto write(kstd::shared_ptr const & device, void const * buffer, size_t offset, size_t size) -> size_t { return process_blocks(device, offset, size, const_cast(buffer), diff --git a/kernel/src/devices/device.cpp b/kernel/src/devices/device.cpp deleted file mode 100644 index 1e7589e..0000000 --- a/kernel/src/devices/device.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "kernel/devices/device.hpp" - -#include - -#include - -namespace kernel::devices -{ - device::device(size_t major, size_t minor, kstd::string const & name) - : m_major(major) - , m_minor(minor) - , m_name(name) - {} - - auto device::major() const -> size_t - { - return m_major; - } - - auto device::minor() const -> size_t - { - return m_minor; - } - - auto device::name() const -> kstd::string const & - { - return m_name; - } -} // namespace kernel::devices \ No newline at end of file diff --git a/kernel/src/devices/storage/controller.cpp b/kernel/src/devices/storage/controller.cpp index 46c45e4..1bef670 100644 --- a/kernel/src/devices/storage/controller.cpp +++ b/kernel/src/devices/storage/controller.cpp @@ -1,6 +1,6 @@ #include "kernel/devices/storage/controller.hpp" -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include #include @@ -21,7 +21,7 @@ namespace kernel::devices::storage return m_major; } - auto controller::device_by_minor(size_t minor) const -> kstd::shared_ptr + auto controller::device_by_minor(size_t minor) const -> kstd::shared_ptr { auto it = std::ranges::find_if(m_devices, [minor](auto const & device) { return device->minor() == minor; }); @@ -37,7 +37,7 @@ namespace kernel::devices::storage return m_devices.size(); } - auto controller::all_devices() const -> kstd::vector> const & + auto controller::all_devices() const -> kstd::vector> const & { return m_devices; } diff --git a/kernel/src/devices/storage/management.cpp b/kernel/src/devices/storage/management.cpp index 62c0ce4..d440bf0 100644 --- a/kernel/src/devices/storage/management.cpp +++ b/kernel/src/devices/storage/management.cpp @@ -3,7 +3,7 @@ #include "kapi/boot_modules.hpp" #include "kapi/system.hpp" -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include "kernel/devices/storage/controller.hpp" #include "kernel/devices/storage/ram_disk/controller.hpp" @@ -61,9 +61,9 @@ namespace kernel::devices::storage return m_controllers; } - auto management::device_by_major_minor(size_t major, size_t minor) -> kstd::shared_ptr + auto management::device_by_major_minor(size_t major, size_t minor) -> kstd::shared_ptr { - kstd::shared_ptr found = nullptr; + kstd::shared_ptr found = nullptr; std::ranges::find_if(m_controllers, [&](auto const & controller) { if (controller != nullptr && controller->major() == major) @@ -77,7 +77,7 @@ namespace kernel::devices::storage return found; } - auto management::determine_boot_device() -> kstd::shared_ptr + auto management::determine_boot_device() -> kstd::shared_ptr { return device_by_major_minor(START_MAJOR, 0); } diff --git a/kernel/src/devices/storage/ram_disk/device.cpp b/kernel/src/devices/storage/ram_disk/device.cpp index 5116c93..8fc3b2a 100644 --- a/kernel/src/devices/storage/ram_disk/device.cpp +++ b/kernel/src/devices/storage/ram_disk/device.cpp @@ -1,8 +1,9 @@ +#include "kernel/devices/storage/ram_disk/device.hpp" + #include "kapi/boot_module/boot_module.hpp" #include "kapi/system.hpp" #include "kernel/devices/block_device.hpp" -#include "kernel/devices/storage/ram_disk/device.hpp" #include #include @@ -21,6 +22,11 @@ namespace kernel::devices::storage::ram_disk , m_boot_module(module) {} + auto device::init() -> bool + { + return m_boot_module.start_address.raw() != 0 && m_boot_module.size > 0; + } + auto device::read_block(size_t block_index, void * buffer) const -> void { if (buffer == nullptr) -- cgit v1.2.3 From 7fc60f9350ebf86e2e13d09af159635ee8a1d086 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 14:25:04 +0200 Subject: kernel: add ram disk device tests --- .../src/devices/storage/ram_disk/device.tests.cpp | 117 +++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 kernel/src/devices/storage/ram_disk/device.tests.cpp (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/storage/ram_disk/device.tests.cpp b/kernel/src/devices/storage/ram_disk/device.tests.cpp new file mode 100644 index 0000000..eacdb04 --- /dev/null +++ b/kernel/src/devices/storage/ram_disk/device.tests.cpp @@ -0,0 +1,117 @@ +#include "kernel/devices/storage/ram_disk/device.hpp" + +#include "kapi/boot_module/boot_module.hpp" +#include "kapi/memory.hpp" + +#include "catch2/matchers/catch_matchers.hpp" +#include "catch2/matchers/catch_matchers_range_equals.hpp" + +#include + +#include +#include +#include +#include + +SCENARIO("RAM Disk Device Construction and Initialization", "[ram_disk_device]") +{ + GIVEN("an empty boot module") + { + kapi::boot_modules::boot_module boot_module{}; + boot_module.start_address = kapi::memory::linear_address{nullptr}; + boot_module.size = 0; + + WHEN("constructing the device") + { + kernel::devices::storage::ram_disk::device device{boot_module, 0, 0}; + + THEN("init return false") + { + REQUIRE_FALSE(device.init()); + } + } + } + + GIVEN("a boot module with a valid start address and size") + { + kapi::boot_modules::boot_module boot_module{}; + boot_module.start_address = kapi::memory::linear_address{reinterpret_cast(0x1000)}; + boot_module.size = 512; + + WHEN("constructing the device") + { + kernel::devices::storage::ram_disk::device device{boot_module, 0, 0}; + + THEN("init return true") + { + REQUIRE(device.init()); + } + } + } +} + +SCENARIO("RAM Disk Device Read and Write", "[ram_disk_device]") +{ + GIVEN("a device initialized with a valid boot module") + { + auto storage = std::vector{4096, std::byte{0xff}}; + auto module = + kapi::boot_modules::boot_module{"test_module", kapi::memory::linear_address{storage.data()}, storage.size()}; + auto device = kernel::devices::storage::ram_disk::device{module, 0, 0}; + REQUIRE(device.init()); + + WHEN("reading a full block from the device") + { + auto buffer = std::vector(device.block_size()); + device.read_block(0, buffer.data()); + + THEN("the buffer is filled with the module data") + { + REQUIRE_THAT(buffer, Catch::Matchers::RangeEquals(std::views::take(storage, device.block_size()))); + } + } + + WHEN("reading from a block index beyond the module size") + { + auto buffer = std::vector(device.block_size()); + device.read_block(10, buffer.data()); + + THEN("the buffer is filled with zeros") + { + REQUIRE_THAT(buffer, Catch::Matchers::RangeEquals(std::vector(device.block_size(), std::byte{0}))); + } + } + + WHEN("reading into a null buffer") + { + REQUIRE_THROWS_AS(device.read_block(0, nullptr), std::runtime_error); + } + + WHEN("writing to a full block") + { + auto buffer = std::vector(device.block_size(), std::byte{0x01}); + device.write_block(0, buffer.data()); + + THEN("the module data is updated") + { + REQUIRE_THAT(std::views::take(storage, device.block_size()), Catch::Matchers::RangeEquals(buffer)); + } + } + + WHEN("writing to a block index beyond the module size") + { + auto buffer = std::vector(device.block_size(), std::byte{0x01}); + device.write_block(10, buffer.data()); + + THEN("the module data is not updated") + { + REQUIRE_THAT(storage, Catch::Matchers::RangeEquals(std::vector{4096, std::byte{0xff}})); + } + } + + WHEN("writing from a null buffer") + { + REQUIRE_THROWS_AS(device.write_block(0, nullptr), std::runtime_error); + } + } +} \ No newline at end of file -- cgit v1.2.3 From d0c532af74d8d486d734904fd330d5dae7f49754 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 13:36:01 +0200 Subject: kapi: add basic device subsystem --- kernel/src/devices/root_bus.cpp | 55 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 kernel/src/devices/root_bus.cpp (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/root_bus.cpp b/kernel/src/devices/root_bus.cpp new file mode 100644 index 0000000..a7f3c1a --- /dev/null +++ b/kernel/src/devices/root_bus.cpp @@ -0,0 +1,55 @@ +#include "kernel/devices/root_bus.hpp" + +#include "kapi/devices.hpp" +#include "kapi/devices/bus.hpp" +#include "kapi/devices/device.hpp" +#include "kapi/system.hpp" + +#include +#include +#include + +#include +#include + +namespace kernel::devices +{ + + root_bus::root_bus() + : kapi::devices::bus{kapi::devices::allocate_major_number(), 0, "system"} + {} + + auto root_bus::add_child(kstd::unique_ptr child) -> void + { + auto observer = m_observers.emplace_back(child.get()); + m_children.push_back(std::move(child)); + + if (m_initialized) + { + kstd::println("Initializing child device '{}'", observer->name()); + if (!observer->init()) + { + kapi::system::panic("[kernel:devices] Failed to initialize child device"); + } + } + } + + auto root_bus::children() const -> kstd::vector> const & + { + return m_observers; + } + + auto root_bus::init() -> bool + { + if (m_initialized) + { + kapi::system::panic("[kernel:devices] Root bus already initialized!"); + } + + return std::ranges::fold_left(m_children, true, [](bool acc, auto & child) -> bool { + kstd::println("[kernel:devices] Initializing child device '{}'", child->name()); + return acc && child->init(); + }); + } + +} // namespace kernel::devices \ No newline at end of file -- cgit v1.2.3 From b84c4c9d8c90f3d3fd5a60de282278912fad2f04 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 13:59:27 +0200 Subject: x86_64/devices: implement ISA bus stub --- kernel/src/devices/root_bus.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/root_bus.cpp b/kernel/src/devices/root_bus.cpp index a7f3c1a..75b5b80 100644 --- a/kernel/src/devices/root_bus.cpp +++ b/kernel/src/devices/root_bus.cpp @@ -24,7 +24,7 @@ namespace kernel::devices auto observer = m_observers.emplace_back(child.get()); m_children.push_back(std::move(child)); - if (m_initialized) + if (m_initialized.test()) { kstd::println("Initializing child device '{}'", observer->name()); if (!observer->init()) @@ -41,7 +41,7 @@ namespace kernel::devices auto root_bus::init() -> bool { - if (m_initialized) + if (m_initialized.test_and_set()) { kapi::system::panic("[kernel:devices] Root bus already initialized!"); } -- cgit v1.2.3 From 66ffd2ad8c793c4eea1527848fe4772e42595718 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 14:24:52 +0200 Subject: kapi: extract common bus code --- kernel/src/devices/root_bus.cpp | 43 ----------------------------------------- 1 file changed, 43 deletions(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/root_bus.cpp b/kernel/src/devices/root_bus.cpp index 75b5b80..d3ba23f 100644 --- a/kernel/src/devices/root_bus.cpp +++ b/kernel/src/devices/root_bus.cpp @@ -1,16 +1,6 @@ #include "kernel/devices/root_bus.hpp" #include "kapi/devices.hpp" -#include "kapi/devices/bus.hpp" -#include "kapi/devices/device.hpp" -#include "kapi/system.hpp" - -#include -#include -#include - -#include -#include namespace kernel::devices { @@ -19,37 +9,4 @@ namespace kernel::devices : kapi::devices::bus{kapi::devices::allocate_major_number(), 0, "system"} {} - auto root_bus::add_child(kstd::unique_ptr child) -> void - { - auto observer = m_observers.emplace_back(child.get()); - m_children.push_back(std::move(child)); - - if (m_initialized.test()) - { - kstd::println("Initializing child device '{}'", observer->name()); - if (!observer->init()) - { - kapi::system::panic("[kernel:devices] Failed to initialize child device"); - } - } - } - - auto root_bus::children() const -> kstd::vector> const & - { - return m_observers; - } - - auto root_bus::init() -> bool - { - if (m_initialized.test_and_set()) - { - kapi::system::panic("[kernel:devices] Root bus already initialized!"); - } - - return std::ranges::fold_left(m_children, true, [](bool acc, auto & child) -> bool { - kstd::println("[kernel:devices] Initializing child device '{}'", child->name()); - return acc && child->init(); - }); - } - } // namespace kernel::devices \ No newline at end of file -- cgit v1.2.3 From 21489576381d827871e7cdf060929c5d7f3d4e9f Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 15:49:14 +0200 Subject: devices: don't automatically allocate major numbers in ctors --- kernel/src/devices/root_bus.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/root_bus.cpp b/kernel/src/devices/root_bus.cpp index d3ba23f..43a35bf 100644 --- a/kernel/src/devices/root_bus.cpp +++ b/kernel/src/devices/root_bus.cpp @@ -6,7 +6,7 @@ namespace kernel::devices { root_bus::root_bus() - : kapi::devices::bus{kapi::devices::allocate_major_number(), 0, "system"} + : kapi::devices::bus{0, 0, "system"} {} } // namespace kernel::devices \ No newline at end of file -- cgit v1.2.3 From f456f1674d48932846eb7b5ec1df630ad67e7e3d Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 17:24:36 +0200 Subject: kernel/acpi: discover local interrupt controllers --- kernel/src/devices/cpu.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 kernel/src/devices/cpu.cpp (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/cpu.cpp b/kernel/src/devices/cpu.cpp new file mode 100644 index 0000000..7147368 --- /dev/null +++ b/kernel/src/devices/cpu.cpp @@ -0,0 +1,97 @@ +#include "kernel/devices/cpu.hpp" + +#include "kapi/acpi.hpp" +#include "kapi/devices.hpp" + +#include +#include + +#include +#include +#include + +namespace kernel::devices +{ + + namespace + { + + auto process_madt(kstd::observer_ptr madt, kapi::devices::bus & cpu) -> void + { + auto static const core_major = kapi::devices::allocate_major_number(); + auto static const lapic_major = kapi::devices::allocate_major_number(); + + auto lapic_address = madt->local_interrupt_controller_address(); + + auto const * current = reinterpret_cast(madt.get()) + sizeof(kapi::acpi::madt_header); + auto const * end = reinterpret_cast(madt.get()) + madt->length(); + + auto bsp_found = false; + auto core_index = 0; + + while (current < end) + { + auto const * sub_table = reinterpret_cast(current); + if (sub_table->type() == 0) + { + auto const * local_apic = reinterpret_cast(sub_table); + if (local_apic->flags() & 0b11) + { + auto is_bsp = !bsp_found; + bsp_found = true; + + auto apic_id = local_apic->apic_id(); + auto core = kstd::make_unique(core_major, core_index, apic_id, is_bsp); + auto lapic = kapi::acpi::create_local_interrupt_controller(lapic_major, core_index, apic_id, lapic_address); + + core->add_child(std::move(lapic)); + cpu.add_child(std::move(core)); + + ++core_index; + } + } + + current += sub_table->length(); + } + + kstd::println("[OS:DEV] Discovered {} CPU cores", core_index); + } + + } // namespace + + cpu::core::core(std::size_t major_number, std::size_t minor_number, std::uint64_t hardware_id, bool is_bsp) + : kapi::devices::bus{major_number, minor_number, "cpu_core"} + , m_hardware_id{hardware_id} + , m_is_bsp{is_bsp} + {} + + auto cpu::core::hardware_id() const -> std::uint64_t + { + return m_hardware_id; + } + + auto cpu::core::is_bsp() const -> bool + { + return m_is_bsp; + } + + cpu::cpu(std::size_t major_number) + : kapi::devices::bus{major_number, 0, "cpu"} + {} + + auto cpu::probe() -> bool + { + auto madt = kapi::acpi::get_table("APIC"); + if (!madt) + { + kstd::println("[OS:DEV] Failed to find ACPI APIC table"); + return false; + } + + auto madt_header = static_cast(madt.get()); + process_madt(kstd::make_observer(madt_header), *this); + + return true; + } + +} // namespace kernel::devices \ No newline at end of file -- cgit v1.2.3 From f50815110789a0f8f6e5ca66ffd49b26578791a9 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 18:43:28 +0200 Subject: kernel: generalize CPU discovery --- kernel/src/devices/cpu.cpp | 58 +++------------------------------------------- 1 file changed, 3 insertions(+), 55 deletions(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/cpu.cpp b/kernel/src/devices/cpu.cpp index 7147368..eb10d74 100644 --- a/kernel/src/devices/cpu.cpp +++ b/kernel/src/devices/cpu.cpp @@ -1,64 +1,16 @@ #include "kernel/devices/cpu.hpp" -#include "kapi/acpi.hpp" #include "kapi/devices.hpp" +#include "kapi/platform.hpp" -#include #include #include #include -#include namespace kernel::devices { - namespace - { - - auto process_madt(kstd::observer_ptr madt, kapi::devices::bus & cpu) -> void - { - auto static const core_major = kapi::devices::allocate_major_number(); - auto static const lapic_major = kapi::devices::allocate_major_number(); - - auto lapic_address = madt->local_interrupt_controller_address(); - - auto const * current = reinterpret_cast(madt.get()) + sizeof(kapi::acpi::madt_header); - auto const * end = reinterpret_cast(madt.get()) + madt->length(); - - auto bsp_found = false; - auto core_index = 0; - - while (current < end) - { - auto const * sub_table = reinterpret_cast(current); - if (sub_table->type() == 0) - { - auto const * local_apic = reinterpret_cast(sub_table); - if (local_apic->flags() & 0b11) - { - auto is_bsp = !bsp_found; - bsp_found = true; - - auto apic_id = local_apic->apic_id(); - auto core = kstd::make_unique(core_major, core_index, apic_id, is_bsp); - auto lapic = kapi::acpi::create_local_interrupt_controller(lapic_major, core_index, apic_id, lapic_address); - - core->add_child(std::move(lapic)); - cpu.add_child(std::move(core)); - - ++core_index; - } - } - - current += sub_table->length(); - } - - kstd::println("[OS:DEV] Discovered {} CPU cores", core_index); - } - - } // namespace - cpu::core::core(std::size_t major_number, std::size_t minor_number, std::uint64_t hardware_id, bool is_bsp) : kapi::devices::bus{major_number, minor_number, "cpu_core"} , m_hardware_id{hardware_id} @@ -81,16 +33,12 @@ namespace kernel::devices auto cpu::probe() -> bool { - auto madt = kapi::acpi::get_table("APIC"); - if (!madt) + if (!kapi::platform::discover_cpu_topology(*this)) { - kstd::println("[OS:DEV] Failed to find ACPI APIC table"); + kstd::println("[OS:DEV] Failed to discover CPU topology"); return false; } - auto madt_header = static_cast(madt.get()); - process_madt(kstd::make_observer(madt_header), *this); - return true; } -- cgit v1.2.3 From 3ad230fab8dc17758559aac3c20ba67a8c619878 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 10 Apr 2026 09:01:59 +0200 Subject: kapi: move platform functions to CPU --- kernel/src/devices/cpu.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/cpu.cpp b/kernel/src/devices/cpu.cpp index eb10d74..85f4d47 100644 --- a/kernel/src/devices/cpu.cpp +++ b/kernel/src/devices/cpu.cpp @@ -1,7 +1,7 @@ #include "kernel/devices/cpu.hpp" +#include "kapi/cpu.hpp" #include "kapi/devices.hpp" -#include "kapi/platform.hpp" #include @@ -33,7 +33,7 @@ namespace kernel::devices auto cpu::probe() -> bool { - if (!kapi::platform::discover_cpu_topology(*this)) + if (!kapi::cpu::discover_topology(*this)) { kstd::println("[OS:DEV] Failed to discover CPU topology"); return false; -- cgit v1.2.3 From dd8dfa3e674d05927e9ed4b7efcb634a634bfdcc Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 10 Apr 2026 10:30:32 +0200 Subject: kapi: move CPU to kapi --- kernel/src/devices/cpu.cpp | 45 --------------------------------------------- 1 file changed, 45 deletions(-) delete mode 100644 kernel/src/devices/cpu.cpp (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/cpu.cpp b/kernel/src/devices/cpu.cpp deleted file mode 100644 index 85f4d47..0000000 --- a/kernel/src/devices/cpu.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "kernel/devices/cpu.hpp" - -#include "kapi/cpu.hpp" -#include "kapi/devices.hpp" - -#include - -#include -#include - -namespace kernel::devices -{ - - cpu::core::core(std::size_t major_number, std::size_t minor_number, std::uint64_t hardware_id, bool is_bsp) - : kapi::devices::bus{major_number, minor_number, "cpu_core"} - , m_hardware_id{hardware_id} - , m_is_bsp{is_bsp} - {} - - auto cpu::core::hardware_id() const -> std::uint64_t - { - return m_hardware_id; - } - - auto cpu::core::is_bsp() const -> bool - { - return m_is_bsp; - } - - cpu::cpu(std::size_t major_number) - : kapi::devices::bus{major_number, 0, "cpu"} - {} - - auto cpu::probe() -> bool - { - if (!kapi::cpu::discover_topology(*this)) - { - kstd::println("[OS:DEV] Failed to discover CPU topology"); - return false; - } - - return true; - } - -} // namespace kernel::devices \ No newline at end of file -- cgit v1.2.3 From ad2a744960ef8359a40e25c81f2b5fee0d8952c4 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 19:17:08 +0200 Subject: add block_device_utils tests --- kernel/src/devices/block_device_utils.cpp | 2 +- kernel/src/devices/block_device_utils.tests.cpp | 189 ++++++++++++++++++++++++ 2 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 kernel/src/devices/block_device_utils.tests.cpp (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/block_device_utils.cpp b/kernel/src/devices/block_device_utils.cpp index 6fe89fe..a1fd5e3 100644 --- a/kernel/src/devices/block_device_utils.cpp +++ b/kernel/src/devices/block_device_utils.cpp @@ -1,9 +1,9 @@ #include "kernel/devices/block_device_utils.hpp" +#include "kapi/devices/device.hpp" #include "kapi/system.hpp" #include "kernel/devices/block_device.hpp" -#include "kapi/devices/device.hpp" #include #include diff --git a/kernel/src/devices/block_device_utils.tests.cpp b/kernel/src/devices/block_device_utils.tests.cpp new file mode 100644 index 0000000..7ecd202 --- /dev/null +++ b/kernel/src/devices/block_device_utils.tests.cpp @@ -0,0 +1,189 @@ +#include "kernel/devices/block_device_utils.hpp" + +#include "kernel/test_support/cpu.hpp" +#include "kernel/test_support/devices/block_device.hpp" + +#include +#include +#include + +#include + +#include +#include + +SCENARIO("reading from a block device with block_device_utils", "[devices][block_device_utils]") +{ + GIVEN("a block device with known data") + { + auto const block_size = 512; + auto device = kstd::make_shared(0, 0, "test_block_device", block_size); + kstd::vector block_data(block_size); + for (size_t i = 0; i < block_data.size(); ++i) + { + block_data[i] = static_cast(i % 256); + } + device->write_block(0, block_data.data()); + device->write_block(1, block_data.data()); + + WHEN("reading from the block device using block_device_utils") + { + kstd::vector read_buffer(block_size); + auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 0, read_buffer.size()); + + THEN("the correct number of bytes is read") + { + REQUIRE(bytes_read == read_buffer.size()); + } + + THEN("the data read matches the data written to the block device") + { + REQUIRE(read_buffer == block_data); + } + } + + WHEN("reading over block boundaries") + { + kstd::vector read_buffer(1024); + auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 256, read_buffer.size()); + + THEN("the correct number of bytes is read") + { + REQUIRE(bytes_read == 1.5 * block_size); + } + + THEN("the data read matches the expected data across block boundaries") + { + for (size_t i = 0; i < bytes_read; ++i) + { + uint8_t expected_value = static_cast((256 + i) % 256); + REQUIRE(read_buffer[i] == expected_value); + } + } + } + + WHEN("reading beyond the device capacity") + { + kstd::vector read_buffer(block_size); + auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 1024, read_buffer.size()); + + THEN("no bytes are read") + { + REQUIRE(bytes_read == 0); + } + } + + WHEN("reading nothing") + { + kstd::vector read_buffer(block_size); + auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 0, 0); + + THEN("no bytes are read") + { + REQUIRE(bytes_read == 0); + } + } + + WHEN("reading with a null buffer") + { + THEN("the system panics") + { + REQUIRE_THROWS_AS(kernel::devices::block_device_utils::read(device, nullptr, 0, 512), kernel::tests::cpu::halt); + } + } + } +} + +SCENARIO("writing to a block device using block_device_utils", "[devices][block_device_utils]") +{ + GIVEN("a block device") + { + auto const block_size = 512; + auto device = kstd::make_shared(0, 0, "test_block_device", block_size); + device->data.resize(2 * block_size); + + WHEN("writing to the block device using block_device_utils") + { + kstd::vector write_buffer(block_size); + for (size_t i = 0; i < write_buffer.size(); ++i) + { + write_buffer[i] = static_cast(i % 256); + } + + auto bytes_written = + kernel::devices::block_device_utils::write(device, write_buffer.data(), 0, write_buffer.size()); + + THEN("the correct number of bytes is written") + { + REQUIRE(bytes_written == write_buffer.size()); + } + + THEN("the data written matches the data read back from the block device") + { + kstd::vector read_buffer(block_size); + device->read_block(0, read_buffer.data()); + REQUIRE(read_buffer == write_buffer); + } + } + + WHEN("writing over block boundaries") + { + kstd::vector write_buffer(2 * block_size); + for (size_t i = 0; i < write_buffer.size(); ++i) + { + write_buffer[i] = static_cast(i % 256); + } + + auto bytes_written = + kernel::devices::block_device_utils::write(device, write_buffer.data(), 256, write_buffer.size()); + + THEN("the correct number of bytes is written") + { + REQUIRE(bytes_written == 1.5 * block_size); + } + + THEN("the data written matches the data read back from the block device across block boundaries") + { + kstd::vector read_buffer(2 * block_size); + auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 256, 2 * block_size); + + for (size_t i = 0; i < bytes_read; ++i) + { + REQUIRE(read_buffer[i] == write_buffer[i]); + } + } + } + + WHEN("writing beyond the device capacity") + { + kstd::vector write_buffer(block_size); + auto bytes_written = + kernel::devices::block_device_utils::write(device, write_buffer.data(), 1024, write_buffer.size()); + + THEN("no bytes are written") + { + REQUIRE(bytes_written == 0); + } + } + + WHEN("writing nothing") + { + kstd::vector write_buffer(block_size); + auto bytes_written = kernel::devices::block_device_utils::write(device, write_buffer.data(), 0, 0); + + THEN("no bytes are written") + { + REQUIRE(bytes_written == 0); + } + } + + WHEN("writing with a null buffer") + { + THEN("the system panics") + { + REQUIRE_THROWS_AS(kernel::devices::block_device_utils::write(device, nullptr, 0, block_size), + kernel::tests::cpu::halt); + } + } + } +} \ No newline at end of file -- cgit v1.2.3 From 8e9e9ffd0528ffa554c336871f1a484c15613bfc Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 19:28:54 +0200 Subject: add block_device tests --- kernel/src/devices/block_device.cpp | 3 +- kernel/src/devices/block_device.tests.cpp | 46 +++++++++++++++++++++++++ kernel/src/devices/block_device_utils.tests.cpp | 4 +-- 3 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 kernel/src/devices/block_device.tests.cpp (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/block_device.cpp b/kernel/src/devices/block_device.cpp index c006198..b7cb26e 100644 --- a/kernel/src/devices/block_device.cpp +++ b/kernel/src/devices/block_device.cpp @@ -1,8 +1,7 @@ #include "kernel/devices/block_device.hpp" -#include "kapi/system.hpp" - #include "kapi/devices/device.hpp" +#include "kapi/system.hpp" #include diff --git a/kernel/src/devices/block_device.tests.cpp b/kernel/src/devices/block_device.tests.cpp new file mode 100644 index 0000000..378437e --- /dev/null +++ b/kernel/src/devices/block_device.tests.cpp @@ -0,0 +1,46 @@ +#include "kernel/test_support/devices/block_device.hpp" + +#include "kernel/test_support/cpu.hpp" + +#include +#include +#include +#include + +#include + +#include + +SCENARIO("Block device construction", "[devices][block_device]") +{ + GIVEN("parameters for a block device") + { + size_t major = 1; + size_t minor = 0; + kstd::string name = "test_block_device"; + size_t block_size = 512; + + WHEN("constructing a block device") + { + auto device = + kstd::make_shared(major, minor, name, block_size, 3 * block_size); + + THEN("the block device has the correct properties") + { + REQUIRE(device->major() == major); + REQUIRE(device->minor() == minor); + REQUIRE(device->name() == name); + REQUIRE(device->block_size() == block_size); + REQUIRE(device->capacity() == 3 * 512); + } + } + + WHEN("constructing a block device with zero block size") + { + THEN("the constructor panics") + { + REQUIRE_THROWS_AS((kernel::tests::devices::block_device(major, minor, name, 0)), kernel::tests::cpu::halt); + } + } + } +} diff --git a/kernel/src/devices/block_device_utils.tests.cpp b/kernel/src/devices/block_device_utils.tests.cpp index 7ecd202..5f27a9b 100644 --- a/kernel/src/devices/block_device_utils.tests.cpp +++ b/kernel/src/devices/block_device_utils.tests.cpp @@ -99,8 +99,8 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_ GIVEN("a block device") { auto const block_size = 512; - auto device = kstd::make_shared(0, 0, "test_block_device", block_size); - device->data.resize(2 * block_size); + auto device = + kstd::make_shared(0, 0, "test_block_device", block_size, 2 * block_size); WHEN("writing to the block device using block_device_utils") { -- cgit v1.2.3 From e599e359f727be29415b63c83f3df620d6e4c53c Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 19:50:38 +0200 Subject: fix is_block_device check, add device_inode and non-block device tests --- kernel/src/devices/block_device_utils.cpp | 5 ++-- kernel/src/devices/block_device_utils.tests.cpp | 32 ++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 3 deletions(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/block_device_utils.cpp b/kernel/src/devices/block_device_utils.cpp index a1fd5e3..59e9b97 100644 --- a/kernel/src/devices/block_device_utils.cpp +++ b/kernel/src/devices/block_device_utils.cpp @@ -31,12 +31,13 @@ namespace kernel::devices::block_device_utils return 0; } - auto * block_dev = static_cast(device.get()); - if (block_dev == nullptr) + if (!device->is_block_device()) { kapi::system::panic("[FILESYSTEM] device_file: expected block_device."); } + auto * block_dev = static_cast(device.get()); + size_t const block_size = block_dev->block_size(); size_t const capacity = block_dev->capacity(); diff --git a/kernel/src/devices/block_device_utils.tests.cpp b/kernel/src/devices/block_device_utils.tests.cpp index 5f27a9b..f78e477 100644 --- a/kernel/src/devices/block_device_utils.tests.cpp +++ b/kernel/src/devices/block_device_utils.tests.cpp @@ -2,6 +2,7 @@ #include "kernel/test_support/cpu.hpp" #include "kernel/test_support/devices/block_device.hpp" +#include "kernel/test_support/devices/character_device.hpp" #include #include @@ -186,4 +187,33 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_ } } } -} \ No newline at end of file +} + +SCENARIO("block_device_utils with a non-block device", "[devices][block_device_utils]") +{ + GIVEN("a non-block device") + { + auto device = kstd::make_shared(0, 0, "test_character_device"); + + WHEN("attempting to read from the non-block device using block_device_utils") + { + kstd::vector read_buffer(512); + THEN("the system panics") + { + REQUIRE_THROWS_AS(kernel::devices::block_device_utils::read(device, read_buffer.data(), 0, read_buffer.size()), + kernel::tests::cpu::halt); + } + } + + WHEN("attempting to write to the non-block device using block_device_utils") + { + kstd::vector write_buffer(512); + THEN("the system panics") + { + REQUIRE_THROWS_AS( + kernel::devices::block_device_utils::write(device, write_buffer.data(), 0, write_buffer.size()), + kernel::tests::cpu::halt); + } + } + } +} -- cgit v1.2.3 From 3c9ad45492d7417c65594fa7fa2fb9a8d5439276 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 9 Apr 2026 08:32:51 +0200 Subject: add deinit functions for singletons in tests --- kernel/src/devices/storage/management.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/storage/management.cpp b/kernel/src/devices/storage/management.cpp index d440bf0..14a045a 100644 --- a/kernel/src/devices/storage/management.cpp +++ b/kernel/src/devices/storage/management.cpp @@ -1,9 +1,9 @@ #include "kernel/devices/storage/management.hpp" #include "kapi/boot_modules.hpp" +#include "kapi/devices/device.hpp" #include "kapi/system.hpp" -#include "kapi/devices/device.hpp" #include "kernel/devices/storage/controller.hpp" #include "kernel/devices/storage/ram_disk/controller.hpp" @@ -14,17 +14,17 @@ #include #include -namespace kernel::devices::storage +namespace { - namespace - { - constexpr size_t static MINORS_PER_DEVICE = 16; - constexpr size_t static START_MAJOR = 1; - constinit size_t static next_free_major = START_MAJOR; + constexpr size_t static MINORS_PER_DEVICE = 16; + constexpr size_t static START_MAJOR = 1; + constinit size_t static next_free_major = START_MAJOR; - constinit auto static active_storage_management = std::optional{}; - } // namespace + constinit auto static active_storage_management = std::optional{}; +} // namespace +namespace kernel::devices::storage +{ auto management::init() -> void { if (active_storage_management) @@ -81,5 +81,13 @@ namespace kernel::devices::storage { return device_by_major_minor(START_MAJOR, 0); } +} // namespace kernel::devices::storage -} // namespace kernel::devices::storage \ No newline at end of file +namespace kernel::tests::devices::storage +{ + auto deinit() -> void + { + active_storage_management.reset(); + next_free_major = START_MAJOR; + } +} // namespace kernel::tests::devices::storage -- cgit v1.2.3 From 97e83ad1466d5962a1e5f5f83fa4c951bfeafb2c Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 9 Apr 2026 09:13:09 +0200 Subject: add devfs filesystem tests, and storage_boot_module_fixture to mock real boot modules --- kernel/src/devices/storage/management.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/storage/management.cpp b/kernel/src/devices/storage/management.cpp index 14a045a..c9fa0a8 100644 --- a/kernel/src/devices/storage/management.cpp +++ b/kernel/src/devices/storage/management.cpp @@ -83,11 +83,11 @@ namespace kernel::devices::storage } } // namespace kernel::devices::storage -namespace kernel::tests::devices::storage +namespace kernel::tests::devices::storage::management { auto deinit() -> void { active_storage_management.reset(); next_free_major = START_MAJOR; } -} // namespace kernel::tests::devices::storage +} // namespace kernel::tests::devices::storage::management -- cgit v1.2.3 From 2d8fed40bd0d0f8144783b6b344dc79944291b72 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 23 Apr 2026 13:31:17 +0200 Subject: chore: organize includes --- kernel/src/devices/block_device_utils.cpp | 4 ++-- kernel/src/devices/storage/management.cpp | 6 +++--- kernel/src/devices/storage/ram_disk/controller.cpp | 4 ++-- kernel/src/devices/storage/ram_disk/device.cpp | 4 ++-- kernel/src/devices/storage/ram_disk/device.tests.cpp | 5 ++--- 5 files changed, 11 insertions(+), 12 deletions(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/block_device_utils.cpp b/kernel/src/devices/block_device_utils.cpp index 59e9b97..3c77308 100644 --- a/kernel/src/devices/block_device_utils.cpp +++ b/kernel/src/devices/block_device_utils.cpp @@ -1,10 +1,10 @@ #include "kernel/devices/block_device_utils.hpp" +#include "kernel/devices/block_device.hpp" + #include "kapi/devices/device.hpp" #include "kapi/system.hpp" -#include "kernel/devices/block_device.hpp" - #include #include #include diff --git a/kernel/src/devices/storage/management.cpp b/kernel/src/devices/storage/management.cpp index c9fa0a8..8ff1b06 100644 --- a/kernel/src/devices/storage/management.cpp +++ b/kernel/src/devices/storage/management.cpp @@ -1,12 +1,12 @@ #include "kernel/devices/storage/management.hpp" +#include "kernel/devices/storage/controller.hpp" +#include "kernel/devices/storage/ram_disk/controller.hpp" + #include "kapi/boot_modules.hpp" #include "kapi/devices/device.hpp" #include "kapi/system.hpp" -#include "kernel/devices/storage/controller.hpp" -#include "kernel/devices/storage/ram_disk/controller.hpp" - #include #include diff --git a/kernel/src/devices/storage/ram_disk/controller.cpp b/kernel/src/devices/storage/ram_disk/controller.cpp index 040e61f..d230533 100644 --- a/kernel/src/devices/storage/ram_disk/controller.cpp +++ b/kernel/src/devices/storage/ram_disk/controller.cpp @@ -1,9 +1,9 @@ #include "kernel/devices/storage/ram_disk/controller.hpp" -#include "kapi/boot_module/boot_module_registry.hpp" - #include "kernel/devices/storage/ram_disk/device.hpp" +#include "kapi/boot_module/boot_module_registry.hpp" + #include #include diff --git a/kernel/src/devices/storage/ram_disk/device.cpp b/kernel/src/devices/storage/ram_disk/device.cpp index 8fc3b2a..c6a1363 100644 --- a/kernel/src/devices/storage/ram_disk/device.cpp +++ b/kernel/src/devices/storage/ram_disk/device.cpp @@ -1,10 +1,10 @@ #include "kernel/devices/storage/ram_disk/device.hpp" +#include "kernel/devices/block_device.hpp" + #include "kapi/boot_module/boot_module.hpp" #include "kapi/system.hpp" -#include "kernel/devices/block_device.hpp" - #include #include diff --git a/kernel/src/devices/storage/ram_disk/device.tests.cpp b/kernel/src/devices/storage/ram_disk/device.tests.cpp index eacdb04..b475c4b 100644 --- a/kernel/src/devices/storage/ram_disk/device.tests.cpp +++ b/kernel/src/devices/storage/ram_disk/device.tests.cpp @@ -3,10 +3,9 @@ #include "kapi/boot_module/boot_module.hpp" #include "kapi/memory.hpp" -#include "catch2/matchers/catch_matchers.hpp" -#include "catch2/matchers/catch_matchers_range_equals.hpp" - #include +#include +#include #include #include -- cgit v1.2.3 From f6f10575f75ac23d06e1d94f7861611503daa7af Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 23 Apr 2026 14:03:28 +0200 Subject: chore: banish relative includes --- kernel/src/devices/block_device.cpp | 6 +++--- kernel/src/devices/block_device.tests.cpp | 4 ++-- kernel/src/devices/block_device_utils.cpp | 8 ++++---- kernel/src/devices/block_device_utils.tests.cpp | 8 ++++---- kernel/src/devices/root_bus.cpp | 4 ++-- kernel/src/devices/storage/controller.cpp | 4 ++-- kernel/src/devices/storage/management.cpp | 12 ++++++------ kernel/src/devices/storage/ram_disk/controller.cpp | 6 +++--- kernel/src/devices/storage/ram_disk/device.cpp | 8 ++++---- kernel/src/devices/storage/ram_disk/device.tests.cpp | 6 +++--- 10 files changed, 33 insertions(+), 33 deletions(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/block_device.cpp b/kernel/src/devices/block_device.cpp index b7cb26e..13d73ac 100644 --- a/kernel/src/devices/block_device.cpp +++ b/kernel/src/devices/block_device.cpp @@ -1,7 +1,7 @@ -#include "kernel/devices/block_device.hpp" +#include -#include "kapi/devices/device.hpp" -#include "kapi/system.hpp" +#include +#include #include diff --git a/kernel/src/devices/block_device.tests.cpp b/kernel/src/devices/block_device.tests.cpp index 378437e..a2ddd2b 100644 --- a/kernel/src/devices/block_device.tests.cpp +++ b/kernel/src/devices/block_device.tests.cpp @@ -1,6 +1,6 @@ -#include "kernel/test_support/devices/block_device.hpp" +#include -#include "kernel/test_support/cpu.hpp" +#include #include #include diff --git a/kernel/src/devices/block_device_utils.cpp b/kernel/src/devices/block_device_utils.cpp index 3c77308..cb8ecba 100644 --- a/kernel/src/devices/block_device_utils.cpp +++ b/kernel/src/devices/block_device_utils.cpp @@ -1,9 +1,9 @@ -#include "kernel/devices/block_device_utils.hpp" +#include -#include "kernel/devices/block_device.hpp" +#include -#include "kapi/devices/device.hpp" -#include "kapi/system.hpp" +#include +#include #include #include diff --git a/kernel/src/devices/block_device_utils.tests.cpp b/kernel/src/devices/block_device_utils.tests.cpp index f78e477..e2e1e65 100644 --- a/kernel/src/devices/block_device_utils.tests.cpp +++ b/kernel/src/devices/block_device_utils.tests.cpp @@ -1,8 +1,8 @@ -#include "kernel/devices/block_device_utils.hpp" +#include -#include "kernel/test_support/cpu.hpp" -#include "kernel/test_support/devices/block_device.hpp" -#include "kernel/test_support/devices/character_device.hpp" +#include +#include +#include #include #include diff --git a/kernel/src/devices/root_bus.cpp b/kernel/src/devices/root_bus.cpp index 43a35bf..1b754f2 100644 --- a/kernel/src/devices/root_bus.cpp +++ b/kernel/src/devices/root_bus.cpp @@ -1,6 +1,6 @@ -#include "kernel/devices/root_bus.hpp" +#include -#include "kapi/devices.hpp" +#include namespace kernel::devices { diff --git a/kernel/src/devices/storage/controller.cpp b/kernel/src/devices/storage/controller.cpp index 1bef670..171b918 100644 --- a/kernel/src/devices/storage/controller.cpp +++ b/kernel/src/devices/storage/controller.cpp @@ -1,6 +1,6 @@ -#include "kernel/devices/storage/controller.hpp" +#include -#include "kapi/devices/device.hpp" +#include #include #include diff --git a/kernel/src/devices/storage/management.cpp b/kernel/src/devices/storage/management.cpp index 8ff1b06..7361cd5 100644 --- a/kernel/src/devices/storage/management.cpp +++ b/kernel/src/devices/storage/management.cpp @@ -1,11 +1,11 @@ -#include "kernel/devices/storage/management.hpp" +#include -#include "kernel/devices/storage/controller.hpp" -#include "kernel/devices/storage/ram_disk/controller.hpp" +#include +#include -#include "kapi/boot_modules.hpp" -#include "kapi/devices/device.hpp" -#include "kapi/system.hpp" +#include +#include +#include #include #include diff --git a/kernel/src/devices/storage/ram_disk/controller.cpp b/kernel/src/devices/storage/ram_disk/controller.cpp index d230533..30441fa 100644 --- a/kernel/src/devices/storage/ram_disk/controller.cpp +++ b/kernel/src/devices/storage/ram_disk/controller.cpp @@ -1,8 +1,8 @@ -#include "kernel/devices/storage/ram_disk/controller.hpp" +#include -#include "kernel/devices/storage/ram_disk/device.hpp" +#include -#include "kapi/boot_module/boot_module_registry.hpp" +#include #include diff --git a/kernel/src/devices/storage/ram_disk/device.cpp b/kernel/src/devices/storage/ram_disk/device.cpp index c6a1363..21b0000 100644 --- a/kernel/src/devices/storage/ram_disk/device.cpp +++ b/kernel/src/devices/storage/ram_disk/device.cpp @@ -1,9 +1,9 @@ -#include "kernel/devices/storage/ram_disk/device.hpp" +#include -#include "kernel/devices/block_device.hpp" +#include -#include "kapi/boot_module/boot_module.hpp" -#include "kapi/system.hpp" +#include +#include #include #include diff --git a/kernel/src/devices/storage/ram_disk/device.tests.cpp b/kernel/src/devices/storage/ram_disk/device.tests.cpp index b475c4b..d0fab76 100644 --- a/kernel/src/devices/storage/ram_disk/device.tests.cpp +++ b/kernel/src/devices/storage/ram_disk/device.tests.cpp @@ -1,7 +1,7 @@ -#include "kernel/devices/storage/ram_disk/device.hpp" +#include -#include "kapi/boot_module/boot_module.hpp" -#include "kapi/memory.hpp" +#include +#include #include #include -- cgit v1.2.3 From 9fc9d3b011db40027e8c1220c535007a786d03ff Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 30 Apr 2026 18:01:23 +0200 Subject: build: upgrade to GCC 16 --- kernel/src/devices/storage/management.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/storage/management.cpp b/kernel/src/devices/storage/management.cpp index 7361cd5..1f2acba 100644 --- a/kernel/src/devices/storage/management.cpp +++ b/kernel/src/devices/storage/management.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace { @@ -63,18 +64,20 @@ namespace kernel::devices::storage auto management::device_by_major_minor(size_t major, size_t minor) -> kstd::shared_ptr { - kstd::shared_ptr found = nullptr; - - std::ranges::find_if(m_controllers, [&](auto const & controller) { + auto found = std::ranges::find_if(m_controllers, [=](auto const & controller) { if (controller != nullptr && controller->major() == major) { - found = controller->device_by_minor(minor); - return found != nullptr; + return controller->device_by_minor(minor) != nullptr; } return false; }); - return found; + if (found != std::ranges::cend(m_controllers)) + { + return found->get()->device_by_minor(minor); + } + + return nullptr; } auto management::determine_boot_device() -> kstd::shared_ptr -- cgit v1.2.3 From e05b52111d952c626c29d92a862ee0d1dce180f3 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 10 May 2026 13:21:25 +0200 Subject: renaming --- kernel/src/devices/storage/management.cpp | 31 +++++++++++++------------- kernel/src/devices/storage/ram_disk/device.cpp | 4 ++-- 2 files changed, 17 insertions(+), 18 deletions(-) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/storage/management.cpp b/kernel/src/devices/storage/management.cpp index 1f2acba..06efc27 100644 --- a/kernel/src/devices/storage/management.cpp +++ b/kernel/src/devices/storage/management.cpp @@ -17,43 +17,42 @@ namespace { - constexpr size_t static MINORS_PER_DEVICE = 16; - constexpr size_t static START_MAJOR = 1; - constinit size_t static next_free_major = START_MAJOR; + constexpr size_t static minors_per_device = 16; + constexpr size_t static start_major = 1; + constinit size_t static next_free_major = start_major; - constinit auto static active_storage_management = std::optional{}; + constinit auto static storage_management = std::optional{}; } // namespace namespace kernel::devices::storage { auto management::init() -> void { - if (active_storage_management) + if (storage_management) { kapi::system::panic("[DEVICES] Storage management has already been initialized."); } - active_storage_management.emplace(management{}); + storage_management.emplace(management{}); - auto current_ram_disk_controller = - kstd::make_shared(&kapi::boot_modules::get_boot_module_registry()); - active_storage_management->add_controller(current_ram_disk_controller); + auto ram_disk_controller = kstd::make_shared(&kapi::boot_modules::get_boot_module_registry()); + storage_management->add_controller(ram_disk_controller); - std::ranges::for_each(active_storage_management->m_controllers, [](auto controller) { controller->probe(); }); + std::ranges::for_each(storage_management->m_controllers, [](auto controller) { controller->probe(); }); } auto management::get() -> management & { - if (!active_storage_management) + if (!storage_management) { kapi::system::panic("[DEVICES] Storage management has not been initialized."); } - return *active_storage_management; + return *storage_management; } auto management::add_controller(kstd::shared_ptr const & controller) -> void { - controller->set_ids(next_free_major++, MINORS_PER_DEVICE); + controller->set_ids(next_free_major++, minors_per_device); m_controllers.push_back(controller); } @@ -82,7 +81,7 @@ namespace kernel::devices::storage auto management::determine_boot_device() -> kstd::shared_ptr { - return device_by_major_minor(START_MAJOR, 0); + return device_by_major_minor(start_major, 0); } } // namespace kernel::devices::storage @@ -90,7 +89,7 @@ namespace kernel::tests::devices::storage::management { auto deinit() -> void { - active_storage_management.reset(); - next_free_major = START_MAJOR; + storage_management.reset(); + next_free_major = start_major; } } // namespace kernel::tests::devices::storage::management diff --git a/kernel/src/devices/storage/ram_disk/device.cpp b/kernel/src/devices/storage/ram_disk/device.cpp index 21b0000..1557204 100644 --- a/kernel/src/devices/storage/ram_disk/device.cpp +++ b/kernel/src/devices/storage/ram_disk/device.cpp @@ -14,11 +14,11 @@ namespace kernel::devices::storage::ram_disk { namespace { - constexpr size_t RAM_DISK_BLOCK_SIZE = 512uz; + constexpr size_t ram_disk_block_size = 512uz; } // namespace device::device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor) - : block_device(major, minor, "ram" + kstd::to_string(minor), RAM_DISK_BLOCK_SIZE) + : block_device(major, minor, "ram" + kstd::to_string(minor), ram_disk_block_size) , m_boot_module(module) {} -- cgit v1.2.3 From 3b2f36d242eb895fd893ec7a674ff608f44f69ac Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 16 May 2026 16:12:36 +0200 Subject: refactoring --- kernel/src/devices/block_device_utils.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'kernel/src/devices') diff --git a/kernel/src/devices/block_device_utils.cpp b/kernel/src/devices/block_device_utils.cpp index cb8ecba..18d1e9d 100644 --- a/kernel/src/devices/block_device_utils.cpp +++ b/kernel/src/devices/block_device_utils.cpp @@ -42,7 +42,9 @@ namespace kernel::devices::block_device_utils size_t const capacity = block_dev->capacity(); if (offset >= capacity) + { return 0; + } size_t const total_to_process = std::min(size, capacity - offset); kstd::vector scratch_buffer{block_size}; -- cgit v1.2.3