aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/CMakeLists.txt4
-rw-r--r--kernel/kapi/boot_module/bus.cpp102
-rw-r--r--kernel/kernel/devices/storage.cpp12
-rw-r--r--kernel/kernel/devices/storage/ram_disk/controller.cpp38
-rw-r--r--kernel/kernel/devices/storage/ram_disk/controller.hpp31
-rw-r--r--kernel/kernel/devices/storage/ram_disk/controller.tests.cpp82
-rw-r--r--kernel/kernel/devices/storage/ram_disk/device.cpp95
-rw-r--r--kernel/kernel/devices/storage/ram_disk/device.hpp60
-rw-r--r--kernel/kernel/devices/storage/ram_disk/device.tests.cpp117
-rw-r--r--kernel/kernel/devices/storage/ram_disk/driver.cpp152
-rw-r--r--kernel/kernel/devices/storage/ram_disk/driver.hpp39
11 files changed, 304 insertions, 428 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index d3e0c015..72283587 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -8,6 +8,7 @@ add_library("kernel::lib" ALIAS "kernel_lib")
target_sources("kernel_lib" PRIVATE
# Kernel-defined KAPI Implementation
"kapi/acpi.cpp"
+ "kapi/boot_module/bus.cpp"
"kapi/boot_modules.cpp"
"kapi/cio.cpp"
"kapi/cpu.cpp"
@@ -43,8 +44,7 @@ target_sources("kernel_lib" PRIVATE
# Storage Device Subsystem
"kernel/devices/storage.cpp"
- "kernel/devices/storage/ram_disk/controller.cpp"
- "kernel/devices/storage/ram_disk/device.cpp"
+ "kernel/devices/storage/ram_disk/driver.cpp"
# Filesystem Subsystem
"kernel/filesystem/dentry.cpp"
diff --git a/kernel/kapi/boot_module/bus.cpp b/kernel/kapi/boot_module/bus.cpp
new file mode 100644
index 00000000..b917866c
--- /dev/null
+++ b/kernel/kapi/boot_module/bus.cpp
@@ -0,0 +1,102 @@
+#include <kapi/boot_module/bus.hpp>
+
+#include <kapi/boot_modules.hpp>
+#include <kapi/devices.hpp>
+
+#include <kstd/format.hpp>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/string.hpp>
+
+#include <cstddef>
+#include <ranges>
+#include <string_view>
+
+namespace kapi::boot_modules
+{
+ auto has_parameter(std::string_view cmdline, std::string_view key, std::string_view value) -> bool
+ {
+ for (auto token : std::views::split(cmdline, ' '))
+ {
+ auto const text = std::string_view{token};
+ auto const equals = text.find('=');
+ if (equals != std::string_view::npos && text.substr(equals) == key && text.substr(equals + 1) == value)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boot_module_device::boot_module_device(std::size_t index, boot_module const & module)
+ : kapi::devices::device{kstd::format("boot_module{}", index)}
+ , m_module(module)
+ {}
+
+ auto boot_module_device::init() -> bool
+ {
+ return true;
+ }
+
+ auto boot_module_device::command_line() const -> std::string_view
+ {
+ return m_module.name;
+ }
+
+ auto boot_module_device::module() const -> boot_modules::boot_module const &
+ {
+ return m_module;
+ }
+
+ auto boot_module_device::query_interface(kapi::devices::interface interface) -> void *
+ {
+ if (interface == boot_module_identification::id)
+ {
+ return static_cast<boot_module_identification *>(this);
+ }
+
+ return kapi::devices::device::query_interface(interface);
+ }
+
+ boot_module_bus::boot_module_bus(boot_module_registry const * registry)
+ : kapi::devices::bus{"boot_modules"}
+ , m_registry(registry)
+ {}
+
+ auto boot_module_bus::enumerate(kapi::devices::bus & self) -> void
+ {
+ std::size_t index = 0;
+
+ for (auto const & module : *m_registry)
+ {
+ self.add_child(kstd::make_shared<boot_module_device>(index++, module));
+ }
+ }
+
+ auto boot_module_bus::match(kapi::devices::device const & dev, kapi::devices::driver const & drv) const
+ -> kstd::result<unsigned>
+ {
+ auto const * ident = dev.as<boot_module_identification>();
+ auto const * claims = drv.as<boot_module_driver_identification>();
+
+ if (!ident || !claims)
+ {
+ return kstd::failure(kapi::devices::driver_match_errc::no_match);
+ }
+
+ auto const [key, value] = claims->claimed_parameter();
+
+ if (!has_parameter(ident->command_line(), key, value))
+ {
+ return kstd::failure(kapi::devices::driver_match_errc::no_match);
+ }
+
+ return 0u;
+ }
+
+ auto boot_module_bus::protocol() -> kapi::devices::bus_protocol *
+ {
+ return this;
+ }
+
+} // namespace kapi::boot_modules
diff --git a/kernel/kernel/devices/storage.cpp b/kernel/kernel/devices/storage.cpp
index d5d6fab7..d5508270 100644
--- a/kernel/kernel/devices/storage.cpp
+++ b/kernel/kernel/devices/storage.cpp
@@ -1,9 +1,11 @@
#include <kernel/devices/storage.hpp>
-#include <kernel/devices/storage/ram_disk/controller.hpp>
+#include <kernel/devices/storage/ram_disk/driver.hpp>
+#include <kapi/boot_module/bus.hpp>
#include <kapi/boot_modules.hpp>
#include <kapi/devices.hpp>
+#include <kapi/devices/driver_registry.hpp>
#include <kstd/memory.hpp>
@@ -11,8 +13,12 @@ namespace kernel::devices::storage
{
auto init() -> void
{
- kapi::devices::get_root_bus()->add_child(
- kstd::make_shared<ram_disk::controller>(&kapi::boot_modules::get_boot_module_registry()));
+ kapi::devices::driver_registry::get().add(kstd::make_shared<ram_disk::driver>());
+
+ auto modules_bus =
+ kstd::make_shared<kapi::boot_modules::boot_module_bus>(&kapi::boot_modules::get_boot_module_registry());
+ kapi::devices::get_root_bus()->add_child(modules_bus);
+ modules_bus->enumerate(*modules_bus);
}
auto determine_boot_device() -> kstd::shared_ptr<kapi::devices::device>
diff --git a/kernel/kernel/devices/storage/ram_disk/controller.cpp b/kernel/kernel/devices/storage/ram_disk/controller.cpp
deleted file mode 100644
index 7550860e..00000000
--- a/kernel/kernel/devices/storage/ram_disk/controller.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-
-#include <kernel/devices/storage/ram_disk/controller.hpp>
-
-#include <kernel/devices/storage/ram_disk/device.hpp>
-
-#include <kapi/boot_modules.hpp>
-#include <kapi/devices.hpp>
-#include <kapi/system.hpp>
-
-#include <algorithm>
-#include <cstddef>
-
-namespace kernel::devices::storage::ram_disk
-{
- controller::controller(kapi::boot_modules::boot_module_registry const * registry)
- : kapi::devices::bus{"ram_disk"}
- , m_boot_module_registry(registry)
- {}
-
- auto controller::enumerate_old() -> bool
- {
- size_t current_device_index = 0;
-
- std::ranges::for_each(*m_boot_module_registry, [this, &current_device_index](auto const & module) {
- auto const disk = kstd::make_shared<ram_disk::device>(module, current_device_index++);
-
- if (auto published = kapi::devices::publish_interface<kapi::devices::block_device>(disk, disk->name());
- !published)
- {
- kapi::system::panic("[DEV:RD] Failed to publish block device interface of '{}'", disk->name());
- }
-
- add_child(std::move(disk));
- });
-
- return true;
- }
-} // namespace kernel::devices::storage::ram_disk \ No newline at end of file
diff --git a/kernel/kernel/devices/storage/ram_disk/controller.hpp b/kernel/kernel/devices/storage/ram_disk/controller.hpp
deleted file mode 100644
index 165fbdbd..00000000
--- a/kernel/kernel/devices/storage/ram_disk/controller.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef TEACH_OS_KERNEL_DEVICES_RAM_DISK_CONTROLLER_HPP
-#define TEACH_OS_KERNEL_DEVICES_RAM_DISK_CONTROLLER_HPP
-
-#include <kapi/boot_modules.hpp>
-#include <kapi/devices.hpp>
-
-namespace kernel::devices::storage::ram_disk
-{
- /**
- * @brief Storage controller that exposes boot modules as RAM-disk devices.
- */
- struct controller : kapi::devices::bus
- {
- /**
- * @brief Create a RAM-disk controller.
- * @param registry Boot module registry as device source.
- */
- explicit controller(kapi::boot_modules::boot_module_registry const * registry);
-
- protected:
- /**
- * @brief Probe boot modules and create RAM-disk devices.
- */
- auto enumerate_old() -> bool override;
-
- private:
- kapi::boot_modules::boot_module_registry const * m_boot_module_registry;
- };
-} // namespace kernel::devices::storage::ram_disk
-
-#endif \ No newline at end of file
diff --git a/kernel/kernel/devices/storage/ram_disk/controller.tests.cpp b/kernel/kernel/devices/storage/ram_disk/controller.tests.cpp
deleted file mode 100644
index 6393043b..00000000
--- a/kernel/kernel/devices/storage/ram_disk/controller.tests.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#include <kernel/devices/storage/ram_disk/controller.hpp>
-
-#include <kapi/boot_modules.hpp>
-#include <kapi/devices.hpp>
-#include <kapi/memory.hpp>
-
-#include <kstd/memory.hpp>
-
-#include <catch2/catch_test_macros.hpp>
-
-#include <cstddef>
-#include <vector>
-
-SCENARIO("The RAM disk controller attaches its devices to the device tree", "[devices][storage][ram_disk]")
-{
- GIVEN("A boot modules registry with one valid module")
- {
- auto storage = std::vector<std::byte>{4096, std::byte{0x0}};
- auto registry = kapi::boot_modules::boot_module_registry{};
- registry.add_boot_module({
- .name = "test_module",
- .start_address = kapi::memory::linear_address{storage.data()},
- .size = storage.size(),
- });
-
- auto controller = kstd::make_shared<kernel::devices::storage::ram_disk::controller>(&registry);
-
- WHEN("the controller is initialized")
- {
- auto succeeded = controller->init();
-
- THEN("initialization succeeds")
- {
- REQUIRE(succeeded);
- }
-
- THEN("the RAM disk is reachable as a child of the controller")
- {
- REQUIRE(controller->children().size() == 1);
- REQUIRE(controller->children()[0]->name() == "ram0");
- }
-
- THEN("the RAM disk is reachable through the global device tree")
- {
- REQUIRE(kapi::devices::find_device("ram0"));
- }
- }
- }
-
- GIVEN("A boot modules registry with one invalid module")
- {
- auto registry = kapi::boot_modules::boot_module_registry{};
- registry.add_boot_module({
- .name = "invalid module",
- .start_address = kapi::memory::linear_address{nullptr},
- .size = 0,
- });
-
- auto controller = kstd::make_shared<kernel::devices::storage::ram_disk::controller>(&registry);
-
- WHEN("the controller is initialized")
- {
- auto succeeded = controller->init();
-
- THEN("initialization fails")
- {
- REQUIRE_FALSE(succeeded);
- }
-
- THEN("the invalid RAM disk i still attache to the tree")
- {
- REQUIRE(controller->children().size() == 1);
- REQUIRE(controller->children()[0]->name() == "ram0");
- }
-
- THEN("the invalid RAM disk reachable through the global device tree")
- {
- REQUIRE(kapi::devices::find_device("ram0"));
- }
- }
- }
-} \ No newline at end of file
diff --git a/kernel/kernel/devices/storage/ram_disk/device.cpp b/kernel/kernel/devices/storage/ram_disk/device.cpp
deleted file mode 100644
index a9de0a2e..00000000
--- a/kernel/kernel/devices/storage/ram_disk/device.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-#include <kernel/devices/storage/ram_disk/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>
-#include <kstd/format.hpp>
-#include <kstd/result.hpp>
-#include <kstd/units.hpp>
-
-#include <cstddef>
-
-using namespace kstd::units_literals;
-
-namespace kernel::devices::storage::ram_disk
-{
- namespace
- {
- constexpr auto ram_disk_block_size = 512_B;
- } // namespace
-
- device::device(kapi::boot_modules::boot_module const & module, std::size_t device_index)
- : kapi::devices::device{kstd::format("ram{}", device_index)}
- , 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 -> kstd::result<kstd::units::bytes>
- {
- if (buffer == nullptr)
- {
- kapi::system::panic("[RAM DISK DEVICE] read_block called with null buffer.");
- }
-
- auto const info = block_device_utils::calculate_transfer(*this, block_index);
-
- if (info.to_transfer > 0_B)
- {
- auto const src = static_cast<std::byte const *>(m_boot_module.start_address) + info.offset;
- kstd::libc::memcpy(buffer, src, info.to_transfer.value);
- }
-
- if (info.remainder > 0_B)
- {
- kstd::libc::memset(static_cast<std::byte *>(buffer) + info.to_transfer, 0, info.remainder.value);
- }
-
- return info.to_transfer;
- }
-
- auto device::write_block(size_t block_index, void const * buffer) -> kstd::result<kstd::units::bytes>
- {
- if (buffer == nullptr)
- {
- kapi::system::panic("[RAM DISK DEVICE] write_block called with null buffer.");
- }
-
- auto const info = block_device_utils::calculate_transfer(*this, block_index);
-
- if (info.to_transfer > 0_B)
- {
- auto const dest = static_cast<std::byte *>(m_boot_module.start_address) + info.offset;
- kstd::libc::memcpy(dest, buffer, info.to_transfer.value);
- }
-
- return info.to_transfer;
- }
-
- 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
deleted file mode 100644
index e4f99633..00000000
--- a/kernel/kernel/devices/storage/ram_disk/device.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_DEVICE_HPP
-#define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_DEVICE_HPP
-
-#include <kapi/boot_module/boot_module.hpp>
-#include <kapi/devices.hpp>
-
-#include <kstd/result.hpp>
-#include <kstd/units.hpp>
-
-#include <cstddef>
-
-namespace kernel::devices::storage::ram_disk
-{
- /**
- * @brief Block device for a boot module.
- */
- struct device final : kapi::devices::device, kapi::devices::block_device
- {
- /**
- * @brief Create a RAM disk for the @p module.
- * @param module Boot module providing the memory region.
- */
- device(kapi::boot_modules::boot_module const & module, std::size_t device_index);
-
- /**
- * @brief Initialize the RAM disk device.
- * @return true if module backing memory is valid, false otherwise.
- */
- auto init() -> bool override;
-
- /**
- * @brief Read one logical block into @p buffer.
- * @param block_index Zero-based block index.
- * @param buffer Destination buffer, must not be null.
- * @note If the request reaches the module end, only available bytes are copied and the rest of the
- * logical block is filled with zeros.
- */
- auto read_block(size_t block_index, void * buffer) const -> kstd::result<kstd::units::bytes> override;
-
- /**
- * @brief Write one logical block from @p buffer.
- * @param block_index Zero-based block index.
- * @param buffer Source buffer, must not be null.
- * @note If the request reaches the module end, only the bytes in the module range are written.
- */
- auto write_block(size_t block_index, void const * buffer) -> kstd::result<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
-
-#endif \ No newline at end of file
diff --git a/kernel/kernel/devices/storage/ram_disk/device.tests.cpp b/kernel/kernel/devices/storage/ram_disk/device.tests.cpp
deleted file mode 100644
index 115afd86..00000000
--- a/kernel/kernel/devices/storage/ram_disk/device.tests.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-#include <kernel/devices/storage/ram_disk/device.hpp>
-
-#include <kapi/boot_module/boot_module.hpp>
-#include <kapi/memory.hpp>
-
-#include <catch2/catch_test_macros.hpp>
-#include <catch2/matchers/catch_matchers.hpp>
-#include <catch2/matchers/catch_matchers_range_equals.hpp>
-
-#include <cstddef>
-#include <ranges>
-#include <stdexcept>
-#include <vector>
-
-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};
-
- 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<std::byte *>(0x1000)};
- boot_module.size = 512;
-
- WHEN("constructing the device")
- {
- kernel::devices::storage::ram_disk::device device{boot_module, 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};
- REQUIRE(device.init());
-
- WHEN("reading a full block from the device")
- {
- auto buffer = std::vector<std::byte>(device.block_size().value);
- CHECK(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().value)));
- }
- }
-
- WHEN("reading from a block index beyond the module size")
- {
- auto buffer = std::vector<std::byte>(device.block_size().value);
- CHECK(device.read_block(10, buffer.data()));
-
- THEN("the buffer is filled with zeros")
- {
- REQUIRE_THAT(buffer,
- Catch::Matchers::RangeEquals(std::vector<std::byte>(device.block_size().value, 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<std::byte>(device.block_size().value, std::byte{0x01});
- CHECK(device.write_block(0, buffer.data()));
-
- THEN("the module data is updated")
- {
- REQUIRE_THAT(std::views::take(storage, device.block_size().value), Catch::Matchers::RangeEquals(buffer));
- }
- }
-
- WHEN("writing to a block index beyond the module size")
- {
- auto buffer = std::vector<std::byte>(device.block_size().value, std::byte{0x01});
- CHECK(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
diff --git a/kernel/kernel/devices/storage/ram_disk/driver.cpp b/kernel/kernel/devices/storage/ram_disk/driver.cpp
new file mode 100644
index 00000000..50313a7a
--- /dev/null
+++ b/kernel/kernel/devices/storage/ram_disk/driver.cpp
@@ -0,0 +1,152 @@
+#include <kernel/devices/storage/ram_disk/driver.hpp>
+
+#include <kernel/devices/block_device_utils.hpp>
+#include <kernel/filesystem/reserved_numbers.hpp>
+
+#include <kapi/boot_module/bus.hpp>
+#include <kapi/boot_modules.hpp>
+#include <kapi/devices.hpp>
+#include <kapi/system.hpp>
+
+#include <kstd/cstring.hpp>
+#include <kstd/format.hpp>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/system_error.hpp>
+#include <kstd/units.hpp>
+
+#include <cstddef>
+#include <cstdint>
+#include <optional>
+#include <string_view>
+#include <utility>
+
+using namespace kstd::units_literals;
+
+namespace kernel::devices::storage::ram_disk
+{
+
+ namespace
+ {
+ constexpr auto ram_disk_block_size = 512_B;
+
+ struct block_device final : kapi::devices::block_device
+ {
+ explicit block_device(kapi::boot_modules::boot_module const & module)
+ : m_module(module)
+ {}
+
+ auto read_block(std::size_t block_index, void * buffer) const -> kstd::result<kstd::units::bytes> override
+ {
+ if (!buffer)
+ {
+ kapi::system::panic("[RAM DISK] read_block called with null buffer.");
+ }
+
+ auto info = block_device_utils::calculate_transfer(*this, block_index);
+
+ if (info.to_transfer > 0_B)
+ {
+ auto source = static_cast<std::byte const *>(m_module.start_address) + info.offset;
+ kstd::libc::memcpy(buffer, source, info.to_transfer.value);
+ }
+
+ if (info.remainder > 0_B)
+ {
+ kstd::libc::memset(static_cast<std::byte *>(buffer) + info.to_transfer, 0, info.remainder.value);
+ }
+
+ return info.to_transfer;
+ }
+
+ auto write_block(std::size_t block_index, void const * buffer) -> kstd::result<kstd::units::bytes> override
+ {
+ if (buffer == nullptr)
+ {
+ kapi::system::panic("[RAM DISK] write_block called with null buffer.");
+ }
+
+ auto const info = block_device_utils::calculate_transfer(*this, block_index);
+
+ if (info.to_transfer > 0_B)
+ {
+ auto const dest = static_cast<std::byte *>(m_module.start_address) + info.offset;
+ kstd::libc::memcpy(dest, buffer, info.to_transfer.value);
+ }
+
+ return info.to_transfer;
+ }
+
+ [[nodiscard]] auto block_size() const -> kstd::units::bytes override
+ {
+ return ram_disk_block_size;
+ }
+
+ [[nodiscard]] auto capacity() const -> kstd::units::bytes override
+ {
+ return kstd::units::bytes{m_module.size};
+ }
+
+ private:
+ kapi::boot_modules::boot_module m_module;
+ };
+
+ } // namespace
+
+ auto driver::probe(kapi::devices::device & device) -> kstd::result<void>
+ {
+ auto interface = device.as<kapi::boot_modules::boot_module_identification>();
+ if (!interface)
+ {
+ return kstd::failure(make_error_code(kstd::errc::invalid_argument));
+ }
+
+ auto const & module = interface->module();
+ if (module.start_address.raw() == 0 || module.size == 0)
+ {
+ return kstd::failure(make_error_code(kstd::errc::invalid_argument));
+ }
+
+ auto implementation = kstd::make_shared<struct block_device>(module);
+ auto name = kstd::format("ram{}", m_next_disk_index);
+
+ auto published = kapi::devices::publish_interface<kapi::devices::block_device>(device.shared_from_this(), name,
+ implementation.get());
+ if (!published)
+ {
+ return published;
+ }
+
+ device.set_driver_data(implementation);
+ ++m_next_disk_index;
+
+ return kstd::success();
+ }
+
+ auto driver::unbind(kapi::devices::device & device) -> void
+ {
+ kapi::devices::interface_registry::get().unpublish(device, kapi::devices::block_device::id);
+ device.set_driver_data(nullptr);
+ }
+
+ auto driver::claimed_parameter() const -> std::pair<std::string_view, std::string_view>
+ {
+ return {"type", "ramdisk"};
+ }
+
+ auto driver::claimed_major() const -> std::optional<std::uint8_t>
+ {
+ return kernel::filesystem::block_major_numbers::ram_disk;
+ }
+
+ auto driver::query_interface(kapi::devices::interface interface) -> void *
+ {
+ if (interface == kapi::boot_modules::boot_module_driver_identification::id)
+ {
+ return static_cast<kapi::boot_modules::boot_module_driver_identification *>(this);
+ }
+
+ return kapi::devices::driver::query_interface(interface);
+ }
+
+} // namespace kernel::devices::storage::ram_disk \ No newline at end of file
diff --git a/kernel/kernel/devices/storage/ram_disk/driver.hpp b/kernel/kernel/devices/storage/ram_disk/driver.hpp
new file mode 100644
index 00000000..c665eb14
--- /dev/null
+++ b/kernel/kernel/devices/storage/ram_disk/driver.hpp
@@ -0,0 +1,39 @@
+#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_DRIVER_HPP
+#define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_DRIVER_HPP
+
+#include <kapi/boot_module/bus.hpp>
+#include <kapi/boot_modules.hpp>
+#include <kapi/devices.hpp>
+
+#include <kstd/result.hpp>
+#include <kstd/units.hpp>
+
+#include <cstddef>
+#include <cstdint>
+#include <optional>
+#include <string_view>
+#include <utility>
+
+namespace kernel::devices::storage::ram_disk
+{
+
+ struct driver final : kapi::devices::driver, kapi::boot_modules::boot_module_driver_identification
+ {
+ [[nodiscard]] auto probe(kapi::devices::device & device) -> kstd::result<void> override;
+
+ auto unbind(kapi::devices::device & device) -> void override;
+
+ [[nodiscard]] auto claimed_parameter() const -> std::pair<std::string_view, std::string_view> override;
+
+ [[nodiscard]] auto claimed_major() const -> std::optional<std::uint8_t> override;
+
+ protected:
+ auto query_interface(kapi::devices::interface interface) -> void * override;
+
+ private:
+ std::size_t m_next_disk_index{};
+ };
+
+} // namespace kernel::devices::storage::ram_disk
+
+#endif \ No newline at end of file