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/CMakeLists.txt | 2 + kernel/include/kernel/devices/root_bus.hpp | 32 +++++++++++++++ kernel/kapi/devices.cpp | 63 ++++++++++++++++++++++++++++++ kernel/src/devices/root_bus.cpp | 55 ++++++++++++++++++++++++++ kernel/src/main.cpp | 4 ++ 5 files changed, 156 insertions(+) create mode 100644 kernel/include/kernel/devices/root_bus.hpp create mode 100644 kernel/kapi/devices.cpp create mode 100644 kernel/src/devices/root_bus.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index f283588..9868eb9 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -3,6 +3,7 @@ add_library("kernel_objs" OBJECT "kapi/boot_modules.cpp" "kapi/cio.cpp" "kapi/cpu.cpp" + "kapi/devices.cpp" "kapi/interrupts.cpp" "kapi/memory.cpp" "kapi/system.cpp" @@ -17,6 +18,7 @@ add_library("kernel_objs" OBJECT "src/memory.cpp" "src/devices/block_device.cpp" "src/devices/block_device_utils.cpp" + "src/devices/root_bus.cpp" "src/devices/storage/controller.cpp" "src/devices/storage/management.cpp" "src/devices/storage/ram_disk/controller.cpp" diff --git a/kernel/include/kernel/devices/root_bus.hpp b/kernel/include/kernel/devices/root_bus.hpp new file mode 100644 index 0000000..f7bfbfb --- /dev/null +++ b/kernel/include/kernel/devices/root_bus.hpp @@ -0,0 +1,32 @@ +#ifndef TEACHOS_KERNEL_DEVICES_ROOT_BUS_HPP +#define TEACHOS_KERNEL_DEVICES_ROOT_BUS_HPP + +#include "kapi/devices/bus.hpp" +#include "kapi/devices/device.hpp" + +#include +#include +#include + +namespace kernel::devices +{ + + struct root_bus final : kapi::devices::bus + { + root_bus(); + + auto add_child(kstd::unique_ptr child) -> void override; + + [[nodiscard]] auto children() const -> kstd::vector> const & override; + + auto init() -> bool override; + + private: + kstd::vector> m_children{}; + kstd::vector> m_observers{}; + bool m_initialized{}; + }; + +} // namespace kernel::devices + +#endif \ No newline at end of file diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp new file mode 100644 index 0000000..dc19ab4 --- /dev/null +++ b/kernel/kapi/devices.cpp @@ -0,0 +1,63 @@ +#include "kapi/devices.hpp" + +#include "kapi/system.hpp" + +#include "kernel/devices/root_bus.hpp" + +#include +#include +#include + +#include +#include +#include +#include + +namespace kapi::devices +{ + + namespace + { + auto constinit next_major_number = std::atomic_size_t{0}; + auto constinit root_bus = std::optional{}; + auto constinit device_tree = kstd::flat_map, kstd::observer_ptr>{}; + } // namespace + + auto init() -> void + { + auto static is_initialized = std::atomic_flag{}; + if (is_initialized.test_and_set()) + { + return; + } + + root_bus.emplace(); + root_bus->init(); + } + + auto get_root_bus() -> bus & + { + if (!root_bus.has_value()) + { + kapi::system::panic("[kernel:devices] Root bus not initialized!"); + } + return *root_bus; + } + + auto allocate_major_number() -> std::size_t + { + return next_major_number++; + } + + auto register_device(device & device) -> bool + { + return device_tree.emplace(std::pair{device.major(), device.minor()}, &device).second; + } + + auto unregister_device(device &) -> bool + { + kstd::println("[kernel:devices] TODO: implement device deregistration"); + return false; + } + +} // namespace kapi::devices \ No newline at end of file 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 diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 37b4c5b..9d6028d 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,6 +1,7 @@ #include "kapi/boot_modules.hpp" #include "kapi/cio.hpp" #include "kapi/cpu.hpp" +#include "kapi/devices.hpp" #include "kapi/interrupts.hpp" #include "kapi/memory.hpp" #include "kapi/system.hpp" @@ -179,6 +180,9 @@ auto main() -> int kstd::println("[OS] Memory subsystem initialized."); kapi::system::memory_initialized(); + kapi::devices::init(); + kstd::println("[OS] System root bus initialized."); + kapi::boot_modules::init(); kstd::println("[OS] Boot module registry initialized."); -- 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/include/kernel/devices/root_bus.hpp | 4 +++- kernel/src/devices/root_bus.cpp | 4 ++-- kernel/src/main.cpp | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/devices/root_bus.hpp b/kernel/include/kernel/devices/root_bus.hpp index f7bfbfb..d92914d 100644 --- a/kernel/include/kernel/devices/root_bus.hpp +++ b/kernel/include/kernel/devices/root_bus.hpp @@ -8,6 +8,8 @@ #include #include +#include + namespace kernel::devices { @@ -24,7 +26,7 @@ namespace kernel::devices private: kstd::vector> m_children{}; kstd::vector> m_observers{}; - bool m_initialized{}; + std::atomic_flag m_initialized{}; }; } // namespace kernel::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!"); } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 9d6028d..eaaf87f 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -183,6 +183,9 @@ auto main() -> int kapi::devices::init(); kstd::println("[OS] System root bus initialized."); + kapi::devices::init_platform_devices(); + kstd::println("[OS] Platform devices initialized."); + kapi::boot_modules::init(); kstd::println("[OS] Boot module registry 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/include/kernel/devices/root_bus.hpp | 18 ------------- kernel/kapi/devices.cpp | 4 +-- kernel/src/devices/root_bus.cpp | 43 ------------------------------ 3 files changed, 2 insertions(+), 63 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/devices/root_bus.hpp b/kernel/include/kernel/devices/root_bus.hpp index d92914d..660b715 100644 --- a/kernel/include/kernel/devices/root_bus.hpp +++ b/kernel/include/kernel/devices/root_bus.hpp @@ -2,13 +2,6 @@ #define TEACHOS_KERNEL_DEVICES_ROOT_BUS_HPP #include "kapi/devices/bus.hpp" -#include "kapi/devices/device.hpp" - -#include -#include -#include - -#include namespace kernel::devices { @@ -16,17 +9,6 @@ namespace kernel::devices struct root_bus final : kapi::devices::bus { root_bus(); - - auto add_child(kstd::unique_ptr child) -> void override; - - [[nodiscard]] auto children() const -> kstd::vector> const & override; - - auto init() -> bool override; - - private: - kstd::vector> m_children{}; - kstd::vector> m_observers{}; - std::atomic_flag m_initialized{}; }; } // namespace kernel::devices diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp index dc19ab4..dbf5e68 100644 --- a/kernel/kapi/devices.cpp +++ b/kernel/kapi/devices.cpp @@ -39,7 +39,7 @@ namespace kapi::devices { if (!root_bus.has_value()) { - kapi::system::panic("[kernel:devices] Root bus not initialized!"); + kapi::system::panic("[OS:DEV] Root bus not initialized!"); } return *root_bus; } @@ -56,7 +56,7 @@ namespace kapi::devices auto unregister_device(device &) -> bool { - kstd::println("[kernel:devices] TODO: implement device deregistration"); + kstd::println("[OS:DEV] TODO: implement device deregistration"); return false; } 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 ab4c59912c526d515e6e72188c08a7f92e5573e8 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 15:07:54 +0200 Subject: x86_64: implement legacy PIT driver --- kernel/kapi/devices.cpp | 6 ++++-- kernel/src/main.cpp | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp index dbf5e68..c0b738e 100644 --- a/kernel/kapi/devices.cpp +++ b/kernel/kapi/devices.cpp @@ -31,8 +31,9 @@ namespace kapi::devices return; } - root_bus.emplace(); - root_bus->init(); + auto & bus = root_bus.emplace(); + register_device(bus); + bus.init(); } auto get_root_bus() -> bus & @@ -51,6 +52,7 @@ namespace kapi::devices auto register_device(device & device) -> bool { + kstd::println("[OS:DEV] Registering device {}@{}:{}", device.name(), device.major(), device.minor()); return device_tree.emplace(std::pair{device.major(), device.minor()}, &device).second; } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index eaaf87f..2eaa2d8 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -173,7 +173,6 @@ auto main() -> int kstd::println("[OS] IO subsystem initialized."); kapi::cpu::init(); - kapi::interrupts::enable(); kapi::memory::init(); kernel::memory::init_heap(kapi::memory::heap_base); @@ -186,6 +185,9 @@ auto main() -> int kapi::devices::init_platform_devices(); kstd::println("[OS] Platform devices initialized."); + kapi::interrupts::enable(); + kstd::println("[OS] Interrupts enabled."); + kapi::boot_modules::init(); kstd::println("[OS] Boot module registry initialized."); -- cgit v1.2.3 From 3e80b6baa8f9666a9dd3cd4531bc68a3de4fee92 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 15:18:05 +0200 Subject: kapi: allow for device searches --- kernel/kapi/devices.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'kernel') diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp index c0b738e..7d35778 100644 --- a/kernel/kapi/devices.cpp +++ b/kernel/kapi/devices.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace kapi::devices @@ -62,4 +63,25 @@ namespace kapi::devices return false; } + auto find_device(std::size_t major, std::size_t minor) -> kstd::observer_ptr + { + if (device_tree.contains(std::pair{major, minor})) + { + return device_tree.at(std::pair{major, minor}); + } + return nullptr; + } + + auto find_device(std::string_view name) -> kstd::observer_ptr + { + for (auto const & [key, value] : device_tree) + { + if (value->name() == name) + { + return value; + } + } + return nullptr; + } + } // namespace kapi::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/kapi/devices.cpp | 2 +- kernel/src/devices/root_bus.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp index 7d35778..031f2c9 100644 --- a/kernel/kapi/devices.cpp +++ b/kernel/kapi/devices.cpp @@ -19,7 +19,7 @@ namespace kapi::devices namespace { - auto constinit next_major_number = std::atomic_size_t{0}; + auto constinit next_major_number = std::atomic_size_t{1}; auto constinit root_bus = std::optional{}; auto constinit device_tree = kstd::flat_map, kstd::observer_ptr>{}; } // namespace 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