aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/CMakeLists.txt1
-rw-r--r--kernel/kernel/devices/block_device.cpp56
-rw-r--r--kernel/kernel/devices/block_device.hpp71
-rw-r--r--kernel/kernel/devices/block_device.tests.cpp47
-rw-r--r--kernel/kernel/devices/block_device_utils.cpp115
-rw-r--r--kernel/kernel/devices/block_device_utils.hpp33
-rw-r--r--kernel/kernel/devices/block_device_utils.tests.cpp52
-rw-r--r--kernel/kernel/devices/storage/ram_disk/device.cpp26
-rw-r--r--kernel/kernel/devices/storage/ram_disk/device.hpp17
-rw-r--r--kernel/kernel/filesystem/device_inode.cpp4
-rw-r--r--kernel/kernel/test_support/devices/block_device.cpp22
-rw-r--r--kernel/kernel/test_support/devices/block_device.hpp12
12 files changed, 155 insertions, 301 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index a73418f0..1f7f66c4 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -35,7 +35,6 @@ target_sources("kernel_lib" PRIVATE
"kernel/memory.cpp"
# Device Subsystem
- "kernel/devices/block_device.cpp"
"kernel/devices/block_device_utils.cpp"
"kernel/devices/root_bus.cpp"
diff --git a/kernel/kernel/devices/block_device.cpp b/kernel/kernel/devices/block_device.cpp
deleted file mode 100644
index 4d85a520..00000000
--- a/kernel/kernel/devices/block_device.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#include <kernel/devices/block_device.hpp>
-
-#include <kapi/devices.hpp>
-#include <kapi/devices/device.hpp>
-#include <kapi/system.hpp>
-
-#include <kstd/string.hpp>
-#include <kstd/units.hpp>
-
-#include <cstddef>
-
-using namespace kstd::units_literals;
-
-namespace kernel::devices
-{
- block_device::block_device(size_t major, size_t minor, kstd::string const & name, kstd::units::bytes block_size)
- : kapi::devices::device(major, minor, name)
- , m_block_size(block_size)
- {
- if (m_block_size == 0_B)
- {
- kapi::system::panic("[DEVICES] block_device constructed with zero block size.");
- }
- }
-
- auto block_device::calculate_transfer(size_t block_index) const -> transfer_info
- {
- auto const offset = block_index * m_block_size;
- auto const limit = size();
-
- auto const available = (offset < limit) ? (limit - offset) : 0_B;
- auto 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 -> kstd::units::bytes
- {
- return kstd::units::bytes{m_block_size};
- }
-
- auto block_device::capacity() const -> kstd::units::bytes
- {
- return size();
- }
-
- auto block_device::query_interface(kapi::devices::interface interface) -> void *
- {
- if (interface == kapi::devices::block_device::id)
- {
- return static_cast<kapi::devices::block_device *>(this);
- }
-
- return kapi::devices::device::query_interface(interface);
- }
-} // namespace kernel::devices \ No newline at end of file
diff --git a/kernel/kernel/devices/block_device.hpp b/kernel/kernel/devices/block_device.hpp
deleted file mode 100644
index 2b3b844c..00000000
--- a/kernel/kernel/devices/block_device.hpp
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP
-#define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP
-
-#include <kapi/devices.hpp>
-
-#include <kstd/result.hpp>
-#include <kstd/string.hpp>
-#include <kstd/units.hpp>
-
-#include <cstddef>
-
-namespace kernel::devices
-{
- /**
- * @brief Base interface for block-addressable devices.
- */
- struct block_device : kapi::devices::device, kapi::devices::block_device
- {
- /**
- * @brief Create a block device descriptor.
- * @param major Device major number.
- * @param minor Device minor number.
- * @param name Device name.
- * @param block_size Size of one logical block in bytes.
- */
- block_device(size_t major, size_t minor, kstd::string const & name, kstd::units::bytes block_size);
-
- /**
- * @brief Return logical block size in bytes.
- * @return One logical block size in bytes.
- */
- [[nodiscard]] auto block_size() const -> kstd::units::bytes override;
-
- /**
- * @brief Return device capacity in bytes.
- * @return Total number of addressable bytes.
- */
- [[nodiscard]] auto capacity() const -> kstd::units::bytes override;
-
- protected:
- /**
- * @brief Information describing the transfer window for one block index.
- */
- struct transfer_info
- {
- kstd::units::bytes offset;
- kstd::units::bytes to_transfer;
- kstd::units::bytes remainder;
- };
-
- /**
- * @brief Return total device size in bytes.
- * @return Total number of addressable bytes.
- */
- [[nodiscard]] virtual auto size() const -> kstd::units::bytes = 0;
-
- /**
- * @brief Compute transfer information for @p block_index.
- * @param block_index Zero-based block index.
- * @return Computed transfer information for one logical block access.
- */
- [[nodiscard]] auto calculate_transfer(size_t block_index) const -> transfer_info;
-
- [[nodiscard]] auto query_interface(kapi::devices::interface interface) -> void * override;
-
- private:
- kstd::units::bytes m_block_size;
- };
-} // namespace kernel::devices
-
-#endif \ No newline at end of file
diff --git a/kernel/kernel/devices/block_device.tests.cpp b/kernel/kernel/devices/block_device.tests.cpp
deleted file mode 100644
index 23af74ef..00000000
--- a/kernel/kernel/devices/block_device.tests.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include <kernel/test_support/devices/block_device.hpp>
-
-#include <kernel/test_support/cpu.hpp>
-
-#include <kstd/memory.hpp>
-#include <kstd/print.hpp>
-#include <kstd/string.hpp>
-#include <kstd/units.hpp>
-#include <kstd/vector.hpp>
-
-#include <catch2/catch_test_macros.hpp>
-
-using namespace kstd::units_literals;
-
-SCENARIO("Block device construction", "[devices][block_device]")
-{
- GIVEN("parameters for a block device")
- {
- auto major = 1uz;
- auto minor = 0uz;
- auto name = "test_block_device";
- auto block_size = 512_B;
-
- WHEN("constructing a block device")
- {
- auto device =
- kstd::make_shared<kernel::tests::devices::block_device>(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_B);
- }
- }
-
- 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_B)), kernel::tests::cpu::halt);
- }
- }
- }
-}
diff --git a/kernel/kernel/devices/block_device_utils.cpp b/kernel/kernel/devices/block_device_utils.cpp
index 1fefd034..a46e10ba 100644
--- a/kernel/kernel/devices/block_device_utils.cpp
+++ b/kernel/kernel/devices/block_device_utils.cpp
@@ -1,11 +1,9 @@
#include <kernel/devices/block_device_utils.hpp>
#include <kapi/devices.hpp>
-#include <kapi/devices/device.hpp>
#include <kapi/system.hpp>
#include <kstd/cstring.hpp>
-#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <kstd/units.hpp>
#include <kstd/vector.hpp>
@@ -18,76 +16,83 @@ using namespace kstd::units_literals;
namespace kernel::devices::block_device_utils
{
- using block_op = kstd::result<kstd::units::bytes> (*)(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);
-
- auto process_blocks(kstd::shared_ptr<kapi::devices::device> const & device, kstd::units::bytes offset,
- kstd::units::bytes size, void * buffer, block_op op) -> kstd::result<kstd::units::bytes>
+ namespace
{
- if (buffer == nullptr)
- {
- kapi::system::panic("[FILESYSTEM] device_file::process_blocks called with null buffer.");
- }
-
- if (size == 0_B)
- {
- return 0_B;
- }
+ using block_op = kstd::result<kstd::units::bytes> (*)(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);
- if (!device->is_a<kapi::devices::block_device>())
+ auto process_blocks(kapi::devices::block_device & device, kstd::units::bytes offset, kstd::units::bytes size,
+ void * buffer, block_op op) -> kstd::result<kstd::units::bytes>
{
- kapi::system::panic("[FILESYSTEM] device_file: expected block_device.");
- }
+ if (buffer == nullptr)
+ {
+ kapi::system::panic("[FILESYSTEM] device_file::process_blocks called with null buffer.");
+ }
- auto * block_dev = device->as<kapi::devices::block_device>();
+ if (size == 0_B)
+ {
+ return 0_B;
+ }
- auto const block_size = block_dev->block_size();
- auto const capacity = block_dev->capacity();
+ auto const block_size = device.block_size();
+ auto const capacity = device.capacity();
- if (offset >= capacity)
- {
- return 0_B;
- }
- auto const total_to_process = std::min(size, capacity - offset);
+ if (offset >= capacity)
+ {
+ return 0_B;
+ }
+ auto const total_to_process = std::min(size, capacity - offset);
- kstd::vector<std::byte> scratch_buffer{block_size.value};
- auto processed = 0_B;
+ kstd::vector<std::byte> scratch_buffer{block_size.value};
+ auto processed = 0_B;
- while (processed < total_to_process)
- {
- auto const absolute_offset = offset + processed;
- auto const block_index = absolute_offset / block_size;
- auto const in_block_offset = absolute_offset % block_size;
- auto const chunk_size = std::min(total_to_process - processed, block_size - in_block_offset);
-
- if (auto result =
- op(block_index, in_block_offset, chunk_size, processed, block_dev, scratch_buffer.data(), buffer);
- !result)
+ while (processed < total_to_process)
{
- return result;
+ auto const absolute_offset = offset + processed;
+ auto const block_index = absolute_offset / block_size;
+ auto const in_block_offset = absolute_offset % block_size;
+ auto const chunk_size = std::min(total_to_process - processed, block_size - in_block_offset);
+
+ if (auto result =
+ op(block_index, in_block_offset, chunk_size, processed, device, scratch_buffer.data(), buffer);
+ !result)
+ {
+ return result;
+ }
+
+ processed += chunk_size;
}
- processed += chunk_size;
+ return processed;
}
+ } // namespace
+
+ auto calculate_transfer(kapi::devices::block_device const & device, size_t block_index) -> transfer_info
+ {
+ auto const offset = block_index * device.block_size();
+ auto const limit = device.capacity();
+
+ auto const available = (offset < limit) ? (limit - offset) : 0_B;
+ auto const to_transfer = (available < device.block_size()) ? available : device.block_size();
- return processed;
+ return {offset, to_transfer, device.block_size() - to_transfer};
}
- auto read(kstd::shared_ptr<kapi::devices::device> const & device, void * buffer, kstd::units::bytes offset,
- kstd::units::bytes size) -> kstd::result<kstd::units::bytes>
+ auto read(kapi::devices::block_device & device, void * buffer, kstd::units::bytes offset, kstd::units::bytes size)
+ -> kstd::result<kstd::units::bytes>
{
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::devices::block_device & device, std::byte * scratch, void * buffer) {
auto * out = static_cast<std::byte *>(buffer);
- if (off == 0_B && len == device->block_size())
+ if (off == 0_B && len == device.block_size())
{
- return device->read_block(idx, out + done);
+ return device.read_block(idx, out + done);
}
else
{
- auto result = device->read_block(idx, scratch);
+ auto result = device.read_block(idx, scratch);
if (result)
{
kstd::libc::memcpy(out + done, scratch + off, len.value);
@@ -97,22 +102,22 @@ namespace kernel::devices::block_device_utils
});
}
- auto write(kstd::shared_ptr<kapi::devices::device> const & device, void const * buffer, kstd::units::bytes offset,
+ auto write(kapi::devices::block_device & device, void const * buffer, kstd::units::bytes offset,
kstd::units::bytes size) -> kstd::result<kstd::units::bytes>
{
return process_blocks(device, offset, size, const_cast<void *>(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::devices::block_device & device, std::byte * scratch, void * buffer) {
auto const * in = static_cast<std::byte const *>(buffer);
- if (off == 0_B && len == device->block_size())
+ if (off == 0_B && len == device.block_size())
{
- return device->write_block(idx, in + done);
+ return device.write_block(idx, in + done);
}
else
{
- return device->read_block(idx, scratch).and_then([&](auto) {
+ return device.read_block(idx, scratch).and_then([&](auto) {
kstd::libc::memcpy(scratch + off, in + done, len.value);
- return device->write_block(idx, scratch);
+ return device.write_block(idx, scratch);
});
}
});
diff --git a/kernel/kernel/devices/block_device_utils.hpp b/kernel/kernel/devices/block_device_utils.hpp
index 6b626180..a3895259 100644
--- a/kernel/kernel/devices/block_device_utils.hpp
+++ b/kernel/kernel/devices/block_device_utils.hpp
@@ -1,20 +1,35 @@
#ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_UTILS_HPP
#define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_UTILS_HPP
-#include <kapi/devices/device.hpp>
+#include <kapi/devices.hpp>
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <kstd/units.hpp>
+#include <cstddef>
+
+/**
+@brief Utility functions for block devices, such as reading/writing data at specific offsets. These functions handle
+the necessary logic to interact with block devices, such as calculating block boundaries and ensuring proper access
+patterns. They abstract away the details of block device interactions, providing a simple interface for reading and
+writing data to block devices.
+*/
namespace kernel::devices::block_device_utils
{
+
/**
- @brief Utility functions for block devices, such as reading/writing data at specific offsets. These functions handle
- the necessary logic to interact with block devices, such as calculating block boundaries and ensuring proper access
- patterns. They abstract away the details of block device interactions, providing a simple interface for reading and
- writing data to block devices.
- */
+ * @brief Information describing the transfer window for one block index.
+ */
+ struct transfer_info
+ {
+ kstd::units::bytes offset;
+ kstd::units::bytes to_transfer;
+ kstd::units::bytes remainder;
+ };
+
+ [[nodiscard]] auto calculate_transfer(kapi::devices::block_device const & device, size_t block_index)
+ -> transfer_info;
/**
@brief Reads data from a @p device into a @p buffer, starting at a specific @p offset and for a given @p size.
@@ -25,8 +40,8 @@ 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(kstd::shared_ptr<kapi::devices::device> const & device, void * buffer, kstd::units::bytes offset,
- kstd::units::bytes size) -> kstd::result<kstd::units::bytes>;
+ auto read(kapi::devices::block_device & device, void * buffer, kstd::units::bytes offset, kstd::units::bytes size)
+ -> kstd::result<kstd::units::bytes>;
/**
@brief Writes data from a @p buffer to a @p device, starting at a specific @p offset and for a given @p size.
@@ -37,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(kstd::shared_ptr<kapi::devices::device> const & device, void const * buffer, kstd::units::bytes offset,
+ auto write(kapi::devices::block_device & device, void const * buffer, kstd::units::bytes offset,
kstd::units::bytes size) -> kstd::result<kstd::units::bytes>;
} // namespace kernel::devices::block_device_utils
diff --git a/kernel/kernel/devices/block_device_utils.tests.cpp b/kernel/kernel/devices/block_device_utils.tests.cpp
index 40c52948..fd68a63b 100644
--- a/kernel/kernel/devices/block_device_utils.tests.cpp
+++ b/kernel/kernel/devices/block_device_utils.tests.cpp
@@ -33,7 +33,7 @@ SCENARIO("reading from a block device with block_device_utils", "[devices][block
WHEN("reading from the block device using block_device_utils")
{
kstd::vector<uint8_t> read_buffer(block_size.value);
- auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 0_B,
+ auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer.data(), 0_B,
kstd::units::bytes{read_buffer.size()});
THEN("the correct number of bytes is read")
@@ -50,7 +50,7 @@ SCENARIO("reading from a block device with block_device_utils", "[devices][block
WHEN("reading over block boundaries")
{
kstd::vector<uint8_t> read_buffer(1024);
- auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 256_B,
+ auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer.data(), 256_B,
kstd::units::bytes{read_buffer.size()});
THEN("the correct number of bytes is read")
@@ -71,7 +71,7 @@ SCENARIO("reading from a block device with block_device_utils", "[devices][block
WHEN("reading beyond the device capacity")
{
kstd::vector<uint8_t> read_buffer(block_size.value);
- auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 1024_B,
+ auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer.data(), 1024_B,
kstd::units::bytes{read_buffer.size()});
THEN("no bytes are read")
@@ -83,7 +83,7 @@ SCENARIO("reading from a block device with block_device_utils", "[devices][block
WHEN("reading nothing")
{
kstd::vector<uint8_t> read_buffer(block_size.value);
- auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 0_B, 0_B);
+ auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer.data(), 0_B, 0_B);
THEN("no bytes are read")
{
@@ -95,7 +95,7 @@ SCENARIO("reading from a block device with block_device_utils", "[devices][block
{
THEN("the system panics")
{
- REQUIRE_THROWS_AS(kernel::devices::block_device_utils::read(device, nullptr, 0_B, 512_B),
+ REQUIRE_THROWS_AS(kernel::devices::block_device_utils::read(*device, nullptr, 0_B, 512_B),
kernel::tests::cpu::halt);
}
}
@@ -118,7 +118,7 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_
write_buffer[i] = static_cast<uint8_t>(i % 256);
}
- auto bytes_written = kernel::devices::block_device_utils::write(device, write_buffer.data(), 0_B,
+ auto bytes_written = kernel::devices::block_device_utils::write(*device, write_buffer.data(), 0_B,
kstd::units::bytes{write_buffer.size()});
THEN("the correct number of bytes is written")
@@ -142,7 +142,7 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_
write_buffer[i] = static_cast<uint8_t>(i % 256);
}
- auto bytes_written = kernel::devices::block_device_utils::write(device, write_buffer.data(), 256_B,
+ auto bytes_written = kernel::devices::block_device_utils::write(*device, write_buffer.data(), 256_B,
kstd::units::bytes{write_buffer.size()});
THEN("the correct number of bytes is written")
@@ -153,7 +153,7 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_
THEN("the data written matches the data read back from the block device across block boundaries")
{
kstd::vector<uint8_t> read_buffer(2 * block_size.value);
- auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 256_B, 2 * block_size);
+ auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer.data(), 256_B, 2 * block_size);
for (size_t i = 0; i < bytes_read.value().value; ++i)
{
@@ -165,7 +165,7 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_
WHEN("writing beyond the device capacity")
{
kstd::vector<uint8_t> write_buffer(block_size.value);
- auto bytes_written = kernel::devices::block_device_utils::write(device, write_buffer.data(), 1024_B,
+ auto bytes_written = kernel::devices::block_device_utils::write(*device, write_buffer.data(), 1024_B,
kstd::units::bytes{write_buffer.size()});
THEN("no bytes are written")
@@ -177,7 +177,7 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_
WHEN("writing nothing")
{
kstd::vector<uint8_t> write_buffer(block_size.value);
- auto bytes_written = kernel::devices::block_device_utils::write(device, write_buffer.data(), 0_B, 0_B);
+ auto bytes_written = kernel::devices::block_device_utils::write(*device, write_buffer.data(), 0_B, 0_B);
THEN("no bytes are written")
{
@@ -189,37 +189,7 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_
{
THEN("the system panics")
{
- REQUIRE_THROWS_AS(kernel::devices::block_device_utils::write(device, nullptr, 0_B, block_size),
- kernel::tests::cpu::halt);
- }
- }
- }
-}
-
-SCENARIO("block_device_utils with a non-block device", "[devices][block_device_utils]")
-{
- GIVEN("a non-block device")
- {
- auto device = kstd::make_shared<kernel::tests::devices::character_device>(0, 0, "test_character_device");
-
- WHEN("attempting to read from the non-block device using block_device_utils")
- {
- kstd::vector<uint8_t> read_buffer(512);
- THEN("the system panics")
- {
- REQUIRE_THROWS_AS(kernel::devices::block_device_utils::read(device, read_buffer.data(), 0_B,
- kstd::units::bytes{read_buffer.size()}),
- kernel::tests::cpu::halt);
- }
- }
-
- WHEN("attempting to write to the non-block device using block_device_utils")
- {
- kstd::vector<uint8_t> write_buffer(512);
- THEN("the system panics")
- {
- REQUIRE_THROWS_AS(kernel::devices::block_device_utils::write(device, write_buffer.data(), 0_B,
- kstd::units::bytes{write_buffer.size()}),
+ REQUIRE_THROWS_AS(kernel::devices::block_device_utils::write(*device, nullptr, 0_B, block_size),
kernel::tests::cpu::halt);
}
}
diff --git a/kernel/kernel/devices/storage/ram_disk/device.cpp b/kernel/kernel/devices/storage/ram_disk/device.cpp
index 1e2f2597..f9fa60bb 100644
--- a/kernel/kernel/devices/storage/ram_disk/device.cpp
+++ b/kernel/kernel/devices/storage/ram_disk/device.cpp
@@ -1,8 +1,9 @@
#include <kernel/devices/storage/ram_disk/device.hpp>
-#include <kernel/devices/block_device.hpp>
+#include <kernel/devices/block_device_utils.hpp>
#include <kapi/boot_module/boot_module.hpp>
+#include <kapi/devices.hpp>
#include <kapi/system.hpp>
#include <kstd/cstring.hpp>
@@ -22,7 +23,7 @@ namespace kernel::devices::storage::ram_disk
} // namespace
device::device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor, std::size_t device_index)
- : block_device(major, minor, kstd::format("ram{}", device_index), ram_disk_block_size)
+ : kapi::devices::device(major, minor, kstd::format("ram{}", device_index))
, m_boot_module(module)
{}
@@ -38,7 +39,7 @@ namespace kernel::devices::storage::ram_disk
kapi::system::panic("[RAM DISK DEVICE] read_block called with null buffer.");
}
- auto const info = calculate_transfer(block_index);
+ auto const info = block_device_utils::calculate_transfer(*this, block_index);
if (info.to_transfer > 0_B)
{
@@ -61,7 +62,7 @@ namespace kernel::devices::storage::ram_disk
kapi::system::panic("[RAM DISK DEVICE] write_block called with null buffer.");
}
- auto const info = calculate_transfer(block_index);
+ auto const info = block_device_utils::calculate_transfer(*this, block_index);
if (info.to_transfer > 0_B)
{
@@ -72,8 +73,23 @@ namespace kernel::devices::storage::ram_disk
return info.to_transfer;
}
- auto device::size() const -> kstd::units::bytes
+ auto device::block_size() const -> kstd::units::bytes
+ {
+ return ram_disk_block_size;
+ }
+
+ auto device::capacity() const noexcept -> kstd::units::bytes
{
return kstd::units::bytes{m_boot_module.size};
}
+
+ auto device::query_interface(kapi::devices::interface interface) -> void *
+ {
+ if (interface == kapi::devices::block_device::id)
+ {
+ return static_cast<kapi::devices::block_device *>(this);
+ }
+
+ return kapi::devices::device::query_interface(interface);
+ }
} // namespace kernel::devices::storage::ram_disk \ No newline at end of file
diff --git a/kernel/kernel/devices/storage/ram_disk/device.hpp b/kernel/kernel/devices/storage/ram_disk/device.hpp
index f4c83187..0bb09875 100644
--- a/kernel/kernel/devices/storage/ram_disk/device.hpp
+++ b/kernel/kernel/devices/storage/ram_disk/device.hpp
@@ -1,9 +1,8 @@
#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_DEVICE_HPP
#define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_DEVICE_HPP
-#include <kernel/devices/block_device.hpp>
-
#include <kapi/boot_module/boot_module.hpp>
+#include <kapi/devices.hpp>
#include <kstd/result.hpp>
#include <kstd/units.hpp>
@@ -15,7 +14,7 @@ namespace kernel::devices::storage::ram_disk
/**
* @brief Block device for a boot module.
*/
- struct device : block_device
+ struct device final : kapi::devices::device, kapi::devices::block_device
{
/**
* @brief Create a RAM disk for the @p module.
@@ -48,12 +47,14 @@ namespace kernel::devices::storage::ram_disk
*/
auto write_block(size_t block_index, void const * buffer) -> kstd::result<kstd::units::bytes> override;
- private:
- /**
- * @brief Return module size in bytes.
- */
- [[nodiscard]] auto size() const -> kstd::units::bytes override;
+ [[nodiscard]] auto block_size() const -> kstd::units::bytes override;
+ [[nodiscard]] auto capacity() const noexcept -> kstd::units::bytes override;
+
+ protected:
+ auto query_interface(kapi::devices::interface interface) -> void * override;
+
+ private:
kapi::boot_modules::boot_module m_boot_module{};
};
} // namespace kernel::devices::storage::ram_disk
diff --git a/kernel/kernel/filesystem/device_inode.cpp b/kernel/kernel/filesystem/device_inode.cpp
index 7019377b..4bff415a 100644
--- a/kernel/kernel/filesystem/device_inode.cpp
+++ b/kernel/kernel/filesystem/device_inode.cpp
@@ -26,7 +26,7 @@ namespace kernel::filesystem
{
if (m_device->is_a<kapi::devices::block_device>())
{
- return devices::block_device_utils::read(m_device, buffer, offset, size);
+ return devices::block_device_utils::read(*m_device->as<kapi::devices::block_device>(), buffer, offset, size);
}
else
{
@@ -39,7 +39,7 @@ namespace kernel::filesystem
{
if (m_device->is_a<kapi::devices::block_device>())
{
- return devices::block_device_utils::write(m_device, buffer, offset, size);
+ return devices::block_device_utils::write(*m_device->as<kapi::devices::block_device>(), buffer, offset, size);
}
else
{
diff --git a/kernel/kernel/test_support/devices/block_device.cpp b/kernel/kernel/test_support/devices/block_device.cpp
index cb80370b..f20ac48d 100644
--- a/kernel/kernel/test_support/devices/block_device.cpp
+++ b/kernel/kernel/test_support/devices/block_device.cpp
@@ -1,6 +1,6 @@
#include <kernel/test_support/devices/block_device.hpp>
-#include <kernel/devices/block_device.hpp>
+#include <kapi/devices.hpp>
#include <kstd/result.hpp>
#include <kstd/string.hpp>
@@ -19,7 +19,8 @@ namespace kernel::tests::devices
{
block_device::block_device(size_t major, size_t minor, kstd::string const & name, kstd::units::bytes block_size,
kstd::units::bytes initial_size)
- : kernel::devices::block_device(major, minor, name, block_size)
+ : kapi::devices::device{major, minor, name}
+ , m_block_size{block_size}
{
data.resize(initial_size.value, 0);
}
@@ -62,8 +63,23 @@ namespace kernel::tests::devices
return block_size();
}
- auto block_device::size() const -> kstd::units::bytes
+ auto block_device::block_size() const -> kstd::units::bytes
+ {
+ return m_block_size;
+ }
+
+ auto block_device::capacity() const -> kstd::units::bytes
{
return kstd::units::bytes{data.size()};
}
+
+ auto block_device::query_interface(kapi::devices::interface interface) -> void *
+ {
+ if (interface == kapi::devices::block_device::id)
+ {
+ return static_cast<kapi::devices::block_device *>(this);
+ }
+
+ return kapi::devices::device::query_interface(interface);
+ }
} // namespace kernel::tests::devices \ No newline at end of file
diff --git a/kernel/kernel/test_support/devices/block_device.hpp b/kernel/kernel/test_support/devices/block_device.hpp
index 147c117c..082ab003 100644
--- a/kernel/kernel/test_support/devices/block_device.hpp
+++ b/kernel/kernel/test_support/devices/block_device.hpp
@@ -1,7 +1,7 @@
#ifndef TEACHOS_KERNEL_TEST_SUPPORT_DEVICES_BLOCK_DEVICE_HPP
#define TEACHOS_KERNEL_TEST_SUPPORT_DEVICES_BLOCK_DEVICE_HPP
-#include <kernel/devices/block_device.hpp>
+#include <kapi/devices.hpp>
#include <kstd/result.hpp>
#include <kstd/string.hpp>
@@ -14,7 +14,7 @@
namespace kernel::tests::devices
{
- struct block_device : kernel::devices::block_device
+ struct block_device final : kapi::devices::device, kapi::devices::block_device
{
block_device(size_t major, size_t minor, kstd::string const & name, kstd::units::bytes block_size,
kstd::units::bytes initial_size = {});
@@ -24,9 +24,15 @@ namespace kernel::tests::devices
auto read_block(size_t block_index, void * buffer) const -> kstd::result<kstd::units::bytes> override;
auto write_block(size_t block_index, void const * buffer) -> kstd::result<kstd::units::bytes> override;
- [[nodiscard]] auto size() const -> kstd::units::bytes override;
+ [[nodiscard]] auto block_size() const -> kstd::units::bytes override;
+ [[nodiscard]] auto capacity() const -> kstd::units::bytes override;
kstd::vector<uint8_t> data{};
+
+ private:
+ [[nodiscard]] auto query_interface(kapi::devices::interface interface) -> void * override;
+
+ kstd::units::bytes m_block_size{};
};
} // namespace kernel::tests::devices