diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-08-01 00:33:56 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-08-01 00:33:56 +0200 |
| commit | 5ce5c28e0f0f034cb7c704f08e59089ef303ff7e (patch) | |
| tree | 6340aef7cee1948d3b6321e83f8c5976ef192180 | |
| parent | 2c9b29799dbf6a706d235d79a3257fc9a42d12d3 (diff) | |
| download | kernel-5ce5c28e0f0f034cb7c704f08e59089ef303ff7e.tar.xz kernel-5ce5c28e0f0f034cb7c704f08e59089ef303ff7e.zip | |
| -rw-r--r-- | arch/x86_64/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | arch/x86_64/arch/drivers/cpu/lapic.cpp | 20 | ||||
| -rw-r--r-- | arch/x86_64/arch/drivers/init.cpp | 29 | ||||
| -rw-r--r-- | arch/x86_64/arch/drivers/init.hpp | 11 | ||||
| -rw-r--r-- | arch/x86_64/arch/drivers/pit.cpp | 18 | ||||
| -rw-r--r-- | arch/x86_64/kapi/devices.cpp | 26 | ||||
| -rw-r--r-- | arch/x86_64/scripts/kernel.ld | 11 | ||||
| -rw-r--r-- | kapi/kapi/devices/driver_registry.hpp | 36 | ||||
| -rw-r--r-- | kernel/kernel/drivers/init.cpp | 31 | ||||
| -rw-r--r-- | kernel/kernel/drivers/pseudo/null.cpp | 18 | ||||
| -rw-r--r-- | kernel/kernel/drivers/pseudo/zero.cpp | 17 | ||||
| -rw-r--r-- | kernel/kernel/drivers/storage/ram_disk.cpp | 17 |
12 files changed, 184 insertions, 51 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt index 19022b5f..fc665c15 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -50,7 +50,6 @@ target_sources("x86_64" PRIVATE "arch/devices/cpu/lapic.cpp" # Drivers - "arch/drivers/init.cpp" "arch/drivers/cpu/lapic.cpp" "arch/drivers/pit.cpp" diff --git a/arch/x86_64/arch/drivers/cpu/lapic.cpp b/arch/x86_64/arch/drivers/cpu/lapic.cpp index 2f74abc4..f8aa8e90 100644 --- a/arch/x86_64/arch/drivers/cpu/lapic.cpp +++ b/arch/x86_64/arch/drivers/cpu/lapic.cpp @@ -4,9 +4,11 @@ #include <kapi/capabilities/facet_id.hpp> #include <kapi/devices.hpp> +#include <kapi/devices/driver_registry.hpp> #include <kapi/memory.hpp> #include <kstd/format.hpp> +#include <kstd/memory.hpp> #include <kstd/mutex.hpp> #include <kstd/print.hpp> #include <kstd/result.hpp> @@ -31,6 +33,22 @@ namespace arch::drivers::cpu constexpr auto offset_of_version = 0u; constexpr auto offset_of_max_lvt_entry = 16u; constexpr auto offset_of_eoi_suppression = 24u; + + struct descriptor final : kapi::devices::driver_descriptor + { + [[nodiscard]] auto make_instance() const -> kstd::shared_ptr<kapi::devices::driver> override + { + return kstd::make_shared<lapic>(); + } + + [[nodiscard]] auto name() const noexcept -> std::string_view override + { + return "intel_lapic"; + } + }; + + [[gnu::used]] + constexpr auto registration = kapi::devices::platform_driver<descriptor>{}; } // namespace enum struct lapic::registers : std::ptrdiff_t @@ -164,4 +182,4 @@ namespace arch::drivers::cpu return kapi::devices::driver::query_facet(facet); } -} // namespace arch::drivers +} // namespace arch::drivers::cpu diff --git a/arch/x86_64/arch/drivers/init.cpp b/arch/x86_64/arch/drivers/init.cpp deleted file mode 100644 index 19f45829..00000000 --- a/arch/x86_64/arch/drivers/init.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include <arch/drivers/init.hpp> - -#include <arch/drivers/cpu/lapic.hpp> -#include <arch/drivers/pit.hpp> - -#include <kapi/devices.hpp> - -#include <kstd/memory.hpp> - -#include <cstdint> - -namespace arch::drivers -{ - - namespace - { - //! The interrupt frequency of the Programmable Interrupt Timer. - constexpr auto pit_frequency_in_hz = std::uint32_t{100u}; - } // namespace - - auto init_legacy_drivers() -> void - { - auto & driver_registry = kapi::devices::driver_registry::get(); - - driver_registry.add(kstd::make_shared<pit>(pit_frequency_in_hz)); - driver_registry.add(kstd::make_shared<cpu::lapic>()); - } - -} // namespace arch::drivers diff --git a/arch/x86_64/arch/drivers/init.hpp b/arch/x86_64/arch/drivers/init.hpp deleted file mode 100644 index 797edb0f..00000000 --- a/arch/x86_64/arch/drivers/init.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_DRIVERS_INIT_HPP -#define TEACHOS_ARCH_X86_64_DRIVERS_INIT_HPP - -namespace arch::drivers -{ - - auto init_legacy_drivers() -> void; - -} - -#endif diff --git a/arch/x86_64/arch/drivers/pit.cpp b/arch/x86_64/arch/drivers/pit.cpp index 49b3f228..e6e98796 100644 --- a/arch/x86_64/arch/drivers/pit.cpp +++ b/arch/x86_64/arch/drivers/pit.cpp @@ -29,6 +29,24 @@ namespace arch::drivers constexpr auto command_offset = 3u; constexpr auto pit_names = std::array{"pit"sv}; + constexpr auto pit_frequency_in_hz = std::uint32_t{100u}; + + struct descriptor final : kapi::devices::driver_descriptor + { + [[nodiscard]] auto make_instance() const -> kstd::shared_ptr<kapi::devices::driver> override + { + return kstd::make_shared<pit>(pit_frequency_in_hz); + } + + [[nodiscard]] auto name() const noexcept -> std::string_view override + { + return "i8253_pit"sv; + } + }; + + [[gnu::used]] + constexpr auto registration = kapi::devices::platform_driver<descriptor>{}; + } // namespace pit::pit(std::uint32_t frequency_in_hz) diff --git a/arch/x86_64/kapi/devices.cpp b/arch/x86_64/kapi/devices.cpp index d9a0b2b9..888b6e20 100644 --- a/arch/x86_64/kapi/devices.cpp +++ b/arch/x86_64/kapi/devices.cpp @@ -2,11 +2,15 @@ #include <arch/bus/cpu.hpp> #include <arch/devices/init.hpp> -#include <arch/drivers/init.hpp> +#include <kapi/devices/driver_registry.hpp> #include <kapi/system.hpp> #include <kstd/memory.hpp> +#include <kstd/print.hpp> + +#include <ranges> +#include <span> namespace kapi::devices { @@ -16,9 +20,27 @@ namespace kapi::devices auto static constinit cpu_bus = kstd::shared_ptr<arch::bus::cpu>{}; } + extern "C" + { + // We need to suppress clang-tidy linting warnings here, since these symbols are generated by the linker and we + // cannot choose their names, unless we wanted to extend the linker script needlessly. + // NOLINTBEGIN(readability-identifier-naming) + extern kstd::observer_ptr<kapi::devices::driver_descriptor> const __start_platform_drivers; + extern kstd::observer_ptr<kapi::devices::driver_descriptor> const __stop_platform_drivers; + // NOLINTEND(readability-identifier-naming) + } + auto init_platform_drivers() -> void { - arch::drivers::init_legacy_drivers(); + auto descriptors = std::span{&__start_platform_drivers, &__stop_platform_drivers} | // + std::views::filter([](auto p) { return p != nullptr; }); + + for (auto driver : descriptors) + { + auto instance = driver->make_instance(); + kstd::println("[x86_64:DRV] registering driver '{}' ({})", instance->name(), driver->name()); + kapi::devices::driver_registry::get().add(driver->make_instance()); + } } auto init_platform_devices() -> void diff --git a/arch/x86_64/scripts/kernel.ld b/arch/x86_64/scripts/kernel.ld index dbb0f8f0..f621c3f1 100644 --- a/arch/x86_64/scripts/kernel.ld +++ b/arch/x86_64/scripts/kernel.ld @@ -75,9 +75,20 @@ SECTIONS . = ALIGN(8); + /* Filesystem driver factories */ PROVIDE(__start_fs_types = .); KEEP(*(fs_types)); PROVIDE(__stop_fs_types = .); + + /* Kernel driver factories */ + PROVIDE(__start_kernel_drivers = .); + KEEP(*(kernel_drivers)); + PROVIDE(__stop_kernel_drivers = .); + + /* Platform driver factories */ + PROVIDE(__start_platform_drivers = .); + KEEP(*(platform_drivers)); + PROVIDE(__stop_platform_drivers = .); } :kernel_rodata .kernel_data ALIGN(4K) : AT (ADDR (.kernel_data) - TEACHOS_VMA) diff --git a/kapi/kapi/devices/driver_registry.hpp b/kapi/kapi/devices/driver_registry.hpp index 8af76b01..196b14c1 100644 --- a/kapi/kapi/devices/driver_registry.hpp +++ b/kapi/kapi/devices/driver_registry.hpp @@ -8,9 +8,45 @@ #include <kstd/memory.hpp> #include <kstd/vector.hpp> +#include <string_view> + namespace kapi::devices { + //! @addtogroup kapi-devices + //! @{ + + struct driver_descriptor + { + virtual ~driver_descriptor() = default; + + //! Get the name of the driver + [[nodiscard]] virtual auto name() const noexcept -> std::string_view = 0; + + //! Create a new instance of the driver represented by this descriptor. + [[nodiscard]] virtual auto make_instance() const -> kstd::shared_ptr<driver> = 0; + }; + + template<typename Type> + struct kernel_driver + { + constexpr auto static instance = Type{}; + [[using gnu: section("kernel_drivers"), used, visibility("hidden")]] constexpr auto static pointer{ + kstd::make_observer<kapi::devices::driver_descriptor const>(&instance), + }; + }; + + template<typename Type> + struct platform_driver + { + constexpr auto static instance = Type{}; + [[using gnu: section("platform_drivers"), used, visibility("hidden")]] constexpr auto static pointer{ + kstd::make_observer<kapi::devices::driver_descriptor const>(&instance), + }; + }; + + //! @} + //! @addtogroup kapi-devices-kernel-defined //! @{ diff --git a/kernel/kernel/drivers/init.cpp b/kernel/kernel/drivers/init.cpp index cd196fa8..97d8f0bc 100644 --- a/kernel/kernel/drivers/init.cpp +++ b/kernel/kernel/drivers/init.cpp @@ -1,25 +1,42 @@ #include <kernel/drivers/init.hpp> -#include <kernel/drivers/pseudo/null.hpp> -#include <kernel/drivers/pseudo/zero.hpp> -#include <kernel/drivers/storage/ram_disk.hpp> - +#include <kapi/devices.hpp> #include <kapi/devices/driver_registry.hpp> #include <kstd/memory.hpp> +#include <kstd/print.hpp> + +#include <ranges> +#include <span> namespace kernel::drivers { + extern "C" + { + // We need to suppress clang-tidy linting warnings here, since these symbols are generated by the linker and we + // cannot choose their names, unless we wanted to extend the linker script needlessly. + // NOLINTBEGIN(readability-identifier-naming) + extern kstd::observer_ptr<kapi::devices::driver_descriptor> const __start_kernel_drivers; + extern kstd::observer_ptr<kapi::devices::driver_descriptor> const __stop_kernel_drivers; + // NOLINTEND(readability-identifier-naming) + } + auto init() -> void { kapi::devices::driver_registry::init(); auto & registry = kapi::devices::driver_registry::get(); - registry.add(kstd::make_shared<kernel::drivers::pseudo::null>()); - registry.add(kstd::make_shared<kernel::drivers::pseudo::zero>()); - registry.add(kstd::make_shared<kernel::drivers::storage::ram_disk>()); + auto descriptors = std::span{&__start_kernel_drivers, &__stop_kernel_drivers} | // + std::views::filter([](auto p) { return p != nullptr; }); + + for (auto driver : descriptors) + { + auto instance = driver->make_instance(); + kstd::println("[OS:DRV] registering driver '{}' ({})", instance->name(), driver->name()); + registry.add(driver->make_instance()); + } } } // namespace kernel::drivers
\ No newline at end of file diff --git a/kernel/kernel/drivers/pseudo/null.cpp b/kernel/kernel/drivers/pseudo/null.cpp index d0df9000..4995cc25 100644 --- a/kernel/kernel/drivers/pseudo/null.cpp +++ b/kernel/kernel/drivers/pseudo/null.cpp @@ -4,6 +4,7 @@ #include <kernel/filesystem/reserved_numbers.hpp> #include <kapi/devices.hpp> +#include <kapi/devices/driver_registry.hpp> #include <kapi/filesystem.hpp> #include <kstd/memory.hpp> @@ -26,6 +27,23 @@ namespace kernel::drivers::pseudo namespace { + struct descriptor final : kapi::devices::driver_descriptor + { + public: + [[nodiscard("")]] auto name() const noexcept -> std::string_view override + { + return "dev_null"; + } + + [[nodiscard("")]] auto make_instance() const -> kstd::shared_ptr<kapi::devices::driver> override + { + return kstd::make_shared<null>(); + } + }; + + [[gnu::used]] + constexpr auto registration = kapi::devices::kernel_driver<descriptor>{}; + struct null_node final : kapi::filesystem::character_special_file { public: diff --git a/kernel/kernel/drivers/pseudo/zero.cpp b/kernel/kernel/drivers/pseudo/zero.cpp index 550a97ff..724ff25c 100644 --- a/kernel/kernel/drivers/pseudo/zero.cpp +++ b/kernel/kernel/drivers/pseudo/zero.cpp @@ -27,6 +27,23 @@ namespace kernel::drivers::pseudo namespace { + struct descriptor final : kapi::devices::driver_descriptor + { + public: + [[nodiscard("")]] auto name() const noexcept -> std::string_view override + { + return "dev_zero"; + } + + [[nodiscard("")]] auto make_instance() const -> kstd::shared_ptr<kapi::devices::driver> override + { + return kstd::make_shared<zero>(); + } + }; + + [[gnu::used]] + constexpr auto registration = kapi::devices::kernel_driver<descriptor>{}; + struct zero_node final : kapi::filesystem::character_special_file { public: diff --git a/kernel/kernel/drivers/storage/ram_disk.cpp b/kernel/kernel/drivers/storage/ram_disk.cpp index 987f4bbc..f7e73cd1 100644 --- a/kernel/kernel/drivers/storage/ram_disk.cpp +++ b/kernel/kernel/drivers/storage/ram_disk.cpp @@ -31,6 +31,23 @@ namespace kernel::drivers::storage { constexpr auto default_block_size = 512_B; + struct descriptor final : kapi::devices::driver_descriptor + { + public: + [[nodiscard("")]] auto name() const noexcept -> std::string_view override + { + return "ram_disk"; + } + + [[nodiscard("")]] auto make_instance() const -> kstd::shared_ptr<kapi::devices::driver> override + { + return kstd::make_shared<ram_disk>(); + } + }; + + [[gnu::used]] + constexpr auto registration = kapi::devices::kernel_driver<descriptor>{}; + struct block_node final : kapi::filesystem::block_special_file { explicit block_node(kapi::boot_modules::module const & module) |
