From 035c8d6e38fd901e6769a81f67b8d9e1e3fcea20 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 26 Feb 2026 11:24:27 +0100 Subject: implemented boot_modules and boot_module_registry, init boot_modules in kernel main --- kernel/CMakeLists.txt | 1 + kernel/kapi/boot_modules.cpp | 21 +++++++++++++++++++++ kernel/src/main.cpp | 4 ++++ 3 files changed, 26 insertions(+) create mode 100644 kernel/kapi/boot_modules.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 02e517c..b7b7c71 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,5 +1,6 @@ add_executable("kernel" # Platform-independent KAPI implementation + "kapi/boot_modules.cpp" "kapi/cio.cpp" "kapi/memory.cpp" "kapi/system.cpp" diff --git a/kernel/kapi/boot_modules.cpp b/kernel/kapi/boot_modules.cpp new file mode 100644 index 0000000..3f0f044 --- /dev/null +++ b/kernel/kapi/boot_modules.cpp @@ -0,0 +1,21 @@ +#include "kapi/boot_modules.hpp" + +#include "kapi/system.hpp" + +#include + +namespace kapi::boot_modules +{ + + constinit auto static registry = std::optional{}; + + auto set_boot_module_registry(boot_module_registry & registry) -> void + { + if (kapi::boot_modules::registry) + { + system::panic("[x86_64] Boot module registry has already been set."); + } + + kapi::boot_modules::registry = registry; + } +} // namespace kapi::boot_modules diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 01bcbb0..117a1d8 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,3 +1,4 @@ +#include "kapi/boot_modules.hpp" #include "kapi/cio.hpp" #include "kapi/memory.hpp" #include "kapi/system.hpp" @@ -16,5 +17,8 @@ auto main() -> int kstd::println("[OS] Memory subsystem initialized."); kapi::system::memory_initialized(); + kapi::boot_modules::init(); + kstd::println("[OS] Boot module registry initialized."); + kapi::system::panic("Returning from kernel main!"); } -- cgit v1.2.3 From 144c3fb3845eb9deb1093c3348af5e02cb2cbbb8 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 26 Feb 2026 11:27:48 +0100 Subject: setup basic devices and RAMDisk structure --- kernel/CMakeLists.txt | 3 +++ kernel/devices/CMakeLists.txt | 27 ++++++++++++++++++++++ kernel/devices/include/devices/BlockDevice.hpp | 11 +++++++++ kernel/devices/include/devices/Device.hpp | 11 +++++++++ .../devices/storage/RAMDisk/RAMDiskController.hpp | 11 +++++++++ .../devices/storage/RAMDisk/RAMDiskDevice.hpp | 11 +++++++++ .../include/devices/storage/StorageController.hpp | 11 +++++++++ .../include/devices/storage/StorageManagement.hpp | 16 +++++++++++++ kernel/devices/src/BlockDevice.cpp | 6 +++++ kernel/devices/src/Device.cpp | 6 +++++ .../src/storage/RAMDisk/RAMDiskController.cpp | 6 +++++ .../devices/src/storage/RAMDisk/RAMDiskDevice.cpp | 6 +++++ kernel/devices/src/storage/StorageController.cpp | 6 +++++ kernel/devices/src/storage/StorageManagement.cpp | 9 ++++++++ 14 files changed, 140 insertions(+) create mode 100644 kernel/devices/CMakeLists.txt create mode 100644 kernel/devices/include/devices/BlockDevice.hpp create mode 100644 kernel/devices/include/devices/Device.hpp create mode 100644 kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp create mode 100644 kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp create mode 100644 kernel/devices/include/devices/storage/StorageController.hpp create mode 100644 kernel/devices/include/devices/storage/StorageManagement.hpp create mode 100644 kernel/devices/src/BlockDevice.cpp create mode 100644 kernel/devices/src/Device.cpp create mode 100644 kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp create mode 100644 kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp create mode 100644 kernel/devices/src/storage/StorageController.cpp create mode 100644 kernel/devices/src/storage/StorageManagement.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index b7b7c71..c3c9698 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,3 +1,5 @@ +add_subdirectory("devices") + add_executable("kernel" # Platform-independent KAPI implementation "kapi/boot_modules.cpp" @@ -24,6 +26,7 @@ target_include_directories("kernel" PRIVATE target_link_libraries("kernel" PRIVATE "os::arch" "os::kapi" + "kernel::devices" ) target_link_options("kernel" PRIVATE diff --git a/kernel/devices/CMakeLists.txt b/kernel/devices/CMakeLists.txt new file mode 100644 index 0000000..80b89bf --- /dev/null +++ b/kernel/devices/CMakeLists.txt @@ -0,0 +1,27 @@ +add_library("kernel_devices" STATIC) +add_library("kernel::devices" ALIAS "kernel_devices") + +target_sources("kernel_devices" PRIVATE + "src/Device.cpp" + "src/BlockDevice.cpp" + "src/storage/StorageController.cpp" + "src/storage/StorageManagement.cpp" + "src/storage/RAMDisk/RAMDiskController.cpp" + "src/storage/RAMDisk/RAMDiskDevice.cpp" +) + +target_sources("kernel_devices" PUBLIC + FILE_SET HEADERS + BASE_DIRS "include" + FILES + "include/devices/Device.hpp" + "include/devices/BlockDevice.hpp" + "include/devices/storage/StorageController.hpp" + "include/devices/storage/StorageManagement.hpp" + "include/devices/storage/RAMDisk/RAMDiskController.hpp" + "include/devices/storage/RAMDisk/RAMDiskDevice.hpp" +) + +target_include_directories("kernel_devices" PUBLIC + "include" +) \ No newline at end of file diff --git a/kernel/devices/include/devices/BlockDevice.hpp b/kernel/devices/include/devices/BlockDevice.hpp new file mode 100644 index 0000000..db66683 --- /dev/null +++ b/kernel/devices/include/devices/BlockDevice.hpp @@ -0,0 +1,11 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP +#define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP + +namespace devices +{ + struct block_device + { + }; +} // namespace devices + +#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/Device.hpp b/kernel/devices/include/devices/Device.hpp new file mode 100644 index 0000000..a3cac42 --- /dev/null +++ b/kernel/devices/include/devices/Device.hpp @@ -0,0 +1,11 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_DEVICE_HPP +#define TEACH_OS_KERNEL_DEVICES_DEVICE_HPP + +namespace devices +{ + struct device + { + }; +} // namespace devices + +#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp new file mode 100644 index 0000000..3fcb645 --- /dev/null +++ b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp @@ -0,0 +1,11 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP +#define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP + +namespace devices::storage::ram_disk +{ + struct ram_disk_controller + { + }; +} // namespace devices::storage::ram_disk + +#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp new file mode 100644 index 0000000..98471cf --- /dev/null +++ b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp @@ -0,0 +1,11 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_DEVICE_HPP +#define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_DEVICE_HPP + +namespace devices::storage::ram_disk +{ + struct ram_disk_device + { + }; +} // namespace devices::storage::ram_disk + +#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/StorageController.hpp b/kernel/devices/include/devices/storage/StorageController.hpp new file mode 100644 index 0000000..3167be0 --- /dev/null +++ b/kernel/devices/include/devices/storage/StorageController.hpp @@ -0,0 +1,11 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP +#define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP + +namespace devices::storage +{ + struct storage_controller + { + }; +} // namespace devices::storage + +#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/StorageManagement.hpp b/kernel/devices/include/devices/storage/StorageManagement.hpp new file mode 100644 index 0000000..2b2eb22 --- /dev/null +++ b/kernel/devices/include/devices/storage/StorageManagement.hpp @@ -0,0 +1,16 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP +#define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP + +namespace devices::storage +{ + struct storage_management + { + //! @qualifier kernel-defined + //! Initialize the storage management subsystem. + auto init() -> void; + + private: + }; +} // namespace devices::storage + +#endif \ No newline at end of file diff --git a/kernel/devices/src/BlockDevice.cpp b/kernel/devices/src/BlockDevice.cpp new file mode 100644 index 0000000..970f7b2 --- /dev/null +++ b/kernel/devices/src/BlockDevice.cpp @@ -0,0 +1,6 @@ +#include "devices/BlockDevice.hpp" + +namespace devices +{ + // TODO BA-FS26 implement block device functionality +} // namespace devices \ No newline at end of file diff --git a/kernel/devices/src/Device.cpp b/kernel/devices/src/Device.cpp new file mode 100644 index 0000000..d755fb9 --- /dev/null +++ b/kernel/devices/src/Device.cpp @@ -0,0 +1,6 @@ +#include "devices/Device.hpp" + +namespace devices +{ + // TODO BA-FS26 implement device functionality +} // namespace devices \ No newline at end of file diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp new file mode 100644 index 0000000..9c6427d --- /dev/null +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp @@ -0,0 +1,6 @@ +#include "devices/storage/RAMDisk/RAMDiskController.hpp" + +namespace devices::storage::ram_disk +{ + // TODO BA-FS26 implement ram disk controller functionality +} // namespace devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp new file mode 100644 index 0000000..8d8f51e --- /dev/null +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp @@ -0,0 +1,6 @@ +#include "devices/storage/RAMDisk/RAMDiskDevice.hpp" + +namespace devices::storage::ram_disk +{ + // TODO BA-FS26 implement ram disk device functionality +} // namespace devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/devices/src/storage/StorageController.cpp b/kernel/devices/src/storage/StorageController.cpp new file mode 100644 index 0000000..fe386cf --- /dev/null +++ b/kernel/devices/src/storage/StorageController.cpp @@ -0,0 +1,6 @@ +#include "devices/storage/StorageController.hpp" + +namespace devices::storage +{ + // TODO BA-FS26 implement storage controller functionality +} // namespace devices::storage \ No newline at end of file diff --git a/kernel/devices/src/storage/StorageManagement.cpp b/kernel/devices/src/storage/StorageManagement.cpp new file mode 100644 index 0000000..f34fa15 --- /dev/null +++ b/kernel/devices/src/storage/StorageManagement.cpp @@ -0,0 +1,9 @@ +#include "devices/storage/StorageManagement.hpp" + +namespace devices::storage +{ + auto storage_management::init() -> void + { + // TODO BA-FS26 implement storage management initialization + } +} // namespace devices::storage \ No newline at end of file -- cgit v1.2.3 From 296d58550e8e1202d83e66034c24e9454a1b67dc Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 27 Feb 2026 23:23:18 +0100 Subject: - add boot_module_registry getter --- kernel/kapi/boot_modules.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/boot_modules.cpp b/kernel/kapi/boot_modules.cpp index 3f0f044..5a0ef7f 100644 --- a/kernel/kapi/boot_modules.cpp +++ b/kernel/kapi/boot_modules.cpp @@ -7,15 +7,28 @@ namespace kapi::boot_modules { - constinit auto static registry = std::optional{}; + namespace + { + constinit auto static registry = std::optional{}; + } // namespace - auto set_boot_module_registry(boot_module_registry & registry) -> void + auto set_boot_module_registry(boot_module_registry & new_registry) -> void { - if (kapi::boot_modules::registry) + if (registry) { system::panic("[x86_64] Boot module registry has already been set."); } - kapi::boot_modules::registry = registry; + registry = new_registry; + } + + auto get_boot_module_registry() -> boot_module_registry & + { + if (!registry) + { + system::panic("[x86_64] Boot module registry has not been initialized."); + } + + return *registry; } } // namespace kapi::boot_modules -- cgit v1.2.3 From 7a9bdbc58361ff22491785d778474571035ad697 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sat, 28 Feb 2026 15:18:56 +0100 Subject: Implement basic structure of storage management --- kernel/devices/CMakeLists.txt | 4 +++ .../include/devices/storage/StorageManagement.hpp | 20 +++++++++-- kernel/devices/src/storage/StorageManagement.cpp | 39 +++++++++++++++++++++- 3 files changed, 59 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/CMakeLists.txt b/kernel/devices/CMakeLists.txt index 80b89bf..8022dee 100644 --- a/kernel/devices/CMakeLists.txt +++ b/kernel/devices/CMakeLists.txt @@ -24,4 +24,8 @@ target_sources("kernel_devices" PUBLIC target_include_directories("kernel_devices" PUBLIC "include" +) + +target_link_libraries("kernel_devices" PRIVATE + "os::kapi" ) \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/StorageManagement.hpp b/kernel/devices/include/devices/storage/StorageManagement.hpp index 2b2eb22..9098312 100644 --- a/kernel/devices/include/devices/storage/StorageManagement.hpp +++ b/kernel/devices/include/devices/storage/StorageManagement.hpp @@ -1,15 +1,29 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP +#include "devices/BlockDevice.hpp" +#include "devices/storage/StorageController.hpp" + +#include + namespace devices::storage { struct storage_management { - //! @qualifier kernel-defined - //! Initialize the storage management subsystem. - auto init() -> void; + // TODO BA-FS26 add documentation + + auto static init() -> void; + auto static get() -> storage_management &; + + auto add_controller(storage_controller * controller) -> void; + + auto add_device(block_device * device) -> void; private: + storage_management() = default; + + std::array m_controllers{}; // TODO BA-FS26 use kstd::vector + std::array m_devices{}; // TODO BA-FS26 use kstd::vector }; } // namespace devices::storage diff --git a/kernel/devices/src/storage/StorageManagement.cpp b/kernel/devices/src/storage/StorageManagement.cpp index f34fa15..14c59ac 100644 --- a/kernel/devices/src/storage/StorageManagement.cpp +++ b/kernel/devices/src/storage/StorageManagement.cpp @@ -1,9 +1,46 @@ #include "devices/storage/StorageManagement.hpp" +#include "kapi/system.hpp" + +#include "devices/BlockDevice.hpp" +#include "devices/storage/StorageController.hpp" + +#include + namespace devices::storage { + namespace + { + constinit auto static active_storage_management = std::optional{}; + } // namespace + auto storage_management::init() -> void { - // TODO BA-FS26 implement storage management initialization + if (active_storage_management) + { + kapi::system::panic("[DEVICES] Storage management has already been initialized."); + } + active_storage_management.emplace(storage_management{}); + } + + 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(storage_controller * controller) -> void + { + m_controllers.at(0) = controller; // TODO BA-FS26 use push_back from kstd:vector } + + auto storage_management::add_device(block_device * device) -> void + { + m_devices.at(0) = device; // TODO BA-FS26 use push_back from kstd:vector + } + } // namespace devices::storage \ No newline at end of file -- cgit v1.2.3 From 2d52fae22143ec94c3741e60fd74374f9675e742 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sat, 28 Feb 2026 17:03:03 +0100 Subject: Implement RAMDiskController and instantiate it in StorageManagement --- kernel/devices/CMakeLists.txt | 1 - .../devices/storage/RAMDisk/RAMDiskController.hpp | 21 +++++++++++++++- .../include/devices/storage/StorageController.hpp | 5 ++++ .../src/storage/RAMDisk/RAMDiskController.cpp | 29 +++++++++++++++++++++- kernel/devices/src/storage/StorageController.cpp | 6 ----- kernel/devices/src/storage/StorageManagement.cpp | 11 ++++++++ 6 files changed, 64 insertions(+), 9 deletions(-) delete mode 100644 kernel/devices/src/storage/StorageController.cpp (limited to 'kernel') diff --git a/kernel/devices/CMakeLists.txt b/kernel/devices/CMakeLists.txt index 8022dee..0707a03 100644 --- a/kernel/devices/CMakeLists.txt +++ b/kernel/devices/CMakeLists.txt @@ -4,7 +4,6 @@ add_library("kernel::devices" ALIAS "kernel_devices") target_sources("kernel_devices" PRIVATE "src/Device.cpp" "src/BlockDevice.cpp" - "src/storage/StorageController.cpp" "src/storage/StorageManagement.cpp" "src/storage/RAMDisk/RAMDiskController.cpp" "src/storage/RAMDisk/RAMDiskDevice.cpp" diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp index 3fcb645..6213ed4 100644 --- a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp +++ b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp @@ -1,10 +1,29 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP +#include "kapi/boot_module/boot_module.hpp" +#include "kapi/boot_module/boot_module_registry.hpp" + +#include "devices/storage/RAMDisk/RAMDiskDevice.hpp" +#include "devices/storage/StorageController.hpp" + +#include +#include + namespace devices::storage::ram_disk { - struct ram_disk_controller + struct ram_disk_controller : storage_controller { + explicit ram_disk_controller(kapi::boot_modules::boot_module_registry const * registry); + + auto probe() -> void override; + auto devices_count() -> size_t override; + + private: + auto create_device_from_boot_module(kapi::boot_modules::boot_module const & module) -> void; + + kapi::boot_modules::boot_module_registry const * m_boot_module_registry; + std::array m_devices{}; // TODO BA-FS26 use kstd::vector }; } // namespace devices::storage::ram_disk diff --git a/kernel/devices/include/devices/storage/StorageController.hpp b/kernel/devices/include/devices/storage/StorageController.hpp index 3167be0..7904d07 100644 --- a/kernel/devices/include/devices/storage/StorageController.hpp +++ b/kernel/devices/include/devices/storage/StorageController.hpp @@ -1,10 +1,15 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP +#include namespace devices::storage { struct storage_controller { + virtual ~storage_controller() = default; + + virtual auto probe() -> void = 0; + virtual auto devices_count() -> size_t = 0; }; } // namespace devices::storage diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp index 9c6427d..c4807b0 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp @@ -1,6 +1,33 @@ #include "devices/storage/RAMDisk/RAMDiskController.hpp" +#include "kapi/boot_module/boot_module.hpp" +#include "kapi/boot_module/boot_module_registry.hpp" + +#include + +#include +#include + namespace devices::storage::ram_disk { - // TODO BA-FS26 implement ram disk controller functionality + 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 + { + std::ranges::for_each(*m_boot_module_registry, + [this](auto const & module) { create_device_from_boot_module(module); }); + } + + auto ram_disk_controller::devices_count() -> size_t + { + return m_devices.size(); + } + + auto create_device_from_boot_module(kapi::boot_modules::boot_module const & module) -> void + { + kstd::println("[RAM DISK CONTROLLER] Found boot module: {} at address {} with size {} bytes", module.name, + module.start_address, module.size); + } } // namespace devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/devices/src/storage/StorageController.cpp b/kernel/devices/src/storage/StorageController.cpp deleted file mode 100644 index fe386cf..0000000 --- a/kernel/devices/src/storage/StorageController.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "devices/storage/StorageController.hpp" - -namespace devices::storage -{ - // TODO BA-FS26 implement storage controller functionality -} // namespace devices::storage \ No newline at end of file diff --git a/kernel/devices/src/storage/StorageManagement.cpp b/kernel/devices/src/storage/StorageManagement.cpp index 14c59ac..9cc9a06 100644 --- a/kernel/devices/src/storage/StorageManagement.cpp +++ b/kernel/devices/src/storage/StorageManagement.cpp @@ -1,8 +1,10 @@ #include "devices/storage/StorageManagement.hpp" +#include "kapi/boot_modules.hpp" #include "kapi/system.hpp" #include "devices/BlockDevice.hpp" +#include "devices/storage/RAMDisk/RAMDiskController.hpp" #include "devices/storage/StorageController.hpp" #include @@ -12,6 +14,7 @@ namespace devices::storage namespace { constinit auto static active_storage_management = std::optional{}; + constinit auto static active_ram_disk_controller = std::optional{}; } // namespace auto storage_management::init() -> void @@ -21,6 +24,14 @@ namespace devices::storage kapi::system::panic("[DEVICES] Storage management has already been initialized."); } active_storage_management.emplace(storage_management{}); + + active_ram_disk_controller.emplace(&kapi::boot_modules::get_boot_module_registry()); + active_storage_management->add_controller(&active_ram_disk_controller.value()); + + for (auto controller : active_storage_management->m_controllers) + { + controller->probe(); + } } auto storage_management::get() -> storage_management & -- cgit v1.2.3 From 22015882dfb4f4d94df88693f5c0f3832c441066 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sat, 28 Feb 2026 17:33:22 +0100 Subject: Fix build --- kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp index c4807b0..3e12e0d 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp @@ -25,7 +25,7 @@ namespace devices::storage::ram_disk return m_devices.size(); } - auto create_device_from_boot_module(kapi::boot_modules::boot_module const & module) -> void + auto ram_disk_controller::create_device_from_boot_module(kapi::boot_modules::boot_module const & module) -> void { kstd::println("[RAM DISK CONTROLLER] Found boot module: {} at address {} with size {} bytes", module.name, module.start_address, module.size); -- cgit v1.2.3 From dd60285848be17083d7ef77fa0ed8896b6e087b7 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sat, 28 Feb 2026 17:33:42 +0100 Subject: Initialize storage management from kernel main --- kernel/src/main.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 117a1d8..0336fef 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -3,6 +3,8 @@ #include "kapi/memory.hpp" #include "kapi/system.hpp" +#include "devices/storage/StorageManagement.hpp" + #include "kernel/memory.hpp" #include @@ -20,5 +22,8 @@ auto main() -> int kapi::boot_modules::init(); kstd::println("[OS] Boot module registry initialized."); + devices::storage::storage_management::init(); + kstd::println("[OS] Storage management initialized."); + kapi::system::panic("Returning from kernel main!"); } -- cgit v1.2.3 From d22f98cb70587dc451db5cfc0abd4b7fd89ee602 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 28 Feb 2026 19:09:54 +0100 Subject: small refactoring, add some todos --- .../include/devices/storage/RAMDisk/RAMDiskController.hpp | 3 ++- kernel/devices/include/devices/storage/StorageController.hpp | 4 ++++ kernel/devices/include/devices/storage/StorageManagement.hpp | 9 ++++----- 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp index 6213ed4..bb61bbc 100644 --- a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp +++ b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp @@ -17,13 +17,14 @@ namespace devices::storage::ram_disk explicit ram_disk_controller(kapi::boot_modules::boot_module_registry const * registry); auto probe() -> void override; + auto devices_count() -> size_t override; private: auto create_device_from_boot_module(kapi::boot_modules::boot_module const & module) -> void; kapi::boot_modules::boot_module_registry const * m_boot_module_registry; - std::array m_devices{}; // TODO BA-FS26 use kstd::vector + std::array m_devices{}; // TODO BA-FS26 use kstd::vector when available }; } // namespace devices::storage::ram_disk diff --git a/kernel/devices/include/devices/storage/StorageController.hpp b/kernel/devices/include/devices/storage/StorageController.hpp index 7904d07..68c6907 100644 --- a/kernel/devices/include/devices/storage/StorageController.hpp +++ b/kernel/devices/include/devices/storage/StorageController.hpp @@ -9,7 +9,11 @@ namespace devices::storage virtual ~storage_controller() = default; virtual auto probe() -> void = 0; + virtual auto devices_count() -> size_t = 0; + + // TODO BA-FS26 + // virtual auto get_device(size_t index) -> std::optional = 0; }; } // namespace devices::storage diff --git a/kernel/devices/include/devices/storage/StorageManagement.hpp b/kernel/devices/include/devices/storage/StorageManagement.hpp index 9098312..c237245 100644 --- a/kernel/devices/include/devices/storage/StorageManagement.hpp +++ b/kernel/devices/include/devices/storage/StorageManagement.hpp @@ -8,22 +8,21 @@ namespace devices::storage { + // TODO BA-FS26 add documentation struct storage_management { - // TODO BA-FS26 add documentation - auto static init() -> void; + auto static get() -> storage_management &; auto add_controller(storage_controller * controller) -> void; - auto add_device(block_device * device) -> void; private: storage_management() = default; - std::array m_controllers{}; // TODO BA-FS26 use kstd::vector - std::array m_devices{}; // TODO BA-FS26 use kstd::vector + std::array m_controllers{}; // TODO BA-FS26 use kstd::vector when available + std::array m_devices{}; // TODO BA-FS26 use kstd::vector when available }; } // namespace devices::storage -- cgit v1.2.3 From 47d94c6e1c0c46a9c5cdce528c8dca588a531595 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 28 Feb 2026 19:15:38 +0100 Subject: implement first draft of RAMDiskDevice --- kernel/devices/include/devices/BlockDevice.hpp | 5 ++++ .../devices/storage/RAMDisk/RAMDiskDevice.hpp | 18 +++++++++++- .../src/storage/RAMDisk/RAMDiskController.cpp | 15 +++++++--- .../devices/src/storage/RAMDisk/RAMDiskDevice.cpp | 34 +++++++++++++++++++++- 4 files changed, 66 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/BlockDevice.hpp b/kernel/devices/include/devices/BlockDevice.hpp index db66683..69d7f81 100644 --- a/kernel/devices/include/devices/BlockDevice.hpp +++ b/kernel/devices/include/devices/BlockDevice.hpp @@ -1,10 +1,15 @@ #ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP #define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP +#include + namespace devices { struct block_device { + virtual ~block_device() = default; + + virtual auto read_block(size_t block_index, void * buffer) const -> void = 0; }; } // namespace devices diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp index 98471cf..aa736a4 100644 --- a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp +++ b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp @@ -1,10 +1,26 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_DEVICE_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_DEVICE_HPP +#include "kapi/memory.hpp" + +#include "devices/BlockDevice.hpp" + +#include + namespace devices::storage::ram_disk { - struct ram_disk_device + struct ram_disk_device : block_device { + constexpr size_t static block_size = 512uz; // TODO BA-FS26 really correct / good?? + + ram_disk_device() = default; + ram_disk_device(kapi::memory::linear_address data_start, size_t data_size); + + auto read_block(size_t block_index, void * buffer) const -> void override; + + private: + kapi::memory::linear_address m_data_start{}; + size_t m_data_size{}; }; } // namespace devices::storage::ram_disk diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp index 3e12e0d..48b9116 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp @@ -3,6 +3,8 @@ #include "kapi/boot_module/boot_module.hpp" #include "kapi/boot_module/boot_module_registry.hpp" +#include "devices/storage/RAMDisk/RAMDiskDevice.hpp" + #include #include @@ -18,16 +20,21 @@ namespace devices::storage::ram_disk { std::ranges::for_each(*m_boot_module_registry, [this](auto const & module) { create_device_from_boot_module(module); }); - } - auto ram_disk_controller::devices_count() -> size_t - { - return m_devices.size(); + // TODO BA-FS26 just for testing, remove again + std::ranges::for_each(m_devices, [](auto const & device) { device.read_block(0, nullptr); }); } auto ram_disk_controller::create_device_from_boot_module(kapi::boot_modules::boot_module const & module) -> void { + m_devices.at(0) = ram_disk_device{module.start_address, module.size}; + kstd::println("[RAM DISK CONTROLLER] Found boot module: {} at address {} with size {} bytes", module.name, module.start_address, module.size); } + + auto ram_disk_controller::devices_count() -> size_t + { + return m_devices.size(); + } } // namespace devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp index 8d8f51e..1e650d8 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp @@ -1,6 +1,38 @@ #include "devices/storage/RAMDisk/RAMDiskDevice.hpp" +#include "kapi/memory.hpp" +#include "kapi/system.hpp" + +#include + +#include + namespace devices::storage::ram_disk { - // TODO BA-FS26 implement ram disk device functionality + ram_disk_device::ram_disk_device(kapi::memory::linear_address data_start, size_t data_size) + : m_data_start(data_start) + , m_data_size(data_size) + {} + + 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 offset = block_index * block_size; + if (offset + block_size > + m_data_size) // TODO BA-FS26 really correct, what if block_size doesn't divide m_data_size? + { + kapi::system::panic("[RAM DISK DEVICE] read_block out of bounds."); + } + + auto const source = static_cast(m_data_start) + offset; + for (size_t i = 0; i < block_size; ++i) + { + kstd::println("address: {}, value: {}", source + i, std::to_integer(*(source + i))); + } + // std::memcpy(buffer, source, block_size); + } } // namespace devices::storage::ram_disk \ No newline at end of file -- cgit v1.2.3 From 9c24c688f945173b5265f6142df2ae377e5dbc18 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 1 Mar 2026 17:42:36 +0100 Subject: refactoring, remove test code --- .../devices/storage/RAMDisk/RAMDiskDevice.hpp | 6 +++--- .../src/storage/RAMDisk/RAMDiskController.cpp | 8 +------- .../devices/src/storage/RAMDisk/RAMDiskDevice.cpp | 23 +++++++++++----------- 3 files changed, 15 insertions(+), 22 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp index aa736a4..eb88f86 100644 --- a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp +++ b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_DEVICE_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_DEVICE_HPP -#include "kapi/memory.hpp" +#include "kapi/boot_module/boot_module.hpp" #include "devices/BlockDevice.hpp" @@ -14,12 +14,12 @@ namespace devices::storage::ram_disk constexpr size_t static block_size = 512uz; // TODO BA-FS26 really correct / good?? ram_disk_device() = default; - ram_disk_device(kapi::memory::linear_address data_start, size_t data_size); + ram_disk_device(kapi::boot_modules::boot_module const & module); auto read_block(size_t block_index, void * buffer) const -> void override; private: - kapi::memory::linear_address m_data_start{}; + kapi::boot_modules::boot_module m_boot_module{}; size_t m_data_size{}; }; } // namespace devices::storage::ram_disk diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp index 48b9116..90a7c0f 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp @@ -20,17 +20,11 @@ namespace devices::storage::ram_disk { std::ranges::for_each(*m_boot_module_registry, [this](auto const & module) { create_device_from_boot_module(module); }); - - // TODO BA-FS26 just for testing, remove again - std::ranges::for_each(m_devices, [](auto const & device) { device.read_block(0, nullptr); }); } auto ram_disk_controller::create_device_from_boot_module(kapi::boot_modules::boot_module const & module) -> void { - m_devices.at(0) = ram_disk_device{module.start_address, module.size}; - - kstd::println("[RAM DISK CONTROLLER] Found boot module: {} at address {} with size {} bytes", module.name, - module.start_address, module.size); + m_devices.at(0) = ram_disk_device{module}; } auto ram_disk_controller::devices_count() -> size_t diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp index 1e650d8..82a3cdf 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp @@ -1,6 +1,6 @@ #include "devices/storage/RAMDisk/RAMDiskDevice.hpp" -#include "kapi/memory.hpp" +#include "kapi/boot_module/boot_module.hpp" #include "kapi/system.hpp" #include @@ -9,26 +9,25 @@ namespace devices::storage::ram_disk { - ram_disk_device::ram_disk_device(kapi::memory::linear_address data_start, size_t data_size) - : m_data_start(data_start) - , m_data_size(data_size) + ram_disk_device::ram_disk_device(kapi::boot_modules::boot_module const & module) + : m_boot_module(module) {} - auto ram_disk_device::read_block(size_t block_index, void * /*buffer*/) const -> void + 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."); - // } + if (buffer == nullptr) + { + kapi::system::panic("[RAM DISK DEVICE] read_block called with null buffer."); + } auto const offset = block_index * block_size; - if (offset + block_size > - m_data_size) // TODO BA-FS26 really correct, what if block_size doesn't divide m_data_size? + // TODO BA-FS26 really correct, what if block_size doesn't divide m_boot_module.size? + if (offset + block_size > m_boot_module.size) { kapi::system::panic("[RAM DISK DEVICE] read_block out of bounds."); } - auto const source = static_cast(m_data_start) + offset; + auto const source = static_cast(m_boot_module.start_address) + offset; for (size_t i = 0; i < block_size; ++i) { kstd::println("address: {}, value: {}", source + i, std::to_integer(*(source + i))); -- cgit v1.2.3 From 9a1b7e18ad2d9c81e176802d9e922baa882a565d Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 1 Mar 2026 17:45:33 +0100 Subject: use stl algorithm --- kernel/devices/src/storage/StorageManagement.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/src/storage/StorageManagement.cpp b/kernel/devices/src/storage/StorageManagement.cpp index 9cc9a06..2daae0a 100644 --- a/kernel/devices/src/storage/StorageManagement.cpp +++ b/kernel/devices/src/storage/StorageManagement.cpp @@ -7,6 +7,7 @@ #include "devices/storage/RAMDisk/RAMDiskController.hpp" #include "devices/storage/StorageController.hpp" +#include #include namespace devices::storage @@ -28,10 +29,7 @@ namespace devices::storage active_ram_disk_controller.emplace(&kapi::boot_modules::get_boot_module_registry()); active_storage_management->add_controller(&active_ram_disk_controller.value()); - for (auto controller : active_storage_management->m_controllers) - { - controller->probe(); - } + std::ranges::for_each(active_storage_management->m_controllers, [](auto controller) { controller->probe(); }); } auto storage_management::get() -> storage_management & -- cgit v1.2.3 From 760f6ca4d59f6bf90f70944df4f418c236f8eab1 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 2 Mar 2026 23:41:56 +0100 Subject: remove not needed m_data_size member --- kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp | 1 - 1 file changed, 1 deletion(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp index eb88f86..fdcef3f 100644 --- a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp +++ b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp @@ -20,7 +20,6 @@ namespace devices::storage::ram_disk private: kapi::boot_modules::boot_module m_boot_module{}; - size_t m_data_size{}; }; } // namespace devices::storage::ram_disk -- cgit v1.2.3 From 9eeaf95fcc6b2d6302d8447940678e1597d26f0a Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 2 Mar 2026 23:44:53 +0100 Subject: copy data into the buffer in ram_disk_device::read_block --- kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp index 82a3cdf..339e7fa 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp @@ -3,7 +3,7 @@ #include "kapi/boot_module/boot_module.hpp" #include "kapi/system.hpp" -#include +#include #include @@ -20,18 +20,12 @@ namespace devices::storage::ram_disk kapi::system::panic("[RAM DISK DEVICE] read_block called with null buffer."); } - auto const offset = block_index * block_size; - // TODO BA-FS26 really correct, what if block_size doesn't divide m_boot_module.size? - if (offset + block_size > m_boot_module.size) - { - kapi::system::panic("[RAM DISK DEVICE] read_block out of bounds."); - } + // TODO BA-FS26 add bounds checking based on module size? + // TODO BA-FS26 fill with 0 after the end of the module, if the block extends beyond it? + auto const offset = block_index * block_size; auto const source = static_cast(m_boot_module.start_address) + offset; - for (size_t i = 0; i < block_size; ++i) - { - kstd::println("address: {}, value: {}", source + i, std::to_integer(*(source + i))); - } - // std::memcpy(buffer, source, block_size); + + kstd::libc::memcpy(buffer, source, block_size); } } // namespace devices::storage::ram_disk \ No newline at end of file -- cgit v1.2.3 From d2e9e3ee57918ddd4a1f81e70304dc15964555ff Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 3 Mar 2026 08:37:56 +0100 Subject: implement function to get a device by major and minor number --- kernel/devices/include/devices/BlockDevice.hpp | 4 +++- kernel/devices/include/devices/Device.hpp | 9 +++++++++ .../include/devices/storage/RAMDisk/RAMDiskController.hpp | 2 ++ .../devices/include/devices/storage/StorageController.hpp | 7 ++++--- .../devices/include/devices/storage/StorageManagement.hpp | 4 ++-- kernel/devices/src/Device.cpp | 13 ++++++++++++- kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp | 15 +++++++++++++++ kernel/devices/src/storage/StorageManagement.cpp | 12 ++++++++++-- 8 files changed, 57 insertions(+), 9 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/BlockDevice.hpp b/kernel/devices/include/devices/BlockDevice.hpp index 69d7f81..9e9ef08 100644 --- a/kernel/devices/include/devices/BlockDevice.hpp +++ b/kernel/devices/include/devices/BlockDevice.hpp @@ -1,11 +1,13 @@ #ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP #define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP +#include "devices/Device.hpp" + #include namespace devices { - struct block_device + struct block_device : device { virtual ~block_device() = default; diff --git a/kernel/devices/include/devices/Device.hpp b/kernel/devices/include/devices/Device.hpp index a3cac42..815049f 100644 --- a/kernel/devices/include/devices/Device.hpp +++ b/kernel/devices/include/devices/Device.hpp @@ -1,10 +1,19 @@ #ifndef TEACH_OS_KERNEL_DEVICES_DEVICE_HPP #define TEACH_OS_KERNEL_DEVICES_DEVICE_HPP +#include namespace devices { struct device { + virtual ~device() = default; + + auto major() const -> size_t; + auto minor() const -> size_t; + + private: + size_t m_major = 0; // TODO BA-FS26 initialize correctly + size_t m_minor = 0; // TODO BA-FS26 initialize correctly }; } // namespace devices diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp index bb61bbc..7d656b1 100644 --- a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp +++ b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp @@ -4,6 +4,7 @@ #include "kapi/boot_module/boot_module.hpp" #include "kapi/boot_module/boot_module_registry.hpp" +#include "devices/BlockDevice.hpp" #include "devices/storage/RAMDisk/RAMDiskDevice.hpp" #include "devices/storage/StorageController.hpp" @@ -19,6 +20,7 @@ namespace devices::storage::ram_disk auto probe() -> void override; auto devices_count() -> size_t override; + auto device_by_major_minor(size_t major, size_t minor) -> block_device * override; private: auto create_device_from_boot_module(kapi::boot_modules::boot_module const & module) -> void; diff --git a/kernel/devices/include/devices/storage/StorageController.hpp b/kernel/devices/include/devices/storage/StorageController.hpp index 68c6907..a51683d 100644 --- a/kernel/devices/include/devices/storage/StorageController.hpp +++ b/kernel/devices/include/devices/storage/StorageController.hpp @@ -1,7 +1,10 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP +#include "devices/BlockDevice.hpp" + #include + namespace devices::storage { struct storage_controller @@ -11,9 +14,7 @@ namespace devices::storage virtual auto probe() -> void = 0; virtual auto devices_count() -> size_t = 0; - - // TODO BA-FS26 - // virtual auto get_device(size_t index) -> std::optional = 0; + virtual auto device_by_major_minor(size_t major, size_t minor) -> block_device * = 0; }; } // namespace devices::storage diff --git a/kernel/devices/include/devices/storage/StorageManagement.hpp b/kernel/devices/include/devices/storage/StorageManagement.hpp index c237245..632ff19 100644 --- a/kernel/devices/include/devices/storage/StorageManagement.hpp +++ b/kernel/devices/include/devices/storage/StorageManagement.hpp @@ -5,6 +5,7 @@ #include "devices/storage/StorageController.hpp" #include +#include namespace devices::storage { @@ -16,13 +17,12 @@ namespace devices::storage auto static get() -> storage_management &; auto add_controller(storage_controller * controller) -> void; - auto add_device(block_device * device) -> void; + auto device_by_major_minor(size_t major, size_t minor) -> block_device *; private: storage_management() = default; std::array m_controllers{}; // TODO BA-FS26 use kstd::vector when available - std::array m_devices{}; // TODO BA-FS26 use kstd::vector when available }; } // namespace devices::storage diff --git a/kernel/devices/src/Device.cpp b/kernel/devices/src/Device.cpp index d755fb9..48ba29b 100644 --- a/kernel/devices/src/Device.cpp +++ b/kernel/devices/src/Device.cpp @@ -1,6 +1,17 @@ #include "devices/Device.hpp" +#include + namespace devices { - // TODO BA-FS26 implement device functionality + + auto device::major() const -> size_t + { + return m_major; + } + + auto device::minor() const -> size_t + { + return m_minor; + } } // namespace devices \ No newline at end of file diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp index 90a7c0f..ec2cb97 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp @@ -3,12 +3,15 @@ #include "kapi/boot_module/boot_module.hpp" #include "kapi/boot_module/boot_module_registry.hpp" +#include "devices/BlockDevice.hpp" #include "devices/storage/RAMDisk/RAMDiskDevice.hpp" #include #include +#include #include +#include namespace devices::storage::ram_disk { @@ -27,6 +30,18 @@ namespace devices::storage::ram_disk m_devices.at(0) = ram_disk_device{module}; } + auto ram_disk_controller::device_by_major_minor(size_t major, size_t minor) -> block_device * + { + auto it = std::ranges::find_if( + m_devices, [major, minor](auto const & device) { return device.major() == major && device.minor() == minor; }); + + if (it != m_devices.end()) + { + return &(*it); + } + return nullptr; + } + auto ram_disk_controller::devices_count() -> size_t { return m_devices.size(); diff --git a/kernel/devices/src/storage/StorageManagement.cpp b/kernel/devices/src/storage/StorageManagement.cpp index 2daae0a..cfc5239 100644 --- a/kernel/devices/src/storage/StorageManagement.cpp +++ b/kernel/devices/src/storage/StorageManagement.cpp @@ -8,6 +8,7 @@ #include "devices/storage/StorageController.hpp" #include +#include #include namespace devices::storage @@ -47,9 +48,16 @@ namespace devices::storage m_controllers.at(0) = controller; // TODO BA-FS26 use push_back from kstd:vector } - auto storage_management::add_device(block_device * device) -> void + auto storage_management::device_by_major_minor(size_t major, size_t minor) -> block_device * { - m_devices.at(0) = device; // TODO BA-FS26 use push_back from kstd:vector + block_device * found = nullptr; + + std::ranges::find_if(m_controllers, [&](auto const controller) { + found = controller->device_by_major_minor(major, minor); + return found != nullptr; + }); + + return found; } } // namespace devices::storage \ No newline at end of file -- cgit v1.2.3 From 52a007ebee4e8ca284ec5767de01c311e9f1860e Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 3 Mar 2026 10:15:20 +0100 Subject: implement major and minor analog to the linux kernel --- kernel/devices/include/devices/BlockDevice.hpp | 1 + kernel/devices/include/devices/Device.hpp | 6 ++++-- .../include/devices/storage/RAMDisk/RAMDiskDevice.hpp | 4 ++-- .../include/devices/storage/StorageController.hpp | 7 +++++++ kernel/devices/src/BlockDevice.cpp | 8 +++++++- kernel/devices/src/Device.cpp | 4 ++++ .../devices/src/storage/RAMDisk/RAMDiskController.cpp | 11 +++++++++++ kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp | 11 +++++++++-- kernel/devices/src/storage/StorageController.cpp | 17 +++++++++++++++++ kernel/devices/src/storage/StorageManagement.cpp | 12 ++++++++++-- 10 files changed, 72 insertions(+), 9 deletions(-) create mode 100644 kernel/devices/src/storage/StorageController.cpp (limited to 'kernel') diff --git a/kernel/devices/include/devices/BlockDevice.hpp b/kernel/devices/include/devices/BlockDevice.hpp index 9e9ef08..2f9d0aa 100644 --- a/kernel/devices/include/devices/BlockDevice.hpp +++ b/kernel/devices/include/devices/BlockDevice.hpp @@ -9,6 +9,7 @@ namespace devices { struct block_device : device { + block_device(size_t major, size_t minor); virtual ~block_device() = default; virtual auto read_block(size_t block_index, void * buffer) const -> void = 0; diff --git a/kernel/devices/include/devices/Device.hpp b/kernel/devices/include/devices/Device.hpp index 815049f..0f93bff 100644 --- a/kernel/devices/include/devices/Device.hpp +++ b/kernel/devices/include/devices/Device.hpp @@ -2,18 +2,20 @@ #define TEACH_OS_KERNEL_DEVICES_DEVICE_HPP #include + namespace devices { struct device { + device(size_t major, size_t minor); virtual ~device() = default; auto major() const -> size_t; auto minor() const -> size_t; private: - size_t m_major = 0; // TODO BA-FS26 initialize correctly - size_t m_minor = 0; // TODO BA-FS26 initialize correctly + size_t m_major; + size_t m_minor; }; } // namespace devices diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp index fdcef3f..de71663 100644 --- a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp +++ b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp @@ -13,8 +13,8 @@ namespace devices::storage::ram_disk { constexpr size_t static block_size = 512uz; // TODO BA-FS26 really correct / good?? - ram_disk_device() = default; - ram_disk_device(kapi::boot_modules::boot_module const & module); + ram_disk_device(); // TODO BA-FS26 remove when kstd::vector is available + ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor); auto read_block(size_t block_index, void * buffer) const -> void override; diff --git a/kernel/devices/include/devices/storage/StorageController.hpp b/kernel/devices/include/devices/storage/StorageController.hpp index a51683d..50fdb34 100644 --- a/kernel/devices/include/devices/storage/StorageController.hpp +++ b/kernel/devices/include/devices/storage/StorageController.hpp @@ -13,8 +13,15 @@ namespace devices::storage virtual auto probe() -> void = 0; + auto set_ids(size_t major, size_t minors_per_dev) -> void; + auto major() const -> size_t; + virtual auto devices_count() -> size_t = 0; virtual auto device_by_major_minor(size_t major, size_t minor) -> block_device * = 0; + + protected: + size_t m_major{}; + size_t m_minors_per_device{}; }; } // namespace devices::storage diff --git a/kernel/devices/src/BlockDevice.cpp b/kernel/devices/src/BlockDevice.cpp index 970f7b2..6d43073 100644 --- a/kernel/devices/src/BlockDevice.cpp +++ b/kernel/devices/src/BlockDevice.cpp @@ -1,6 +1,12 @@ #include "devices/BlockDevice.hpp" +#include "devices/Device.hpp" + +#include + namespace devices { - // TODO BA-FS26 implement block device functionality + block_device::block_device(size_t major, size_t minor) + : device(major, minor) + {} } // namespace devices \ No newline at end of file diff --git a/kernel/devices/src/Device.cpp b/kernel/devices/src/Device.cpp index 48ba29b..38fdd48 100644 --- a/kernel/devices/src/Device.cpp +++ b/kernel/devices/src/Device.cpp @@ -4,6 +4,10 @@ namespace devices { + device::device(size_t major, size_t minor) + : m_major(major) + , m_minor(minor) + {} auto device::major() const -> size_t { diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp index ec2cb97..1f70e2d 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp @@ -21,6 +21,17 @@ namespace devices::storage::ram_disk auto ram_disk_controller::probe() -> void { + size_t current_device_index = 0; // Starte bei 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; + + // TODO BA-FS26 use push_back from kstd::vector when available + m_devices.at(0) = ram_disk_device{module, m_major, minor}; + + current_device_index++; + }); + std::ranges::for_each(*m_boot_module_registry, [this](auto const & module) { create_device_from_boot_module(module); }); } diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp index 339e7fa..f33cf94 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp @@ -3,14 +3,21 @@ #include "kapi/boot_module/boot_module.hpp" #include "kapi/system.hpp" +#include "devices/BlockDevice.hpp" + #include #include namespace devices::storage::ram_disk { - ram_disk_device::ram_disk_device(kapi::boot_modules::boot_module const & module) - : m_boot_module(module) + ram_disk_device::ram_disk_device() // TODO BA-FS26 remove when kstd::vector is available + : block_device(0, 0) + {} + + ram_disk_device::ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor) + : block_device(major, minor) + , m_boot_module(module) {} auto ram_disk_device::read_block(size_t block_index, void * buffer) const -> void diff --git a/kernel/devices/src/storage/StorageController.cpp b/kernel/devices/src/storage/StorageController.cpp new file mode 100644 index 0000000..d11a175 --- /dev/null +++ b/kernel/devices/src/storage/StorageController.cpp @@ -0,0 +1,17 @@ +#include "devices/storage/StorageController.hpp" + +#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; + } +} // namespace devices::storage \ No newline at end of file diff --git a/kernel/devices/src/storage/StorageManagement.cpp b/kernel/devices/src/storage/StorageManagement.cpp index cfc5239..58d8510 100644 --- a/kernel/devices/src/storage/StorageManagement.cpp +++ b/kernel/devices/src/storage/StorageManagement.cpp @@ -15,6 +15,9 @@ namespace devices::storage { namespace { + constexpr size_t static MINORS_PER_DEVICE = 16; + constinit size_t static next_free_major = 1; + constinit auto static active_storage_management = std::optional{}; constinit auto static active_ram_disk_controller = std::optional{}; } // namespace @@ -45,6 +48,7 @@ namespace devices::storage auto storage_management::add_controller(storage_controller * controller) -> void { + controller->set_ids(next_free_major++, MINORS_PER_DEVICE); m_controllers.at(0) = controller; // TODO BA-FS26 use push_back from kstd:vector } @@ -53,8 +57,12 @@ namespace devices::storage block_device * found = nullptr; std::ranges::find_if(m_controllers, [&](auto const controller) { - found = controller->device_by_major_minor(major, minor); - return found != nullptr; + if (controller != nullptr && controller->major() == major) + { + found = controller->device_by_major_minor(major, minor); + return found != nullptr; + } + return false; }); return found; -- cgit v1.2.3 From a8ebcdb0d16fe224d8f05577ea367864cb2fa9c2 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 3 Mar 2026 10:24:23 +0100 Subject: fix build add test code to read a block from device --- .../devices/storage/RAMDisk/RAMDiskController.hpp | 2 -- .../src/storage/RAMDisk/RAMDiskController.cpp | 26 ++++++++++++++-------- 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp index 7d656b1..699c547 100644 --- a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp +++ b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp @@ -23,8 +23,6 @@ namespace devices::storage::ram_disk auto device_by_major_minor(size_t major, size_t minor) -> block_device * override; private: - auto create_device_from_boot_module(kapi::boot_modules::boot_module const & module) -> void; - kapi::boot_modules::boot_module_registry const * m_boot_module_registry; std::array m_devices{}; // TODO BA-FS26 use kstd::vector when available }; diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp index 1f70e2d..1235c46 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp @@ -24,21 +24,29 @@ namespace devices::storage::ram_disk size_t current_device_index = 0; // Starte bei 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; + auto const minor = current_device_index++ * m_minors_per_device; // TODO BA-FS26 use push_back from kstd::vector when available m_devices.at(0) = ram_disk_device{module, m_major, minor}; - - current_device_index++; }); - std::ranges::for_each(*m_boot_module_registry, - [this](auto const & module) { create_device_from_boot_module(module); }); - } + std::ranges::for_each(m_devices, [](auto device) { + std::array buffer{}; + device.read_block(0, buffer.data()); - auto ram_disk_controller::create_device_from_boot_module(kapi::boot_modules::boot_module const & module) -> void - { - m_devices.at(0) = ram_disk_device{module}; + kstd::println("Contents of Block 0 for device:"); + + for (size_t i = 0; i < buffer.size(); ++i) + { + kstd::print("{:02x} ", static_cast(buffer[i])); + + if ((i + 1) % 16 == 0) + { + kstd::println(""); + } + } + kstd::println("--- End of Block ---"); + }); } auto ram_disk_controller::device_by_major_minor(size_t major, size_t minor) -> block_device * -- cgit v1.2.3 From 14d06ffce75625c8cd0cfa705d33c410fc934937 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 3 Mar 2026 10:37:53 +0100 Subject: fix build, refactoring --- kernel/devices/CMakeLists.txt | 1 + kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp | 1 - kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp | 3 +-- 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/CMakeLists.txt b/kernel/devices/CMakeLists.txt index 0707a03..8022dee 100644 --- a/kernel/devices/CMakeLists.txt +++ b/kernel/devices/CMakeLists.txt @@ -4,6 +4,7 @@ add_library("kernel::devices" ALIAS "kernel_devices") target_sources("kernel_devices" PRIVATE "src/Device.cpp" "src/BlockDevice.cpp" + "src/storage/StorageController.cpp" "src/storage/StorageManagement.cpp" "src/storage/RAMDisk/RAMDiskController.cpp" "src/storage/RAMDisk/RAMDiskDevice.cpp" diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp index 699c547..3e6e2bd 100644 --- a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp +++ b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp @@ -1,7 +1,6 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP -#include "kapi/boot_module/boot_module.hpp" #include "kapi/boot_module/boot_module_registry.hpp" #include "devices/BlockDevice.hpp" diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp index 1235c46..d76f2cd 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp @@ -1,6 +1,5 @@ #include "devices/storage/RAMDisk/RAMDiskController.hpp" -#include "kapi/boot_module/boot_module.hpp" #include "kapi/boot_module/boot_module_registry.hpp" #include "devices/BlockDevice.hpp" @@ -21,7 +20,7 @@ namespace devices::storage::ram_disk auto ram_disk_controller::probe() -> void { - size_t current_device_index = 0; // Starte bei 0 + 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; -- cgit v1.2.3 From 43875979efea5dd73f63ac66c4fcc697c752f6ef Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 3 Mar 2026 11:20:22 +0100 Subject: implement write_block in RAMDiskDevice --- kernel/devices/include/devices/BlockDevice.hpp | 1 + .../include/devices/storage/RAMDisk/RAMDiskDevice.hpp | 1 + kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp | 16 ++++++++++++++++ 3 files changed, 18 insertions(+) (limited to 'kernel') diff --git a/kernel/devices/include/devices/BlockDevice.hpp b/kernel/devices/include/devices/BlockDevice.hpp index 2f9d0aa..65d765b 100644 --- a/kernel/devices/include/devices/BlockDevice.hpp +++ b/kernel/devices/include/devices/BlockDevice.hpp @@ -13,6 +13,7 @@ namespace devices virtual ~block_device() = default; virtual auto read_block(size_t block_index, void * buffer) const -> void = 0; + virtual auto write_block(size_t block_index, void const * buffer) -> void = 0; }; } // namespace devices diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp index de71663..b3838e4 100644 --- a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp +++ b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp @@ -17,6 +17,7 @@ namespace devices::storage::ram_disk ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor); auto read_block(size_t block_index, void * buffer) const -> void override; + auto write_block(size_t block_index, void const * buffer) -> void override; private: kapi::boot_modules::boot_module m_boot_module{}; diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp index f33cf94..1bc475d 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp @@ -35,4 +35,20 @@ namespace devices::storage::ram_disk kstd::libc::memcpy(buffer, source, block_size); } + + 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."); + } + + // TODO BA-FS26 add bounds checking based on module size? + // TODO BA-FS26 ignore writes beyond the end of the module? + + auto const offset = block_index * block_size; + auto const destination = static_cast(m_boot_module.start_address) + offset; + + kstd::libc::memcpy(destination, buffer, block_size); + } } // namespace devices::storage::ram_disk \ No newline at end of file -- cgit v1.2.3 From e9839b25356c420193cf8b90ed5043eb07aabff0 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 3 Mar 2026 12:42:40 +0100 Subject: remove test code --- .../devices/src/storage/RAMDisk/RAMDiskController.cpp | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp index d76f2cd..5c18dac 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp @@ -10,7 +10,6 @@ #include #include #include -#include namespace devices::storage::ram_disk { @@ -28,24 +27,6 @@ namespace devices::storage::ram_disk // TODO BA-FS26 use push_back from kstd::vector when available m_devices.at(0) = ram_disk_device{module, m_major, minor}; }); - - std::ranges::for_each(m_devices, [](auto device) { - std::array buffer{}; - device.read_block(0, buffer.data()); - - kstd::println("Contents of Block 0 for device:"); - - for (size_t i = 0; i < buffer.size(); ++i) - { - kstd::print("{:02x} ", static_cast(buffer[i])); - - if ((i + 1) % 16 == 0) - { - kstd::println(""); - } - } - kstd::println("--- End of Block ---"); - }); } auto ram_disk_controller::device_by_major_minor(size_t major, size_t minor) -> block_device * -- cgit v1.2.3 From 880cd2194507c95449949f799d48a4b8ff3e0cd5 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 3 Mar 2026 13:52:30 +0100 Subject: implement determine_boot_device --- kernel/devices/include/devices/storage/StorageManagement.hpp | 2 ++ kernel/devices/src/storage/StorageManagement.cpp | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/storage/StorageManagement.hpp b/kernel/devices/include/devices/storage/StorageManagement.hpp index 632ff19..226fb28 100644 --- a/kernel/devices/include/devices/storage/StorageManagement.hpp +++ b/kernel/devices/include/devices/storage/StorageManagement.hpp @@ -17,7 +17,9 @@ namespace devices::storage auto static get() -> storage_management &; auto add_controller(storage_controller * controller) -> void; + auto device_by_major_minor(size_t major, size_t minor) -> block_device *; + auto determine_boot_device() -> block_device *; private: storage_management() = default; diff --git a/kernel/devices/src/storage/StorageManagement.cpp b/kernel/devices/src/storage/StorageManagement.cpp index 58d8510..1b0d2cc 100644 --- a/kernel/devices/src/storage/StorageManagement.cpp +++ b/kernel/devices/src/storage/StorageManagement.cpp @@ -16,7 +16,8 @@ namespace devices::storage namespace { constexpr size_t static MINORS_PER_DEVICE = 16; - constinit size_t static next_free_major = 1; + 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 active_ram_disk_controller = std::optional{}; @@ -68,4 +69,10 @@ namespace devices::storage return found; } + auto storage_management::determine_boot_device() -> block_device * + { + // TODO BA-FS26 better way? + return device_by_major_minor(START_MAJOR, 0); + } + } // namespace devices::storage \ No newline at end of file -- cgit v1.2.3 From 1883c8bbcbd2aeff57ce8f2dac1289f68418bbc7 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 3 Mar 2026 13:54:48 +0100 Subject: handle read / write behind module boundaries --- .../devices/src/storage/RAMDisk/RAMDiskDevice.cpp | 33 +++++++++++++++------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp index 1bc475d..627641c 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp @@ -27,13 +27,22 @@ namespace devices::storage::ram_disk kapi::system::panic("[RAM DISK DEVICE] read_block called with null buffer."); } - // TODO BA-FS26 add bounds checking based on module size? - // TODO BA-FS26 fill with 0 after the end of the module, if the block extends beyond it? + size_t const offset = block_index * block_size; + size_t const limit = m_boot_module.size; - auto const offset = block_index * block_size; - auto const source = static_cast(m_boot_module.start_address) + offset; + size_t const available = (offset < limit) ? (limit - offset) : 0; + size_t const to_copy = (available < block_size) ? available : block_size; - kstd::libc::memcpy(buffer, source, block_size); + if (to_copy > 0) + { + auto const source = static_cast(m_boot_module.start_address) + offset; + kstd::libc::memcpy(buffer, source, to_copy); + } + + if (to_copy < block_size) + { + kstd::libc::memset(static_cast(buffer) + to_copy, std::byte{0}, block_size - to_copy); + } } auto ram_disk_device::write_block(size_t block_index, void const * buffer) -> void @@ -43,12 +52,16 @@ namespace devices::storage::ram_disk kapi::system::panic("[RAM DISK DEVICE] write_block called with null buffer."); } - // TODO BA-FS26 add bounds checking based on module size? - // TODO BA-FS26 ignore writes beyond the end of the module? + size_t const offset = block_index * block_size; + size_t const limit = m_boot_module.size; - auto const offset = block_index * block_size; - auto const destination = static_cast(m_boot_module.start_address) + offset; + if (offset >= limit) + return; - kstd::libc::memcpy(destination, buffer, block_size); + size_t const available = limit - offset; + size_t const to_write = (available < block_size) ? available : block_size; + + auto const destination = static_cast(m_boot_module.start_address) + offset; + kstd::libc::memcpy(destination, buffer, to_write); } } // namespace devices::storage::ram_disk \ No newline at end of file -- cgit v1.2.3 From 2ae7a868b867289b9591d662972f559d412315c3 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 3 Mar 2026 14:11:49 +0100 Subject: refactoring read and write block calculations --- kernel/devices/include/devices/BlockDevice.hpp | 15 +++++++- .../devices/storage/RAMDisk/RAMDiskDevice.hpp | 4 +- kernel/devices/src/BlockDevice.cpp | 14 ++++++- .../devices/src/storage/RAMDisk/RAMDiskDevice.cpp | 44 +++++++++++----------- 4 files changed, 52 insertions(+), 25 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/BlockDevice.hpp b/kernel/devices/include/devices/BlockDevice.hpp index 65d765b..56e26d0 100644 --- a/kernel/devices/include/devices/BlockDevice.hpp +++ b/kernel/devices/include/devices/BlockDevice.hpp @@ -9,11 +9,24 @@ namespace devices { struct block_device : device { - block_device(size_t major, size_t minor); + block_device(size_t major, size_t minor, size_t block_size); virtual ~block_device() = default; virtual auto read_block(size_t block_index, void * buffer) const -> void = 0; virtual auto write_block(size_t block_index, void const * buffer) -> void = 0; + + protected: + struct transfer_info + { + size_t offset; + size_t to_transfer; + size_t remainder; + }; + + virtual auto size() const -> size_t = 0; + auto calculate_transfer(size_t block_index) const -> transfer_info; + + size_t m_block_size; }; } // namespace devices diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp index b3838e4..5971970 100644 --- a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp +++ b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp @@ -11,8 +11,6 @@ namespace devices::storage::ram_disk { struct ram_disk_device : block_device { - constexpr size_t static block_size = 512uz; // TODO BA-FS26 really correct / good?? - ram_disk_device(); // TODO BA-FS26 remove when kstd::vector is available ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor); @@ -20,6 +18,8 @@ namespace devices::storage::ram_disk auto write_block(size_t block_index, void const * buffer) -> void override; private: + auto size() const -> size_t override; + kapi::boot_modules::boot_module m_boot_module{}; }; } // namespace devices::storage::ram_disk diff --git a/kernel/devices/src/BlockDevice.cpp b/kernel/devices/src/BlockDevice.cpp index 6d43073..edc0109 100644 --- a/kernel/devices/src/BlockDevice.cpp +++ b/kernel/devices/src/BlockDevice.cpp @@ -6,7 +6,19 @@ namespace devices { - block_device::block_device(size_t major, size_t minor) + block_device::block_device(size_t major, size_t minor, size_t block_size) : device(major, minor) + , m_block_size(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}; + } } // namespace devices \ No newline at end of file diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp index 627641c..f3b8799 100644 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp +++ b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp @@ -11,12 +11,17 @@ namespace devices::storage::ram_disk { + namespace + { + constexpr size_t RAM_DISK_BLOCK_SIZE = 512uz; // TODO BA-FS26 really correct / good?? + } // namespace + ram_disk_device::ram_disk_device() // TODO BA-FS26 remove when kstd::vector is available - : block_device(0, 0) + : block_device(0, 0, RAM_DISK_BLOCK_SIZE) {} ram_disk_device::ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor) - : block_device(major, minor) + : block_device(major, minor, RAM_DISK_BLOCK_SIZE) , m_boot_module(module) {} @@ -27,21 +32,17 @@ namespace devices::storage::ram_disk kapi::system::panic("[RAM DISK DEVICE] read_block called with null buffer."); } - size_t const offset = block_index * block_size; - size_t const limit = m_boot_module.size; + auto const info = calculate_transfer(block_index); - size_t const available = (offset < limit) ? (limit - offset) : 0; - size_t const to_copy = (available < block_size) ? available : block_size; - - if (to_copy > 0) + if (info.to_transfer > 0) { - auto const source = static_cast(m_boot_module.start_address) + offset; - kstd::libc::memcpy(buffer, source, to_copy); + auto const src = static_cast(m_boot_module.start_address) + info.offset; + kstd::libc::memcpy(buffer, src, info.to_transfer); } - if (to_copy < block_size) + if (info.remainder > 0) { - kstd::libc::memset(static_cast(buffer) + to_copy, std::byte{0}, block_size - to_copy); + kstd::libc::memset(static_cast(buffer) + info.to_transfer, 0, info.remainder); } } @@ -52,16 +53,17 @@ namespace devices::storage::ram_disk kapi::system::panic("[RAM DISK DEVICE] write_block called with null buffer."); } - size_t const offset = block_index * block_size; - size_t const limit = m_boot_module.size; - - if (offset >= limit) - return; + auto const info = calculate_transfer(block_index); - size_t const available = limit - offset; - size_t const to_write = (available < block_size) ? available : block_size; + 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 const destination = static_cast(m_boot_module.start_address) + offset; - kstd::libc::memcpy(destination, buffer, to_write); + auto ram_disk_device::size() const -> size_t + { + return m_boot_module.size; } } // namespace devices::storage::ram_disk \ No newline at end of file -- cgit v1.2.3 From 5268bf6622463c3d233683fe56ae9977baf8eeaa Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 3 Mar 2026 16:57:02 +0100 Subject: rename files to snake_case (temp_device part1 -> renamed to device later, due to capital-/lower-letter problem) --- kernel/devices/CMakeLists.txt | 24 +++---- kernel/devices/include/devices/BlockDevice.hpp | 33 --------- kernel/devices/include/devices/Device.hpp | 22 ------ kernel/devices/include/devices/block_device.hpp | 33 +++++++++ .../devices/storage/RAMDisk/RAMDiskController.hpp | 30 --------- .../devices/storage/RAMDisk/RAMDiskDevice.hpp | 27 -------- .../include/devices/storage/StorageController.hpp | 28 -------- .../include/devices/storage/StorageManagement.hpp | 31 --------- .../storage/ram_disk/ram_disk_controller.hpp | 30 +++++++++ .../devices/storage/ram_disk/ram_disk_device.hpp | 27 ++++++++ .../include/devices/storage/storage_controller.hpp | 28 ++++++++ .../include/devices/storage/storage_management.hpp | 31 +++++++++ kernel/devices/include/devices/temp_device.hpp | 22 ++++++ kernel/devices/src/BlockDevice.cpp | 24 ------- kernel/devices/src/Device.cpp | 21 ------ kernel/devices/src/block_device.cpp | 24 +++++++ .../src/storage/RAMDisk/RAMDiskController.cpp | 48 ------------- .../devices/src/storage/RAMDisk/RAMDiskDevice.cpp | 69 ------------------- kernel/devices/src/storage/StorageController.cpp | 17 ----- kernel/devices/src/storage/StorageManagement.cpp | 78 ---------------------- .../src/storage/ram_disk/ram_disk_controller.cpp | 48 +++++++++++++ .../src/storage/ram_disk/ram_disk_device.cpp | 69 +++++++++++++++++++ kernel/devices/src/storage/storage_controller.cpp | 17 +++++ kernel/devices/src/storage/storage_management.cpp | 78 ++++++++++++++++++++++ kernel/devices/src/temp_device.cpp | 21 ++++++ kernel/src/main.cpp | 2 +- 26 files changed, 441 insertions(+), 441 deletions(-) delete mode 100644 kernel/devices/include/devices/BlockDevice.hpp delete mode 100644 kernel/devices/include/devices/Device.hpp create mode 100644 kernel/devices/include/devices/block_device.hpp delete mode 100644 kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp delete mode 100644 kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp delete mode 100644 kernel/devices/include/devices/storage/StorageController.hpp delete mode 100644 kernel/devices/include/devices/storage/StorageManagement.hpp create mode 100644 kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp create mode 100644 kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp create mode 100644 kernel/devices/include/devices/storage/storage_controller.hpp create mode 100644 kernel/devices/include/devices/storage/storage_management.hpp create mode 100644 kernel/devices/include/devices/temp_device.hpp delete mode 100644 kernel/devices/src/BlockDevice.cpp delete mode 100644 kernel/devices/src/Device.cpp create mode 100644 kernel/devices/src/block_device.cpp delete mode 100644 kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp delete mode 100644 kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp delete mode 100644 kernel/devices/src/storage/StorageController.cpp delete mode 100644 kernel/devices/src/storage/StorageManagement.cpp create mode 100644 kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp create mode 100644 kernel/devices/src/storage/ram_disk/ram_disk_device.cpp create mode 100644 kernel/devices/src/storage/storage_controller.cpp create mode 100644 kernel/devices/src/storage/storage_management.cpp create mode 100644 kernel/devices/src/temp_device.cpp (limited to 'kernel') diff --git a/kernel/devices/CMakeLists.txt b/kernel/devices/CMakeLists.txt index 8022dee..691bb11 100644 --- a/kernel/devices/CMakeLists.txt +++ b/kernel/devices/CMakeLists.txt @@ -2,24 +2,24 @@ add_library("kernel_devices" STATIC) add_library("kernel::devices" ALIAS "kernel_devices") target_sources("kernel_devices" PRIVATE - "src/Device.cpp" - "src/BlockDevice.cpp" - "src/storage/StorageController.cpp" - "src/storage/StorageManagement.cpp" - "src/storage/RAMDisk/RAMDiskController.cpp" - "src/storage/RAMDisk/RAMDiskDevice.cpp" + "src/temp_device.cpp" + "src/block_device.cpp" + "src/storage/storage_controller.cpp" + "src/storage/storage_management.cpp" + "src/storage/ram_disk/ram_disk_controller.cpp" + "src/storage/ram_disk/ram_disk_device.cpp" ) target_sources("kernel_devices" PUBLIC FILE_SET HEADERS BASE_DIRS "include" FILES - "include/devices/Device.hpp" - "include/devices/BlockDevice.hpp" - "include/devices/storage/StorageController.hpp" - "include/devices/storage/StorageManagement.hpp" - "include/devices/storage/RAMDisk/RAMDiskController.hpp" - "include/devices/storage/RAMDisk/RAMDiskDevice.hpp" + "include/devices/temp_device.hpp" + "include/devices/block_device.hpp" + "include/devices/storage/storage_controller.hpp" + "include/devices/storage/storage_management.hpp" + "include/devices/storage/ram_disk/ram_disk_controller.hpp" + "include/devices/storage/ram_disk/ram_disk_device.hpp" ) target_include_directories("kernel_devices" PUBLIC diff --git a/kernel/devices/include/devices/BlockDevice.hpp b/kernel/devices/include/devices/BlockDevice.hpp deleted file mode 100644 index 56e26d0..0000000 --- a/kernel/devices/include/devices/BlockDevice.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP -#define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP - -#include "devices/Device.hpp" - -#include - -namespace devices -{ - struct block_device : device - { - block_device(size_t major, size_t minor, size_t block_size); - virtual ~block_device() = default; - - virtual auto read_block(size_t block_index, void * buffer) const -> void = 0; - virtual auto write_block(size_t block_index, void const * buffer) -> void = 0; - - protected: - struct transfer_info - { - size_t offset; - size_t to_transfer; - size_t remainder; - }; - - virtual auto size() const -> size_t = 0; - auto calculate_transfer(size_t block_index) const -> transfer_info; - - size_t m_block_size; - }; -} // namespace devices - -#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/Device.hpp b/kernel/devices/include/devices/Device.hpp deleted file mode 100644 index 0f93bff..0000000 --- a/kernel/devices/include/devices/Device.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_DEVICE_HPP -#define TEACH_OS_KERNEL_DEVICES_DEVICE_HPP - -#include - -namespace devices -{ - struct device - { - device(size_t major, size_t minor); - virtual ~device() = default; - - auto major() const -> size_t; - auto minor() const -> size_t; - - private: - size_t m_major; - size_t m_minor; - }; -} // namespace devices - -#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/block_device.hpp b/kernel/devices/include/devices/block_device.hpp new file mode 100644 index 0000000..d1e4249 --- /dev/null +++ b/kernel/devices/include/devices/block_device.hpp @@ -0,0 +1,33 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP +#define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP + +#include "devices/temp_device.hpp" + +#include + +namespace devices +{ + struct block_device : device + { + block_device(size_t major, size_t minor, size_t block_size); + virtual ~block_device() = default; + + virtual auto read_block(size_t block_index, void * buffer) const -> void = 0; + virtual auto write_block(size_t block_index, void const * buffer) -> void = 0; + + protected: + struct transfer_info + { + size_t offset; + size_t to_transfer; + size_t remainder; + }; + + virtual auto size() const -> size_t = 0; + auto calculate_transfer(size_t block_index) const -> transfer_info; + + size_t m_block_size; + }; +} // namespace devices + +#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp deleted file mode 100644 index 3e6e2bd..0000000 --- a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskController.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP -#define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP - -#include "kapi/boot_module/boot_module_registry.hpp" - -#include "devices/BlockDevice.hpp" -#include "devices/storage/RAMDisk/RAMDiskDevice.hpp" -#include "devices/storage/StorageController.hpp" - -#include -#include - -namespace devices::storage::ram_disk -{ - struct ram_disk_controller : storage_controller - { - explicit ram_disk_controller(kapi::boot_modules::boot_module_registry const * registry); - - auto probe() -> void override; - - auto devices_count() -> size_t override; - auto device_by_major_minor(size_t major, size_t minor) -> block_device * override; - - private: - kapi::boot_modules::boot_module_registry const * m_boot_module_registry; - std::array m_devices{}; // TODO BA-FS26 use kstd::vector when available - }; -} // namespace devices::storage::ram_disk - -#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp b/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp deleted file mode 100644 index 5971970..0000000 --- a/kernel/devices/include/devices/storage/RAMDisk/RAMDiskDevice.hpp +++ /dev/null @@ -1,27 +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 "devices/BlockDevice.hpp" - -#include - -namespace devices::storage::ram_disk -{ - struct ram_disk_device : block_device - { - ram_disk_device(); // TODO BA-FS26 remove when kstd::vector is available - ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor); - - auto read_block(size_t block_index, void * buffer) const -> void override; - auto write_block(size_t block_index, void const * buffer) -> void override; - - private: - auto size() const -> size_t override; - - kapi::boot_modules::boot_module m_boot_module{}; - }; -} // namespace devices::storage::ram_disk - -#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/StorageController.hpp b/kernel/devices/include/devices/storage/StorageController.hpp deleted file mode 100644 index 50fdb34..0000000 --- a/kernel/devices/include/devices/storage/StorageController.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP -#define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP - -#include "devices/BlockDevice.hpp" - -#include - -namespace devices::storage -{ - struct storage_controller - { - virtual ~storage_controller() = default; - - virtual auto probe() -> void = 0; - - auto set_ids(size_t major, size_t minors_per_dev) -> void; - auto major() const -> size_t; - - virtual auto devices_count() -> size_t = 0; - virtual auto device_by_major_minor(size_t major, size_t minor) -> block_device * = 0; - - protected: - size_t m_major{}; - size_t m_minors_per_device{}; - }; -} // namespace devices::storage - -#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/StorageManagement.hpp b/kernel/devices/include/devices/storage/StorageManagement.hpp deleted file mode 100644 index 226fb28..0000000 --- a/kernel/devices/include/devices/storage/StorageManagement.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP -#define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP - -#include "devices/BlockDevice.hpp" -#include "devices/storage/StorageController.hpp" - -#include -#include - -namespace devices::storage -{ - // TODO BA-FS26 add documentation - struct storage_management - { - auto static init() -> void; - - auto static get() -> storage_management &; - - auto add_controller(storage_controller * controller) -> void; - - auto device_by_major_minor(size_t major, size_t minor) -> block_device *; - auto determine_boot_device() -> block_device *; - - private: - storage_management() = default; - - std::array m_controllers{}; // TODO BA-FS26 use kstd::vector when available - }; -} // namespace devices::storage - -#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp b/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp new file mode 100644 index 0000000..f050ba0 --- /dev/null +++ b/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp @@ -0,0 +1,30 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP +#define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP + +#include "kapi/boot_module/boot_module_registry.hpp" + +#include "devices/block_device.hpp" +#include "devices/storage/ram_disk/ram_disk_device.hpp" +#include "devices/storage/storage_controller.hpp" + +#include +#include + +namespace devices::storage::ram_disk +{ + struct ram_disk_controller : storage_controller + { + explicit ram_disk_controller(kapi::boot_modules::boot_module_registry const * registry); + + auto probe() -> void override; + + auto devices_count() -> size_t override; + auto device_by_major_minor(size_t major, size_t minor) -> block_device * override; + + private: + kapi::boot_modules::boot_module_registry const * m_boot_module_registry; + std::array m_devices{}; // TODO BA-FS26 use kstd::vector when available + }; +} // namespace devices::storage::ram_disk + +#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp b/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp new file mode 100644 index 0000000..1f0292f --- /dev/null +++ b/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp @@ -0,0 +1,27 @@ +#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 "devices/block_device.hpp" + +#include + +namespace devices::storage::ram_disk +{ + struct ram_disk_device : block_device + { + ram_disk_device(); // TODO BA-FS26 remove when kstd::vector is available + ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor); + + auto read_block(size_t block_index, void * buffer) const -> void override; + auto write_block(size_t block_index, void const * buffer) -> void override; + + private: + auto size() const -> size_t override; + + kapi::boot_modules::boot_module m_boot_module{}; + }; +} // namespace devices::storage::ram_disk + +#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/storage_controller.hpp b/kernel/devices/include/devices/storage/storage_controller.hpp new file mode 100644 index 0000000..0c09815 --- /dev/null +++ b/kernel/devices/include/devices/storage/storage_controller.hpp @@ -0,0 +1,28 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP +#define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP + +#include "devices/block_device.hpp" + +#include + +namespace devices::storage +{ + struct storage_controller + { + virtual ~storage_controller() = default; + + virtual auto probe() -> void = 0; + + auto set_ids(size_t major, size_t minors_per_dev) -> void; + auto major() const -> size_t; + + virtual auto devices_count() -> size_t = 0; + virtual auto device_by_major_minor(size_t major, size_t minor) -> block_device * = 0; + + protected: + size_t m_major{}; + size_t m_minors_per_device{}; + }; +} // namespace devices::storage + +#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/storage_management.hpp b/kernel/devices/include/devices/storage/storage_management.hpp new file mode 100644 index 0000000..c4f5679 --- /dev/null +++ b/kernel/devices/include/devices/storage/storage_management.hpp @@ -0,0 +1,31 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP +#define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP + +#include "devices/block_device.hpp" +#include "devices/storage/storage_controller.hpp" + +#include +#include + +namespace devices::storage +{ + // TODO BA-FS26 add documentation + struct storage_management + { + auto static init() -> void; + + auto static get() -> storage_management &; + + auto add_controller(storage_controller * controller) -> void; + + auto device_by_major_minor(size_t major, size_t minor) -> block_device *; + auto determine_boot_device() -> block_device *; + + private: + storage_management() = default; + + std::array m_controllers{}; // TODO BA-FS26 use kstd::vector when available + }; +} // namespace devices::storage + +#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/temp_device.hpp b/kernel/devices/include/devices/temp_device.hpp new file mode 100644 index 0000000..0f93bff --- /dev/null +++ b/kernel/devices/include/devices/temp_device.hpp @@ -0,0 +1,22 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_DEVICE_HPP +#define TEACH_OS_KERNEL_DEVICES_DEVICE_HPP + +#include + +namespace devices +{ + struct device + { + device(size_t major, size_t minor); + virtual ~device() = default; + + auto major() const -> size_t; + auto minor() const -> size_t; + + private: + size_t m_major; + size_t m_minor; + }; +} // namespace devices + +#endif \ No newline at end of file diff --git a/kernel/devices/src/BlockDevice.cpp b/kernel/devices/src/BlockDevice.cpp deleted file mode 100644 index edc0109..0000000 --- a/kernel/devices/src/BlockDevice.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "devices/BlockDevice.hpp" - -#include "devices/Device.hpp" - -#include - -namespace devices -{ - block_device::block_device(size_t major, size_t minor, size_t block_size) - : device(major, minor) - , m_block_size(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}; - } -} // namespace devices \ No newline at end of file diff --git a/kernel/devices/src/Device.cpp b/kernel/devices/src/Device.cpp deleted file mode 100644 index 38fdd48..0000000 --- a/kernel/devices/src/Device.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "devices/Device.hpp" - -#include - -namespace devices -{ - device::device(size_t major, size_t minor) - : m_major(major) - , m_minor(minor) - {} - - auto device::major() const -> size_t - { - return m_major; - } - - auto device::minor() const -> size_t - { - return m_minor; - } -} // namespace devices \ No newline at end of file diff --git a/kernel/devices/src/block_device.cpp b/kernel/devices/src/block_device.cpp new file mode 100644 index 0000000..dd0fd44 --- /dev/null +++ b/kernel/devices/src/block_device.cpp @@ -0,0 +1,24 @@ +#include "devices/block_device.hpp" + +#include "devices/temp_device.hpp" + +#include + +namespace devices +{ + block_device::block_device(size_t major, size_t minor, size_t block_size) + : device(major, minor) + , m_block_size(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}; + } +} // namespace devices \ No newline at end of file diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp deleted file mode 100644 index 5c18dac..0000000 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskController.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "devices/storage/RAMDisk/RAMDiskController.hpp" - -#include "kapi/boot_module/boot_module_registry.hpp" - -#include "devices/BlockDevice.hpp" -#include "devices/storage/RAMDisk/RAMDiskDevice.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; - - // TODO BA-FS26 use push_back from kstd::vector when available - m_devices.at(0) = ram_disk_device{module, m_major, minor}; - }); - } - - auto ram_disk_controller::device_by_major_minor(size_t major, size_t minor) -> block_device * - { - auto it = std::ranges::find_if( - m_devices, [major, minor](auto const & device) { return device.major() == major && device.minor() == minor; }); - - if (it != m_devices.end()) - { - return &(*it); - } - return nullptr; - } - - auto ram_disk_controller::devices_count() -> size_t - { - return m_devices.size(); - } -} // namespace devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp b/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp deleted file mode 100644 index f3b8799..0000000 --- a/kernel/devices/src/storage/RAMDisk/RAMDiskDevice.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "devices/storage/RAMDisk/RAMDiskDevice.hpp" - -#include "kapi/boot_module/boot_module.hpp" -#include "kapi/system.hpp" - -#include "devices/BlockDevice.hpp" - -#include - -#include - -namespace devices::storage::ram_disk -{ - namespace - { - constexpr size_t RAM_DISK_BLOCK_SIZE = 512uz; // TODO BA-FS26 really correct / good?? - } // namespace - - ram_disk_device::ram_disk_device() // TODO BA-FS26 remove when kstd::vector is available - : block_device(0, 0, RAM_DISK_BLOCK_SIZE) - {} - - ram_disk_device::ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor) - : block_device(major, 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/devices/src/storage/StorageController.cpp b/kernel/devices/src/storage/StorageController.cpp deleted file mode 100644 index d11a175..0000000 --- a/kernel/devices/src/storage/StorageController.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "devices/storage/StorageController.hpp" - -#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; - } -} // namespace devices::storage \ No newline at end of file diff --git a/kernel/devices/src/storage/StorageManagement.cpp b/kernel/devices/src/storage/StorageManagement.cpp deleted file mode 100644 index 1b0d2cc..0000000 --- a/kernel/devices/src/storage/StorageManagement.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "devices/storage/StorageManagement.hpp" - -#include "kapi/boot_modules.hpp" -#include "kapi/system.hpp" - -#include "devices/BlockDevice.hpp" -#include "devices/storage/RAMDisk/RAMDiskController.hpp" -#include "devices/storage/StorageController.hpp" - -#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{}; - constinit auto static active_ram_disk_controller = 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{}); - - active_ram_disk_controller.emplace(&kapi::boot_modules::get_boot_module_registry()); - active_storage_management->add_controller(&active_ram_disk_controller.value()); - - 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(storage_controller * controller) -> void - { - controller->set_ids(next_free_major++, MINORS_PER_DEVICE); - m_controllers.at(0) = controller; // TODO BA-FS26 use push_back from kstd:vector - } - - auto storage_management::device_by_major_minor(size_t major, size_t minor) -> block_device * - { - block_device * found = nullptr; - - std::ranges::find_if(m_controllers, [&](auto const controller) { - if (controller != nullptr && controller->major() == major) - { - found = controller->device_by_major_minor(major, minor); - return found != nullptr; - } - return false; - }); - - return found; - } - - auto storage_management::determine_boot_device() -> block_device * - { - // TODO BA-FS26 better way? - return device_by_major_minor(START_MAJOR, 0); - } - -} // namespace devices::storage \ No newline at end of file diff --git a/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp b/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp new file mode 100644 index 0000000..09f1c85 --- /dev/null +++ b/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp @@ -0,0 +1,48 @@ +#include "devices/storage/ram_disk/ram_disk_controller.hpp" + +#include "kapi/boot_module/boot_module_registry.hpp" + +#include "devices/block_device.hpp" +#include "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; + + // TODO BA-FS26 use push_back from kstd::vector when available + m_devices.at(0) = ram_disk_device{module, m_major, minor}; + }); + } + + auto ram_disk_controller::device_by_major_minor(size_t major, size_t minor) -> block_device * + { + auto it = std::ranges::find_if( + m_devices, [major, minor](auto const & device) { return device.major() == major && device.minor() == minor; }); + + if (it != m_devices.end()) + { + return &(*it); + } + return nullptr; + } + + auto ram_disk_controller::devices_count() -> size_t + { + return m_devices.size(); + } +} // namespace devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp b/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp new file mode 100644 index 0000000..3bd3967 --- /dev/null +++ b/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp @@ -0,0 +1,69 @@ +#include "devices/storage/ram_disk/ram_disk_device.hpp" + +#include "kapi/boot_module/boot_module.hpp" +#include "kapi/system.hpp" + +#include "devices/block_device.hpp" + +#include + +#include + +namespace devices::storage::ram_disk +{ + namespace + { + constexpr size_t RAM_DISK_BLOCK_SIZE = 512uz; // TODO BA-FS26 really correct / good?? + } // namespace + + ram_disk_device::ram_disk_device() // TODO BA-FS26 remove when kstd::vector is available + : block_device(0, 0, RAM_DISK_BLOCK_SIZE) + {} + + ram_disk_device::ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor) + : block_device(major, 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/devices/src/storage/storage_controller.cpp b/kernel/devices/src/storage/storage_controller.cpp new file mode 100644 index 0000000..f95f533 --- /dev/null +++ b/kernel/devices/src/storage/storage_controller.cpp @@ -0,0 +1,17 @@ +#include "devices/storage/storage_controller.hpp" + +#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; + } +} // namespace devices::storage \ No newline at end of file diff --git a/kernel/devices/src/storage/storage_management.cpp b/kernel/devices/src/storage/storage_management.cpp new file mode 100644 index 0000000..1530d7a --- /dev/null +++ b/kernel/devices/src/storage/storage_management.cpp @@ -0,0 +1,78 @@ +#include "devices/storage/storage_management.hpp" + +#include "kapi/boot_modules.hpp" +#include "kapi/system.hpp" + +#include "devices/block_device.hpp" +#include "devices/storage/ram_disk/ram_disk_controller.hpp" +#include "devices/storage/storage_controller.hpp" + +#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{}; + constinit auto static active_ram_disk_controller = 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{}); + + active_ram_disk_controller.emplace(&kapi::boot_modules::get_boot_module_registry()); + active_storage_management->add_controller(&active_ram_disk_controller.value()); + + 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(storage_controller * controller) -> void + { + controller->set_ids(next_free_major++, MINORS_PER_DEVICE); + m_controllers.at(0) = controller; // TODO BA-FS26 use push_back from kstd:vector + } + + auto storage_management::device_by_major_minor(size_t major, size_t minor) -> block_device * + { + block_device * found = nullptr; + + std::ranges::find_if(m_controllers, [&](auto const controller) { + if (controller != nullptr && controller->major() == major) + { + found = controller->device_by_major_minor(major, minor); + return found != nullptr; + } + return false; + }); + + return found; + } + + auto storage_management::determine_boot_device() -> block_device * + { + // TODO BA-FS26 better way? + return device_by_major_minor(START_MAJOR, 0); + } + +} // namespace devices::storage \ No newline at end of file diff --git a/kernel/devices/src/temp_device.cpp b/kernel/devices/src/temp_device.cpp new file mode 100644 index 0000000..dae20b5 --- /dev/null +++ b/kernel/devices/src/temp_device.cpp @@ -0,0 +1,21 @@ +#include "devices/temp_device.hpp" + +#include + +namespace devices +{ + device::device(size_t major, size_t minor) + : m_major(major) + , m_minor(minor) + {} + + auto device::major() const -> size_t + { + return m_major; + } + + auto device::minor() const -> size_t + { + return m_minor; + } +} // namespace devices \ No newline at end of file diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 0336fef..07aa8ae 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -3,7 +3,7 @@ #include "kapi/memory.hpp" #include "kapi/system.hpp" -#include "devices/storage/StorageManagement.hpp" +#include "devices/storage/storage_management.hpp" #include "kernel/memory.hpp" -- cgit v1.2.3 From 332903fcfc2d1b79b9b201cc98dd65125d2018e6 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 3 Mar 2026 17:01:46 +0100 Subject: rename temp_device back to device --- kernel/devices/CMakeLists.txt | 4 ++-- kernel/devices/include/devices/block_device.hpp | 2 +- kernel/devices/include/devices/device.hpp | 22 ++++++++++++++++++++++ kernel/devices/include/devices/temp_device.hpp | 22 ---------------------- kernel/devices/src/block_device.cpp | 2 +- kernel/devices/src/device.cpp | 21 +++++++++++++++++++++ kernel/devices/src/temp_device.cpp | 21 --------------------- 7 files changed, 47 insertions(+), 47 deletions(-) create mode 100644 kernel/devices/include/devices/device.hpp delete mode 100644 kernel/devices/include/devices/temp_device.hpp create mode 100644 kernel/devices/src/device.cpp delete mode 100644 kernel/devices/src/temp_device.cpp (limited to 'kernel') diff --git a/kernel/devices/CMakeLists.txt b/kernel/devices/CMakeLists.txt index 691bb11..15d03fa 100644 --- a/kernel/devices/CMakeLists.txt +++ b/kernel/devices/CMakeLists.txt @@ -2,7 +2,7 @@ add_library("kernel_devices" STATIC) add_library("kernel::devices" ALIAS "kernel_devices") target_sources("kernel_devices" PRIVATE - "src/temp_device.cpp" + "src/device.cpp" "src/block_device.cpp" "src/storage/storage_controller.cpp" "src/storage/storage_management.cpp" @@ -14,7 +14,7 @@ target_sources("kernel_devices" PUBLIC FILE_SET HEADERS BASE_DIRS "include" FILES - "include/devices/temp_device.hpp" + "include/devices/device.hpp" "include/devices/block_device.hpp" "include/devices/storage/storage_controller.hpp" "include/devices/storage/storage_management.hpp" diff --git a/kernel/devices/include/devices/block_device.hpp b/kernel/devices/include/devices/block_device.hpp index d1e4249..240cb3b 100644 --- a/kernel/devices/include/devices/block_device.hpp +++ b/kernel/devices/include/devices/block_device.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP #define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP -#include "devices/temp_device.hpp" +#include "devices/device.hpp" #include diff --git a/kernel/devices/include/devices/device.hpp b/kernel/devices/include/devices/device.hpp new file mode 100644 index 0000000..0f93bff --- /dev/null +++ b/kernel/devices/include/devices/device.hpp @@ -0,0 +1,22 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_DEVICE_HPP +#define TEACH_OS_KERNEL_DEVICES_DEVICE_HPP + +#include + +namespace devices +{ + struct device + { + device(size_t major, size_t minor); + virtual ~device() = default; + + auto major() const -> size_t; + auto minor() const -> size_t; + + private: + size_t m_major; + size_t m_minor; + }; +} // namespace devices + +#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/temp_device.hpp b/kernel/devices/include/devices/temp_device.hpp deleted file mode 100644 index 0f93bff..0000000 --- a/kernel/devices/include/devices/temp_device.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_DEVICE_HPP -#define TEACH_OS_KERNEL_DEVICES_DEVICE_HPP - -#include - -namespace devices -{ - struct device - { - device(size_t major, size_t minor); - virtual ~device() = default; - - auto major() const -> size_t; - auto minor() const -> size_t; - - private: - size_t m_major; - size_t m_minor; - }; -} // namespace devices - -#endif \ No newline at end of file diff --git a/kernel/devices/src/block_device.cpp b/kernel/devices/src/block_device.cpp index dd0fd44..dd63638 100644 --- a/kernel/devices/src/block_device.cpp +++ b/kernel/devices/src/block_device.cpp @@ -1,6 +1,6 @@ #include "devices/block_device.hpp" -#include "devices/temp_device.hpp" +#include "devices/device.hpp" #include diff --git a/kernel/devices/src/device.cpp b/kernel/devices/src/device.cpp new file mode 100644 index 0000000..aa5c1bb --- /dev/null +++ b/kernel/devices/src/device.cpp @@ -0,0 +1,21 @@ +#include "devices/device.hpp" + +#include + +namespace devices +{ + device::device(size_t major, size_t minor) + : m_major(major) + , m_minor(minor) + {} + + auto device::major() const -> size_t + { + return m_major; + } + + auto device::minor() const -> size_t + { + return m_minor; + } +} // namespace devices \ No newline at end of file diff --git a/kernel/devices/src/temp_device.cpp b/kernel/devices/src/temp_device.cpp deleted file mode 100644 index dae20b5..0000000 --- a/kernel/devices/src/temp_device.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "devices/temp_device.hpp" - -#include - -namespace devices -{ - device::device(size_t major, size_t minor) - : m_major(major) - , m_minor(minor) - {} - - auto device::major() const -> size_t - { - return m_major; - } - - auto device::minor() const -> size_t - { - return m_minor; - } -} // namespace devices \ No newline at end of file -- cgit v1.2.3 From 6afdc8ecb3d0d533597621d640910f5faf50331d Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 4 Mar 2026 10:16:23 +0100 Subject: add comments --- kernel/devices/include/devices/block_device.hpp | 44 ++++++++++++++++++++++ kernel/devices/include/devices/device.hpp | 22 +++++++++++ .../storage/ram_disk/ram_disk_controller.hpp | 22 +++++++++++ .../devices/storage/ram_disk/ram_disk_device.hpp | 27 +++++++++++++ .../include/devices/storage/storage_controller.hpp | 33 ++++++++++++++++ .../include/devices/storage/storage_management.hpp | 40 +++++++++++++++++++- 6 files changed, 187 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/block_device.hpp b/kernel/devices/include/devices/block_device.hpp index 240cb3b..78a2606 100644 --- a/kernel/devices/include/devices/block_device.hpp +++ b/kernel/devices/include/devices/block_device.hpp @@ -7,15 +7,49 @@ namespace devices { + /** + * @brief Base interface for block-addressable devices. + */ struct block_device : device { + /** + * @brief Create a block device descriptor. + * @param major Device major number. + * @param minor Device minor number. + * @param block_size Size of one logical block in bytes. + */ block_device(size_t major, size_t minor, size_t block_size); + + /** + * @brief Virtual destructor for block device. + */ virtual ~block_device() = default; + /** + * @brief Read data from the block at @p block_index into @p buffer. + * @param block_index Zero-based block index. + * @param buffer Destination buffer. + * @warning Panics if @p buffer is null. + * @note Reads up to one logical block (see constructor @p block_size). Implementations may perform a partial + * transfer for the final block when fewer than @p block_size bytes remain. + */ virtual auto read_block(size_t block_index, void * buffer) const -> void = 0; + + /** + * @brief Write data to the block at @p block_index. + * @param block_index Zero-based block index. + * @param buffer Source buffer, must not be null. + * @warning Panics if @p buffer is null. + * @note Writes up to one logical block (see constructor @p block_size). + * Implementations may perform a partial transfer for the final block when + * fewer than @p block_size bytes remain. + */ virtual auto write_block(size_t block_index, void const * buffer) -> void = 0; protected: + /** + * @brief Information describing the transfer window for one block index. + */ struct transfer_info { size_t offset; @@ -23,7 +57,17 @@ namespace devices size_t remainder; }; + /** + * @brief Return total device size in bytes. + * @return Total number of addressable bytes. + */ virtual auto size() const -> size_t = 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. + */ auto calculate_transfer(size_t block_index) const -> transfer_info; size_t m_block_size; diff --git a/kernel/devices/include/devices/device.hpp b/kernel/devices/include/devices/device.hpp index 0f93bff..cbf77c2 100644 --- a/kernel/devices/include/devices/device.hpp +++ b/kernel/devices/include/devices/device.hpp @@ -5,17 +5,39 @@ namespace devices { + /** + * @brief Base device identified by a major and minor number. + */ struct device { + /** + * @brief Create a device identifier from @p major and @p minor. + * @param major Device major number. + * @param minor Device minor number. + */ device(size_t major, size_t minor); + + /** + * @brief Virtual destructor for device. + */ virtual ~device() = default; + /** + * @brief Returns the major number of the device. + * @return Device major number. + */ auto major() const -> size_t; + + /** + * @brief Returns the minor number of the device. + * @return Device minor number. + */ auto minor() const -> size_t; private: size_t m_major; size_t m_minor; + // TODO BA-FS26 add name }; } // namespace devices diff --git a/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp b/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp index f050ba0..05cac88 100644 --- a/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp +++ b/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp @@ -12,17 +12,39 @@ namespace devices::storage::ram_disk { + /** + * @brief Storage controller that exposes boot modules as RAM-disk devices. + */ struct ram_disk_controller : storage_controller { + /** + * @brief Create a RAM-disk controller. + * @param registry Boot module registry as device source. + */ explicit ram_disk_controller(kapi::boot_modules::boot_module_registry const * registry); + /** + * @brief Probe boot modules and create RAM-disk devices. + */ auto probe() -> void override; + /** + * @brief Return the number of managed RAM-disk devices. + * @return Number of managed devices. + */ auto devices_count() -> size_t override; + + /** + * @brief Look up a RAM-disk device by major/minor numbers. + * @param major Device major number. + * @param minor Device minor number. + * @return Matching block device, or nullptr if no device matches. + */ auto device_by_major_minor(size_t major, size_t minor) -> block_device * override; private: kapi::boot_modules::boot_module_registry const * m_boot_module_registry; + std::array m_devices{}; // TODO BA-FS26 use kstd::vector when available }; } // namespace devices::storage::ram_disk diff --git a/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp b/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp index 1f0292f..eebbcd7 100644 --- a/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp +++ b/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp @@ -9,15 +9,42 @@ namespace devices::storage::ram_disk { + /** + * @brief Block device for a boot module. + */ struct ram_disk_device : block_device { ram_disk_device(); // TODO BA-FS26 remove when kstd::vector is available + + /** + * @brief Create a RAM disk for the @p module. + * @param module Boot module providing the memory region. + * @param major Device major number. + * @param minor Device minor number. + */ ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor); + /** + * @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 -> void 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) -> void override; private: + /** + * @brief Return module size in bytes. + */ auto size() const -> size_t override; kapi::boot_modules::boot_module m_boot_module{}; diff --git a/kernel/devices/include/devices/storage/storage_controller.hpp b/kernel/devices/include/devices/storage/storage_controller.hpp index 0c09815..18c7232 100644 --- a/kernel/devices/include/devices/storage/storage_controller.hpp +++ b/kernel/devices/include/devices/storage/storage_controller.hpp @@ -7,16 +7,49 @@ namespace devices::storage { + /** + * @brief Base interface for storage controllers. + * + * A storage controller probes for devices and resolves devices by major/minor + * numbers. + */ struct storage_controller { + /** + * @brief Virtual destructor. + */ virtual ~storage_controller() = default; + /** + * @brief Probe the controller and register discovered devices. + */ virtual auto probe() -> void = 0; + /** + * @brief Assign the major number and minor stride for this controller. + * @param major Major number assigned to this controller. + * @param minors_per_dev Minor number stride between devices. + */ auto set_ids(size_t major, size_t minors_per_dev) -> void; + + /** + * @brief Return the assigned major number. + * @return Assigned major number. + */ auto major() const -> size_t; + /** + * @brief Return the number of devices managed by this controller. + * @return Number of managed devices. + */ virtual auto devices_count() -> size_t = 0; + + /** + * @brief Find a managed device by major/minor numbers. + * @param major Device major number. + * @param minor Device minor number. + * @return Matching block device, or nullptr if no device matches. + */ virtual auto device_by_major_minor(size_t major, size_t minor) -> block_device * = 0; protected: diff --git a/kernel/devices/include/devices/storage/storage_management.hpp b/kernel/devices/include/devices/storage/storage_management.hpp index c4f5679..2bed459 100644 --- a/kernel/devices/include/devices/storage/storage_management.hpp +++ b/kernel/devices/include/devices/storage/storage_management.hpp @@ -9,19 +9,57 @@ namespace devices::storage { - // TODO BA-FS26 add documentation + /** + * @brief Global storage subsystem manager. + * + * Owns registered storage controllers and provides device lookup by + * major/minor numbers. + */ struct storage_management { + /** + * @brief Initialize global storage management. + * + * Creates the singleton instance, registers controllers and probes + * them for devices. + * + * @warning Panics if called more than once. + */ auto static init() -> void; + /** + * @brief Return the active storage manager singleton. + * @return Reference to the active storage manager. + * @warning Panics if storage management has not been initialized. + */ auto static get() -> storage_management &; + /** + * @brief Register a storage controller. + * @param controller Controller to register. + * + * Assigns controller IDs (major number range and minors per device). + */ auto add_controller(storage_controller * controller) -> void; + /** + * @brief Find a block device by major/minor numbers. + * @param major Device major number. + * @param minor Device minor number. + * @return Matching block device, or nullptr if no device matches. + */ auto device_by_major_minor(size_t major, size_t minor) -> block_device *; + + /** + * @brief Determine the boot device. + * @return Boot device, or nullptr if it cannot be determined. + */ auto determine_boot_device() -> block_device *; private: + /** + * @brief Private default constructor for storage management singleton. + */ storage_management() = default; std::array m_controllers{}; // TODO BA-FS26 use kstd::vector when available -- cgit v1.2.3 From 79aaf6113a9eca042ccc6f656fac6c7c243c608b Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sat, 7 Mar 2026 13:46:24 +0100 Subject: Simplify device lookup in storage controllers by removing redundant major number --- .../devices/include/devices/storage/ram_disk/ram_disk_controller.hpp | 2 +- kernel/devices/include/devices/storage/storage_controller.hpp | 2 +- kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp | 5 ++--- kernel/devices/src/storage/storage_management.cpp | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp b/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp index 05cac88..424082d 100644 --- a/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp +++ b/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp @@ -40,7 +40,7 @@ namespace devices::storage::ram_disk * @param minor Device minor number. * @return Matching block device, or nullptr if no device matches. */ - auto device_by_major_minor(size_t major, size_t minor) -> block_device * override; + auto device_by_minor(size_t minor) -> block_device * override; private: kapi::boot_modules::boot_module_registry const * m_boot_module_registry; diff --git a/kernel/devices/include/devices/storage/storage_controller.hpp b/kernel/devices/include/devices/storage/storage_controller.hpp index 18c7232..0c7cf83 100644 --- a/kernel/devices/include/devices/storage/storage_controller.hpp +++ b/kernel/devices/include/devices/storage/storage_controller.hpp @@ -50,7 +50,7 @@ namespace devices::storage * @param minor Device minor number. * @return Matching block device, or nullptr if no device matches. */ - virtual auto device_by_major_minor(size_t major, size_t minor) -> block_device * = 0; + virtual auto device_by_minor(size_t minor) -> block_device * = 0; protected: size_t m_major{}; diff --git a/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp b/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp index 09f1c85..9f9537f 100644 --- a/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp +++ b/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp @@ -29,10 +29,9 @@ namespace devices::storage::ram_disk }); } - auto ram_disk_controller::device_by_major_minor(size_t major, size_t minor) -> block_device * + auto ram_disk_controller::device_by_minor(size_t minor) -> block_device * { - auto it = std::ranges::find_if( - m_devices, [major, minor](auto const & device) { return device.major() == major && device.minor() == minor; }); + auto it = std::ranges::find_if(m_devices, [minor](auto const & device) { return device.minor() == minor; }); if (it != m_devices.end()) { diff --git a/kernel/devices/src/storage/storage_management.cpp b/kernel/devices/src/storage/storage_management.cpp index 1530d7a..a5b6503 100644 --- a/kernel/devices/src/storage/storage_management.cpp +++ b/kernel/devices/src/storage/storage_management.cpp @@ -60,7 +60,7 @@ namespace devices::storage std::ranges::find_if(m_controllers, [&](auto const controller) { if (controller != nullptr && controller->major() == major) { - found = controller->device_by_major_minor(major, minor); + found = controller->device_by_minor(minor); return found != nullptr; } return false; -- cgit v1.2.3 From 2f4001cdb1f528d8a0d255d81ac3a8b9aa522fac Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 7 Mar 2026 13:55:40 +0100 Subject: implement first draft of a file_descriptor_table and open_file_description --- kernel/CMakeLists.txt | 2 + kernel/filesystem/CMakeLists.txt | 25 +++++++ kernel/filesystem/include/filesystem/file.hpp | 19 +++++ .../include/filesystem/file_descriptor_table.hpp | 28 ++++++++ .../include/filesystem/open_file_description.hpp | 24 +++++++ kernel/filesystem/src/file.cpp | 6 ++ kernel/filesystem/src/file_descriptor_table.cpp | 81 ++++++++++++++++++++++ kernel/filesystem/src/open_file_description.cpp | 24 +++++++ kernel/src/main.cpp | 4 ++ 9 files changed, 213 insertions(+) create mode 100644 kernel/filesystem/CMakeLists.txt create mode 100644 kernel/filesystem/include/filesystem/file.hpp create mode 100644 kernel/filesystem/include/filesystem/file_descriptor_table.hpp create mode 100644 kernel/filesystem/include/filesystem/open_file_description.hpp create mode 100644 kernel/filesystem/src/file.cpp create mode 100644 kernel/filesystem/src/file_descriptor_table.cpp create mode 100644 kernel/filesystem/src/open_file_description.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index c3c9698..830c527 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory("devices") +add_subdirectory("filesystem") add_executable("kernel" # Platform-independent KAPI implementation @@ -27,6 +28,7 @@ target_link_libraries("kernel" PRIVATE "os::arch" "os::kapi" "kernel::devices" + "kernel::filesystem" ) target_link_options("kernel" PRIVATE diff --git a/kernel/filesystem/CMakeLists.txt b/kernel/filesystem/CMakeLists.txt new file mode 100644 index 0000000..2a93c62 --- /dev/null +++ b/kernel/filesystem/CMakeLists.txt @@ -0,0 +1,25 @@ +add_library("kernel_filesystem" STATIC) +add_library("kernel::filesystem" ALIAS "kernel_filesystem") + +target_sources("kernel_filesystem" PRIVATE + "src/file.cpp" + "src/open_file_description.cpp" + "src/file_descriptor_table.cpp" +) + +target_sources("kernel_filesystem" PUBLIC + FILE_SET HEADERS + BASE_DIRS "include" + FILES + "include/filesystem/file.hpp" + "include/filesystem/open_file_description.hpp" + "include/filesystem/file_descriptor_table.hpp" +) + +target_include_directories("kernel_filesystem" PUBLIC + "include" +) + +target_link_libraries("kernel_filesystem" PRIVATE + "os::kapi" +) diff --git a/kernel/filesystem/include/filesystem/file.hpp b/kernel/filesystem/include/filesystem/file.hpp new file mode 100644 index 0000000..e7e1b12 --- /dev/null +++ b/kernel/filesystem/include/filesystem/file.hpp @@ -0,0 +1,19 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_FILE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_FILE_HPP + +#include + +namespace filesystem +{ + struct file + { + virtual ~file() = default; + + virtual auto open() -> void = 0; + + virtual auto read(void * buffer, size_t offset, size_t size) const -> size_t = 0; + virtual auto write(void const * buffer, size_t offset, size_t size) -> size_t = 0; + }; +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/filesystem/include/filesystem/file_descriptor_table.hpp b/kernel/filesystem/include/filesystem/file_descriptor_table.hpp new file mode 100644 index 0000000..a865d32 --- /dev/null +++ b/kernel/filesystem/include/filesystem/file_descriptor_table.hpp @@ -0,0 +1,28 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP + +#include "open_file_description.hpp" + +#include + +namespace filesystem +{ + struct file_descriptor_table + { + auto static init() -> void; + auto static get() -> file_descriptor_table &; + + ~file_descriptor_table() = default; + + auto add_file(open_file_description & f) -> int; + auto get_file(int fd) -> open_file_description &; + auto remove_file(int fd) -> void; + + private: + file_descriptor_table() = default; + + std::array m_open_files{}; // TODO BA-FS26 use kstd::vector when available + }; +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/filesystem/include/filesystem/open_file_description.hpp b/kernel/filesystem/include/filesystem/open_file_description.hpp new file mode 100644 index 0000000..e4febbd --- /dev/null +++ b/kernel/filesystem/include/filesystem/open_file_description.hpp @@ -0,0 +1,24 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP + +#include "file.hpp" + +#include + +namespace filesystem +{ + struct open_file_description + { + ~open_file_description() = default; + + auto read(void * buffer, size_t size) -> size_t; + auto write(void const * buffer, size_t size) -> size_t; + + private: + file * m_file{}; + size_t m_offset{0}; + }; + +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/filesystem/src/file.cpp b/kernel/filesystem/src/file.cpp new file mode 100644 index 0000000..c67ad1a --- /dev/null +++ b/kernel/filesystem/src/file.cpp @@ -0,0 +1,6 @@ +#include "filesystem/file.hpp" + +namespace filesystem +{ + // TODO BA-FS26 +} \ No newline at end of file diff --git a/kernel/filesystem/src/file_descriptor_table.cpp b/kernel/filesystem/src/file_descriptor_table.cpp new file mode 100644 index 0000000..0c79431 --- /dev/null +++ b/kernel/filesystem/src/file_descriptor_table.cpp @@ -0,0 +1,81 @@ +#include "filesystem/file_descriptor_table.hpp" + +#include "kapi/system.hpp" + +#include "filesystem/open_file_description.hpp" + +#include +#include +#include + +namespace filesystem +{ + namespace + { + constinit auto static global_file_descriptor_table = std::optional{}; + } // namespace + + auto file_descriptor_table::init() -> void + { + if (global_file_descriptor_table) + { + kapi::system::panic("[FILESYSTEM] File descriptor table has already been initialized."); + } + + global_file_descriptor_table.emplace(file_descriptor_table{}); + } + + auto file_descriptor_table::get() -> file_descriptor_table & + { + if (!global_file_descriptor_table) + { + kapi::system::panic("[FILESYSTEM] File descriptor table has not been initialized."); + } + + return *global_file_descriptor_table; + } + + auto file_descriptor_table::add_file(open_file_description & f) -> int + { + auto it = std::ranges::find(m_open_files, nullptr); + if (it != m_open_files.end()) + { + *it = &f; + return static_cast(it - m_open_files.begin()); + } + + return -1; + } + + auto file_descriptor_table::get_file(int fd) -> open_file_description & + { + if (fd < 0) + { + kapi::system::panic("[FILESYSTEM] get_file called with negative descriptor."); + } + + auto const index = static_cast(fd); + if (index >= m_open_files.size() || m_open_files[index] == nullptr) + { + kapi::system::panic("[FILESYSTEM] get_file called with invalid descriptor."); + } + + return *m_open_files[index]; + } + + auto file_descriptor_table::remove_file(int fd) -> void + { + if (fd < 0) + { + kapi::system::panic("[FILESYSTEM] remove_file called with negative descriptor."); + } + + auto const index = static_cast(fd); + if (index >= m_open_files.size()) + { + kapi::system::panic("[FILESYSTEM] remove_file called with out-of-range descriptor."); + } + + m_open_files[index] = nullptr; + } +} // namespace filesystem \ No newline at end of file diff --git a/kernel/filesystem/src/open_file_description.cpp b/kernel/filesystem/src/open_file_description.cpp new file mode 100644 index 0000000..8c20397 --- /dev/null +++ b/kernel/filesystem/src/open_file_description.cpp @@ -0,0 +1,24 @@ +#include "filesystem/open_file_description.hpp" + +#include "filesystem/file.hpp" + +#include + +namespace filesystem +{ + auto open_file_description::read(void * buffer, size_t size) -> size_t + { + // TODO BA-FS26 nullptr check + auto read_bytes = m_file->read(buffer, m_offset, size); + m_offset += read_bytes; + return read_bytes; + } + + auto open_file_description::write(void const * buffer, size_t size) -> size_t + { + // TODO BA-FS26 nullptr check + auto written_bytes = m_file->write(buffer, m_offset, size); + m_offset += written_bytes; + return written_bytes; + } +} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 07aa8ae..4b74bd4 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -4,6 +4,7 @@ #include "kapi/system.hpp" #include "devices/storage/storage_management.hpp" +#include "filesystem/file_descriptor_table.hpp" #include "kernel/memory.hpp" @@ -25,5 +26,8 @@ auto main() -> int devices::storage::storage_management::init(); kstd::println("[OS] Storage management initialized."); + filesystem::file_descriptor_table::init(); + kstd::println("[OS] Global file descriptor table initialized."); + kapi::system::panic("Returning from kernel main!"); } -- cgit v1.2.3 From 9ae5a230b1cd1f842c1a7c64392a0bccdba01a2d Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 7 Mar 2026 17:04:24 +0100 Subject: implement read and write bytes from device --- kernel/devices/include/devices/block_device.hpp | 22 ++++ kernel/devices/include/devices/device.hpp | 9 ++ kernel/devices/src/block_device.cpp | 19 +++- kernel/filesystem/CMakeLists.txt | 6 +- .../filesystem/include/filesystem/device_file.hpp | 30 ++++++ .../include/filesystem/open_file_description.hpp | 2 + kernel/filesystem/src/device_file.cpp | 119 +++++++++++++++++++++ kernel/filesystem/src/open_file_description.cpp | 4 + 8 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 kernel/filesystem/include/filesystem/device_file.hpp create mode 100644 kernel/filesystem/src/device_file.cpp (limited to 'kernel') diff --git a/kernel/devices/include/devices/block_device.hpp b/kernel/devices/include/devices/block_device.hpp index 78a2606..9bca53f 100644 --- a/kernel/devices/include/devices/block_device.hpp +++ b/kernel/devices/include/devices/block_device.hpp @@ -46,6 +46,28 @@ namespace devices */ virtual auto write_block(size_t block_index, void const * buffer) -> void = 0; + /** + * @brief Return logical block size in bytes. + * @return One logical block size in bytes. + */ + auto block_size() const -> size_t; + + /** + * @brief Return device capacity in bytes. + * @return Total number of addressable bytes. + */ + auto capacity() const -> size_t; + + /** + * @brief Override to identify block devices. + * @return true if this device is a block device, false otherwise. + */ + + auto is_block_device() const -> bool override + { + return true; + } + protected: /** * @brief Information describing the transfer window for one block index. diff --git a/kernel/devices/include/devices/device.hpp b/kernel/devices/include/devices/device.hpp index cbf77c2..7f9f9e1 100644 --- a/kernel/devices/include/devices/device.hpp +++ b/kernel/devices/include/devices/device.hpp @@ -34,6 +34,15 @@ namespace devices */ auto minor() const -> size_t; + /** + * @brief Check if the device is a block device. + * @return true if this device is a block device, false otherwise. + */ + virtual auto is_block_device() const -> bool + { + return false; + } + private: size_t m_major; size_t m_minor; diff --git a/kernel/devices/src/block_device.cpp b/kernel/devices/src/block_device.cpp index dd63638..2f0c2ca 100644 --- a/kernel/devices/src/block_device.cpp +++ b/kernel/devices/src/block_device.cpp @@ -1,5 +1,7 @@ #include "devices/block_device.hpp" +#include "kapi/system.hpp" + #include "devices/device.hpp" #include @@ -9,7 +11,12 @@ namespace devices block_device::block_device(size_t major, size_t minor, size_t block_size) : device(major, minor) , 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 { @@ -21,4 +28,14 @@ namespace devices 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/filesystem/CMakeLists.txt b/kernel/filesystem/CMakeLists.txt index 2a93c62..1d74585 100644 --- a/kernel/filesystem/CMakeLists.txt +++ b/kernel/filesystem/CMakeLists.txt @@ -3,6 +3,7 @@ add_library("kernel::filesystem" ALIAS "kernel_filesystem") target_sources("kernel_filesystem" PRIVATE "src/file.cpp" + "src/device_file.cpp" "src/open_file_description.cpp" "src/file_descriptor_table.cpp" ) @@ -12,6 +13,7 @@ target_sources("kernel_filesystem" PUBLIC BASE_DIRS "include" FILES "include/filesystem/file.hpp" + "include/filesystem/device_file.hpp" "include/filesystem/open_file_description.hpp" "include/filesystem/file_descriptor_table.hpp" ) @@ -20,6 +22,8 @@ target_include_directories("kernel_filesystem" PUBLIC "include" ) -target_link_libraries("kernel_filesystem" PRIVATE +target_link_libraries("kernel_filesystem" PUBLIC + "kernel::devices" +PRIVATE "os::kapi" ) diff --git a/kernel/filesystem/include/filesystem/device_file.hpp b/kernel/filesystem/include/filesystem/device_file.hpp new file mode 100644 index 0000000..08d81f6 --- /dev/null +++ b/kernel/filesystem/include/filesystem/device_file.hpp @@ -0,0 +1,30 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVICE_FILE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_FILE_HPP + +#include "devices/block_device.hpp" +#include "devices/device.hpp" +#include "filesystem/file.hpp" + +#include + +namespace filesystem +{ + struct device_file : file + { + device_file(devices::device * device); + + auto open() -> void override; + + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + + private: + 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(size_t offset, size_t size, void * buffer, block_op op) const -> size_t; + + devices::device * m_device; + }; +} // namespace filesystem + +#endif diff --git a/kernel/filesystem/include/filesystem/open_file_description.hpp b/kernel/filesystem/include/filesystem/open_file_description.hpp index e4febbd..3241ea4 100644 --- a/kernel/filesystem/include/filesystem/open_file_description.hpp +++ b/kernel/filesystem/include/filesystem/open_file_description.hpp @@ -9,6 +9,8 @@ namespace filesystem { struct open_file_description { + open_file_description(file * file); + ~open_file_description() = default; auto read(void * buffer, size_t size) -> size_t; diff --git a/kernel/filesystem/src/device_file.cpp b/kernel/filesystem/src/device_file.cpp new file mode 100644 index 0000000..a6c234c --- /dev/null +++ b/kernel/filesystem/src/device_file.cpp @@ -0,0 +1,119 @@ +#include "filesystem/device_file.hpp" + +#include "kapi/system.hpp" + +#include "devices/block_device.hpp" +#include "devices/device.hpp" + +#include + +#include +#include +#include + +namespace filesystem +{ + device_file::device_file(devices::device * device) + : m_device(device) + { + if (m_device == nullptr) + { + kapi::system::panic("[FILESYSTEM] device_file constructed with null device."); + } + } + + auto device_file::open() -> void + { + // Hook point for permission checks or lazy metadata loading. + } + + auto device_file::read(void * buffer, size_t offset, size_t size) const -> size_t + { + if (m_device->is_block_device()) + { + return process_blocks(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); + } + }); + } + else + { + kapi::system::panic("[FILESYSTEM] device_file::read called on non-block device."); + } + } + + auto device_file::write(void const * buffer, size_t offset, size_t size) -> size_t + { + if (m_device->is_block_device()) + { + return process_blocks(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); + } + }); + } + else + { + kapi::system::panic("[FILESYSTEM] device_file::write called on non-block device."); + } + } + + auto device_file::process_blocks(size_t offset, size_t size, void * buffer, block_op op) const -> size_t + { + if (buffer == nullptr) + { + kapi::system::panic("[FILESYSTEM] device_file::write called with null buffer."); + } + + if (size == 0) + { + return 0; + } + + auto * block_dev = static_cast(m_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); + + std::array scratch_buffer{}; // TODO BA-FS26 better solution than fixed scratch_buffer ?? + 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; + } +} // namespace filesystem diff --git a/kernel/filesystem/src/open_file_description.cpp b/kernel/filesystem/src/open_file_description.cpp index 8c20397..1f0410c 100644 --- a/kernel/filesystem/src/open_file_description.cpp +++ b/kernel/filesystem/src/open_file_description.cpp @@ -6,6 +6,10 @@ namespace filesystem { + open_file_description::open_file_description(file * file) + : m_file(file) + {} + auto open_file_description::read(void * buffer, size_t size) -> size_t { // TODO BA-FS26 nullptr check -- cgit v1.2.3 From 58aea4f1bbb4f24d4fc4cda5501d753886968234 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 9 Mar 2026 23:54:28 +0100 Subject: small refactoring --- kernel/filesystem/include/filesystem/open_file_description.hpp | 4 ++-- kernel/filesystem/src/open_file_description.cpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/filesystem/include/filesystem/open_file_description.hpp b/kernel/filesystem/include/filesystem/open_file_description.hpp index 3241ea4..1589196 100644 --- a/kernel/filesystem/include/filesystem/open_file_description.hpp +++ b/kernel/filesystem/include/filesystem/open_file_description.hpp @@ -17,8 +17,8 @@ namespace filesystem auto write(void const * buffer, size_t size) -> size_t; private: - file * m_file{}; - size_t m_offset{0}; + file * m_file; + size_t m_offset; }; } // namespace filesystem diff --git a/kernel/filesystem/src/open_file_description.cpp b/kernel/filesystem/src/open_file_description.cpp index 1f0410c..d483746 100644 --- a/kernel/filesystem/src/open_file_description.cpp +++ b/kernel/filesystem/src/open_file_description.cpp @@ -8,6 +8,7 @@ namespace filesystem { open_file_description::open_file_description(file * file) : m_file(file) + , m_offset(0) {} auto open_file_description::read(void * buffer, size_t size) -> size_t -- cgit v1.2.3 From 7430778a773cfdb97bed3c77c17f7c737706ba6a Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 9 Mar 2026 23:54:54 +0100 Subject: add todos --- kernel/filesystem/src/device_file.cpp | 1 + kernel/filesystem/src/file_descriptor_table.cpp | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'kernel') diff --git a/kernel/filesystem/src/device_file.cpp b/kernel/filesystem/src/device_file.cpp index a6c234c..34195db 100644 --- a/kernel/filesystem/src/device_file.cpp +++ b/kernel/filesystem/src/device_file.cpp @@ -99,6 +99,7 @@ namespace filesystem return 0; size_t const total_to_process = std::min(size, capacity - offset); + // TODO BA-FS26 use kstd::vector when available std::array scratch_buffer{}; // TODO BA-FS26 better solution than fixed scratch_buffer ?? auto processed = 0uz; diff --git a/kernel/filesystem/src/file_descriptor_table.cpp b/kernel/filesystem/src/file_descriptor_table.cpp index 0c79431..645da9f 100644 --- a/kernel/filesystem/src/file_descriptor_table.cpp +++ b/kernel/filesystem/src/file_descriptor_table.cpp @@ -49,11 +49,13 @@ namespace filesystem auto file_descriptor_table::get_file(int fd) -> open_file_description & { + // TODO BA-FS26 do not panic, its an user error if (fd < 0) { kapi::system::panic("[FILESYSTEM] get_file called with negative descriptor."); } + // TODO BA-FS26 do not panic, its an user error auto const index = static_cast(fd); if (index >= m_open_files.size() || m_open_files[index] == nullptr) { @@ -65,17 +67,21 @@ namespace filesystem auto file_descriptor_table::remove_file(int fd) -> void { + // TODO BA-FS26 do not panic, its an user error if (fd < 0) { kapi::system::panic("[FILESYSTEM] remove_file called with negative descriptor."); } + // TODO BA-FS26 do not panic, its an user error auto const index = static_cast(fd); if (index >= m_open_files.size()) { kapi::system::panic("[FILESYSTEM] remove_file called with out-of-range descriptor."); } + // TODO BA-FS26 + // delete m_open_files[index]; m_open_files[index] = nullptr; } } // namespace filesystem \ No newline at end of file -- cgit v1.2.3 From 22a32e2ab9fcb779a7359cec9b0244f262661288 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 11 Mar 2026 18:15:54 +0100 Subject: use optional instead of pointer, improve error handling (do not just panic, return std::nullopt) --- .../include/filesystem/file_descriptor_table.hpp | 7 +++++-- kernel/filesystem/src/file_descriptor_table.cpp | 24 ++++++++-------------- 2 files changed, 14 insertions(+), 17 deletions(-) (limited to 'kernel') diff --git a/kernel/filesystem/include/filesystem/file_descriptor_table.hpp b/kernel/filesystem/include/filesystem/file_descriptor_table.hpp index a865d32..44fd428 100644 --- a/kernel/filesystem/include/filesystem/file_descriptor_table.hpp +++ b/kernel/filesystem/include/filesystem/file_descriptor_table.hpp @@ -4,6 +4,7 @@ #include "open_file_description.hpp" #include +#include namespace filesystem { @@ -15,13 +16,15 @@ namespace filesystem ~file_descriptor_table() = default; auto add_file(open_file_description & f) -> int; - auto get_file(int fd) -> open_file_description &; + auto get_file(int fd) -> std::optional; auto remove_file(int fd) -> void; private: file_descriptor_table() = default; - std::array m_open_files{}; // TODO BA-FS26 use kstd::vector when available + // TODO BA-FS26 use kstd::shared_ptr when available + // TODO BA-FS26 use kstd::vector when available + std::array, 32> m_open_files{}; }; } // namespace filesystem diff --git a/kernel/filesystem/src/file_descriptor_table.cpp b/kernel/filesystem/src/file_descriptor_table.cpp index 645da9f..286678c 100644 --- a/kernel/filesystem/src/file_descriptor_table.cpp +++ b/kernel/filesystem/src/file_descriptor_table.cpp @@ -37,29 +37,27 @@ namespace filesystem auto file_descriptor_table::add_file(open_file_description & f) -> int { - auto it = std::ranges::find(m_open_files, nullptr); + auto it = std::ranges::find_if(m_open_files, [](auto & open_file) { return !open_file.has_value(); }); if (it != m_open_files.end()) { - *it = &f; + *it = f; return static_cast(it - m_open_files.begin()); } return -1; } - auto file_descriptor_table::get_file(int fd) -> open_file_description & + auto file_descriptor_table::get_file(int fd) -> std::optional { - // TODO BA-FS26 do not panic, its an user error if (fd < 0) { - kapi::system::panic("[FILESYSTEM] get_file called with negative descriptor."); + return std::nullopt; } - // TODO BA-FS26 do not panic, its an user error auto const index = static_cast(fd); - if (index >= m_open_files.size() || m_open_files[index] == nullptr) + if (index >= m_open_files.size() || !m_open_files[index].has_value()) { - kapi::system::panic("[FILESYSTEM] get_file called with invalid descriptor."); + return std::nullopt; } return *m_open_files[index]; @@ -67,21 +65,17 @@ namespace filesystem auto file_descriptor_table::remove_file(int fd) -> void { - // TODO BA-FS26 do not panic, its an user error if (fd < 0) { - kapi::system::panic("[FILESYSTEM] remove_file called with negative descriptor."); + return; } - // TODO BA-FS26 do not panic, its an user error auto const index = static_cast(fd); if (index >= m_open_files.size()) { - kapi::system::panic("[FILESYSTEM] remove_file called with out-of-range descriptor."); + return; } - // TODO BA-FS26 - // delete m_open_files[index]; - m_open_files[index] = nullptr; + m_open_files[index].reset(); } } // namespace filesystem \ No newline at end of file -- cgit v1.2.3 From 9f27b540c160d1990791b62017e68cce622dcee5 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 11 Mar 2026 18:19:50 +0100 Subject: remove not needed cpp file --- kernel/filesystem/src/file.cpp | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 kernel/filesystem/src/file.cpp (limited to 'kernel') diff --git a/kernel/filesystem/src/file.cpp b/kernel/filesystem/src/file.cpp deleted file mode 100644 index c67ad1a..0000000 --- a/kernel/filesystem/src/file.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "filesystem/file.hpp" - -namespace filesystem -{ - // TODO BA-FS26 -} \ No newline at end of file -- cgit v1.2.3 From 85cde8c30c522659364bd0cb39c179e8b9dbbe07 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 11 Mar 2026 18:20:08 +0100 Subject: renaming --- kernel/filesystem/src/file_descriptor_table.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/filesystem/src/file_descriptor_table.cpp b/kernel/filesystem/src/file_descriptor_table.cpp index 286678c..49c08cd 100644 --- a/kernel/filesystem/src/file_descriptor_table.cpp +++ b/kernel/filesystem/src/file_descriptor_table.cpp @@ -35,12 +35,12 @@ namespace filesystem return *global_file_descriptor_table; } - auto file_descriptor_table::add_file(open_file_description & f) -> int + auto file_descriptor_table::add_file(open_file_description & file_description) -> int { auto it = std::ranges::find_if(m_open_files, [](auto & open_file) { return !open_file.has_value(); }); if (it != m_open_files.end()) { - *it = f; + *it = file_description; return static_cast(it - m_open_files.begin()); } -- cgit v1.2.3 From 0e6a3205dccbc44b61cf9eb2d9ea906149f8295f Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 11 Mar 2026 20:50:51 +0100 Subject: fix build --- kernel/filesystem/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) (limited to 'kernel') diff --git a/kernel/filesystem/CMakeLists.txt b/kernel/filesystem/CMakeLists.txt index 1d74585..a5a964f 100644 --- a/kernel/filesystem/CMakeLists.txt +++ b/kernel/filesystem/CMakeLists.txt @@ -2,7 +2,6 @@ add_library("kernel_filesystem" STATIC) add_library("kernel::filesystem" ALIAS "kernel_filesystem") target_sources("kernel_filesystem" PRIVATE - "src/file.cpp" "src/device_file.cpp" "src/open_file_description.cpp" "src/file_descriptor_table.cpp" -- cgit v1.2.3 From 6234691efe02fa095c6efa476606e8c5ff579710 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sun, 15 Mar 2026 14:18:16 +0100 Subject: Add inode_file and inode structure --- kernel/filesystem/CMakeLists.txt | 10 +++++-- kernel/filesystem/include/filesystem/inode.hpp | 14 +++++++++ .../filesystem/include/filesystem/inode_file.hpp | 25 ++++++++++++++++ kernel/filesystem/src/inode.cpp | 20 +++++++++++++ kernel/filesystem/src/inode_file.cpp | 33 ++++++++++++++++++++++ 5 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 kernel/filesystem/include/filesystem/inode.hpp create mode 100644 kernel/filesystem/include/filesystem/inode_file.hpp create mode 100644 kernel/filesystem/src/inode.cpp create mode 100644 kernel/filesystem/src/inode_file.cpp (limited to 'kernel') diff --git a/kernel/filesystem/CMakeLists.txt b/kernel/filesystem/CMakeLists.txt index a5a964f..126b54e 100644 --- a/kernel/filesystem/CMakeLists.txt +++ b/kernel/filesystem/CMakeLists.txt @@ -3,18 +3,22 @@ add_library("kernel::filesystem" ALIAS "kernel_filesystem") target_sources("kernel_filesystem" PRIVATE "src/device_file.cpp" - "src/open_file_description.cpp" "src/file_descriptor_table.cpp" + "src/inode_file.cpp" + "src/inode.cpp" + "src/open_file_description.cpp" ) target_sources("kernel_filesystem" PUBLIC FILE_SET HEADERS BASE_DIRS "include" FILES - "include/filesystem/file.hpp" "include/filesystem/device_file.hpp" - "include/filesystem/open_file_description.hpp" "include/filesystem/file_descriptor_table.hpp" + "include/filesystem/file.hpp" + "include/filesystem/inode_file.hpp" + "include/filesystem/inode.hpp" + "include/filesystem/open_file_description.hpp" ) target_include_directories("kernel_filesystem" PUBLIC diff --git a/kernel/filesystem/include/filesystem/inode.hpp b/kernel/filesystem/include/filesystem/inode.hpp new file mode 100644 index 0000000..44ec09a --- /dev/null +++ b/kernel/filesystem/include/filesystem/inode.hpp @@ -0,0 +1,14 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP + +#include +namespace filesystem +{ + struct inode + { + auto read(void * buffer, size_t offset, size_t size) const -> size_t; + auto write(void const * buffer, size_t offset, size_t size) -> size_t; + }; +} // namespace filesystem + +#endif diff --git a/kernel/filesystem/include/filesystem/inode_file.hpp b/kernel/filesystem/include/filesystem/inode_file.hpp new file mode 100644 index 0000000..c091280 --- /dev/null +++ b/kernel/filesystem/include/filesystem/inode_file.hpp @@ -0,0 +1,25 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_FILE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_INODE_FILE_HPP + +#include "filesystem/file.hpp" +#include "filesystem/inode.hpp" + +#include + +namespace filesystem +{ + struct inode_file : file + { + explicit inode_file(inode * inode); + + auto open() -> void override; + + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + + private: + inode * m_inode; + }; +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/filesystem/src/inode.cpp b/kernel/filesystem/src/inode.cpp new file mode 100644 index 0000000..7bca507 --- /dev/null +++ b/kernel/filesystem/src/inode.cpp @@ -0,0 +1,20 @@ +#include "filesystem/inode.hpp" + +#include "kapi/system.hpp" + +#include + +namespace filesystem +{ + auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t + { + // TODO BA-FS26 + return 0; + } + + auto inode::write(void const *, size_t, size_t) -> size_t + { + kapi::system::panic("[FILESYSTEM] inode::write is not implemented yet"); + return 0; + } +} // namespace filesystem \ No newline at end of file diff --git a/kernel/filesystem/src/inode_file.cpp b/kernel/filesystem/src/inode_file.cpp new file mode 100644 index 0000000..071661f --- /dev/null +++ b/kernel/filesystem/src/inode_file.cpp @@ -0,0 +1,33 @@ +#include "filesystem/inode_file.hpp" + +#include "kapi/system.hpp" + +#include "filesystem/inode.hpp" + +#include + +namespace filesystem +{ + inode_file::inode_file(inode * inode) + : m_inode(inode) + { + if (!m_inode) + { + kapi::system::panic("[FILESYSTEM] inode_file constructed with null inode"); + } + } + + auto inode_file::open() -> void + { + // Hook point for permission checks or lazy metadata loading. + } + + auto inode_file::read(void * buffer, size_t offset, size_t size) const -> size_t + { + return m_inode->read(buffer, offset, size); + } + auto inode_file::write(void const * buffer, size_t offset, size_t size) -> size_t + { + return m_inode->write(buffer, offset, size); + } +} // namespace filesystem \ No newline at end of file -- cgit v1.2.3 From afda1c1473919e5d9337614075283a50e865be90 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sun, 15 Mar 2026 14:18:30 +0100 Subject: Refactor device_file --- kernel/filesystem/include/filesystem/device_file.hpp | 2 +- kernel/filesystem/src/device_file.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/filesystem/include/filesystem/device_file.hpp b/kernel/filesystem/include/filesystem/device_file.hpp index 08d81f6..033317b 100644 --- a/kernel/filesystem/include/filesystem/device_file.hpp +++ b/kernel/filesystem/include/filesystem/device_file.hpp @@ -11,7 +11,7 @@ namespace filesystem { struct device_file : file { - device_file(devices::device * device); + explicit device_file(devices::device * device); auto open() -> void override; diff --git a/kernel/filesystem/src/device_file.cpp b/kernel/filesystem/src/device_file.cpp index 34195db..f11638e 100644 --- a/kernel/filesystem/src/device_file.cpp +++ b/kernel/filesystem/src/device_file.cpp @@ -16,7 +16,7 @@ namespace filesystem device_file::device_file(devices::device * device) : m_device(device) { - if (m_device == nullptr) + if (!m_device) { kapi::system::panic("[FILESYSTEM] device_file constructed with null device."); } -- cgit v1.2.3 From 1453fbedde547d9e69cdad659df667f43a8dc750 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sun, 15 Mar 2026 14:31:41 +0100 Subject: Create basic VFS structure --- kernel/filesystem/CMakeLists.txt | 2 ++ kernel/filesystem/include/filesystem/vfs.hpp | 21 +++++++++++++++++ kernel/filesystem/src/vfs.cpp | 34 ++++++++++++++++++++++++++++ kernel/src/main.cpp | 4 ++++ 4 files changed, 61 insertions(+) create mode 100644 kernel/filesystem/include/filesystem/vfs.hpp create mode 100644 kernel/filesystem/src/vfs.cpp (limited to 'kernel') diff --git a/kernel/filesystem/CMakeLists.txt b/kernel/filesystem/CMakeLists.txt index 126b54e..a1c625e 100644 --- a/kernel/filesystem/CMakeLists.txt +++ b/kernel/filesystem/CMakeLists.txt @@ -7,6 +7,7 @@ target_sources("kernel_filesystem" PRIVATE "src/inode_file.cpp" "src/inode.cpp" "src/open_file_description.cpp" + "src/vfs.cpp" ) target_sources("kernel_filesystem" PUBLIC @@ -19,6 +20,7 @@ target_sources("kernel_filesystem" PUBLIC "include/filesystem/inode_file.hpp" "include/filesystem/inode.hpp" "include/filesystem/open_file_description.hpp" + "include/filesystem/vfs.hpp" ) target_include_directories("kernel_filesystem" PUBLIC diff --git a/kernel/filesystem/include/filesystem/vfs.hpp b/kernel/filesystem/include/filesystem/vfs.hpp new file mode 100644 index 0000000..671128e --- /dev/null +++ b/kernel/filesystem/include/filesystem/vfs.hpp @@ -0,0 +1,21 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP + +#include +namespace filesystem +{ + struct vfs + { + auto static init() -> void; + auto static get() -> vfs &; + + ~vfs() = default; + + // auto do_mount(std::string_view const & path) -> + + private: + vfs() = default; + }; +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/filesystem/src/vfs.cpp b/kernel/filesystem/src/vfs.cpp new file mode 100644 index 0000000..27f1db9 --- /dev/null +++ b/kernel/filesystem/src/vfs.cpp @@ -0,0 +1,34 @@ +#include "filesystem/vfs.hpp" + +#include "kapi/system.hpp" + +#include + +namespace filesystem +{ + namespace + { + constinit auto static active_vfs = std::optional{}; + } + + auto vfs::init() -> void + { + if (active_vfs) + { + kapi::system::panic("[FILESYSTEM] vfs has already been initialized."); + } + + active_vfs.emplace(vfs{}); + } + + auto vfs::get() -> vfs & + { + if (!active_vfs) + { + kapi::system::panic("[FILESYSTEM] vfs has not been initialized."); + } + + return *active_vfs; + } + +} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 4b74bd4..07fb81b 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -5,6 +5,7 @@ #include "devices/storage/storage_management.hpp" #include "filesystem/file_descriptor_table.hpp" +#include "filesystem/vfs.hpp" #include "kernel/memory.hpp" @@ -29,5 +30,8 @@ auto main() -> int filesystem::file_descriptor_table::init(); kstd::println("[OS] Global file descriptor table initialized."); + filesystem::vfs::init(); + kstd::println("[OS] Virtual filesystem initialized."); + kapi::system::panic("Returning from kernel main!"); } -- cgit v1.2.3 From 76219d593867f6e0c86c9f65ec90c3da18877e2a Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sun, 15 Mar 2026 15:10:49 +0100 Subject: Add basic structure for ext2_filesystem, filesystem and mount --- kernel/filesystem/CMakeLists.txt | 6 +++++ .../include/filesystem/ext2/ext2_filesystem.hpp | 18 +++++++++++++ .../filesystem/include/filesystem/filesystem.hpp | 23 +++++++++++++++++ kernel/filesystem/include/filesystem/mount.hpp | 24 +++++++++++++++++ kernel/filesystem/src/ext2/ext2_filesystem.cpp | 16 ++++++++++++ kernel/filesystem/src/filesystem.cpp | 11 ++++++++ kernel/filesystem/src/mount.cpp | 30 ++++++++++++++++++++++ 7 files changed, 128 insertions(+) create mode 100644 kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp create mode 100644 kernel/filesystem/include/filesystem/filesystem.hpp create mode 100644 kernel/filesystem/include/filesystem/mount.hpp create mode 100644 kernel/filesystem/src/ext2/ext2_filesystem.cpp create mode 100644 kernel/filesystem/src/filesystem.cpp create mode 100644 kernel/filesystem/src/mount.cpp (limited to 'kernel') diff --git a/kernel/filesystem/CMakeLists.txt b/kernel/filesystem/CMakeLists.txt index a1c625e..a6b4e49 100644 --- a/kernel/filesystem/CMakeLists.txt +++ b/kernel/filesystem/CMakeLists.txt @@ -3,9 +3,12 @@ add_library("kernel::filesystem" ALIAS "kernel_filesystem") target_sources("kernel_filesystem" PRIVATE "src/device_file.cpp" + "src/ext2/ext2_filesystem.cpp" "src/file_descriptor_table.cpp" + "src/filesystem.cpp" "src/inode_file.cpp" "src/inode.cpp" + "src/mount.cpp" "src/open_file_description.cpp" "src/vfs.cpp" ) @@ -15,10 +18,13 @@ target_sources("kernel_filesystem" PUBLIC BASE_DIRS "include" FILES "include/filesystem/device_file.hpp" + "include/filesystem/ext2/ext2_filesystem.hpp" "include/filesystem/file_descriptor_table.hpp" "include/filesystem/file.hpp" + "include/filesystem/filesystem.hpp" "include/filesystem/inode_file.hpp" "include/filesystem/inode.hpp" + "include/filesystem/mount.hpp" "include/filesystem/open_file_description.hpp" "include/filesystem/vfs.hpp" ) diff --git a/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp b/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp new file mode 100644 index 0000000..0027475 --- /dev/null +++ b/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp @@ -0,0 +1,18 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP + +#include "devices/block_device.hpp" +#include "filesystem/filesystem.hpp" + +namespace filesystem::ext2 +{ + struct ext2_filesystem : filesystem + { + auto mount(devices::block_device * block_device) -> int override; + + private: + devices::block_device * m_block_device{}; + }; +} // namespace filesystem::ext2 + +#endif diff --git a/kernel/filesystem/include/filesystem/filesystem.hpp b/kernel/filesystem/include/filesystem/filesystem.hpp new file mode 100644 index 0000000..d5704c1 --- /dev/null +++ b/kernel/filesystem/include/filesystem/filesystem.hpp @@ -0,0 +1,23 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP + +#include "devices/block_device.hpp" +#include "filesystem/inode.hpp" + +namespace filesystem +{ + struct filesystem + { + virtual ~filesystem() = default; + + virtual auto mount(devices::block_device * block_device) -> int = 0; + + auto root_inode() -> inode *; + + protected: + inode * m_root_inode{}; // TODO BA-FS26 set during mount? + }; + +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/filesystem/include/filesystem/mount.hpp b/kernel/filesystem/include/filesystem/mount.hpp new file mode 100644 index 0000000..793c042 --- /dev/null +++ b/kernel/filesystem/include/filesystem/mount.hpp @@ -0,0 +1,24 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_MOUNT_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_MOUNT_HPP + +#include "filesystem/filesystem.hpp" + +#include + +namespace filesystem +{ + struct mount + { + mount() = default; // TODO BA-FS26 remove again when kstd::vector is available and used in vfs + mount(std::string_view const & path, filesystem * fs); + + auto path() const -> std::string_view; + auto get_filesystem() const -> filesystem *; + + private: + std::string_view m_path; + filesystem * m_filesystem{}; + }; +} // namespace filesystem + +#endif diff --git a/kernel/filesystem/src/ext2/ext2_filesystem.cpp b/kernel/filesystem/src/ext2/ext2_filesystem.cpp new file mode 100644 index 0000000..bdd430d --- /dev/null +++ b/kernel/filesystem/src/ext2/ext2_filesystem.cpp @@ -0,0 +1,16 @@ +#include "filesystem/ext2/ext2_filesystem.hpp" + +#include "devices/block_device.hpp" + +namespace filesystem::ext2 +{ + auto ext2_filesystem::mount(devices::block_device * block_device) -> int + { + if (!block_device) + { + return -1; // TODO BA-FS26 panic or errorcode? + } + // TODO BA-FS26 implement + return 0; + } +} // namespace filesystem::ext2 \ No newline at end of file diff --git a/kernel/filesystem/src/filesystem.cpp b/kernel/filesystem/src/filesystem.cpp new file mode 100644 index 0000000..d6a2f25 --- /dev/null +++ b/kernel/filesystem/src/filesystem.cpp @@ -0,0 +1,11 @@ +#include "filesystem/filesystem.hpp" + +#include "filesystem/inode.hpp" + +namespace filesystem +{ + auto filesystem::root_inode() -> inode * + { + return m_root_inode; + } +} // namespace filesystem \ No newline at end of file diff --git a/kernel/filesystem/src/mount.cpp b/kernel/filesystem/src/mount.cpp new file mode 100644 index 0000000..6594598 --- /dev/null +++ b/kernel/filesystem/src/mount.cpp @@ -0,0 +1,30 @@ +#include "filesystem/mount.hpp" + +#include "kapi/system.hpp" + +#include "filesystem/filesystem.hpp" + +#include + +namespace filesystem +{ + mount::mount(std::string_view const & path, filesystem * fs) + : m_path(path) + , m_filesystem(fs) + { + if (!m_filesystem) + { + kapi::system::panic("[FILESYSTEM] mount initialized with null filesystem."); + } + } + + auto mount::path() const -> std::string_view + { + return m_path; + } + + auto mount::get_filesystem() const -> filesystem * + { + return m_filesystem; + } +} // namespace filesystem \ No newline at end of file -- cgit v1.2.3 From e87963115bcdc0f0534bc2194bf3f7e3d3f3e2b6 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 15 Mar 2026 15:35:04 +0100 Subject: move test code into separate function --- kernel/src/main.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 07fb81b..011821a 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -4,21 +4,92 @@ #include "kapi/system.hpp" #include "devices/storage/storage_management.hpp" +#include "filesystem/device_file.hpp" #include "filesystem/file_descriptor_table.hpp" +#include "filesystem/open_file_description.hpp" #include "filesystem/vfs.hpp" #include "kernel/memory.hpp" +#include #include +#include +#include +#include + +auto run_test_code() -> void +{ + // setup + auto fd_table = filesystem::file_descriptor_table::get(); + auto storage_mgmt = devices::storage::storage_management::get(); + auto device = storage_mgmt.device_by_major_minor(1, 0); + + filesystem::device_file dev_file(device); + filesystem::open_file_description ofd(&dev_file); + auto fd_index = fd_table.add_file(ofd); + + // use: read two bytes and write two again + auto fd = fd_table.get_file(fd_index); + if (!fd) + { + kstd::os::panic("test code failed"); + } + + std::array buffer{}; + auto number_of_read_bytes = fd->read(buffer.data(), buffer.size()); + + for (size_t i = 0; i < number_of_read_bytes; ++i) + { + kstd::print("{:02x} ", static_cast(buffer[i])); + + if ((i + 1) % 16 == 0) + { + kstd::println(""); + } + } + kstd::println("---"); + + // write half of the file new + std::array write_buffer{std::byte{0xBB}, std::byte{0xAA}}; + auto written_bytes = fd->write(write_buffer.data(), write_buffer.size()); + + kstd::println("written bytes: {}", written_bytes); + + fd_table.remove_file(fd_index); + + // use: read four bytes again -> two old bytes two new bytes + filesystem::open_file_description ofd1(&dev_file); + fd_index = fd_table.add_file(ofd1); + auto fd1 = fd_table.get_file(fd_index); + + if (!fd1) + { + kstd::os::panic("test code failed"); + } + + std::array buffer1{}; + number_of_read_bytes = fd1->read(buffer1.data(), buffer1.size()); + + for (size_t i = 0; i < number_of_read_bytes; ++i) + { + kstd::print("{:02x} ", static_cast(buffer1[i])); + + if ((i + 1) % 16 == 0) + { + kstd::println(""); + } + } + kstd::println("---"); +} + auto main() -> int { kapi::cio::init(); kstd::println("[OS] IO subsystem initialized."); kapi::memory::init(); - kernel::memory::init_heap(kapi::memory::heap_base); - kstd::println("[OS] Memory subsystem initialized."); + kernel::memory::init_heap(kapi::memory::heap_base); kstd::println("[OS] Memory subsystem initialized."); kapi::system::memory_initialized(); kapi::boot_modules::init(); @@ -33,5 +104,7 @@ auto main() -> int filesystem::vfs::init(); kstd::println("[OS] Virtual filesystem initialized."); + run_test_code(); + kapi::system::panic("Returning from kernel main!"); } -- cgit v1.2.3 From ace2d2178315d4b4ff1d969feed562a53d7a66c1 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 15 Mar 2026 15:53:29 +0100 Subject: mount root filesystem --- kernel/filesystem/include/filesystem/vfs.hpp | 8 ++++++++ kernel/filesystem/src/vfs.cpp | 28 +++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/filesystem/include/filesystem/vfs.hpp b/kernel/filesystem/include/filesystem/vfs.hpp index 671128e..5998137 100644 --- a/kernel/filesystem/include/filesystem/vfs.hpp +++ b/kernel/filesystem/include/filesystem/vfs.hpp @@ -1,7 +1,12 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP #define TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP +#include "filesystem/mount.hpp" + +#include +#include #include + namespace filesystem { struct vfs @@ -15,6 +20,9 @@ namespace filesystem private: vfs() = default; + + std::optional m_root_mount; + std::array m_mounts; // TODO BA-FS26 remove when kstd::vector is available and used }; } // namespace filesystem diff --git a/kernel/filesystem/src/vfs.cpp b/kernel/filesystem/src/vfs.cpp index 27f1db9..3f2576f 100644 --- a/kernel/filesystem/src/vfs.cpp +++ b/kernel/filesystem/src/vfs.cpp @@ -2,6 +2,10 @@ #include "kapi/system.hpp" +#include "devices/storage/storage_management.hpp" +#include "filesystem/ext2/ext2_filesystem.hpp" +#include "filesystem/mount.hpp" + #include namespace filesystem @@ -9,7 +13,11 @@ namespace filesystem namespace { constinit auto static active_vfs = std::optional{}; - } + + // TODO BA-FS26 @Felix better solution? while dynamic memory not available? + // TODO BA-FS26 remove when dynamic memory available; + constinit auto static root_fs = std::optional{}; + } // namespace auto vfs::init() -> void { @@ -19,6 +27,24 @@ namespace filesystem } active_vfs.emplace(vfs{}); + + auto storage_mgmt = devices::storage::storage_management::get(); + if (auto boot_device = storage_mgmt.determine_boot_device()) + { + root_fs.emplace(ext2::ext2_filesystem{}); + if (root_fs->mount(boot_device) != 0) + { + kapi::system::panic("[FILESYSTEM] Failed to mount root filesystem."); + } + + active_vfs->m_root_mount = mount{"/", &*root_fs}; + + // TODO BA-FS26 mount all the other devices to "/dev/ramxy" + } + else + { + // TODO BA-FS26 ?? what when no boot_device == no modules loaded?? + } } auto vfs::get() -> vfs & -- cgit v1.2.3 From 8eed4d31cf1d07d43e99d53da0fe3a401ce9e85e Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 15 Mar 2026 16:24:42 +0100 Subject: every device has a name, generate ram disk device names --- kernel/devices/include/devices/block_device.hpp | 4 +++- kernel/devices/include/devices/device.hpp | 12 ++++++++++-- kernel/devices/src/block_device.cpp | 5 +++-- kernel/devices/src/device.cpp | 9 ++++++++- kernel/devices/src/storage/ram_disk/ram_disk_device.cpp | 16 ++++++++++++++-- 5 files changed, 38 insertions(+), 8 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/block_device.hpp b/kernel/devices/include/devices/block_device.hpp index 9bca53f..a2c849f 100644 --- a/kernel/devices/include/devices/block_device.hpp +++ b/kernel/devices/include/devices/block_device.hpp @@ -4,6 +4,7 @@ #include "devices/device.hpp" #include +#include namespace devices { @@ -16,9 +17,10 @@ namespace devices * @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, size_t block_size); + block_device(size_t major, size_t minor, std::string_view name, size_t block_size); /** * @brief Virtual destructor for block device. diff --git a/kernel/devices/include/devices/device.hpp b/kernel/devices/include/devices/device.hpp index 7f9f9e1..d1c202d 100644 --- a/kernel/devices/include/devices/device.hpp +++ b/kernel/devices/include/devices/device.hpp @@ -2,6 +2,7 @@ #define TEACH_OS_KERNEL_DEVICES_DEVICE_HPP #include +#include namespace devices { @@ -14,8 +15,9 @@ namespace devices * @brief Create a device identifier from @p major and @p minor. * @param major Device major number. * @param minor Device minor number. + * @param name Device name. */ - device(size_t major, size_t minor); + device(size_t major, size_t minor, std::string_view name); /** * @brief Virtual destructor for device. @@ -34,6 +36,12 @@ namespace devices */ auto minor() const -> size_t; + /** + * @brief Returns the name of the device. + * @return Device name. + */ + auto name() const -> std::string_view; + /** * @brief Check if the device is a block device. * @return true if this device is a block device, false otherwise. @@ -46,7 +54,7 @@ namespace devices private: size_t m_major; size_t m_minor; - // TODO BA-FS26 add name + std::string_view m_name; }; } // namespace devices diff --git a/kernel/devices/src/block_device.cpp b/kernel/devices/src/block_device.cpp index 2f0c2ca..40f842a 100644 --- a/kernel/devices/src/block_device.cpp +++ b/kernel/devices/src/block_device.cpp @@ -5,11 +5,12 @@ #include "devices/device.hpp" #include +#include namespace devices { - block_device::block_device(size_t major, size_t minor, size_t block_size) - : device(major, minor) + 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) diff --git a/kernel/devices/src/device.cpp b/kernel/devices/src/device.cpp index aa5c1bb..8184321 100644 --- a/kernel/devices/src/device.cpp +++ b/kernel/devices/src/device.cpp @@ -1,12 +1,14 @@ #include "devices/device.hpp" #include +#include namespace devices { - device::device(size_t major, size_t minor) + 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 @@ -18,4 +20,9 @@ namespace devices { 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/devices/src/storage/ram_disk/ram_disk_device.cpp b/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp index 3bd3967..8e9988d 100644 --- a/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp +++ b/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp @@ -7,21 +7,33 @@ #include +#include #include +#include namespace devices::storage::ram_disk { namespace { constexpr size_t RAM_DISK_BLOCK_SIZE = 512uz; // TODO BA-FS26 really correct / good?? + + // 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() // TODO BA-FS26 remove when kstd::vector is available - : block_device(0, 0, RAM_DISK_BLOCK_SIZE) + : block_device(0, 0, determine_device_name(0), RAM_DISK_BLOCK_SIZE) {} ram_disk_device::ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor) - : block_device(major, minor, RAM_DISK_BLOCK_SIZE) + : block_device(major, minor, determine_device_name(minor), RAM_DISK_BLOCK_SIZE) , m_boot_module(module) {} -- cgit v1.2.3 From 2af1bbc99e2a8fc4b86bb31023dbbb077b1cbc97 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 15 Mar 2026 16:49:07 +0100 Subject: move m_devices from ram_disk_controller to storage_controller, store point to devices --- .../storage/ram_disk/ram_disk_controller.hpp | 21 ---------------- .../include/devices/storage/storage_controller.hpp | 7 ++++-- .../include/devices/storage/storage_management.hpp | 10 ++++---- .../src/storage/ram_disk/ram_disk_controller.cpp | 28 ++++++++-------------- kernel/devices/src/storage/storage_controller.cpp | 19 +++++++++++++++ kernel/devices/src/storage/storage_management.cpp | 10 ++++---- .../include/filesystem/ext2/ext2_filesystem.hpp | 6 ++--- .../filesystem/include/filesystem/filesystem.hpp | 4 ++-- kernel/filesystem/src/ext2/ext2_filesystem.cpp | 6 ++--- 9 files changed, 52 insertions(+), 59 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp b/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp index 424082d..f69f8d8 100644 --- a/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp +++ b/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp @@ -3,13 +3,8 @@ #include "kapi/boot_module/boot_module_registry.hpp" -#include "devices/block_device.hpp" -#include "devices/storage/ram_disk/ram_disk_device.hpp" #include "devices/storage/storage_controller.hpp" -#include -#include - namespace devices::storage::ram_disk { /** @@ -28,24 +23,8 @@ namespace devices::storage::ram_disk */ auto probe() -> void override; - /** - * @brief Return the number of managed RAM-disk devices. - * @return Number of managed devices. - */ - auto devices_count() -> size_t override; - - /** - * @brief Look up a RAM-disk device by major/minor numbers. - * @param major Device major number. - * @param minor Device minor number. - * @return Matching block device, or nullptr if no device matches. - */ - auto device_by_minor(size_t minor) -> block_device * override; - private: kapi::boot_modules::boot_module_registry const * m_boot_module_registry; - - std::array m_devices{}; // TODO BA-FS26 use kstd::vector when available }; } // namespace devices::storage::ram_disk diff --git a/kernel/devices/include/devices/storage/storage_controller.hpp b/kernel/devices/include/devices/storage/storage_controller.hpp index 0c7cf83..697d3c3 100644 --- a/kernel/devices/include/devices/storage/storage_controller.hpp +++ b/kernel/devices/include/devices/storage/storage_controller.hpp @@ -2,7 +2,9 @@ #define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP #include "devices/block_device.hpp" +#include "devices/device.hpp" +#include #include namespace devices::storage @@ -42,7 +44,7 @@ namespace devices::storage * @brief Return the number of devices managed by this controller. * @return Number of managed devices. */ - virtual auto devices_count() -> size_t = 0; + auto devices_count() -> size_t; /** * @brief Find a managed device by major/minor numbers. @@ -50,11 +52,12 @@ namespace devices::storage * @param minor Device minor number. * @return Matching block device, or nullptr if no device matches. */ - virtual auto device_by_minor(size_t minor) -> block_device * = 0; + auto device_by_minor(size_t minor) -> device *; protected: size_t m_major{}; size_t m_minors_per_device{}; + std::array m_devices{}; // TODO BA-FS26 use kstd::vector when available }; } // namespace devices::storage diff --git a/kernel/devices/include/devices/storage/storage_management.hpp b/kernel/devices/include/devices/storage/storage_management.hpp index 2bed459..6ca8db7 100644 --- a/kernel/devices/include/devices/storage/storage_management.hpp +++ b/kernel/devices/include/devices/storage/storage_management.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP -#include "devices/block_device.hpp" +#include "devices/device.hpp" #include "devices/storage/storage_controller.hpp" #include @@ -43,18 +43,18 @@ namespace devices::storage auto add_controller(storage_controller * controller) -> void; /** - * @brief Find a block device by major/minor numbers. + * @brief Find a device by major/minor numbers. * @param major Device major number. * @param minor Device minor number. - * @return Matching block device, or nullptr if no device matches. + * @return Matching device, or nullptr if no device matches. */ - auto device_by_major_minor(size_t major, size_t minor) -> block_device *; + auto device_by_major_minor(size_t major, size_t minor) -> device *; /** * @brief Determine the boot device. * @return Boot device, or nullptr if it cannot be determined. */ - auto determine_boot_device() -> block_device *; + auto determine_boot_device() -> device *; private: /** diff --git a/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp b/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp index 9f9537f..b57dcfb 100644 --- a/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp +++ b/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp @@ -2,7 +2,6 @@ #include "kapi/boot_module/boot_module_registry.hpp" -#include "devices/block_device.hpp" #include "devices/storage/ram_disk/ram_disk_device.hpp" #include @@ -10,9 +9,17 @@ #include #include #include +#include namespace devices::storage::ram_disk { + namespace + { + // TODO BA-FS26 @Felix gibts besseren weg (ausser dynamic Memory) + // TODO BA-FS26 remove again, when dynamic memory available + constinit auto static active_ram_disk_device = std::optional{}; + } // namespace + ram_disk_controller::ram_disk_controller(kapi::boot_modules::boot_module_registry const * registry) : m_boot_module_registry(registry) {} @@ -25,23 +32,8 @@ namespace devices::storage::ram_disk auto const minor = current_device_index++ * m_minors_per_device; // TODO BA-FS26 use push_back from kstd::vector when available - m_devices.at(0) = ram_disk_device{module, m_major, minor}; + active_ram_disk_device.emplace(module, m_major, minor); + m_devices.at(0) = &*active_ram_disk_device; }); } - - auto ram_disk_controller::device_by_minor(size_t minor) -> block_device * - { - 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 ram_disk_controller::devices_count() -> size_t - { - return m_devices.size(); - } } // namespace devices::storage::ram_disk \ No newline at end of file diff --git a/kernel/devices/src/storage/storage_controller.cpp b/kernel/devices/src/storage/storage_controller.cpp index f95f533..d127a8c 100644 --- a/kernel/devices/src/storage/storage_controller.cpp +++ b/kernel/devices/src/storage/storage_controller.cpp @@ -1,5 +1,8 @@ #include "devices/storage/storage_controller.hpp" +#include "devices/device.hpp" + +#include #include namespace devices::storage @@ -14,4 +17,20 @@ namespace devices::storage { return m_major; } + + auto storage_controller::device_by_minor(size_t minor) -> device * + { + 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() -> size_t + { + return m_devices.size(); + } } // namespace devices::storage \ No newline at end of file diff --git a/kernel/devices/src/storage/storage_management.cpp b/kernel/devices/src/storage/storage_management.cpp index a5b6503..a981359 100644 --- a/kernel/devices/src/storage/storage_management.cpp +++ b/kernel/devices/src/storage/storage_management.cpp @@ -3,7 +3,7 @@ #include "kapi/boot_modules.hpp" #include "kapi/system.hpp" -#include "devices/block_device.hpp" +#include "devices/device.hpp" #include "devices/storage/ram_disk/ram_disk_controller.hpp" #include "devices/storage/storage_controller.hpp" @@ -20,6 +20,7 @@ namespace devices::storage constinit size_t static next_free_major = START_MAJOR; constinit auto static active_storage_management = std::optional{}; + // TODO BA-FS26 remove again, when dynamic memory available constinit auto static active_ram_disk_controller = std::optional{}; } // namespace @@ -53,9 +54,9 @@ namespace devices::storage m_controllers.at(0) = controller; // TODO BA-FS26 use push_back from kstd:vector } - auto storage_management::device_by_major_minor(size_t major, size_t minor) -> block_device * + auto storage_management::device_by_major_minor(size_t major, size_t minor) -> device * { - block_device * found = nullptr; + device * found = nullptr; std::ranges::find_if(m_controllers, [&](auto const controller) { if (controller != nullptr && controller->major() == major) @@ -69,9 +70,8 @@ namespace devices::storage return found; } - auto storage_management::determine_boot_device() -> block_device * + auto storage_management::determine_boot_device() -> device * { - // TODO BA-FS26 better way? return device_by_major_minor(START_MAJOR, 0); } diff --git a/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp b/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp index 0027475..91ba14a 100644 --- a/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp +++ b/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp @@ -1,17 +1,17 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP -#include "devices/block_device.hpp" +#include "devices/device.hpp" #include "filesystem/filesystem.hpp" namespace filesystem::ext2 { struct ext2_filesystem : filesystem { - auto mount(devices::block_device * block_device) -> int override; + auto mount(devices::device * device) -> int override; private: - devices::block_device * m_block_device{}; + devices::device * m_device{}; }; } // namespace filesystem::ext2 diff --git a/kernel/filesystem/include/filesystem/filesystem.hpp b/kernel/filesystem/include/filesystem/filesystem.hpp index d5704c1..113b239 100644 --- a/kernel/filesystem/include/filesystem/filesystem.hpp +++ b/kernel/filesystem/include/filesystem/filesystem.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP -#include "devices/block_device.hpp" +#include "devices/device.hpp" #include "filesystem/inode.hpp" namespace filesystem @@ -10,7 +10,7 @@ namespace filesystem { virtual ~filesystem() = default; - virtual auto mount(devices::block_device * block_device) -> int = 0; + virtual auto mount(devices::device * device) -> int = 0; auto root_inode() -> inode *; diff --git a/kernel/filesystem/src/ext2/ext2_filesystem.cpp b/kernel/filesystem/src/ext2/ext2_filesystem.cpp index bdd430d..7111d13 100644 --- a/kernel/filesystem/src/ext2/ext2_filesystem.cpp +++ b/kernel/filesystem/src/ext2/ext2_filesystem.cpp @@ -1,12 +1,12 @@ #include "filesystem/ext2/ext2_filesystem.hpp" -#include "devices/block_device.hpp" +#include "devices/device.hpp" namespace filesystem::ext2 { - auto ext2_filesystem::mount(devices::block_device * block_device) -> int + auto ext2_filesystem::mount(devices::device * device) -> int { - if (!block_device) + if (!device) { return -1; // TODO BA-FS26 panic or errorcode? } -- cgit v1.2.3 From 94a92c50cc209ebfa53a9734aff403945a3c9a77 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 15 Mar 2026 18:30:09 +0100 Subject: improve constness, expose controllers and devices --- kernel/devices/include/devices/storage/storage_controller.hpp | 9 ++++++--- kernel/devices/include/devices/storage/storage_management.hpp | 4 ++++ kernel/devices/src/storage/storage_controller.cpp | 10 ++++++++-- kernel/devices/src/storage/storage_management.cpp | 6 ++++++ 4 files changed, 24 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/storage/storage_controller.hpp b/kernel/devices/include/devices/storage/storage_controller.hpp index 697d3c3..0518e32 100644 --- a/kernel/devices/include/devices/storage/storage_controller.hpp +++ b/kernel/devices/include/devices/storage/storage_controller.hpp @@ -1,7 +1,6 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP -#include "devices/block_device.hpp" #include "devices/device.hpp" #include @@ -44,7 +43,11 @@ namespace devices::storage * @brief Return the number of devices managed by this controller. * @return Number of managed devices. */ - auto devices_count() -> size_t; + auto devices_count() const -> size_t; + + // TODO BA-FS26 add comment + // TODO BA-FS26 use kstd::vector when available + auto all_devices() const -> std::array const &; /** * @brief Find a managed device by major/minor numbers. @@ -52,7 +55,7 @@ namespace devices::storage * @param minor Device minor number. * @return Matching block device, or nullptr if no device matches. */ - auto device_by_minor(size_t minor) -> device *; + auto device_by_minor(size_t minor) const -> device *; protected: size_t m_major{}; diff --git a/kernel/devices/include/devices/storage/storage_management.hpp b/kernel/devices/include/devices/storage/storage_management.hpp index 6ca8db7..4bc7cbd 100644 --- a/kernel/devices/include/devices/storage/storage_management.hpp +++ b/kernel/devices/include/devices/storage/storage_management.hpp @@ -42,6 +42,10 @@ namespace devices::storage */ auto add_controller(storage_controller * controller) -> void; + // TODO BA-FS26 add comment + // TODO BA-FS26 use kstd::vector when available + auto all_controllers() const -> std::array const &; + /** * @brief Find a device by major/minor numbers. * @param major Device major number. diff --git a/kernel/devices/src/storage/storage_controller.cpp b/kernel/devices/src/storage/storage_controller.cpp index d127a8c..d9bc806 100644 --- a/kernel/devices/src/storage/storage_controller.cpp +++ b/kernel/devices/src/storage/storage_controller.cpp @@ -3,6 +3,7 @@ #include "devices/device.hpp" #include +#include #include namespace devices::storage @@ -18,7 +19,7 @@ namespace devices::storage return m_major; } - auto storage_controller::device_by_minor(size_t minor) -> device * + auto storage_controller::device_by_minor(size_t minor) const -> device * { auto it = std::ranges::find_if(m_devices, [minor](auto const & device) { return device->minor() == minor; }); @@ -29,8 +30,13 @@ namespace devices::storage return nullptr; } - auto storage_controller::devices_count() -> size_t + auto storage_controller::devices_count() const -> size_t { return m_devices.size(); } + + auto storage_controller::all_devices() const -> std::array const & + { + return m_devices; + } } // namespace devices::storage \ No newline at end of file diff --git a/kernel/devices/src/storage/storage_management.cpp b/kernel/devices/src/storage/storage_management.cpp index a981359..e1f1bcc 100644 --- a/kernel/devices/src/storage/storage_management.cpp +++ b/kernel/devices/src/storage/storage_management.cpp @@ -8,6 +8,7 @@ #include "devices/storage/storage_controller.hpp" #include +#include #include #include @@ -54,6 +55,11 @@ namespace devices::storage m_controllers.at(0) = controller; // TODO BA-FS26 use push_back from kstd:vector } + auto storage_management::all_controllers() const -> std::array const & + { + return m_controllers; + } + auto storage_management::device_by_major_minor(size_t major, size_t minor) -> device * { device * found = nullptr; -- cgit v1.2.3 From 5c274e8676006201eb2536f4a09d63fab109e538 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 15 Mar 2026 18:30:32 +0100 Subject: small refactoring --- kernel/devices/src/storage/ram_disk/ram_disk_device.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp b/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp index 8e9988d..d05ae7a 100644 --- a/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp +++ b/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp @@ -19,12 +19,13 @@ namespace devices::storage::ram_disk // TODO BA-FS26 @Felix // TODO BA-FS26 currently only names for 9 minor devices - constinit std::array NAME = {'r', 'a', 'm', '0', '\0'}; + // TODO BA-FS26 when this length is changed, also change the one in vfs.cpp + 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}; + name[3] = '0' + minor; + return std::string_view{name}; } } // namespace -- cgit v1.2.3 From e355d5e6aa84b1ea4de70820159b5f1af13bc6f8 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 15 Mar 2026 18:32:16 +0100 Subject: implement first draft of make_device_node --- kernel/filesystem/include/filesystem/vfs.hpp | 2 ++ kernel/filesystem/src/vfs.cpp | 31 +++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/filesystem/include/filesystem/vfs.hpp b/kernel/filesystem/include/filesystem/vfs.hpp index 5998137..67fd5df 100644 --- a/kernel/filesystem/include/filesystem/vfs.hpp +++ b/kernel/filesystem/include/filesystem/vfs.hpp @@ -1,6 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP #define TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP +#include "devices/device.hpp" #include "filesystem/mount.hpp" #include @@ -17,6 +18,7 @@ namespace filesystem ~vfs() = default; // auto do_mount(std::string_view const & path) -> + auto make_device_node(devices::device * device) -> void; private: vfs() = default; diff --git a/kernel/filesystem/src/vfs.cpp b/kernel/filesystem/src/vfs.cpp index 3f2576f..573994a 100644 --- a/kernel/filesystem/src/vfs.cpp +++ b/kernel/filesystem/src/vfs.cpp @@ -2,11 +2,17 @@ #include "kapi/system.hpp" +#include "devices/device.hpp" #include "devices/storage/storage_management.hpp" #include "filesystem/ext2/ext2_filesystem.hpp" #include "filesystem/mount.hpp" +#include + +#include +#include #include +#include namespace filesystem { @@ -17,6 +23,12 @@ namespace filesystem // TODO BA-FS26 @Felix better solution? while dynamic memory not available? // TODO BA-FS26 remove when dynamic memory available; constinit auto static root_fs = std::optional{}; + // TODO BA-FS26 use kstd::vector when available + constinit auto static filesystems = std::array, 1>{}; + + // TODO BA-FS26 @Felix + // TODO BA-FS26 depends on the length of ram_disk_device name + constinit std::array device_mount_path = {'/', 'd', 'e', 'v', '/', 'x', 'x', 'x', 'x', '\0'}; } // namespace auto vfs::init() -> void @@ -39,7 +51,9 @@ namespace filesystem active_vfs->m_root_mount = mount{"/", &*root_fs}; - // TODO BA-FS26 mount all the other devices to "/dev/ramxy" + std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto controller) { + std::ranges::for_each(controller->all_devices(), [&](auto device) { active_vfs->make_device_node(device); }); + }); } else { @@ -57,4 +71,19 @@ namespace filesystem return *active_vfs; } + auto vfs::make_device_node(devices::device * device) -> void + { + auto device_name = device->name(); + kstd::libc::memcpy(&device_mount_path[5], device_name.data(), device_name.size()); + + // TODO BA-FS26 use kstd::vector and push_back when available + filesystems[0].emplace(ext2::ext2_filesystem{}); + if (filesystems[0]->mount(device) != 0) + { + kapi::system::panic("[FILESYSTEM] Failed to mount device filesystem."); + } + + m_mounts[0] = mount{std::string_view{device_mount_path.data()}, &*filesystems[0]}; + } + } // namespace filesystem \ No newline at end of file -- cgit v1.2.3 From f52f4eb4aff3f8346c9ba73bcc57db4ca6fc6cb2 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 15 Mar 2026 18:49:34 +0100 Subject: implement first draft of custody --- kernel/filesystem/CMakeLists.txt | 6 +++-- kernel/filesystem/include/filesystem/custody.hpp | 21 ++++++++++++++++++ kernel/filesystem/src/custody.cpp | 28 ++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 kernel/filesystem/include/filesystem/custody.hpp create mode 100644 kernel/filesystem/src/custody.cpp (limited to 'kernel') diff --git a/kernel/filesystem/CMakeLists.txt b/kernel/filesystem/CMakeLists.txt index a6b4e49..19f1be1 100644 --- a/kernel/filesystem/CMakeLists.txt +++ b/kernel/filesystem/CMakeLists.txt @@ -2,8 +2,9 @@ add_library("kernel_filesystem" STATIC) add_library("kernel::filesystem" ALIAS "kernel_filesystem") target_sources("kernel_filesystem" PRIVATE - "src/device_file.cpp" "src/ext2/ext2_filesystem.cpp" + "src/custody.cpp" + "src/device_file.cpp" "src/file_descriptor_table.cpp" "src/filesystem.cpp" "src/inode_file.cpp" @@ -17,8 +18,9 @@ target_sources("kernel_filesystem" PUBLIC FILE_SET HEADERS BASE_DIRS "include" FILES - "include/filesystem/device_file.hpp" "include/filesystem/ext2/ext2_filesystem.hpp" + "include/filesystem/custody.hpp" + "include/filesystem/device_file.hpp" "include/filesystem/file_descriptor_table.hpp" "include/filesystem/file.hpp" "include/filesystem/filesystem.hpp" diff --git a/kernel/filesystem/include/filesystem/custody.hpp b/kernel/filesystem/include/filesystem/custody.hpp new file mode 100644 index 0000000..9ee984d --- /dev/null +++ b/kernel/filesystem/include/filesystem/custody.hpp @@ -0,0 +1,21 @@ +#ifndef TEACH_OS_KERNEL_CUSTODY_HPP +#define TEACH_OS_KERNEL_CUSTODY_HPP + +#include "filesystem/inode.hpp" + +namespace filesystem +{ + struct custody + { + custody(custody * parent, inode * node); + + [[nodiscard]] auto get_inode() const -> inode *; + [[nodiscard]] auto get_parent() const -> custody *; + + private: + custody * m_parent; + inode * m_inode; + }; +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/filesystem/src/custody.cpp b/kernel/filesystem/src/custody.cpp new file mode 100644 index 0000000..614e63b --- /dev/null +++ b/kernel/filesystem/src/custody.cpp @@ -0,0 +1,28 @@ +#include "filesystem/custody.hpp" + +#include "kapi/system.hpp" + +#include "filesystem/inode.hpp" + +namespace filesystem +{ + custody::custody(custody * parent, inode * node) + : m_parent(parent) + , m_inode(node) + { + if (!m_inode) + { + kapi::system::panic("[FILESYSTEM] custody constructed with null inode."); + } + } + + auto custody::get_inode() const -> inode * + { + return m_inode; + } + + auto custody::get_parent() const -> custody * + { + return m_parent; + } +} // namespace filesystem \ No newline at end of file -- cgit v1.2.3 From 6d8ae9c708d43ab3d98d6a1f2fbb4e5f74a4a2aa Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 15 Mar 2026 18:51:26 +0100 Subject: improve constness --- kernel/filesystem/include/filesystem/file_descriptor_table.hpp | 2 +- kernel/filesystem/include/filesystem/filesystem.hpp | 2 +- kernel/filesystem/include/filesystem/mount.hpp | 4 ++-- kernel/filesystem/include/filesystem/vfs.hpp | 2 -- kernel/filesystem/src/file_descriptor_table.cpp | 2 +- kernel/filesystem/src/filesystem.cpp | 2 +- 6 files changed, 6 insertions(+), 8 deletions(-) (limited to 'kernel') diff --git a/kernel/filesystem/include/filesystem/file_descriptor_table.hpp b/kernel/filesystem/include/filesystem/file_descriptor_table.hpp index 44fd428..3ac03d1 100644 --- a/kernel/filesystem/include/filesystem/file_descriptor_table.hpp +++ b/kernel/filesystem/include/filesystem/file_descriptor_table.hpp @@ -16,7 +16,7 @@ namespace filesystem ~file_descriptor_table() = default; auto add_file(open_file_description & f) -> int; - auto get_file(int fd) -> std::optional; + [[nodiscard]] auto get_file(int fd) const -> std::optional; auto remove_file(int fd) -> void; private: diff --git a/kernel/filesystem/include/filesystem/filesystem.hpp b/kernel/filesystem/include/filesystem/filesystem.hpp index 113b239..a5a1047 100644 --- a/kernel/filesystem/include/filesystem/filesystem.hpp +++ b/kernel/filesystem/include/filesystem/filesystem.hpp @@ -12,7 +12,7 @@ namespace filesystem virtual auto mount(devices::device * device) -> int = 0; - auto root_inode() -> inode *; + [[nodiscard]] auto root_inode() const -> inode *; protected: inode * m_root_inode{}; // TODO BA-FS26 set during mount? diff --git a/kernel/filesystem/include/filesystem/mount.hpp b/kernel/filesystem/include/filesystem/mount.hpp index 793c042..fe5d9cc 100644 --- a/kernel/filesystem/include/filesystem/mount.hpp +++ b/kernel/filesystem/include/filesystem/mount.hpp @@ -12,8 +12,8 @@ namespace filesystem mount() = default; // TODO BA-FS26 remove again when kstd::vector is available and used in vfs mount(std::string_view const & path, filesystem * fs); - auto path() const -> std::string_view; - auto get_filesystem() const -> filesystem *; + [[nodiscard]] auto path() const -> std::string_view; + [[nodiscard]] auto get_filesystem() const -> filesystem *; private: std::string_view m_path; diff --git a/kernel/filesystem/include/filesystem/vfs.hpp b/kernel/filesystem/include/filesystem/vfs.hpp index 67fd5df..182666d 100644 --- a/kernel/filesystem/include/filesystem/vfs.hpp +++ b/kernel/filesystem/include/filesystem/vfs.hpp @@ -6,7 +6,6 @@ #include #include -#include namespace filesystem { @@ -17,7 +16,6 @@ namespace filesystem ~vfs() = default; - // auto do_mount(std::string_view const & path) -> auto make_device_node(devices::device * device) -> void; private: diff --git a/kernel/filesystem/src/file_descriptor_table.cpp b/kernel/filesystem/src/file_descriptor_table.cpp index 49c08cd..eb9a281 100644 --- a/kernel/filesystem/src/file_descriptor_table.cpp +++ b/kernel/filesystem/src/file_descriptor_table.cpp @@ -47,7 +47,7 @@ namespace filesystem return -1; } - auto file_descriptor_table::get_file(int fd) -> std::optional + auto file_descriptor_table::get_file(int fd) const -> std::optional { if (fd < 0) { diff --git a/kernel/filesystem/src/filesystem.cpp b/kernel/filesystem/src/filesystem.cpp index d6a2f25..2c63766 100644 --- a/kernel/filesystem/src/filesystem.cpp +++ b/kernel/filesystem/src/filesystem.cpp @@ -4,7 +4,7 @@ namespace filesystem { - auto filesystem::root_inode() -> inode * + auto filesystem::root_inode() const -> inode * { return m_root_inode; } -- cgit v1.2.3 From 760752ef2045aaceb0393911a0919f9bc0104282 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 15 Mar 2026 20:37:14 +0100 Subject: implement first inode draft, fix make_device_node, implement first draft of resolve_path (currently with temp m_device_nodes in vfs -> has later to be deleted again, just for tests) --- .../filesystem/include/filesystem/filesystem.hpp | 4 +- kernel/filesystem/include/filesystem/inode.hpp | 15 +++++ kernel/filesystem/include/filesystem/vfs.hpp | 15 ++++- kernel/filesystem/src/ext2/ext2_filesystem.cpp | 4 ++ kernel/filesystem/src/filesystem.cpp | 2 +- kernel/filesystem/src/inode.cpp | 56 ++++++++++++++++ kernel/filesystem/src/vfs.cpp | 77 ++++++++++++++++++---- 7 files changed, 156 insertions(+), 17 deletions(-) (limited to 'kernel') diff --git a/kernel/filesystem/include/filesystem/filesystem.hpp b/kernel/filesystem/include/filesystem/filesystem.hpp index a5a1047..2077ed6 100644 --- a/kernel/filesystem/include/filesystem/filesystem.hpp +++ b/kernel/filesystem/include/filesystem/filesystem.hpp @@ -12,10 +12,10 @@ namespace filesystem virtual auto mount(devices::device * device) -> int = 0; - [[nodiscard]] auto root_inode() const -> inode *; + [[nodiscard]] auto root_inode() const -> inode const &; protected: - inode * m_root_inode{}; // TODO BA-FS26 set during mount? + inode m_root_inode{}; // TODO BA-FS26 set during mount? }; } // namespace filesystem diff --git a/kernel/filesystem/include/filesystem/inode.hpp b/kernel/filesystem/include/filesystem/inode.hpp index 44ec09a..eb8440f 100644 --- a/kernel/filesystem/include/filesystem/inode.hpp +++ b/kernel/filesystem/include/filesystem/inode.hpp @@ -1,13 +1,28 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP +#include "devices/device.hpp" + #include + namespace filesystem { struct inode { + inode() = default; + explicit inode(devices::device * device); + + [[nodiscard]] auto is_device() const -> bool; + [[nodiscard]] auto is_block_device() const -> bool; + [[nodiscard]] auto major_device() const -> size_t; + [[nodiscard]] auto minor_device() const -> size_t; + [[nodiscard]] auto backing_device() const -> devices::device *; + auto read(void * buffer, size_t offset, size_t size) const -> size_t; auto write(void const * buffer, size_t offset, size_t size) -> size_t; + + private: + devices::device * m_device{}; }; } // namespace filesystem diff --git a/kernel/filesystem/include/filesystem/vfs.hpp b/kernel/filesystem/include/filesystem/vfs.hpp index 182666d..a881241 100644 --- a/kernel/filesystem/include/filesystem/vfs.hpp +++ b/kernel/filesystem/include/filesystem/vfs.hpp @@ -2,10 +2,14 @@ #define TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP #include "devices/device.hpp" +#include "filesystem/custody.hpp" +#include "filesystem/inode.hpp" #include "filesystem/mount.hpp" +#include "filesystem/open_file_description.hpp" #include #include +#include namespace filesystem { @@ -16,13 +20,22 @@ namespace filesystem ~vfs() = default; - auto make_device_node(devices::device * device) -> void; + auto open(std::string_view path) -> std::optional; private: + struct device_node_entry + { + std::string_view name; + inode node; + }; + vfs() = default; + auto make_device_node(devices::device * device) -> void; + [[nodiscard]] auto resolve_path(std::string_view path) -> std::optional; std::optional m_root_mount; std::array m_mounts; // TODO BA-FS26 remove when kstd::vector is available and used + std::array, 10> m_device_nodes; // TODO BA-FS26 use kstd::vector }; } // namespace filesystem diff --git a/kernel/filesystem/src/ext2/ext2_filesystem.cpp b/kernel/filesystem/src/ext2/ext2_filesystem.cpp index 7111d13..97257a2 100644 --- a/kernel/filesystem/src/ext2/ext2_filesystem.cpp +++ b/kernel/filesystem/src/ext2/ext2_filesystem.cpp @@ -1,6 +1,7 @@ #include "filesystem/ext2/ext2_filesystem.hpp" #include "devices/device.hpp" +#include "filesystem/inode.hpp" namespace filesystem::ext2 { @@ -10,6 +11,9 @@ namespace filesystem::ext2 { return -1; // TODO BA-FS26 panic or errorcode? } + + m_root_inode = inode{}; // TODO BA-FS26 set properly during mount? + // TODO BA-FS26 implement return 0; } diff --git a/kernel/filesystem/src/filesystem.cpp b/kernel/filesystem/src/filesystem.cpp index 2c63766..cdfe7f8 100644 --- a/kernel/filesystem/src/filesystem.cpp +++ b/kernel/filesystem/src/filesystem.cpp @@ -4,7 +4,7 @@ namespace filesystem { - auto filesystem::root_inode() const -> inode * + auto filesystem::root_inode() const -> inode const & { return m_root_inode; } diff --git a/kernel/filesystem/src/inode.cpp b/kernel/filesystem/src/inode.cpp index 7bca507..a1427e2 100644 --- a/kernel/filesystem/src/inode.cpp +++ b/kernel/filesystem/src/inode.cpp @@ -2,18 +2,74 @@ #include "kapi/system.hpp" +#include "devices/device.hpp" + #include namespace filesystem { + inode::inode(devices::device * device) + : m_device(device) + { + if (!m_device) + { + kapi::system::panic("[FILESYSTEM] inode constructed with null device."); + } + } + + auto inode::is_device() const -> bool + { + return m_device != nullptr; + } + + auto inode::is_block_device() const -> bool + { + return is_device() && m_device->is_block_device(); + } + + auto inode::major_device() const -> size_t + { + if (!is_device()) + { + kapi::system::panic("[FILESYSTEM] inode::major_device called on non-device inode."); + } + + return m_device->major(); + } + + auto inode::minor_device() const -> size_t + { + if (!is_device()) + { + kapi::system::panic("[FILESYSTEM] inode::minor_device called on non-device inode."); + } + + return m_device->minor(); + } + + auto inode::backing_device() const -> devices::device * + { + return m_device; + } + auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t { + if (is_device()) + { + kapi::system::panic("[FILESYSTEM] inode::read called on device inode. Open it as a device file first."); + } + // TODO BA-FS26 return 0; } auto inode::write(void const *, size_t, size_t) -> size_t { + if (is_device()) + { + kapi::system::panic("[FILESYSTEM] inode::write called on device inode. Open it as a device file first."); + } + kapi::system::panic("[FILESYSTEM] inode::write is not implemented yet"); return 0; } diff --git a/kernel/filesystem/src/vfs.cpp b/kernel/filesystem/src/vfs.cpp index 573994a..2ecf847 100644 --- a/kernel/filesystem/src/vfs.cpp +++ b/kernel/filesystem/src/vfs.cpp @@ -4,13 +4,17 @@ #include "devices/device.hpp" #include "devices/storage/storage_management.hpp" +#include "filesystem/custody.hpp" +#include "filesystem/device_file.hpp" #include "filesystem/ext2/ext2_filesystem.hpp" +#include "filesystem/inode.hpp" +#include "filesystem/inode_file.hpp" #include "filesystem/mount.hpp" +#include "filesystem/open_file_description.hpp" #include #include -#include #include #include @@ -23,12 +27,11 @@ namespace filesystem // TODO BA-FS26 @Felix better solution? while dynamic memory not available? // TODO BA-FS26 remove when dynamic memory available; constinit auto static root_fs = std::optional{}; - // TODO BA-FS26 use kstd::vector when available - constinit auto static filesystems = std::array, 1>{}; - // TODO BA-FS26 @Felix - // TODO BA-FS26 depends on the length of ram_disk_device name - constinit std::array device_mount_path = {'/', 'd', 'e', 'v', '/', 'x', 'x', 'x', 'x', '\0'}; + // TODO BA-FS26 remove when dynamic memory available; + constinit auto static temp_device_file = std::optional{}; + // TODO BA-FS26 remove when dynamic memory available; + constinit auto static temp_inode_file = std::optional{}; } // namespace auto vfs::init() -> void @@ -71,19 +74,67 @@ namespace filesystem return *active_vfs; } + auto vfs::open(std::string_view path) -> std::optional + { + if (auto custody = resolve_path(path)) + { + auto * node = custody->get_inode(); + if (node->is_device()) + { + temp_device_file.emplace(node->backing_device()); + temp_device_file->open(); + return open_file_description{&*temp_device_file}; + } + + temp_inode_file.emplace(node); + temp_inode_file->open(); + return open_file_description{&*temp_inode_file}; + } + + return std::nullopt; + } + auto vfs::make_device_node(devices::device * device) -> void { - auto device_name = device->name(); - kstd::libc::memcpy(&device_mount_path[5], device_name.data(), device_name.size()); + if (!device) + { + kapi::system::panic("[FILESYSTEM] make_device_node called with null device."); + } + + auto const device_name = device->name(); + + // TODO BA-FS26 this logic isn't needed anymore when kstd::vector available, just use push_back + auto const slot = std::ranges::find_if(m_device_nodes, [](auto const & entry) { return !entry.has_value(); }); + if (slot == m_device_nodes.end()) + { + kapi::system::panic("[FILESYSTEM] No free slot available for device nodes."); + } + + slot->emplace(device_node_entry{device_name, inode{device}}); + } + + auto vfs::resolve_path(std::string_view path) -> std::optional + { + // TODO BA-FS26 implement real path resolution with mounts and directories etc. + // For now, just support device nodes at /dev/. - // TODO BA-FS26 use kstd::vector and push_back when available - filesystems[0].emplace(ext2::ext2_filesystem{}); - if (filesystems[0]->mount(device) != 0) + constexpr auto device_prefix = std::string_view{"/dev/"}; + if (path.starts_with(device_prefix)) { - kapi::system::panic("[FILESYSTEM] Failed to mount device filesystem."); + auto const device_name = path.substr(device_prefix.size()); + auto entry = std::ranges::find_if(m_device_nodes, [&](auto const & device_entry) { + return device_entry.has_value() && device_entry->name == device_name; + }); + + if (entry != m_device_nodes.end()) + { + return custody{nullptr, &entry->value().node}; + } + + return std::nullopt; } - m_mounts[0] = mount{std::string_view{device_mount_path.data()}, &*filesystems[0]}; + return std::nullopt; } } // namespace filesystem \ No newline at end of file -- cgit v1.2.3 From 62005f563e3c29b079c69380905a82fd0d91c975 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 16 Mar 2026 18:27:59 +0100 Subject: add first draft of inode metadata --- kernel/filesystem/CMakeLists.txt | 1 + .../include/filesystem/ext2/ext2_filesystem.hpp | 4 +++ .../filesystem/include/filesystem/filesystem.hpp | 6 +++- kernel/filesystem/include/filesystem/inode.hpp | 7 +++++ .../include/filesystem/inode_metadata.hpp | 24 +++++++++++++++ kernel/filesystem/src/ext2/ext2_filesystem.cpp | 14 +++++++-- kernel/filesystem/src/filesystem.cpp | 9 ++++-- kernel/filesystem/src/inode.cpp | 34 ++++++++++++++++++++-- 8 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 kernel/filesystem/include/filesystem/inode_metadata.hpp (limited to 'kernel') diff --git a/kernel/filesystem/CMakeLists.txt b/kernel/filesystem/CMakeLists.txt index 19f1be1..bb2090a 100644 --- a/kernel/filesystem/CMakeLists.txt +++ b/kernel/filesystem/CMakeLists.txt @@ -25,6 +25,7 @@ target_sources("kernel_filesystem" PUBLIC "include/filesystem/file.hpp" "include/filesystem/filesystem.hpp" "include/filesystem/inode_file.hpp" + "include/filesystem/inode_metadata.hpp" "include/filesystem/inode.hpp" "include/filesystem/mount.hpp" "include/filesystem/open_file_description.hpp" diff --git a/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp b/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp index 91ba14a..cba2192 100644 --- a/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp +++ b/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp @@ -3,12 +3,16 @@ #include "devices/device.hpp" #include "filesystem/filesystem.hpp" +#include "filesystem/inode.hpp" + +#include namespace filesystem::ext2 { struct ext2_filesystem : filesystem { auto mount(devices::device * device) -> int override; + auto lookup(inode const & parent, std::string_view name) -> inode * override; private: devices::device * m_device{}; diff --git a/kernel/filesystem/include/filesystem/filesystem.hpp b/kernel/filesystem/include/filesystem/filesystem.hpp index 2077ed6..8deb336 100644 --- a/kernel/filesystem/include/filesystem/filesystem.hpp +++ b/kernel/filesystem/include/filesystem/filesystem.hpp @@ -4,6 +4,8 @@ #include "devices/device.hpp" #include "filesystem/inode.hpp" +#include + namespace filesystem { struct filesystem @@ -11,8 +13,10 @@ namespace filesystem virtual ~filesystem() = default; virtual auto mount(devices::device * device) -> int = 0; + virtual auto lookup(inode const & parent, std::string_view name) -> inode * = 0; - [[nodiscard]] auto root_inode() const -> inode const &; + [[nodiscard]] auto root_inode() -> inode *; + [[nodiscard]] auto root_inode() const -> inode const *; protected: inode m_root_inode{}; // TODO BA-FS26 set during mount? diff --git a/kernel/filesystem/include/filesystem/inode.hpp b/kernel/filesystem/include/filesystem/inode.hpp index eb8440f..bceabb6 100644 --- a/kernel/filesystem/include/filesystem/inode.hpp +++ b/kernel/filesystem/include/filesystem/inode.hpp @@ -2,6 +2,7 @@ #define TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP #include "devices/device.hpp" +#include "filesystem/inode_metadata.hpp" #include @@ -10,8 +11,13 @@ namespace filesystem struct inode { inode() = default; + explicit inode(inode_kind kind); explicit inode(devices::device * device); + [[nodiscard]] auto metadata() const -> inode_metadata; + + [[nodiscard]] auto is_directory() const -> bool; + [[nodiscard]] auto is_regular() const -> bool; [[nodiscard]] auto is_device() const -> bool; [[nodiscard]] auto is_block_device() const -> bool; [[nodiscard]] auto major_device() const -> size_t; @@ -22,6 +28,7 @@ namespace filesystem auto write(void const * buffer, size_t offset, size_t size) -> size_t; private: + inode_kind m_kind{inode_kind::regular}; devices::device * m_device{}; }; } // namespace filesystem diff --git a/kernel/filesystem/include/filesystem/inode_metadata.hpp b/kernel/filesystem/include/filesystem/inode_metadata.hpp new file mode 100644 index 0000000..ed5a09d --- /dev/null +++ b/kernel/filesystem/include/filesystem/inode_metadata.hpp @@ -0,0 +1,24 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_METADATA_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_INODE_METADATA_HPP + +#include +#include + +namespace filesystem +{ + enum class inode_kind + { + regular, + directory, + device + }; + + struct inode_metadata + { + inode_kind kind{inode_kind::regular}; + std::optional major{}; + std::optional minor{}; + }; +} // namespace filesystem + +#endif // TEACH_OS_KERNEL_FILESYSTEM_INODE_METADATA_HPP \ No newline at end of file diff --git a/kernel/filesystem/src/ext2/ext2_filesystem.cpp b/kernel/filesystem/src/ext2/ext2_filesystem.cpp index 97257a2..f092ddf 100644 --- a/kernel/filesystem/src/ext2/ext2_filesystem.cpp +++ b/kernel/filesystem/src/ext2/ext2_filesystem.cpp @@ -3,6 +3,8 @@ #include "devices/device.hpp" #include "filesystem/inode.hpp" +#include + namespace filesystem::ext2 { auto ext2_filesystem::mount(devices::device * device) -> int @@ -12,9 +14,17 @@ namespace filesystem::ext2 return -1; // TODO BA-FS26 panic or errorcode? } - m_root_inode = inode{}; // TODO BA-FS26 set properly during mount? + m_device = device; + // TODO BA-FS26 load proper root inode from ext2 metadata + m_root_inode = inode{inode_kind::directory}; // TODO BA-FS26 implement return 0; } -} // namespace filesystem::ext2 \ No newline at end of file + + auto ext2_filesystem::lookup(inode const & /*parent*/, std::string_view /*name*/) -> inode * + { + // TODO BA-FS26 implement ext2 directory traversal and inode loading + return nullptr; + } +} // namespace filesystem::ext2 diff --git a/kernel/filesystem/src/filesystem.cpp b/kernel/filesystem/src/filesystem.cpp index cdfe7f8..a06bccc 100644 --- a/kernel/filesystem/src/filesystem.cpp +++ b/kernel/filesystem/src/filesystem.cpp @@ -4,8 +4,13 @@ namespace filesystem { - auto filesystem::root_inode() const -> inode const & + auto filesystem::root_inode() -> inode * { - return m_root_inode; + return &m_root_inode; + } + + auto filesystem::root_inode() const -> inode const * + { + return &m_root_inode; } } // namespace filesystem \ No newline at end of file diff --git a/kernel/filesystem/src/inode.cpp b/kernel/filesystem/src/inode.cpp index a1427e2..17aa52a 100644 --- a/kernel/filesystem/src/inode.cpp +++ b/kernel/filesystem/src/inode.cpp @@ -3,13 +3,19 @@ #include "kapi/system.hpp" #include "devices/device.hpp" +#include "filesystem/inode_metadata.hpp" #include namespace filesystem { + inode::inode(inode_kind kind) + : m_kind(kind) + {} + inode::inode(devices::device * device) - : m_device(device) + : m_kind(inode_kind::device) + , m_device(device) { if (!m_device) { @@ -17,9 +23,33 @@ namespace filesystem } } + auto inode::metadata() const -> inode_metadata + { + auto meta = inode_metadata{}; + meta.kind = m_kind; + + if (is_device()) + { + meta.major = m_device->major(); + meta.minor = m_device->minor(); + } + + return meta; + } + + auto inode::is_directory() const -> bool + { + return m_kind == inode_kind::directory; + } + + auto inode::is_regular() const -> bool + { + return m_kind == inode_kind::regular; + } + auto inode::is_device() const -> bool { - return m_device != nullptr; + return m_kind == inode_kind::device; } auto inode::is_block_device() const -> bool -- cgit v1.2.3 From b0e2fec58c93c8e993f0ecba0dc4862bde760b1b Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 16 Mar 2026 18:53:50 +0100 Subject: remove comment --- kernel/devices/src/storage/ram_disk/ram_disk_device.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'kernel') diff --git a/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp b/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp index d05ae7a..774e949 100644 --- a/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp +++ b/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp @@ -19,7 +19,6 @@ namespace devices::storage::ram_disk // TODO BA-FS26 @Felix // TODO BA-FS26 currently only names for 9 minor devices - // TODO BA-FS26 when this length is changed, also change the one in vfs.cpp constinit std::array name = {'r', 'a', 'm', '0', '\0'}; auto determine_device_name(size_t minor) -> std::string_view -- cgit v1.2.3 From bcedba978671d4947c63bdcd044e10fae9a7be66 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 16 Mar 2026 19:00:00 +0100 Subject: add todo --- kernel/filesystem/include/filesystem/vfs.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/filesystem/include/filesystem/vfs.hpp b/kernel/filesystem/include/filesystem/vfs.hpp index a881241..1d95d4a 100644 --- a/kernel/filesystem/include/filesystem/vfs.hpp +++ b/kernel/filesystem/include/filesystem/vfs.hpp @@ -35,7 +35,8 @@ namespace filesystem std::optional m_root_mount; std::array m_mounts; // TODO BA-FS26 remove when kstd::vector is available and used - std::array, 10> m_device_nodes; // TODO BA-FS26 use kstd::vector + std::array, 10> + m_device_nodes; // TODO BA-FS26 use kstd::vector // TODO BA-FS26 remove again, use }; } // namespace filesystem -- cgit v1.2.3 From 9391c5881a8a635677312df80888e972d7175cfa Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 17 Mar 2026 09:13:43 +0100 Subject: fix lint issues --- kernel/devices/include/devices/block_device.hpp | 10 +++++----- kernel/devices/include/devices/device.hpp | 12 ++++++------ .../include/devices/storage/ram_disk/ram_disk_device.hpp | 2 +- .../devices/include/devices/storage/storage_controller.hpp | 8 ++++---- .../devices/include/devices/storage/storage_management.hpp | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/block_device.hpp b/kernel/devices/include/devices/block_device.hpp index a2c849f..4831be5 100644 --- a/kernel/devices/include/devices/block_device.hpp +++ b/kernel/devices/include/devices/block_device.hpp @@ -52,20 +52,20 @@ namespace devices * @brief Return logical block size in bytes. * @return One logical block size in bytes. */ - auto block_size() const -> size_t; + [[nodiscard]] auto block_size() const -> size_t; /** * @brief Return device capacity in bytes. * @return Total number of addressable bytes. */ - auto capacity() const -> size_t; + [[nodiscard]] auto capacity() const -> size_t; /** * @brief Override to identify block devices. * @return true if this device is a block device, false otherwise. */ - auto is_block_device() const -> bool override + [[nodiscard]] auto is_block_device() const -> bool override { return true; } @@ -85,14 +85,14 @@ namespace devices * @brief Return total device size in bytes. * @return Total number of addressable bytes. */ - virtual auto size() const -> size_t = 0; + [[nodiscard]] virtual auto size() const -> size_t = 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. */ - auto calculate_transfer(size_t block_index) const -> transfer_info; + [[nodiscard]] auto calculate_transfer(size_t block_index) const -> transfer_info; size_t m_block_size; }; diff --git a/kernel/devices/include/devices/device.hpp b/kernel/devices/include/devices/device.hpp index d1c202d..d6f520f 100644 --- a/kernel/devices/include/devices/device.hpp +++ b/kernel/devices/include/devices/device.hpp @@ -7,12 +7,12 @@ namespace devices { /** - * @brief Base device identified by a major and minor number. + * @brief Base device identified by a major, minor number and name. */ struct device { /** - * @brief Create a device identifier from @p major and @p minor. + * @brief Create a device identifier from @p major, @p minor and @p name. * @param major Device major number. * @param minor Device minor number. * @param name Device name. @@ -28,25 +28,25 @@ namespace devices * @brief Returns the major number of the device. * @return Device major number. */ - auto major() const -> size_t; + [[nodiscard]] auto major() const -> size_t; /** * @brief Returns the minor number of the device. * @return Device minor number. */ - auto minor() const -> size_t; + [[nodiscard]] auto minor() const -> size_t; /** * @brief Returns the name of the device. * @return Device name. */ - auto name() const -> std::string_view; + [[nodiscard]] auto name() const -> std::string_view; /** * @brief Check if the device is a block device. * @return true if this device is a block device, false otherwise. */ - virtual auto is_block_device() const -> bool + [[nodiscard]] virtual auto is_block_device() const -> bool { return false; } diff --git a/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp b/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp index eebbcd7..678ee99 100644 --- a/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp +++ b/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp @@ -45,7 +45,7 @@ namespace devices::storage::ram_disk /** * @brief Return module size in bytes. */ - auto size() const -> size_t override; + [[nodiscard]] auto size() const -> size_t override; kapi::boot_modules::boot_module m_boot_module{}; }; diff --git a/kernel/devices/include/devices/storage/storage_controller.hpp b/kernel/devices/include/devices/storage/storage_controller.hpp index 0518e32..d10d27d 100644 --- a/kernel/devices/include/devices/storage/storage_controller.hpp +++ b/kernel/devices/include/devices/storage/storage_controller.hpp @@ -37,17 +37,17 @@ namespace devices::storage * @brief Return the assigned major number. * @return Assigned major number. */ - auto major() const -> size_t; + [[nodiscard]] auto major() const -> size_t; /** * @brief Return the number of devices managed by this controller. * @return Number of managed devices. */ - auto devices_count() const -> size_t; + [[nodiscard]] auto devices_count() const -> size_t; // TODO BA-FS26 add comment // TODO BA-FS26 use kstd::vector when available - auto all_devices() const -> std::array const &; + [[nodiscard]] auto all_devices() const -> std::array const &; /** * @brief Find a managed device by major/minor numbers. @@ -55,7 +55,7 @@ namespace devices::storage * @param minor Device minor number. * @return Matching block device, or nullptr if no device matches. */ - auto device_by_minor(size_t minor) const -> device *; + [[nodiscard]] auto device_by_minor(size_t minor) const -> device *; protected: size_t m_major{}; diff --git a/kernel/devices/include/devices/storage/storage_management.hpp b/kernel/devices/include/devices/storage/storage_management.hpp index 4bc7cbd..550db65 100644 --- a/kernel/devices/include/devices/storage/storage_management.hpp +++ b/kernel/devices/include/devices/storage/storage_management.hpp @@ -44,7 +44,7 @@ namespace devices::storage // TODO BA-FS26 add comment // TODO BA-FS26 use kstd::vector when available - auto all_controllers() const -> std::array const &; + [[nodiscard]] auto all_controllers() const -> std::array const &; /** * @brief Find a device by major/minor numbers. -- cgit v1.2.3 From 5801be615a50bf465a9663b7f75cafbcf0870f5c Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 17 Mar 2026 11:49:13 +0100 Subject: use kstd::vector instead of std::array and replace plain-pointers with kstd::shared_ptr --- .../devices/storage/ram_disk/ram_disk_device.hpp | 2 - .../include/devices/storage/storage_controller.hpp | 11 +++--- .../include/devices/storage/storage_management.hpp | 15 ++++---- .../src/storage/ram_disk/ram_disk_controller.cpp | 15 +------- .../src/storage/ram_disk/ram_disk_device.cpp | 4 -- kernel/devices/src/storage/storage_controller.cpp | 8 ++-- kernel/devices/src/storage/storage_management.cpp | 25 ++++++------ kernel/filesystem/include/filesystem/custody.hpp | 12 +++--- .../filesystem/include/filesystem/device_file.hpp | 6 ++- .../include/filesystem/ext2/ext2_filesystem.hpp | 6 ++- .../include/filesystem/file_descriptor_table.hpp | 6 +-- .../filesystem/include/filesystem/filesystem.hpp | 7 ++-- kernel/filesystem/include/filesystem/inode.hpp | 8 ++-- .../filesystem/include/filesystem/inode_file.hpp | 6 ++- kernel/filesystem/include/filesystem/mount.hpp | 9 +++-- .../include/filesystem/open_file_description.hpp | 5 ++- kernel/filesystem/include/filesystem/vfs.hpp | 15 +++++--- kernel/filesystem/src/custody.cpp | 8 ++-- kernel/filesystem/src/device_file.cpp | 16 +++++--- kernel/filesystem/src/ext2/ext2_filesystem.cpp | 5 ++- kernel/filesystem/src/file_descriptor_table.cpp | 9 +++-- kernel/filesystem/src/filesystem.cpp | 9 +---- kernel/filesystem/src/inode.cpp | 6 ++- kernel/filesystem/src/inode_file.cpp | 4 +- kernel/filesystem/src/mount.cpp | 6 ++- kernel/filesystem/src/open_file_description.cpp | 14 +++++-- kernel/filesystem/src/vfs.cpp | 45 +++++++--------------- kernel/src/main.cpp | 19 ++++----- 28 files changed, 154 insertions(+), 147 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp b/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp index 678ee99..1edf48c 100644 --- a/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp +++ b/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp @@ -14,8 +14,6 @@ namespace devices::storage::ram_disk */ struct ram_disk_device : block_device { - ram_disk_device(); // TODO BA-FS26 remove when kstd::vector is available - /** * @brief Create a RAM disk for the @p module. * @param module Boot module providing the memory region. diff --git a/kernel/devices/include/devices/storage/storage_controller.hpp b/kernel/devices/include/devices/storage/storage_controller.hpp index d10d27d..e90b01c 100644 --- a/kernel/devices/include/devices/storage/storage_controller.hpp +++ b/kernel/devices/include/devices/storage/storage_controller.hpp @@ -3,7 +3,9 @@ #include "devices/device.hpp" -#include +#include +#include + #include namespace devices::storage @@ -46,8 +48,7 @@ namespace devices::storage [[nodiscard]] auto devices_count() const -> size_t; // TODO BA-FS26 add comment - // TODO BA-FS26 use kstd::vector when available - [[nodiscard]] auto all_devices() const -> std::array const &; + [[nodiscard]] auto all_devices() const -> kstd::vector> const &; /** * @brief Find a managed device by major/minor numbers. @@ -55,12 +56,12 @@ namespace devices::storage * @param minor Device minor number. * @return Matching block device, or nullptr if no device matches. */ - [[nodiscard]] auto device_by_minor(size_t minor) const -> device *; + [[nodiscard]] auto device_by_minor(size_t minor) const -> kstd::shared_ptr; protected: size_t m_major{}; size_t m_minors_per_device{}; - std::array m_devices{}; // TODO BA-FS26 use kstd::vector when available + kstd::vector> m_devices{}; }; } // namespace devices::storage diff --git a/kernel/devices/include/devices/storage/storage_management.hpp b/kernel/devices/include/devices/storage/storage_management.hpp index 550db65..dc2f6c9 100644 --- a/kernel/devices/include/devices/storage/storage_management.hpp +++ b/kernel/devices/include/devices/storage/storage_management.hpp @@ -4,7 +4,9 @@ #include "devices/device.hpp" #include "devices/storage/storage_controller.hpp" -#include +#include +#include + #include namespace devices::storage @@ -40,11 +42,10 @@ namespace devices::storage * * Assigns controller IDs (major number range and minors per device). */ - auto add_controller(storage_controller * controller) -> void; + auto add_controller(kstd::shared_ptr controller) -> void; // TODO BA-FS26 add comment - // TODO BA-FS26 use kstd::vector when available - [[nodiscard]] auto all_controllers() const -> std::array const &; + [[nodiscard]] auto all_controllers() const -> kstd::vector> const &; /** * @brief Find a device by major/minor numbers. @@ -52,13 +53,13 @@ namespace devices::storage * @param minor Device minor number. * @return Matching device, or nullptr if no device matches. */ - auto device_by_major_minor(size_t major, size_t minor) -> device *; + auto device_by_major_minor(size_t major, size_t minor) -> kstd::shared_ptr; /** * @brief Determine the boot device. * @return Boot device, or nullptr if it cannot be determined. */ - auto determine_boot_device() -> device *; + auto determine_boot_device() -> kstd::shared_ptr; private: /** @@ -66,7 +67,7 @@ namespace devices::storage */ storage_management() = default; - std::array m_controllers{}; // TODO BA-FS26 use kstd::vector when available + kstd::vector> m_controllers{}; }; } // namespace devices::storage diff --git a/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp b/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp index b57dcfb..3d14faf 100644 --- a/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp +++ b/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp @@ -4,22 +4,14 @@ #include "devices/storage/ram_disk/ram_disk_device.hpp" +#include #include #include -#include #include -#include namespace devices::storage::ram_disk { - namespace - { - // TODO BA-FS26 @Felix gibts besseren weg (ausser dynamic Memory) - // TODO BA-FS26 remove again, when dynamic memory available - constinit auto static active_ram_disk_device = std::optional{}; - } // namespace - ram_disk_controller::ram_disk_controller(kapi::boot_modules::boot_module_registry const * registry) : m_boot_module_registry(registry) {} @@ -30,10 +22,7 @@ namespace devices::storage::ram_disk 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; - - // TODO BA-FS26 use push_back from kstd::vector when available - active_ram_disk_device.emplace(module, m_major, minor); - m_devices.at(0) = &*active_ram_disk_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/devices/src/storage/ram_disk/ram_disk_device.cpp b/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp index 774e949..6ff2a83 100644 --- a/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp +++ b/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp @@ -28,10 +28,6 @@ namespace devices::storage::ram_disk } } // namespace - ram_disk_device::ram_disk_device() // TODO BA-FS26 remove when kstd::vector is available - : block_device(0, 0, determine_device_name(0), RAM_DISK_BLOCK_SIZE) - {} - 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) diff --git a/kernel/devices/src/storage/storage_controller.cpp b/kernel/devices/src/storage/storage_controller.cpp index d9bc806..16d40f4 100644 --- a/kernel/devices/src/storage/storage_controller.cpp +++ b/kernel/devices/src/storage/storage_controller.cpp @@ -2,8 +2,10 @@ #include "devices/device.hpp" +#include +#include + #include -#include #include namespace devices::storage @@ -19,7 +21,7 @@ namespace devices::storage return m_major; } - auto storage_controller::device_by_minor(size_t minor) const -> device * + 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; }); @@ -35,7 +37,7 @@ namespace devices::storage return m_devices.size(); } - auto storage_controller::all_devices() const -> std::array const & + auto storage_controller::all_devices() const -> kstd::vector> const & { return m_devices; } diff --git a/kernel/devices/src/storage/storage_management.cpp b/kernel/devices/src/storage/storage_management.cpp index e1f1bcc..00449fb 100644 --- a/kernel/devices/src/storage/storage_management.cpp +++ b/kernel/devices/src/storage/storage_management.cpp @@ -7,8 +7,10 @@ #include "devices/storage/ram_disk/ram_disk_controller.hpp" #include "devices/storage/storage_controller.hpp" +#include +#include + #include -#include #include #include @@ -21,8 +23,6 @@ namespace devices::storage constinit size_t static next_free_major = START_MAJOR; constinit auto static active_storage_management = std::optional{}; - // TODO BA-FS26 remove again, when dynamic memory available - constinit auto static active_ram_disk_controller = std::optional{}; } // namespace auto storage_management::init() -> void @@ -33,8 +33,9 @@ namespace devices::storage } active_storage_management.emplace(storage_management{}); - active_ram_disk_controller.emplace(&kapi::boot_modules::get_boot_module_registry()); - active_storage_management->add_controller(&active_ram_disk_controller.value()); + 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(); }); } @@ -49,22 +50,22 @@ namespace devices::storage return *active_storage_management; } - auto storage_management::add_controller(storage_controller * controller) -> void + auto storage_management::add_controller(kstd::shared_ptr controller) -> void { controller->set_ids(next_free_major++, MINORS_PER_DEVICE); - m_controllers.at(0) = controller; // TODO BA-FS26 use push_back from kstd:vector + m_controllers.push_back(controller); } - auto storage_management::all_controllers() const -> std::array const & + 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) -> device * + auto storage_management::device_by_major_minor(size_t major, size_t minor) -> kstd::shared_ptr { - device * found = nullptr; + kstd::shared_ptr found = nullptr; - std::ranges::find_if(m_controllers, [&](auto const controller) { + std::ranges::find_if(m_controllers, [&](auto const & controller) { if (controller != nullptr && controller->major() == major) { found = controller->device_by_minor(minor); @@ -76,7 +77,7 @@ namespace devices::storage return found; } - auto storage_management::determine_boot_device() -> device * + auto storage_management::determine_boot_device() -> kstd::shared_ptr { return device_by_major_minor(START_MAJOR, 0); } diff --git a/kernel/filesystem/include/filesystem/custody.hpp b/kernel/filesystem/include/filesystem/custody.hpp index 9ee984d..b6eae22 100644 --- a/kernel/filesystem/include/filesystem/custody.hpp +++ b/kernel/filesystem/include/filesystem/custody.hpp @@ -3,18 +3,20 @@ #include "filesystem/inode.hpp" +#include + namespace filesystem { struct custody { - custody(custody * parent, inode * node); + custody(kstd::shared_ptr parent, kstd::shared_ptr node); - [[nodiscard]] auto get_inode() const -> inode *; - [[nodiscard]] auto get_parent() const -> custody *; + [[nodiscard]] auto get_inode() const -> kstd::shared_ptr; + [[nodiscard]] auto get_parent() const -> kstd::shared_ptr; private: - custody * m_parent; - inode * m_inode; + kstd::shared_ptr m_parent; + kstd::shared_ptr m_inode; }; } // namespace filesystem diff --git a/kernel/filesystem/include/filesystem/device_file.hpp b/kernel/filesystem/include/filesystem/device_file.hpp index 033317b..4dce37f 100644 --- a/kernel/filesystem/include/filesystem/device_file.hpp +++ b/kernel/filesystem/include/filesystem/device_file.hpp @@ -5,13 +5,15 @@ #include "devices/device.hpp" #include "filesystem/file.hpp" +#include + #include namespace filesystem { struct device_file : file { - explicit device_file(devices::device * device); + explicit device_file(kstd::shared_ptr device); auto open() -> void override; @@ -23,7 +25,7 @@ namespace filesystem std::byte * scratch, void * buffer); auto process_blocks(size_t offset, size_t size, void * buffer, block_op op) const -> size_t; - devices::device * m_device; + kstd::shared_ptr m_device; }; } // namespace filesystem diff --git a/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp b/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp index cba2192..dd52e72 100644 --- a/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp +++ b/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp @@ -5,17 +5,19 @@ #include "filesystem/filesystem.hpp" #include "filesystem/inode.hpp" +#include + #include namespace filesystem::ext2 { struct ext2_filesystem : filesystem { - auto mount(devices::device * device) -> int override; + auto mount(kstd::shared_ptr device) -> int override; auto lookup(inode const & parent, std::string_view name) -> inode * override; private: - devices::device * m_device{}; + kstd::shared_ptr m_device{}; }; } // namespace filesystem::ext2 diff --git a/kernel/filesystem/include/filesystem/file_descriptor_table.hpp b/kernel/filesystem/include/filesystem/file_descriptor_table.hpp index 3ac03d1..6d78532 100644 --- a/kernel/filesystem/include/filesystem/file_descriptor_table.hpp +++ b/kernel/filesystem/include/filesystem/file_descriptor_table.hpp @@ -3,7 +3,8 @@ #include "open_file_description.hpp" -#include +#include + #include namespace filesystem @@ -23,8 +24,7 @@ namespace filesystem file_descriptor_table() = default; // TODO BA-FS26 use kstd::shared_ptr when available - // TODO BA-FS26 use kstd::vector when available - std::array, 32> m_open_files{}; + kstd::vector> m_open_files{}; }; } // namespace filesystem diff --git a/kernel/filesystem/include/filesystem/filesystem.hpp b/kernel/filesystem/include/filesystem/filesystem.hpp index 8deb336..eabefc0 100644 --- a/kernel/filesystem/include/filesystem/filesystem.hpp +++ b/kernel/filesystem/include/filesystem/filesystem.hpp @@ -4,6 +4,8 @@ #include "devices/device.hpp" #include "filesystem/inode.hpp" +#include + #include namespace filesystem @@ -12,11 +14,10 @@ namespace filesystem { virtual ~filesystem() = default; - virtual auto mount(devices::device * device) -> int = 0; + virtual auto mount(kstd::shared_ptr device) -> int = 0; virtual auto lookup(inode const & parent, std::string_view name) -> inode * = 0; - [[nodiscard]] auto root_inode() -> inode *; - [[nodiscard]] auto root_inode() const -> inode const *; + [[nodiscard]] auto root_inode() const -> inode const &; protected: inode m_root_inode{}; // TODO BA-FS26 set during mount? diff --git a/kernel/filesystem/include/filesystem/inode.hpp b/kernel/filesystem/include/filesystem/inode.hpp index bceabb6..2b5ee6c 100644 --- a/kernel/filesystem/include/filesystem/inode.hpp +++ b/kernel/filesystem/include/filesystem/inode.hpp @@ -4,6 +4,8 @@ #include "devices/device.hpp" #include "filesystem/inode_metadata.hpp" +#include + #include namespace filesystem @@ -12,7 +14,7 @@ namespace filesystem { inode() = default; explicit inode(inode_kind kind); - explicit inode(devices::device * device); + explicit inode(kstd::shared_ptr device); [[nodiscard]] auto metadata() const -> inode_metadata; @@ -22,14 +24,14 @@ namespace filesystem [[nodiscard]] auto is_block_device() const -> bool; [[nodiscard]] auto major_device() const -> size_t; [[nodiscard]] auto minor_device() const -> size_t; - [[nodiscard]] auto backing_device() const -> devices::device *; + [[nodiscard]] auto backing_device() const -> kstd::shared_ptr; auto read(void * buffer, size_t offset, size_t size) const -> size_t; auto write(void const * buffer, size_t offset, size_t size) -> size_t; private: inode_kind m_kind{inode_kind::regular}; - devices::device * m_device{}; + kstd::shared_ptr m_device{}; }; } // namespace filesystem diff --git a/kernel/filesystem/include/filesystem/inode_file.hpp b/kernel/filesystem/include/filesystem/inode_file.hpp index c091280..512f51d 100644 --- a/kernel/filesystem/include/filesystem/inode_file.hpp +++ b/kernel/filesystem/include/filesystem/inode_file.hpp @@ -4,13 +4,15 @@ #include "filesystem/file.hpp" #include "filesystem/inode.hpp" +#include + #include namespace filesystem { struct inode_file : file { - explicit inode_file(inode * inode); + explicit inode_file(kstd::shared_ptr inode); auto open() -> void override; @@ -18,7 +20,7 @@ namespace filesystem auto write(void const * buffer, size_t offset, size_t size) -> size_t override; private: - inode * m_inode; + kstd::shared_ptr m_inode; }; } // namespace filesystem diff --git a/kernel/filesystem/include/filesystem/mount.hpp b/kernel/filesystem/include/filesystem/mount.hpp index fe5d9cc..f28de74 100644 --- a/kernel/filesystem/include/filesystem/mount.hpp +++ b/kernel/filesystem/include/filesystem/mount.hpp @@ -3,21 +3,22 @@ #include "filesystem/filesystem.hpp" +#include + #include namespace filesystem { struct mount { - mount() = default; // TODO BA-FS26 remove again when kstd::vector is available and used in vfs - mount(std::string_view const & path, filesystem * fs); + mount(std::string_view const & path, kstd::shared_ptr fs); [[nodiscard]] auto path() const -> std::string_view; - [[nodiscard]] auto get_filesystem() const -> filesystem *; + [[nodiscard]] auto get_filesystem() const -> kstd::shared_ptr; private: std::string_view m_path; - filesystem * m_filesystem{}; + kstd::shared_ptr m_filesystem{}; }; } // namespace filesystem diff --git a/kernel/filesystem/include/filesystem/open_file_description.hpp b/kernel/filesystem/include/filesystem/open_file_description.hpp index 1589196..035b0ee 100644 --- a/kernel/filesystem/include/filesystem/open_file_description.hpp +++ b/kernel/filesystem/include/filesystem/open_file_description.hpp @@ -2,6 +2,7 @@ #define TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP #include "file.hpp" +#include #include @@ -9,7 +10,7 @@ namespace filesystem { struct open_file_description { - open_file_description(file * file); + open_file_description(kstd::shared_ptr file); ~open_file_description() = default; @@ -17,7 +18,7 @@ namespace filesystem auto write(void const * buffer, size_t size) -> size_t; private: - file * m_file; + kstd::shared_ptr m_file; size_t m_offset; }; diff --git a/kernel/filesystem/include/filesystem/vfs.hpp b/kernel/filesystem/include/filesystem/vfs.hpp index 1d95d4a..9c89044 100644 --- a/kernel/filesystem/include/filesystem/vfs.hpp +++ b/kernel/filesystem/include/filesystem/vfs.hpp @@ -3,11 +3,14 @@ #include "devices/device.hpp" #include "filesystem/custody.hpp" +#include "filesystem/ext2/ext2_filesystem.hpp" #include "filesystem/inode.hpp" #include "filesystem/mount.hpp" #include "filesystem/open_file_description.hpp" -#include +#include +#include + #include #include @@ -26,17 +29,17 @@ namespace filesystem struct device_node_entry { std::string_view name; - inode node; + kstd::shared_ptr node; }; vfs() = default; - auto make_device_node(devices::device * device) -> void; + auto make_device_node(kstd::shared_ptr device) -> void; [[nodiscard]] auto resolve_path(std::string_view path) -> std::optional; + kstd::shared_ptr m_root_fs; std::optional m_root_mount; - std::array m_mounts; // TODO BA-FS26 remove when kstd::vector is available and used - std::array, 10> - m_device_nodes; // TODO BA-FS26 use kstd::vector // TODO BA-FS26 remove again, use + // kstd::vector m_mounts; // TODO BA-FS26 really needed? + kstd::vector> m_device_nodes; // TODO BA-FS26 remove again, use devtempfs }; } // namespace filesystem diff --git a/kernel/filesystem/src/custody.cpp b/kernel/filesystem/src/custody.cpp index 614e63b..7a58229 100644 --- a/kernel/filesystem/src/custody.cpp +++ b/kernel/filesystem/src/custody.cpp @@ -4,9 +4,11 @@ #include "filesystem/inode.hpp" +#include + namespace filesystem { - custody::custody(custody * parent, inode * node) + custody::custody(kstd::shared_ptr parent, kstd::shared_ptr node) : m_parent(parent) , m_inode(node) { @@ -16,12 +18,12 @@ namespace filesystem } } - auto custody::get_inode() const -> inode * + auto custody::get_inode() const -> kstd::shared_ptr { return m_inode; } - auto custody::get_parent() const -> custody * + auto custody::get_parent() const -> kstd::shared_ptr { return m_parent; } diff --git a/kernel/filesystem/src/device_file.cpp b/kernel/filesystem/src/device_file.cpp index f11638e..882c9b1 100644 --- a/kernel/filesystem/src/device_file.cpp +++ b/kernel/filesystem/src/device_file.cpp @@ -6,14 +6,15 @@ #include "devices/device.hpp" #include +#include +#include #include -#include #include namespace filesystem { - device_file::device_file(devices::device * device) + device_file::device_file(kstd::shared_ptr device) : m_device(device) { if (!m_device) @@ -90,7 +91,13 @@ namespace filesystem return 0; } - auto * block_dev = static_cast(m_device); + // @Felix rtti not activated why? e.g. dynamic_cast does not work, whats with std::dynamic_pointer_cast + // online: rtti overhead, bad design, ... ? + auto * block_dev = static_cast(m_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(); @@ -99,8 +106,7 @@ namespace filesystem return 0; size_t const total_to_process = std::min(size, capacity - offset); - // TODO BA-FS26 use kstd::vector when available - std::array scratch_buffer{}; // TODO BA-FS26 better solution than fixed scratch_buffer ?? + kstd::vector scratch_buffer{block_size}; auto processed = 0uz; while (processed < total_to_process) diff --git a/kernel/filesystem/src/ext2/ext2_filesystem.cpp b/kernel/filesystem/src/ext2/ext2_filesystem.cpp index f092ddf..2ae5ab7 100644 --- a/kernel/filesystem/src/ext2/ext2_filesystem.cpp +++ b/kernel/filesystem/src/ext2/ext2_filesystem.cpp @@ -2,12 +2,15 @@ #include "devices/device.hpp" #include "filesystem/inode.hpp" +#include "filesystem/inode_metadata.hpp" + +#include #include namespace filesystem::ext2 { - auto ext2_filesystem::mount(devices::device * device) -> int + auto ext2_filesystem::mount(kstd::shared_ptr device) -> int { if (!device) { diff --git a/kernel/filesystem/src/file_descriptor_table.cpp b/kernel/filesystem/src/file_descriptor_table.cpp index eb9a281..64fad0c 100644 --- a/kernel/filesystem/src/file_descriptor_table.cpp +++ b/kernel/filesystem/src/file_descriptor_table.cpp @@ -44,7 +44,8 @@ namespace filesystem return static_cast(it - m_open_files.begin()); } - return -1; + m_open_files.push_back(file_description); + return static_cast(m_open_files.size() - 1); } auto file_descriptor_table::get_file(int fd) const -> std::optional @@ -55,12 +56,12 @@ namespace filesystem } auto const index = static_cast(fd); - if (index >= m_open_files.size() || !m_open_files[index].has_value()) + if (index >= m_open_files.size() || !m_open_files.at(fd).has_value()) { return std::nullopt; } - return *m_open_files[index]; + return m_open_files.at(fd); } auto file_descriptor_table::remove_file(int fd) -> void @@ -76,6 +77,6 @@ namespace filesystem return; } - m_open_files[index].reset(); + m_open_files.at(fd).reset(); } } // namespace filesystem \ No newline at end of file diff --git a/kernel/filesystem/src/filesystem.cpp b/kernel/filesystem/src/filesystem.cpp index a06bccc..cdfe7f8 100644 --- a/kernel/filesystem/src/filesystem.cpp +++ b/kernel/filesystem/src/filesystem.cpp @@ -4,13 +4,8 @@ namespace filesystem { - auto filesystem::root_inode() -> inode * + auto filesystem::root_inode() const -> inode const & { - return &m_root_inode; - } - - auto filesystem::root_inode() const -> inode const * - { - return &m_root_inode; + return m_root_inode; } } // namespace filesystem \ No newline at end of file diff --git a/kernel/filesystem/src/inode.cpp b/kernel/filesystem/src/inode.cpp index 17aa52a..10a9a30 100644 --- a/kernel/filesystem/src/inode.cpp +++ b/kernel/filesystem/src/inode.cpp @@ -5,6 +5,8 @@ #include "devices/device.hpp" #include "filesystem/inode_metadata.hpp" +#include + #include namespace filesystem @@ -13,7 +15,7 @@ namespace filesystem : m_kind(kind) {} - inode::inode(devices::device * device) + inode::inode(kstd::shared_ptr device) : m_kind(inode_kind::device) , m_device(device) { @@ -77,7 +79,7 @@ namespace filesystem return m_device->minor(); } - auto inode::backing_device() const -> devices::device * + auto inode::backing_device() const -> kstd::shared_ptr { return m_device; } diff --git a/kernel/filesystem/src/inode_file.cpp b/kernel/filesystem/src/inode_file.cpp index 071661f..b68b3ee 100644 --- a/kernel/filesystem/src/inode_file.cpp +++ b/kernel/filesystem/src/inode_file.cpp @@ -4,11 +4,13 @@ #include "filesystem/inode.hpp" +#include + #include namespace filesystem { - inode_file::inode_file(inode * inode) + inode_file::inode_file(kstd::shared_ptr inode) : m_inode(inode) { if (!m_inode) diff --git a/kernel/filesystem/src/mount.cpp b/kernel/filesystem/src/mount.cpp index 6594598..53a8143 100644 --- a/kernel/filesystem/src/mount.cpp +++ b/kernel/filesystem/src/mount.cpp @@ -4,11 +4,13 @@ #include "filesystem/filesystem.hpp" +#include + #include namespace filesystem { - mount::mount(std::string_view const & path, filesystem * fs) + mount::mount(std::string_view const & path, kstd::shared_ptr fs) : m_path(path) , m_filesystem(fs) { @@ -23,7 +25,7 @@ namespace filesystem return m_path; } - auto mount::get_filesystem() const -> filesystem * + auto mount::get_filesystem() const -> kstd::shared_ptr { return m_filesystem; } diff --git a/kernel/filesystem/src/open_file_description.cpp b/kernel/filesystem/src/open_file_description.cpp index d483746..9ebf67d 100644 --- a/kernel/filesystem/src/open_file_description.cpp +++ b/kernel/filesystem/src/open_file_description.cpp @@ -2,18 +2,25 @@ #include "filesystem/file.hpp" +#include +#include + #include namespace filesystem { - open_file_description::open_file_description(file * file) + open_file_description::open_file_description(kstd::shared_ptr file) : m_file(file) , m_offset(0) - {} + { + if (!file) + { + kstd::os::panic("[FILESYSTEM] open_file_description constructed with null file."); + } + } auto open_file_description::read(void * buffer, size_t size) -> size_t { - // TODO BA-FS26 nullptr check auto read_bytes = m_file->read(buffer, m_offset, size); m_offset += read_bytes; return read_bytes; @@ -21,7 +28,6 @@ namespace filesystem auto open_file_description::write(void const * buffer, size_t size) -> size_t { - // TODO BA-FS26 nullptr check auto written_bytes = m_file->write(buffer, m_offset, size); m_offset += written_bytes; return written_bytes; diff --git a/kernel/filesystem/src/vfs.cpp b/kernel/filesystem/src/vfs.cpp index 2ecf847..578fde4 100644 --- a/kernel/filesystem/src/vfs.cpp +++ b/kernel/filesystem/src/vfs.cpp @@ -13,6 +13,7 @@ #include "filesystem/open_file_description.hpp" #include +#include #include #include @@ -23,15 +24,6 @@ namespace filesystem namespace { constinit auto static active_vfs = std::optional{}; - - // TODO BA-FS26 @Felix better solution? while dynamic memory not available? - // TODO BA-FS26 remove when dynamic memory available; - constinit auto static root_fs = std::optional{}; - - // TODO BA-FS26 remove when dynamic memory available; - constinit auto static temp_device_file = std::optional{}; - // TODO BA-FS26 remove when dynamic memory available; - constinit auto static temp_inode_file = std::optional{}; } // namespace auto vfs::init() -> void @@ -46,13 +38,13 @@ namespace filesystem auto storage_mgmt = devices::storage::storage_management::get(); if (auto boot_device = storage_mgmt.determine_boot_device()) { - root_fs.emplace(ext2::ext2_filesystem{}); - if (root_fs->mount(boot_device) != 0) + active_vfs->m_root_fs = kstd::make_shared(); + if (active_vfs->m_root_fs->mount(boot_device) != 0) { kapi::system::panic("[FILESYSTEM] Failed to mount root filesystem."); } - active_vfs->m_root_mount = mount{"/", &*root_fs}; + active_vfs->m_root_mount = mount{"/", active_vfs->m_root_fs}; std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto controller) { std::ranges::for_each(controller->all_devices(), [&](auto device) { active_vfs->make_device_node(device); }); @@ -78,39 +70,30 @@ namespace filesystem { if (auto custody = resolve_path(path)) { - auto * node = custody->get_inode(); + auto node = custody->get_inode(); if (node->is_device()) { - temp_device_file.emplace(node->backing_device()); - temp_device_file->open(); - return open_file_description{&*temp_device_file}; + auto current_device_file = kstd::make_shared(node->backing_device()); + current_device_file->open(); + return open_file_description{current_device_file}; } - temp_inode_file.emplace(node); - temp_inode_file->open(); - return open_file_description{&*temp_inode_file}; + auto current_inode_file = kstd::make_shared(node); + current_inode_file->open(); + return open_file_description{current_inode_file}; } return std::nullopt; } - auto vfs::make_device_node(devices::device * device) -> void + auto vfs::make_device_node(kstd::shared_ptr device) -> void { if (!device) { kapi::system::panic("[FILESYSTEM] make_device_node called with null device."); } - auto const device_name = device->name(); - - // TODO BA-FS26 this logic isn't needed anymore when kstd::vector available, just use push_back - auto const slot = std::ranges::find_if(m_device_nodes, [](auto const & entry) { return !entry.has_value(); }); - if (slot == m_device_nodes.end()) - { - kapi::system::panic("[FILESYSTEM] No free slot available for device nodes."); - } - - slot->emplace(device_node_entry{device_name, inode{device}}); + m_device_nodes.push_back(device_node_entry{device->name(), kstd::make_shared(device)}); } auto vfs::resolve_path(std::string_view path) -> std::optional @@ -128,7 +111,7 @@ namespace filesystem if (entry != m_device_nodes.end()) { - return custody{nullptr, &entry->value().node}; + return custody{static_cast>(nullptr), entry->value().node}; } return std::nullopt; diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 011821a..cf3afdf 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -8,13 +8,13 @@ #include "filesystem/file_descriptor_table.hpp" #include "filesystem/open_file_description.hpp" #include "filesystem/vfs.hpp" - #include "kernel/memory.hpp" +#include #include #include +#include -#include #include #include @@ -25,8 +25,8 @@ auto run_test_code() -> void auto storage_mgmt = devices::storage::storage_management::get(); auto device = storage_mgmt.device_by_major_minor(1, 0); - filesystem::device_file dev_file(device); - filesystem::open_file_description ofd(&dev_file); + auto dev_file = kstd::make_shared(device); + filesystem::open_file_description ofd(dev_file); auto fd_index = fd_table.add_file(ofd); // use: read two bytes and write two again @@ -36,7 +36,7 @@ auto run_test_code() -> void kstd::os::panic("test code failed"); } - std::array buffer{}; + kstd::vector buffer{2}; auto number_of_read_bytes = fd->read(buffer.data(), buffer.size()); for (size_t i = 0; i < number_of_read_bytes; ++i) @@ -51,7 +51,7 @@ auto run_test_code() -> void kstd::println("---"); // write half of the file new - std::array write_buffer{std::byte{0xBB}, std::byte{0xAA}}; + kstd::vector write_buffer{std::byte{0xBB}, std::byte{0xAA}}; auto written_bytes = fd->write(write_buffer.data(), write_buffer.size()); kstd::println("written bytes: {}", written_bytes); @@ -59,7 +59,7 @@ auto run_test_code() -> void fd_table.remove_file(fd_index); // use: read four bytes again -> two old bytes two new bytes - filesystem::open_file_description ofd1(&dev_file); + filesystem::open_file_description ofd1(dev_file); fd_index = fd_table.add_file(ofd1); auto fd1 = fd_table.get_file(fd_index); @@ -68,7 +68,7 @@ auto run_test_code() -> void kstd::os::panic("test code failed"); } - std::array buffer1{}; + kstd::vector buffer1{4}; number_of_read_bytes = fd1->read(buffer1.data(), buffer1.size()); for (size_t i = 0; i < number_of_read_bytes; ++i) @@ -89,7 +89,8 @@ auto main() -> int kstd::println("[OS] IO subsystem initialized."); kapi::memory::init(); - kernel::memory::init_heap(kapi::memory::heap_base); kstd::println("[OS] Memory subsystem initialized."); + kernel::memory::init_heap(kapi::memory::heap_base); + kstd::println("[OS] Memory subsystem initialized."); kapi::system::memory_initialized(); kapi::boot_modules::init(); -- cgit v1.2.3 From 3f8af998aaf87d83af3af6c5708d8a84b775b50e Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 17 Mar 2026 12:24:07 +0100 Subject: write comments --- kernel/devices/include/devices/storage/storage_controller.hpp | 5 ++++- kernel/devices/include/devices/storage/storage_management.hpp | 5 ++++- kernel/devices/src/storage/ram_disk/ram_disk_device.cpp | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/storage/storage_controller.hpp b/kernel/devices/include/devices/storage/storage_controller.hpp index e90b01c..7760fc9 100644 --- a/kernel/devices/include/devices/storage/storage_controller.hpp +++ b/kernel/devices/include/devices/storage/storage_controller.hpp @@ -47,7 +47,10 @@ namespace devices::storage */ [[nodiscard]] auto devices_count() const -> size_t; - // TODO BA-FS26 add comment + /** + * @brief Return all devices managed by this controller. + * @return Vector of all managed devices. + */ [[nodiscard]] auto all_devices() const -> kstd::vector> const &; /** diff --git a/kernel/devices/include/devices/storage/storage_management.hpp b/kernel/devices/include/devices/storage/storage_management.hpp index dc2f6c9..65211c8 100644 --- a/kernel/devices/include/devices/storage/storage_management.hpp +++ b/kernel/devices/include/devices/storage/storage_management.hpp @@ -44,7 +44,10 @@ namespace devices::storage */ auto add_controller(kstd::shared_ptr controller) -> void; - // TODO BA-FS26 add comment + /** + * @brief Return all registered storage controllers. + * @return Vector of all registered storage controllers. + */ [[nodiscard]] auto all_controllers() const -> kstd::vector> const &; /** diff --git a/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp b/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp index 6ff2a83..91a278e 100644 --- a/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp +++ b/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp @@ -15,7 +15,7 @@ namespace devices::storage::ram_disk { namespace { - constexpr size_t RAM_DISK_BLOCK_SIZE = 512uz; // TODO BA-FS26 really correct / good?? + constexpr size_t RAM_DISK_BLOCK_SIZE = 512uz; // TODO BA-FS26 @Felix // TODO BA-FS26 currently only names for 9 minor devices -- cgit v1.2.3 From f1885d0d09d5d94ad326f2257c9502b9545f0e79 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 17 Mar 2026 12:39:17 +0100 Subject: use const & wherever applicable --- kernel/devices/include/devices/storage/storage_management.hpp | 2 +- kernel/devices/src/storage/storage_management.cpp | 2 +- kernel/filesystem/include/filesystem/custody.hpp | 6 +++--- kernel/filesystem/include/filesystem/device_file.hpp | 2 +- kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp | 2 +- kernel/filesystem/include/filesystem/filesystem.hpp | 2 +- kernel/filesystem/include/filesystem/inode.hpp | 4 ++-- kernel/filesystem/include/filesystem/inode_file.hpp | 2 +- kernel/filesystem/include/filesystem/mount.hpp | 4 ++-- kernel/filesystem/include/filesystem/open_file_description.hpp | 3 ++- kernel/filesystem/include/filesystem/vfs.hpp | 2 +- kernel/filesystem/src/custody.cpp | 6 +++--- kernel/filesystem/src/device_file.cpp | 2 +- kernel/filesystem/src/ext2/ext2_filesystem.cpp | 2 +- kernel/filesystem/src/inode.cpp | 4 ++-- kernel/filesystem/src/inode_file.cpp | 2 +- kernel/filesystem/src/mount.cpp | 4 ++-- kernel/filesystem/src/open_file_description.cpp | 2 +- kernel/filesystem/src/vfs.cpp | 4 ++-- 19 files changed, 29 insertions(+), 28 deletions(-) (limited to 'kernel') diff --git a/kernel/devices/include/devices/storage/storage_management.hpp b/kernel/devices/include/devices/storage/storage_management.hpp index 65211c8..f8ffda8 100644 --- a/kernel/devices/include/devices/storage/storage_management.hpp +++ b/kernel/devices/include/devices/storage/storage_management.hpp @@ -42,7 +42,7 @@ namespace devices::storage * * Assigns controller IDs (major number range and minors per device). */ - auto add_controller(kstd::shared_ptr controller) -> void; + auto add_controller(kstd::shared_ptr const & controller) -> void; /** * @brief Return all registered storage controllers. diff --git a/kernel/devices/src/storage/storage_management.cpp b/kernel/devices/src/storage/storage_management.cpp index 00449fb..25885ad 100644 --- a/kernel/devices/src/storage/storage_management.cpp +++ b/kernel/devices/src/storage/storage_management.cpp @@ -50,7 +50,7 @@ namespace devices::storage return *active_storage_management; } - auto storage_management::add_controller(kstd::shared_ptr controller) -> void + 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); diff --git a/kernel/filesystem/include/filesystem/custody.hpp b/kernel/filesystem/include/filesystem/custody.hpp index b6eae22..0124eb6 100644 --- a/kernel/filesystem/include/filesystem/custody.hpp +++ b/kernel/filesystem/include/filesystem/custody.hpp @@ -9,10 +9,10 @@ namespace filesystem { struct custody { - custody(kstd::shared_ptr parent, kstd::shared_ptr node); + custody(kstd::shared_ptr const & parent, kstd::shared_ptr const & node); - [[nodiscard]] auto get_inode() const -> kstd::shared_ptr; - [[nodiscard]] auto get_parent() const -> kstd::shared_ptr; + [[nodiscard]] auto get_inode() const -> kstd::shared_ptr const &; + [[nodiscard]] auto get_parent() const -> kstd::shared_ptr const &; private: kstd::shared_ptr m_parent; diff --git a/kernel/filesystem/include/filesystem/device_file.hpp b/kernel/filesystem/include/filesystem/device_file.hpp index 4dce37f..dad4ea5 100644 --- a/kernel/filesystem/include/filesystem/device_file.hpp +++ b/kernel/filesystem/include/filesystem/device_file.hpp @@ -13,7 +13,7 @@ namespace filesystem { struct device_file : file { - explicit device_file(kstd::shared_ptr device); + explicit device_file(kstd::shared_ptr const & device); auto open() -> void override; diff --git a/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp b/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp index dd52e72..37448a1 100644 --- a/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp +++ b/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp @@ -13,7 +13,7 @@ namespace filesystem::ext2 { struct ext2_filesystem : filesystem { - auto mount(kstd::shared_ptr device) -> int override; + auto mount(kstd::shared_ptr const & device) -> int override; auto lookup(inode const & parent, std::string_view name) -> inode * override; private: diff --git a/kernel/filesystem/include/filesystem/filesystem.hpp b/kernel/filesystem/include/filesystem/filesystem.hpp index eabefc0..934f883 100644 --- a/kernel/filesystem/include/filesystem/filesystem.hpp +++ b/kernel/filesystem/include/filesystem/filesystem.hpp @@ -14,7 +14,7 @@ namespace filesystem { virtual ~filesystem() = default; - virtual auto mount(kstd::shared_ptr device) -> int = 0; + virtual auto mount(kstd::shared_ptr const & device) -> int = 0; virtual auto lookup(inode const & parent, std::string_view name) -> inode * = 0; [[nodiscard]] auto root_inode() const -> inode const &; diff --git a/kernel/filesystem/include/filesystem/inode.hpp b/kernel/filesystem/include/filesystem/inode.hpp index 2b5ee6c..abfe2cf 100644 --- a/kernel/filesystem/include/filesystem/inode.hpp +++ b/kernel/filesystem/include/filesystem/inode.hpp @@ -14,7 +14,7 @@ namespace filesystem { inode() = default; explicit inode(inode_kind kind); - explicit inode(kstd::shared_ptr device); + explicit inode(kstd::shared_ptr const & device); [[nodiscard]] auto metadata() const -> inode_metadata; @@ -24,7 +24,7 @@ namespace filesystem [[nodiscard]] auto is_block_device() const -> bool; [[nodiscard]] auto major_device() const -> size_t; [[nodiscard]] auto minor_device() const -> size_t; - [[nodiscard]] auto backing_device() const -> kstd::shared_ptr; + [[nodiscard]] auto backing_device() const -> kstd::shared_ptr const &; auto read(void * buffer, size_t offset, size_t size) const -> size_t; auto write(void const * buffer, size_t offset, size_t size) -> size_t; diff --git a/kernel/filesystem/include/filesystem/inode_file.hpp b/kernel/filesystem/include/filesystem/inode_file.hpp index 512f51d..5f8a95e 100644 --- a/kernel/filesystem/include/filesystem/inode_file.hpp +++ b/kernel/filesystem/include/filesystem/inode_file.hpp @@ -12,7 +12,7 @@ namespace filesystem { struct inode_file : file { - explicit inode_file(kstd::shared_ptr inode); + explicit inode_file(kstd::shared_ptr const & inode); auto open() -> void override; diff --git a/kernel/filesystem/include/filesystem/mount.hpp b/kernel/filesystem/include/filesystem/mount.hpp index f28de74..46a68e2 100644 --- a/kernel/filesystem/include/filesystem/mount.hpp +++ b/kernel/filesystem/include/filesystem/mount.hpp @@ -11,10 +11,10 @@ namespace filesystem { struct mount { - mount(std::string_view const & path, kstd::shared_ptr fs); + mount(std::string_view const & path, kstd::shared_ptr const & fs); [[nodiscard]] auto path() const -> std::string_view; - [[nodiscard]] auto get_filesystem() const -> kstd::shared_ptr; + [[nodiscard]] auto get_filesystem() const -> kstd::shared_ptr const &; private: std::string_view m_path; diff --git a/kernel/filesystem/include/filesystem/open_file_description.hpp b/kernel/filesystem/include/filesystem/open_file_description.hpp index 035b0ee..5ff094d 100644 --- a/kernel/filesystem/include/filesystem/open_file_description.hpp +++ b/kernel/filesystem/include/filesystem/open_file_description.hpp @@ -2,6 +2,7 @@ #define TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP #include "file.hpp" + #include #include @@ -10,7 +11,7 @@ namespace filesystem { struct open_file_description { - open_file_description(kstd::shared_ptr file); + open_file_description(kstd::shared_ptr const & file); ~open_file_description() = default; diff --git a/kernel/filesystem/include/filesystem/vfs.hpp b/kernel/filesystem/include/filesystem/vfs.hpp index 9c89044..e16a961 100644 --- a/kernel/filesystem/include/filesystem/vfs.hpp +++ b/kernel/filesystem/include/filesystem/vfs.hpp @@ -33,7 +33,7 @@ namespace filesystem }; vfs() = default; - auto make_device_node(kstd::shared_ptr device) -> void; + auto make_device_node(kstd::shared_ptr const & device) -> void; [[nodiscard]] auto resolve_path(std::string_view path) -> std::optional; kstd::shared_ptr m_root_fs; diff --git a/kernel/filesystem/src/custody.cpp b/kernel/filesystem/src/custody.cpp index 7a58229..3a87345 100644 --- a/kernel/filesystem/src/custody.cpp +++ b/kernel/filesystem/src/custody.cpp @@ -8,7 +8,7 @@ namespace filesystem { - custody::custody(kstd::shared_ptr parent, kstd::shared_ptr node) + custody::custody(kstd::shared_ptr const & parent, kstd::shared_ptr const & node) : m_parent(parent) , m_inode(node) { @@ -18,12 +18,12 @@ namespace filesystem } } - auto custody::get_inode() const -> kstd::shared_ptr + auto custody::get_inode() const -> kstd::shared_ptr const & { return m_inode; } - auto custody::get_parent() const -> kstd::shared_ptr + auto custody::get_parent() const -> kstd::shared_ptr const & { return m_parent; } diff --git a/kernel/filesystem/src/device_file.cpp b/kernel/filesystem/src/device_file.cpp index 882c9b1..699c161 100644 --- a/kernel/filesystem/src/device_file.cpp +++ b/kernel/filesystem/src/device_file.cpp @@ -14,7 +14,7 @@ namespace filesystem { - device_file::device_file(kstd::shared_ptr device) + device_file::device_file(kstd::shared_ptr const & device) : m_device(device) { if (!m_device) diff --git a/kernel/filesystem/src/ext2/ext2_filesystem.cpp b/kernel/filesystem/src/ext2/ext2_filesystem.cpp index 2ae5ab7..a82a098 100644 --- a/kernel/filesystem/src/ext2/ext2_filesystem.cpp +++ b/kernel/filesystem/src/ext2/ext2_filesystem.cpp @@ -10,7 +10,7 @@ namespace filesystem::ext2 { - auto ext2_filesystem::mount(kstd::shared_ptr device) -> int + auto ext2_filesystem::mount(kstd::shared_ptr const & device) -> int { if (!device) { diff --git a/kernel/filesystem/src/inode.cpp b/kernel/filesystem/src/inode.cpp index 10a9a30..231ee33 100644 --- a/kernel/filesystem/src/inode.cpp +++ b/kernel/filesystem/src/inode.cpp @@ -15,7 +15,7 @@ namespace filesystem : m_kind(kind) {} - inode::inode(kstd::shared_ptr device) + inode::inode(kstd::shared_ptr const & device) : m_kind(inode_kind::device) , m_device(device) { @@ -79,7 +79,7 @@ namespace filesystem return m_device->minor(); } - auto inode::backing_device() const -> kstd::shared_ptr + auto inode::backing_device() const -> kstd::shared_ptr const & { return m_device; } diff --git a/kernel/filesystem/src/inode_file.cpp b/kernel/filesystem/src/inode_file.cpp index b68b3ee..0b8bdf9 100644 --- a/kernel/filesystem/src/inode_file.cpp +++ b/kernel/filesystem/src/inode_file.cpp @@ -10,7 +10,7 @@ namespace filesystem { - inode_file::inode_file(kstd::shared_ptr inode) + inode_file::inode_file(kstd::shared_ptr const & inode) : m_inode(inode) { if (!m_inode) diff --git a/kernel/filesystem/src/mount.cpp b/kernel/filesystem/src/mount.cpp index 53a8143..021b074 100644 --- a/kernel/filesystem/src/mount.cpp +++ b/kernel/filesystem/src/mount.cpp @@ -10,7 +10,7 @@ namespace filesystem { - mount::mount(std::string_view const & path, kstd::shared_ptr fs) + mount::mount(std::string_view const & path, kstd::shared_ptr const & fs) : m_path(path) , m_filesystem(fs) { @@ -25,7 +25,7 @@ namespace filesystem return m_path; } - auto mount::get_filesystem() const -> kstd::shared_ptr + auto mount::get_filesystem() const -> kstd::shared_ptr const & { return m_filesystem; } diff --git a/kernel/filesystem/src/open_file_description.cpp b/kernel/filesystem/src/open_file_description.cpp index 9ebf67d..cddee76 100644 --- a/kernel/filesystem/src/open_file_description.cpp +++ b/kernel/filesystem/src/open_file_description.cpp @@ -9,7 +9,7 @@ namespace filesystem { - open_file_description::open_file_description(kstd::shared_ptr file) + open_file_description::open_file_description(kstd::shared_ptr const & file) : m_file(file) , m_offset(0) { diff --git a/kernel/filesystem/src/vfs.cpp b/kernel/filesystem/src/vfs.cpp index 578fde4..c0f1c3a 100644 --- a/kernel/filesystem/src/vfs.cpp +++ b/kernel/filesystem/src/vfs.cpp @@ -86,7 +86,7 @@ namespace filesystem return std::nullopt; } - auto vfs::make_device_node(kstd::shared_ptr device) -> void + auto vfs::make_device_node(kstd::shared_ptr const & device) -> void { if (!device) { @@ -111,7 +111,7 @@ namespace filesystem if (entry != m_device_nodes.end()) { - return custody{static_cast>(nullptr), entry->value().node}; + return custody{nullptr, entry->value().node}; } return std::nullopt; -- cgit v1.2.3 From 01d59096b1ade0b3d4e1ce77e11065b31bbd1003 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 17 Mar 2026 16:04:15 +0100 Subject: remove comment --- kernel/filesystem/src/device_file.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'kernel') diff --git a/kernel/filesystem/src/device_file.cpp b/kernel/filesystem/src/device_file.cpp index 699c161..8fc159a 100644 --- a/kernel/filesystem/src/device_file.cpp +++ b/kernel/filesystem/src/device_file.cpp @@ -91,8 +91,6 @@ namespace filesystem return 0; } - // @Felix rtti not activated why? e.g. dynamic_cast does not work, whats with std::dynamic_pointer_cast - // online: rtti overhead, bad design, ... ? auto * block_dev = static_cast(m_device.get()); if (block_dev == nullptr) { -- cgit v1.2.3 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/CMakeLists.txt | 21 +++- kernel/devices/CMakeLists.txt | 31 ------ kernel/devices/include/devices/block_device.hpp | 101 ----------------- kernel/devices/include/devices/device.hpp | 61 ---------- .../storage/ram_disk/ram_disk_controller.hpp | 31 ------ .../devices/storage/ram_disk/ram_disk_device.hpp | 52 --------- .../include/devices/storage/storage_controller.hpp | 71 ------------ .../include/devices/storage/storage_management.hpp | 77 ------------- kernel/devices/src/block_device.cpp | 42 ------- kernel/devices/src/device.cpp | 28 ----- .../src/storage/ram_disk/ram_disk_controller.cpp | 28 ----- .../src/storage/ram_disk/ram_disk_device.cpp | 77 ------------- kernel/devices/src/storage/storage_controller.cpp | 44 -------- kernel/devices/src/storage/storage_management.cpp | 85 -------------- kernel/filesystem/CMakeLists.txt | 43 ------- kernel/filesystem/include/filesystem/custody.hpp | 23 ---- .../filesystem/include/filesystem/device_file.hpp | 32 ------ .../include/filesystem/ext2/ext2_filesystem.hpp | 24 ---- kernel/filesystem/include/filesystem/file.hpp | 19 ---- .../include/filesystem/file_descriptor_table.hpp | 31 ------ .../filesystem/include/filesystem/filesystem.hpp | 28 ----- kernel/filesystem/include/filesystem/inode.hpp | 38 ------- .../filesystem/include/filesystem/inode_file.hpp | 27 ----- .../include/filesystem/inode_metadata.hpp | 24 ---- kernel/filesystem/include/filesystem/mount.hpp | 25 ----- .../include/filesystem/open_file_description.hpp | 28 ----- kernel/filesystem/include/filesystem/vfs.hpp | 46 -------- kernel/filesystem/src/custody.cpp | 30 ----- kernel/filesystem/src/device_file.cpp | 124 --------------------- kernel/filesystem/src/ext2/ext2_filesystem.cpp | 33 ------ kernel/filesystem/src/file_descriptor_table.cpp | 82 -------------- kernel/filesystem/src/filesystem.cpp | 11 -- kernel/filesystem/src/inode.cpp | 108 ------------------ kernel/filesystem/src/inode_file.cpp | 35 ------ kernel/filesystem/src/mount.cpp | 32 ------ kernel/filesystem/src/open_file_description.cpp | 35 ------ kernel/filesystem/src/vfs.cpp | 123 -------------------- kernel/include/kernel/devices/block_device.hpp | 101 +++++++++++++++++ kernel/include/kernel/devices/device.hpp | 61 ++++++++++ .../storage/ram_disk/ram_disk_controller.hpp | 31 ++++++ .../devices/storage/ram_disk/ram_disk_device.hpp | 52 +++++++++ .../kernel/devices/storage/storage_controller.hpp | 71 ++++++++++++ .../kernel/devices/storage/storage_management.hpp | 77 +++++++++++++ kernel/include/kernel/filesystem/custody.hpp | 23 ++++ kernel/include/kernel/filesystem/device_file.hpp | 32 ++++++ .../kernel/filesystem/ext2/ext2_filesystem.hpp | 24 ++++ kernel/include/kernel/filesystem/file.hpp | 19 ++++ .../kernel/filesystem/file_descriptor_table.hpp | 31 ++++++ kernel/include/kernel/filesystem/filesystem.hpp | 28 +++++ kernel/include/kernel/filesystem/inode.hpp | 38 +++++++ kernel/include/kernel/filesystem/inode_file.hpp | 27 +++++ .../include/kernel/filesystem/inode_metadata.hpp | 24 ++++ kernel/include/kernel/filesystem/mount.hpp | 25 +++++ .../kernel/filesystem/open_file_description.hpp | 28 +++++ kernel/include/kernel/filesystem/vfs.hpp | 46 ++++++++ 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 ++++++++++++++ kernel/src/filesystem/custody.cpp | 30 +++++ kernel/src/filesystem/device_file.cpp | 124 +++++++++++++++++++++ kernel/src/filesystem/ext2/ext2_filesystem.cpp | 33 ++++++ kernel/src/filesystem/file_descriptor_table.cpp | 82 ++++++++++++++ kernel/src/filesystem/filesystem.cpp | 11 ++ kernel/src/filesystem/inode.cpp | 108 ++++++++++++++++++ kernel/src/filesystem/inode_file.cpp | 35 ++++++ kernel/src/filesystem/mount.cpp | 32 ++++++ kernel/src/filesystem/open_file_description.cpp | 35 ++++++ kernel/src/filesystem/vfs.cpp | 123 ++++++++++++++++++++ kernel/src/main.cpp | 10 +- 72 files changed, 1676 insertions(+), 1739 deletions(-) delete mode 100644 kernel/devices/CMakeLists.txt delete mode 100644 kernel/devices/include/devices/block_device.hpp delete mode 100644 kernel/devices/include/devices/device.hpp delete mode 100644 kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp delete mode 100644 kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp delete mode 100644 kernel/devices/include/devices/storage/storage_controller.hpp delete mode 100644 kernel/devices/include/devices/storage/storage_management.hpp delete mode 100644 kernel/devices/src/block_device.cpp delete mode 100644 kernel/devices/src/device.cpp delete mode 100644 kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp delete mode 100644 kernel/devices/src/storage/ram_disk/ram_disk_device.cpp delete mode 100644 kernel/devices/src/storage/storage_controller.cpp delete mode 100644 kernel/devices/src/storage/storage_management.cpp delete mode 100644 kernel/filesystem/CMakeLists.txt delete mode 100644 kernel/filesystem/include/filesystem/custody.hpp delete mode 100644 kernel/filesystem/include/filesystem/device_file.hpp delete mode 100644 kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp delete mode 100644 kernel/filesystem/include/filesystem/file.hpp delete mode 100644 kernel/filesystem/include/filesystem/file_descriptor_table.hpp delete mode 100644 kernel/filesystem/include/filesystem/filesystem.hpp delete mode 100644 kernel/filesystem/include/filesystem/inode.hpp delete mode 100644 kernel/filesystem/include/filesystem/inode_file.hpp delete mode 100644 kernel/filesystem/include/filesystem/inode_metadata.hpp delete mode 100644 kernel/filesystem/include/filesystem/mount.hpp delete mode 100644 kernel/filesystem/include/filesystem/open_file_description.hpp delete mode 100644 kernel/filesystem/include/filesystem/vfs.hpp delete mode 100644 kernel/filesystem/src/custody.cpp delete mode 100644 kernel/filesystem/src/device_file.cpp delete mode 100644 kernel/filesystem/src/ext2/ext2_filesystem.cpp delete mode 100644 kernel/filesystem/src/file_descriptor_table.cpp delete mode 100644 kernel/filesystem/src/filesystem.cpp delete mode 100644 kernel/filesystem/src/inode.cpp delete mode 100644 kernel/filesystem/src/inode_file.cpp delete mode 100644 kernel/filesystem/src/mount.cpp delete mode 100644 kernel/filesystem/src/open_file_description.cpp delete mode 100644 kernel/filesystem/src/vfs.cpp create mode 100644 kernel/include/kernel/devices/block_device.hpp create mode 100644 kernel/include/kernel/devices/device.hpp create mode 100644 kernel/include/kernel/devices/storage/ram_disk/ram_disk_controller.hpp create mode 100644 kernel/include/kernel/devices/storage/ram_disk/ram_disk_device.hpp create mode 100644 kernel/include/kernel/devices/storage/storage_controller.hpp create mode 100644 kernel/include/kernel/devices/storage/storage_management.hpp create mode 100644 kernel/include/kernel/filesystem/custody.hpp create mode 100644 kernel/include/kernel/filesystem/device_file.hpp create mode 100644 kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp create mode 100644 kernel/include/kernel/filesystem/file.hpp create mode 100644 kernel/include/kernel/filesystem/file_descriptor_table.hpp create mode 100644 kernel/include/kernel/filesystem/filesystem.hpp create mode 100644 kernel/include/kernel/filesystem/inode.hpp create mode 100644 kernel/include/kernel/filesystem/inode_file.hpp create mode 100644 kernel/include/kernel/filesystem/inode_metadata.hpp create mode 100644 kernel/include/kernel/filesystem/mount.hpp create mode 100644 kernel/include/kernel/filesystem/open_file_description.hpp create mode 100644 kernel/include/kernel/filesystem/vfs.hpp 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 create mode 100644 kernel/src/filesystem/custody.cpp create mode 100644 kernel/src/filesystem/device_file.cpp create mode 100644 kernel/src/filesystem/ext2/ext2_filesystem.cpp create mode 100644 kernel/src/filesystem/file_descriptor_table.cpp create mode 100644 kernel/src/filesystem/filesystem.cpp create mode 100644 kernel/src/filesystem/inode.cpp create mode 100644 kernel/src/filesystem/inode_file.cpp create mode 100644 kernel/src/filesystem/mount.cpp create mode 100644 kernel/src/filesystem/open_file_description.cpp create mode 100644 kernel/src/filesystem/vfs.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 830c527..398022c 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,6 +1,3 @@ -add_subdirectory("devices") -add_subdirectory("filesystem") - add_executable("kernel" # Platform-independent KAPI implementation "kapi/boot_modules.cpp" @@ -18,6 +15,22 @@ add_executable("kernel" "src/memory/block_list_allocator.cpp" "src/memory/operators.cpp" "src/memory.cpp" + "src/devices/device.cpp" + "src/devices/block_device.cpp" + "src/devices/storage/storage_controller.cpp" + "src/devices/storage/storage_management.cpp" + "src/devices/storage/ram_disk/ram_disk_controller.cpp" + "src/devices/storage/ram_disk/ram_disk_device.cpp" + "src/filesystem/ext2/ext2_filesystem.cpp" + "src/filesystem/custody.cpp" + "src/filesystem/device_file.cpp" + "src/filesystem/file_descriptor_table.cpp" + "src/filesystem/filesystem.cpp" + "src/filesystem/inode_file.cpp" + "src/filesystem/inode.cpp" + "src/filesystem/mount.cpp" + "src/filesystem/open_file_description.cpp" + "src/filesystem/vfs.cpp" ) target_include_directories("kernel" PRIVATE @@ -27,8 +40,6 @@ target_include_directories("kernel" PRIVATE target_link_libraries("kernel" PRIVATE "os::arch" "os::kapi" - "kernel::devices" - "kernel::filesystem" ) target_link_options("kernel" PRIVATE diff --git a/kernel/devices/CMakeLists.txt b/kernel/devices/CMakeLists.txt deleted file mode 100644 index 15d03fa..0000000 --- a/kernel/devices/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -add_library("kernel_devices" STATIC) -add_library("kernel::devices" ALIAS "kernel_devices") - -target_sources("kernel_devices" PRIVATE - "src/device.cpp" - "src/block_device.cpp" - "src/storage/storage_controller.cpp" - "src/storage/storage_management.cpp" - "src/storage/ram_disk/ram_disk_controller.cpp" - "src/storage/ram_disk/ram_disk_device.cpp" -) - -target_sources("kernel_devices" PUBLIC - FILE_SET HEADERS - BASE_DIRS "include" - FILES - "include/devices/device.hpp" - "include/devices/block_device.hpp" - "include/devices/storage/storage_controller.hpp" - "include/devices/storage/storage_management.hpp" - "include/devices/storage/ram_disk/ram_disk_controller.hpp" - "include/devices/storage/ram_disk/ram_disk_device.hpp" -) - -target_include_directories("kernel_devices" PUBLIC - "include" -) - -target_link_libraries("kernel_devices" PRIVATE - "os::kapi" -) \ No newline at end of file diff --git a/kernel/devices/include/devices/block_device.hpp b/kernel/devices/include/devices/block_device.hpp deleted file mode 100644 index 4831be5..0000000 --- a/kernel/devices/include/devices/block_device.hpp +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP -#define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP - -#include "devices/device.hpp" - -#include -#include - -namespace devices -{ - /** - * @brief Base interface for block-addressable devices. - */ - struct block_device : 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, std::string_view name, size_t block_size); - - /** - * @brief Virtual destructor for block device. - */ - virtual ~block_device() = default; - - /** - * @brief Read data from the block at @p block_index into @p buffer. - * @param block_index Zero-based block index. - * @param buffer Destination buffer. - * @warning Panics if @p buffer is null. - * @note Reads up to one logical block (see constructor @p block_size). Implementations may perform a partial - * transfer for the final block when fewer than @p block_size bytes remain. - */ - virtual auto read_block(size_t block_index, void * buffer) const -> void = 0; - - /** - * @brief Write data to the block at @p block_index. - * @param block_index Zero-based block index. - * @param buffer Source buffer, must not be null. - * @warning Panics if @p buffer is null. - * @note Writes up to one logical block (see constructor @p block_size). - * Implementations may perform a partial transfer for the final block when - * fewer than @p block_size bytes remain. - */ - virtual auto write_block(size_t block_index, void const * buffer) -> void = 0; - - /** - * @brief Return logical block size in bytes. - * @return One logical block size in bytes. - */ - [[nodiscard]] auto block_size() const -> size_t; - - /** - * @brief Return device capacity in bytes. - * @return Total number of addressable bytes. - */ - [[nodiscard]] auto capacity() const -> size_t; - - /** - * @brief Override to identify block devices. - * @return true if this device is a block device, false otherwise. - */ - - [[nodiscard]] auto is_block_device() const -> bool override - { - return true; - } - - protected: - /** - * @brief Information describing the transfer window for one block index. - */ - struct transfer_info - { - size_t offset; - size_t to_transfer; - size_t remainder; - }; - - /** - * @brief Return total device size in bytes. - * @return Total number of addressable bytes. - */ - [[nodiscard]] virtual auto size() const -> size_t = 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; - - size_t m_block_size; - }; -} // namespace devices - -#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/device.hpp b/kernel/devices/include/devices/device.hpp deleted file mode 100644 index d6f520f..0000000 --- a/kernel/devices/include/devices/device.hpp +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_DEVICE_HPP -#define TEACH_OS_KERNEL_DEVICES_DEVICE_HPP - -#include -#include - -namespace devices -{ - /** - * @brief Base device identified by a major, minor number and name. - */ - struct device - { - /** - * @brief Create a device identifier from @p major, @p minor and @p name. - * @param major Device major number. - * @param minor Device minor number. - * @param name Device name. - */ - device(size_t major, size_t minor, std::string_view name); - - /** - * @brief Virtual destructor for device. - */ - virtual ~device() = default; - - /** - * @brief Returns the major number of the device. - * @return Device major number. - */ - [[nodiscard]] auto major() const -> size_t; - - /** - * @brief Returns the minor number of the device. - * @return Device minor number. - */ - [[nodiscard]] auto minor() const -> size_t; - - /** - * @brief Returns the name of the device. - * @return Device name. - */ - [[nodiscard]] auto name() const -> std::string_view; - - /** - * @brief Check if the device is a block device. - * @return true if this device is a block device, false otherwise. - */ - [[nodiscard]] virtual auto is_block_device() const -> bool - { - return false; - } - - private: - size_t m_major; - size_t m_minor; - std::string_view m_name; - }; -} // namespace devices - -#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp b/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp deleted file mode 100644 index f69f8d8..0000000 --- a/kernel/devices/include/devices/storage/ram_disk/ram_disk_controller.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP -#define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP - -#include "kapi/boot_module/boot_module_registry.hpp" - -#include "devices/storage/storage_controller.hpp" - -namespace devices::storage::ram_disk -{ - /** - * @brief Storage controller that exposes boot modules as RAM-disk devices. - */ - struct ram_disk_controller : storage_controller - { - /** - * @brief Create a RAM-disk controller. - * @param registry Boot module registry as device source. - */ - explicit ram_disk_controller(kapi::boot_modules::boot_module_registry const * registry); - - /** - * @brief Probe boot modules and create RAM-disk devices. - */ - auto probe() -> void override; - - private: - kapi::boot_modules::boot_module_registry const * m_boot_module_registry; - }; -} // namespace devices::storage::ram_disk - -#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp b/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp deleted file mode 100644 index 1edf48c..0000000 --- a/kernel/devices/include/devices/storage/ram_disk/ram_disk_device.hpp +++ /dev/null @@ -1,52 +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 "devices/block_device.hpp" - -#include - -namespace devices::storage::ram_disk -{ - /** - * @brief Block device for a boot module. - */ - struct ram_disk_device : block_device - { - /** - * @brief Create a RAM disk for the @p module. - * @param module Boot module providing the memory region. - * @param major Device major number. - * @param minor Device minor number. - */ - ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor); - - /** - * @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 -> void 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) -> void override; - - private: - /** - * @brief Return module size in bytes. - */ - [[nodiscard]] auto size() const -> size_t override; - - kapi::boot_modules::boot_module m_boot_module{}; - }; -} // namespace devices::storage::ram_disk - -#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/storage_controller.hpp b/kernel/devices/include/devices/storage/storage_controller.hpp deleted file mode 100644 index 7760fc9..0000000 --- a/kernel/devices/include/devices/storage/storage_controller.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP -#define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP - -#include "devices/device.hpp" - -#include -#include - -#include - -namespace devices::storage -{ - /** - * @brief Base interface for storage controllers. - * - * A storage controller probes for devices and resolves devices by major/minor - * numbers. - */ - struct storage_controller - { - /** - * @brief Virtual destructor. - */ - virtual ~storage_controller() = default; - - /** - * @brief Probe the controller and register discovered devices. - */ - virtual auto probe() -> void = 0; - - /** - * @brief Assign the major number and minor stride for this controller. - * @param major Major number assigned to this controller. - * @param minors_per_dev Minor number stride between devices. - */ - auto set_ids(size_t major, size_t minors_per_dev) -> void; - - /** - * @brief Return the assigned major number. - * @return Assigned major number. - */ - [[nodiscard]] auto major() const -> size_t; - - /** - * @brief Return the number of devices managed by this controller. - * @return Number of managed devices. - */ - [[nodiscard]] auto devices_count() const -> size_t; - - /** - * @brief Return all devices managed by this controller. - * @return Vector of all managed devices. - */ - [[nodiscard]] auto all_devices() const -> kstd::vector> const &; - - /** - * @brief Find a managed device by major/minor numbers. - * @param major Device major number. - * @param minor Device minor number. - * @return Matching block device, or nullptr if no device matches. - */ - [[nodiscard]] auto device_by_minor(size_t minor) const -> kstd::shared_ptr; - - protected: - size_t m_major{}; - size_t m_minors_per_device{}; - kstd::vector> m_devices{}; - }; -} // namespace devices::storage - -#endif \ No newline at end of file diff --git a/kernel/devices/include/devices/storage/storage_management.hpp b/kernel/devices/include/devices/storage/storage_management.hpp deleted file mode 100644 index f8ffda8..0000000 --- a/kernel/devices/include/devices/storage/storage_management.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP -#define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP - -#include "devices/device.hpp" -#include "devices/storage/storage_controller.hpp" - -#include -#include - -#include - -namespace devices::storage -{ - /** - * @brief Global storage subsystem manager. - * - * Owns registered storage controllers and provides device lookup by - * major/minor numbers. - */ - struct storage_management - { - /** - * @brief Initialize global storage management. - * - * Creates the singleton instance, registers controllers and probes - * them for devices. - * - * @warning Panics if called more than once. - */ - auto static init() -> void; - - /** - * @brief Return the active storage manager singleton. - * @return Reference to the active storage manager. - * @warning Panics if storage management has not been initialized. - */ - auto static get() -> storage_management &; - - /** - * @brief Register a storage controller. - * @param controller Controller to register. - * - * Assigns controller IDs (major number range and minors per device). - */ - auto add_controller(kstd::shared_ptr const & controller) -> void; - - /** - * @brief Return all registered storage controllers. - * @return Vector of all registered storage controllers. - */ - [[nodiscard]] auto all_controllers() const -> kstd::vector> const &; - - /** - * @brief Find a device by major/minor numbers. - * @param major Device major number. - * @param minor Device minor number. - * @return Matching device, or nullptr if no device matches. - */ - auto device_by_major_minor(size_t major, size_t minor) -> kstd::shared_ptr; - - /** - * @brief Determine the boot device. - * @return Boot device, or nullptr if it cannot be determined. - */ - auto determine_boot_device() -> kstd::shared_ptr; - - private: - /** - * @brief Private default constructor for storage management singleton. - */ - storage_management() = default; - - kstd::vector> m_controllers{}; - }; -} // namespace devices::storage - -#endif \ No newline at end of file diff --git a/kernel/devices/src/block_device.cpp b/kernel/devices/src/block_device.cpp deleted file mode 100644 index 40f842a..0000000 --- a/kernel/devices/src/block_device.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "devices/block_device.hpp" - -#include "kapi/system.hpp" - -#include "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/devices/src/device.cpp b/kernel/devices/src/device.cpp deleted file mode 100644 index 8184321..0000000 --- a/kernel/devices/src/device.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "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/devices/src/storage/ram_disk/ram_disk_controller.cpp b/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp deleted file mode 100644 index 3d14faf..0000000 --- a/kernel/devices/src/storage/ram_disk/ram_disk_controller.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "devices/storage/ram_disk/ram_disk_controller.hpp" - -#include "kapi/boot_module/boot_module_registry.hpp" - -#include "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/devices/src/storage/ram_disk/ram_disk_device.cpp b/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp deleted file mode 100644 index 91a278e..0000000 --- a/kernel/devices/src/storage/ram_disk/ram_disk_device.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "devices/storage/ram_disk/ram_disk_device.hpp" - -#include "kapi/boot_module/boot_module.hpp" -#include "kapi/system.hpp" - -#include "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/devices/src/storage/storage_controller.cpp b/kernel/devices/src/storage/storage_controller.cpp deleted file mode 100644 index 16d40f4..0000000 --- a/kernel/devices/src/storage/storage_controller.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "devices/storage/storage_controller.hpp" - -#include "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/devices/src/storage/storage_management.cpp b/kernel/devices/src/storage/storage_management.cpp deleted file mode 100644 index 25885ad..0000000 --- a/kernel/devices/src/storage/storage_management.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "devices/storage/storage_management.hpp" - -#include "kapi/boot_modules.hpp" -#include "kapi/system.hpp" - -#include "devices/device.hpp" -#include "devices/storage/ram_disk/ram_disk_controller.hpp" -#include "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 diff --git a/kernel/filesystem/CMakeLists.txt b/kernel/filesystem/CMakeLists.txt deleted file mode 100644 index bb2090a..0000000 --- a/kernel/filesystem/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -add_library("kernel_filesystem" STATIC) -add_library("kernel::filesystem" ALIAS "kernel_filesystem") - -target_sources("kernel_filesystem" PRIVATE - "src/ext2/ext2_filesystem.cpp" - "src/custody.cpp" - "src/device_file.cpp" - "src/file_descriptor_table.cpp" - "src/filesystem.cpp" - "src/inode_file.cpp" - "src/inode.cpp" - "src/mount.cpp" - "src/open_file_description.cpp" - "src/vfs.cpp" -) - -target_sources("kernel_filesystem" PUBLIC - FILE_SET HEADERS - BASE_DIRS "include" - FILES - "include/filesystem/ext2/ext2_filesystem.hpp" - "include/filesystem/custody.hpp" - "include/filesystem/device_file.hpp" - "include/filesystem/file_descriptor_table.hpp" - "include/filesystem/file.hpp" - "include/filesystem/filesystem.hpp" - "include/filesystem/inode_file.hpp" - "include/filesystem/inode_metadata.hpp" - "include/filesystem/inode.hpp" - "include/filesystem/mount.hpp" - "include/filesystem/open_file_description.hpp" - "include/filesystem/vfs.hpp" -) - -target_include_directories("kernel_filesystem" PUBLIC - "include" -) - -target_link_libraries("kernel_filesystem" PUBLIC - "kernel::devices" -PRIVATE - "os::kapi" -) diff --git a/kernel/filesystem/include/filesystem/custody.hpp b/kernel/filesystem/include/filesystem/custody.hpp deleted file mode 100644 index 0124eb6..0000000 --- a/kernel/filesystem/include/filesystem/custody.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef TEACH_OS_KERNEL_CUSTODY_HPP -#define TEACH_OS_KERNEL_CUSTODY_HPP - -#include "filesystem/inode.hpp" - -#include - -namespace filesystem -{ - struct custody - { - custody(kstd::shared_ptr const & parent, kstd::shared_ptr const & node); - - [[nodiscard]] auto get_inode() const -> kstd::shared_ptr const &; - [[nodiscard]] auto get_parent() const -> kstd::shared_ptr const &; - - private: - kstd::shared_ptr m_parent; - kstd::shared_ptr m_inode; - }; -} // namespace filesystem - -#endif \ No newline at end of file diff --git a/kernel/filesystem/include/filesystem/device_file.hpp b/kernel/filesystem/include/filesystem/device_file.hpp deleted file mode 100644 index dad4ea5..0000000 --- a/kernel/filesystem/include/filesystem/device_file.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVICE_FILE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_FILE_HPP - -#include "devices/block_device.hpp" -#include "devices/device.hpp" -#include "filesystem/file.hpp" - -#include - -#include - -namespace filesystem -{ - struct device_file : file - { - explicit device_file(kstd::shared_ptr const & device); - - auto open() -> void override; - - auto read(void * buffer, size_t offset, size_t size) const -> size_t override; - auto write(void const * buffer, size_t offset, size_t size) -> size_t override; - - private: - 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(size_t offset, size_t size, void * buffer, block_op op) const -> size_t; - - kstd::shared_ptr m_device; - }; -} // namespace filesystem - -#endif diff --git a/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp b/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp deleted file mode 100644 index 37448a1..0000000 --- a/kernel/filesystem/include/filesystem/ext2/ext2_filesystem.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP - -#include "devices/device.hpp" -#include "filesystem/filesystem.hpp" -#include "filesystem/inode.hpp" - -#include - -#include - -namespace filesystem::ext2 -{ - struct ext2_filesystem : filesystem - { - auto mount(kstd::shared_ptr const & device) -> int override; - auto lookup(inode const & parent, std::string_view name) -> inode * override; - - private: - kstd::shared_ptr m_device{}; - }; -} // namespace filesystem::ext2 - -#endif diff --git a/kernel/filesystem/include/filesystem/file.hpp b/kernel/filesystem/include/filesystem/file.hpp deleted file mode 100644 index e7e1b12..0000000 --- a/kernel/filesystem/include/filesystem/file.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_FILE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_FILE_HPP - -#include - -namespace filesystem -{ - struct file - { - virtual ~file() = default; - - virtual auto open() -> void = 0; - - virtual auto read(void * buffer, size_t offset, size_t size) const -> size_t = 0; - virtual auto write(void const * buffer, size_t offset, size_t size) -> size_t = 0; - }; -} // namespace filesystem - -#endif \ No newline at end of file diff --git a/kernel/filesystem/include/filesystem/file_descriptor_table.hpp b/kernel/filesystem/include/filesystem/file_descriptor_table.hpp deleted file mode 100644 index 6d78532..0000000 --- a/kernel/filesystem/include/filesystem/file_descriptor_table.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP - -#include "open_file_description.hpp" - -#include - -#include - -namespace filesystem -{ - struct file_descriptor_table - { - auto static init() -> void; - auto static get() -> file_descriptor_table &; - - ~file_descriptor_table() = default; - - auto add_file(open_file_description & f) -> int; - [[nodiscard]] auto get_file(int fd) const -> std::optional; - auto remove_file(int fd) -> void; - - private: - file_descriptor_table() = default; - - // TODO BA-FS26 use kstd::shared_ptr when available - kstd::vector> m_open_files{}; - }; -} // namespace filesystem - -#endif \ No newline at end of file diff --git a/kernel/filesystem/include/filesystem/filesystem.hpp b/kernel/filesystem/include/filesystem/filesystem.hpp deleted file mode 100644 index 934f883..0000000 --- a/kernel/filesystem/include/filesystem/filesystem.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP - -#include "devices/device.hpp" -#include "filesystem/inode.hpp" - -#include - -#include - -namespace filesystem -{ - struct filesystem - { - virtual ~filesystem() = default; - - virtual auto mount(kstd::shared_ptr const & device) -> int = 0; - virtual auto lookup(inode const & parent, std::string_view name) -> inode * = 0; - - [[nodiscard]] auto root_inode() const -> inode const &; - - protected: - inode m_root_inode{}; // TODO BA-FS26 set during mount? - }; - -} // namespace filesystem - -#endif \ No newline at end of file diff --git a/kernel/filesystem/include/filesystem/inode.hpp b/kernel/filesystem/include/filesystem/inode.hpp deleted file mode 100644 index abfe2cf..0000000 --- a/kernel/filesystem/include/filesystem/inode.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP - -#include "devices/device.hpp" -#include "filesystem/inode_metadata.hpp" - -#include - -#include - -namespace filesystem -{ - struct inode - { - inode() = default; - explicit inode(inode_kind kind); - explicit inode(kstd::shared_ptr const & device); - - [[nodiscard]] auto metadata() const -> inode_metadata; - - [[nodiscard]] auto is_directory() const -> bool; - [[nodiscard]] auto is_regular() const -> bool; - [[nodiscard]] auto is_device() const -> bool; - [[nodiscard]] auto is_block_device() const -> bool; - [[nodiscard]] auto major_device() const -> size_t; - [[nodiscard]] auto minor_device() const -> size_t; - [[nodiscard]] auto backing_device() const -> kstd::shared_ptr const &; - - auto read(void * buffer, size_t offset, size_t size) const -> size_t; - auto write(void const * buffer, size_t offset, size_t size) -> size_t; - - private: - inode_kind m_kind{inode_kind::regular}; - kstd::shared_ptr m_device{}; - }; -} // namespace filesystem - -#endif diff --git a/kernel/filesystem/include/filesystem/inode_file.hpp b/kernel/filesystem/include/filesystem/inode_file.hpp deleted file mode 100644 index 5f8a95e..0000000 --- a/kernel/filesystem/include/filesystem/inode_file.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_FILE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_INODE_FILE_HPP - -#include "filesystem/file.hpp" -#include "filesystem/inode.hpp" - -#include - -#include - -namespace filesystem -{ - struct inode_file : file - { - explicit inode_file(kstd::shared_ptr const & inode); - - auto open() -> void override; - - auto read(void * buffer, size_t offset, size_t size) const -> size_t override; - auto write(void const * buffer, size_t offset, size_t size) -> size_t override; - - private: - kstd::shared_ptr m_inode; - }; -} // namespace filesystem - -#endif \ No newline at end of file diff --git a/kernel/filesystem/include/filesystem/inode_metadata.hpp b/kernel/filesystem/include/filesystem/inode_metadata.hpp deleted file mode 100644 index ed5a09d..0000000 --- a/kernel/filesystem/include/filesystem/inode_metadata.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_METADATA_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_INODE_METADATA_HPP - -#include -#include - -namespace filesystem -{ - enum class inode_kind - { - regular, - directory, - device - }; - - struct inode_metadata - { - inode_kind kind{inode_kind::regular}; - std::optional major{}; - std::optional minor{}; - }; -} // namespace filesystem - -#endif // TEACH_OS_KERNEL_FILESYSTEM_INODE_METADATA_HPP \ No newline at end of file diff --git a/kernel/filesystem/include/filesystem/mount.hpp b/kernel/filesystem/include/filesystem/mount.hpp deleted file mode 100644 index 46a68e2..0000000 --- a/kernel/filesystem/include/filesystem/mount.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_MOUNT_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_MOUNT_HPP - -#include "filesystem/filesystem.hpp" - -#include - -#include - -namespace filesystem -{ - struct mount - { - mount(std::string_view const & path, kstd::shared_ptr const & fs); - - [[nodiscard]] auto path() const -> std::string_view; - [[nodiscard]] auto get_filesystem() const -> kstd::shared_ptr const &; - - private: - std::string_view m_path; - kstd::shared_ptr m_filesystem{}; - }; -} // namespace filesystem - -#endif diff --git a/kernel/filesystem/include/filesystem/open_file_description.hpp b/kernel/filesystem/include/filesystem/open_file_description.hpp deleted file mode 100644 index 5ff094d..0000000 --- a/kernel/filesystem/include/filesystem/open_file_description.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP - -#include "file.hpp" - -#include - -#include - -namespace filesystem -{ - struct open_file_description - { - open_file_description(kstd::shared_ptr const & file); - - ~open_file_description() = default; - - auto read(void * buffer, size_t size) -> size_t; - auto write(void const * buffer, size_t size) -> size_t; - - private: - kstd::shared_ptr m_file; - size_t m_offset; - }; - -} // namespace filesystem - -#endif \ No newline at end of file diff --git a/kernel/filesystem/include/filesystem/vfs.hpp b/kernel/filesystem/include/filesystem/vfs.hpp deleted file mode 100644 index e16a961..0000000 --- a/kernel/filesystem/include/filesystem/vfs.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP - -#include "devices/device.hpp" -#include "filesystem/custody.hpp" -#include "filesystem/ext2/ext2_filesystem.hpp" -#include "filesystem/inode.hpp" -#include "filesystem/mount.hpp" -#include "filesystem/open_file_description.hpp" - -#include -#include - -#include -#include - -namespace filesystem -{ - struct vfs - { - auto static init() -> void; - auto static get() -> vfs &; - - ~vfs() = default; - - auto open(std::string_view path) -> std::optional; - - private: - struct device_node_entry - { - std::string_view name; - kstd::shared_ptr node; - }; - - vfs() = default; - auto make_device_node(kstd::shared_ptr const & device) -> void; - [[nodiscard]] auto resolve_path(std::string_view path) -> std::optional; - - kstd::shared_ptr m_root_fs; - std::optional m_root_mount; - // kstd::vector m_mounts; // TODO BA-FS26 really needed? - kstd::vector> m_device_nodes; // TODO BA-FS26 remove again, use devtempfs - }; -} // namespace filesystem - -#endif \ No newline at end of file diff --git a/kernel/filesystem/src/custody.cpp b/kernel/filesystem/src/custody.cpp deleted file mode 100644 index 3a87345..0000000 --- a/kernel/filesystem/src/custody.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "filesystem/custody.hpp" - -#include "kapi/system.hpp" - -#include "filesystem/inode.hpp" - -#include - -namespace filesystem -{ - custody::custody(kstd::shared_ptr const & parent, kstd::shared_ptr const & node) - : m_parent(parent) - , m_inode(node) - { - if (!m_inode) - { - kapi::system::panic("[FILESYSTEM] custody constructed with null inode."); - } - } - - auto custody::get_inode() const -> kstd::shared_ptr const & - { - return m_inode; - } - - auto custody::get_parent() const -> kstd::shared_ptr const & - { - return m_parent; - } -} // namespace filesystem \ No newline at end of file diff --git a/kernel/filesystem/src/device_file.cpp b/kernel/filesystem/src/device_file.cpp deleted file mode 100644 index 8fc159a..0000000 --- a/kernel/filesystem/src/device_file.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include "filesystem/device_file.hpp" - -#include "kapi/system.hpp" - -#include "devices/block_device.hpp" -#include "devices/device.hpp" - -#include -#include -#include - -#include -#include - -namespace filesystem -{ - device_file::device_file(kstd::shared_ptr const & device) - : m_device(device) - { - if (!m_device) - { - kapi::system::panic("[FILESYSTEM] device_file constructed with null device."); - } - } - - auto device_file::open() -> void - { - // Hook point for permission checks or lazy metadata loading. - } - - auto device_file::read(void * buffer, size_t offset, size_t size) const -> size_t - { - if (m_device->is_block_device()) - { - return process_blocks(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); - } - }); - } - else - { - kapi::system::panic("[FILESYSTEM] device_file::read called on non-block device."); - } - } - - auto device_file::write(void const * buffer, size_t offset, size_t size) -> size_t - { - if (m_device->is_block_device()) - { - return process_blocks(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); - } - }); - } - else - { - kapi::system::panic("[FILESYSTEM] device_file::write called on non-block device."); - } - } - - auto device_file::process_blocks(size_t offset, size_t size, void * buffer, block_op op) const -> size_t - { - if (buffer == nullptr) - { - kapi::system::panic("[FILESYSTEM] device_file::write called with null buffer."); - } - - if (size == 0) - { - return 0; - } - - auto * block_dev = static_cast(m_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; - } -} // namespace filesystem diff --git a/kernel/filesystem/src/ext2/ext2_filesystem.cpp b/kernel/filesystem/src/ext2/ext2_filesystem.cpp deleted file mode 100644 index a82a098..0000000 --- a/kernel/filesystem/src/ext2/ext2_filesystem.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "filesystem/ext2/ext2_filesystem.hpp" - -#include "devices/device.hpp" -#include "filesystem/inode.hpp" -#include "filesystem/inode_metadata.hpp" - -#include - -#include - -namespace filesystem::ext2 -{ - auto ext2_filesystem::mount(kstd::shared_ptr const & device) -> int - { - if (!device) - { - return -1; // TODO BA-FS26 panic or errorcode? - } - - m_device = device; - // TODO BA-FS26 load proper root inode from ext2 metadata - m_root_inode = inode{inode_kind::directory}; - - // TODO BA-FS26 implement - return 0; - } - - auto ext2_filesystem::lookup(inode const & /*parent*/, std::string_view /*name*/) -> inode * - { - // TODO BA-FS26 implement ext2 directory traversal and inode loading - return nullptr; - } -} // namespace filesystem::ext2 diff --git a/kernel/filesystem/src/file_descriptor_table.cpp b/kernel/filesystem/src/file_descriptor_table.cpp deleted file mode 100644 index 64fad0c..0000000 --- a/kernel/filesystem/src/file_descriptor_table.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "filesystem/file_descriptor_table.hpp" - -#include "kapi/system.hpp" - -#include "filesystem/open_file_description.hpp" - -#include -#include -#include - -namespace filesystem -{ - namespace - { - constinit auto static global_file_descriptor_table = std::optional{}; - } // namespace - - auto file_descriptor_table::init() -> void - { - if (global_file_descriptor_table) - { - kapi::system::panic("[FILESYSTEM] File descriptor table has already been initialized."); - } - - global_file_descriptor_table.emplace(file_descriptor_table{}); - } - - auto file_descriptor_table::get() -> file_descriptor_table & - { - if (!global_file_descriptor_table) - { - kapi::system::panic("[FILESYSTEM] File descriptor table has not been initialized."); - } - - return *global_file_descriptor_table; - } - - auto file_descriptor_table::add_file(open_file_description & file_description) -> int - { - auto it = std::ranges::find_if(m_open_files, [](auto & open_file) { return !open_file.has_value(); }); - if (it != m_open_files.end()) - { - *it = file_description; - return static_cast(it - m_open_files.begin()); - } - - m_open_files.push_back(file_description); - return static_cast(m_open_files.size() - 1); - } - - auto file_descriptor_table::get_file(int fd) const -> std::optional - { - if (fd < 0) - { - return std::nullopt; - } - - auto const index = static_cast(fd); - if (index >= m_open_files.size() || !m_open_files.at(fd).has_value()) - { - return std::nullopt; - } - - return m_open_files.at(fd); - } - - auto file_descriptor_table::remove_file(int fd) -> void - { - if (fd < 0) - { - return; - } - - auto const index = static_cast(fd); - if (index >= m_open_files.size()) - { - return; - } - - m_open_files.at(fd).reset(); - } -} // namespace filesystem \ No newline at end of file diff --git a/kernel/filesystem/src/filesystem.cpp b/kernel/filesystem/src/filesystem.cpp deleted file mode 100644 index cdfe7f8..0000000 --- a/kernel/filesystem/src/filesystem.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "filesystem/filesystem.hpp" - -#include "filesystem/inode.hpp" - -namespace filesystem -{ - auto filesystem::root_inode() const -> inode const & - { - return m_root_inode; - } -} // namespace filesystem \ No newline at end of file diff --git a/kernel/filesystem/src/inode.cpp b/kernel/filesystem/src/inode.cpp deleted file mode 100644 index 231ee33..0000000 --- a/kernel/filesystem/src/inode.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include "filesystem/inode.hpp" - -#include "kapi/system.hpp" - -#include "devices/device.hpp" -#include "filesystem/inode_metadata.hpp" - -#include - -#include - -namespace filesystem -{ - inode::inode(inode_kind kind) - : m_kind(kind) - {} - - inode::inode(kstd::shared_ptr const & device) - : m_kind(inode_kind::device) - , m_device(device) - { - if (!m_device) - { - kapi::system::panic("[FILESYSTEM] inode constructed with null device."); - } - } - - auto inode::metadata() const -> inode_metadata - { - auto meta = inode_metadata{}; - meta.kind = m_kind; - - if (is_device()) - { - meta.major = m_device->major(); - meta.minor = m_device->minor(); - } - - return meta; - } - - auto inode::is_directory() const -> bool - { - return m_kind == inode_kind::directory; - } - - auto inode::is_regular() const -> bool - { - return m_kind == inode_kind::regular; - } - - auto inode::is_device() const -> bool - { - return m_kind == inode_kind::device; - } - - auto inode::is_block_device() const -> bool - { - return is_device() && m_device->is_block_device(); - } - - auto inode::major_device() const -> size_t - { - if (!is_device()) - { - kapi::system::panic("[FILESYSTEM] inode::major_device called on non-device inode."); - } - - return m_device->major(); - } - - auto inode::minor_device() const -> size_t - { - if (!is_device()) - { - kapi::system::panic("[FILESYSTEM] inode::minor_device called on non-device inode."); - } - - return m_device->minor(); - } - - auto inode::backing_device() const -> kstd::shared_ptr const & - { - return m_device; - } - - auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t - { - if (is_device()) - { - kapi::system::panic("[FILESYSTEM] inode::read called on device inode. Open it as a device file first."); - } - - // TODO BA-FS26 - return 0; - } - - auto inode::write(void const *, size_t, size_t) -> size_t - { - if (is_device()) - { - kapi::system::panic("[FILESYSTEM] inode::write called on device inode. Open it as a device file first."); - } - - kapi::system::panic("[FILESYSTEM] inode::write is not implemented yet"); - return 0; - } -} // namespace filesystem \ No newline at end of file diff --git a/kernel/filesystem/src/inode_file.cpp b/kernel/filesystem/src/inode_file.cpp deleted file mode 100644 index 0b8bdf9..0000000 --- a/kernel/filesystem/src/inode_file.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "filesystem/inode_file.hpp" - -#include "kapi/system.hpp" - -#include "filesystem/inode.hpp" - -#include - -#include - -namespace filesystem -{ - inode_file::inode_file(kstd::shared_ptr const & inode) - : m_inode(inode) - { - if (!m_inode) - { - kapi::system::panic("[FILESYSTEM] inode_file constructed with null inode"); - } - } - - auto inode_file::open() -> void - { - // Hook point for permission checks or lazy metadata loading. - } - - auto inode_file::read(void * buffer, size_t offset, size_t size) const -> size_t - { - return m_inode->read(buffer, offset, size); - } - auto inode_file::write(void const * buffer, size_t offset, size_t size) -> size_t - { - return m_inode->write(buffer, offset, size); - } -} // namespace filesystem \ No newline at end of file diff --git a/kernel/filesystem/src/mount.cpp b/kernel/filesystem/src/mount.cpp deleted file mode 100644 index 021b074..0000000 --- a/kernel/filesystem/src/mount.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "filesystem/mount.hpp" - -#include "kapi/system.hpp" - -#include "filesystem/filesystem.hpp" - -#include - -#include - -namespace filesystem -{ - mount::mount(std::string_view const & path, kstd::shared_ptr const & fs) - : m_path(path) - , m_filesystem(fs) - { - if (!m_filesystem) - { - kapi::system::panic("[FILESYSTEM] mount initialized with null filesystem."); - } - } - - auto mount::path() const -> std::string_view - { - return m_path; - } - - auto mount::get_filesystem() const -> kstd::shared_ptr const & - { - return m_filesystem; - } -} // namespace filesystem \ No newline at end of file diff --git a/kernel/filesystem/src/open_file_description.cpp b/kernel/filesystem/src/open_file_description.cpp deleted file mode 100644 index cddee76..0000000 --- a/kernel/filesystem/src/open_file_description.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "filesystem/open_file_description.hpp" - -#include "filesystem/file.hpp" - -#include -#include - -#include - -namespace filesystem -{ - open_file_description::open_file_description(kstd::shared_ptr const & file) - : m_file(file) - , m_offset(0) - { - if (!file) - { - kstd::os::panic("[FILESYSTEM] open_file_description constructed with null file."); - } - } - - auto open_file_description::read(void * buffer, size_t size) -> size_t - { - auto read_bytes = m_file->read(buffer, m_offset, size); - m_offset += read_bytes; - return read_bytes; - } - - auto open_file_description::write(void const * buffer, size_t size) -> size_t - { - auto written_bytes = m_file->write(buffer, m_offset, size); - m_offset += written_bytes; - return written_bytes; - } -} // namespace filesystem \ No newline at end of file diff --git a/kernel/filesystem/src/vfs.cpp b/kernel/filesystem/src/vfs.cpp deleted file mode 100644 index c0f1c3a..0000000 --- a/kernel/filesystem/src/vfs.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include "filesystem/vfs.hpp" - -#include "kapi/system.hpp" - -#include "devices/device.hpp" -#include "devices/storage/storage_management.hpp" -#include "filesystem/custody.hpp" -#include "filesystem/device_file.hpp" -#include "filesystem/ext2/ext2_filesystem.hpp" -#include "filesystem/inode.hpp" -#include "filesystem/inode_file.hpp" -#include "filesystem/mount.hpp" -#include "filesystem/open_file_description.hpp" - -#include -#include - -#include -#include -#include - -namespace filesystem -{ - namespace - { - constinit auto static active_vfs = std::optional{}; - } // namespace - - auto vfs::init() -> void - { - if (active_vfs) - { - kapi::system::panic("[FILESYSTEM] vfs has already been initialized."); - } - - active_vfs.emplace(vfs{}); - - auto storage_mgmt = devices::storage::storage_management::get(); - if (auto boot_device = storage_mgmt.determine_boot_device()) - { - active_vfs->m_root_fs = kstd::make_shared(); - if (active_vfs->m_root_fs->mount(boot_device) != 0) - { - kapi::system::panic("[FILESYSTEM] Failed to mount root filesystem."); - } - - active_vfs->m_root_mount = mount{"/", active_vfs->m_root_fs}; - - std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto controller) { - std::ranges::for_each(controller->all_devices(), [&](auto device) { active_vfs->make_device_node(device); }); - }); - } - else - { - // TODO BA-FS26 ?? what when no boot_device == no modules loaded?? - } - } - - auto vfs::get() -> vfs & - { - if (!active_vfs) - { - kapi::system::panic("[FILESYSTEM] vfs has not been initialized."); - } - - return *active_vfs; - } - - auto vfs::open(std::string_view path) -> std::optional - { - if (auto custody = resolve_path(path)) - { - auto node = custody->get_inode(); - if (node->is_device()) - { - auto current_device_file = kstd::make_shared(node->backing_device()); - current_device_file->open(); - return open_file_description{current_device_file}; - } - - auto current_inode_file = kstd::make_shared(node); - current_inode_file->open(); - return open_file_description{current_inode_file}; - } - - return std::nullopt; - } - - auto vfs::make_device_node(kstd::shared_ptr const & device) -> void - { - if (!device) - { - kapi::system::panic("[FILESYSTEM] make_device_node called with null device."); - } - - m_device_nodes.push_back(device_node_entry{device->name(), kstd::make_shared(device)}); - } - - auto vfs::resolve_path(std::string_view path) -> std::optional - { - // TODO BA-FS26 implement real path resolution with mounts and directories etc. - // For now, just support device nodes at /dev/. - - constexpr auto device_prefix = std::string_view{"/dev/"}; - if (path.starts_with(device_prefix)) - { - auto const device_name = path.substr(device_prefix.size()); - auto entry = std::ranges::find_if(m_device_nodes, [&](auto const & device_entry) { - return device_entry.has_value() && device_entry->name == device_name; - }); - - if (entry != m_device_nodes.end()) - { - return custody{nullptr, entry->value().node}; - } - - return std::nullopt; - } - - return std::nullopt; - } - -} // namespace filesystem \ No newline at end of file diff --git a/kernel/include/kernel/devices/block_device.hpp b/kernel/include/kernel/devices/block_device.hpp new file mode 100644 index 0000000..2a6f061 --- /dev/null +++ b/kernel/include/kernel/devices/block_device.hpp @@ -0,0 +1,101 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP +#define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP + +#include "kernel/devices/device.hpp" + +#include +#include + +namespace devices +{ + /** + * @brief Base interface for block-addressable devices. + */ + struct block_device : 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, std::string_view name, size_t block_size); + + /** + * @brief Virtual destructor for block device. + */ + virtual ~block_device() = default; + + /** + * @brief Read data from the block at @p block_index into @p buffer. + * @param block_index Zero-based block index. + * @param buffer Destination buffer. + * @warning Panics if @p buffer is null. + * @note Reads up to one logical block (see constructor @p block_size). Implementations may perform a partial + * transfer for the final block when fewer than @p block_size bytes remain. + */ + virtual auto read_block(size_t block_index, void * buffer) const -> void = 0; + + /** + * @brief Write data to the block at @p block_index. + * @param block_index Zero-based block index. + * @param buffer Source buffer, must not be null. + * @warning Panics if @p buffer is null. + * @note Writes up to one logical block (see constructor @p block_size). + * Implementations may perform a partial transfer for the final block when + * fewer than @p block_size bytes remain. + */ + virtual auto write_block(size_t block_index, void const * buffer) -> void = 0; + + /** + * @brief Return logical block size in bytes. + * @return One logical block size in bytes. + */ + [[nodiscard]] auto block_size() const -> size_t; + + /** + * @brief Return device capacity in bytes. + * @return Total number of addressable bytes. + */ + [[nodiscard]] auto capacity() const -> size_t; + + /** + * @brief Override to identify block devices. + * @return true if this device is a block device, false otherwise. + */ + + [[nodiscard]] auto is_block_device() const -> bool override + { + return true; + } + + protected: + /** + * @brief Information describing the transfer window for one block index. + */ + struct transfer_info + { + size_t offset; + size_t to_transfer; + size_t remainder; + }; + + /** + * @brief Return total device size in bytes. + * @return Total number of addressable bytes. + */ + [[nodiscard]] virtual auto size() const -> size_t = 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; + + size_t m_block_size; + }; +} // namespace devices + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/device.hpp b/kernel/include/kernel/devices/device.hpp new file mode 100644 index 0000000..d6f520f --- /dev/null +++ b/kernel/include/kernel/devices/device.hpp @@ -0,0 +1,61 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_DEVICE_HPP +#define TEACH_OS_KERNEL_DEVICES_DEVICE_HPP + +#include +#include + +namespace devices +{ + /** + * @brief Base device identified by a major, minor number and name. + */ + struct device + { + /** + * @brief Create a device identifier from @p major, @p minor and @p name. + * @param major Device major number. + * @param minor Device minor number. + * @param name Device name. + */ + device(size_t major, size_t minor, std::string_view name); + + /** + * @brief Virtual destructor for device. + */ + virtual ~device() = default; + + /** + * @brief Returns the major number of the device. + * @return Device major number. + */ + [[nodiscard]] auto major() const -> size_t; + + /** + * @brief Returns the minor number of the device. + * @return Device minor number. + */ + [[nodiscard]] auto minor() const -> size_t; + + /** + * @brief Returns the name of the device. + * @return Device name. + */ + [[nodiscard]] auto name() const -> std::string_view; + + /** + * @brief Check if the device is a block device. + * @return true if this device is a block device, false otherwise. + */ + [[nodiscard]] virtual auto is_block_device() const -> bool + { + return false; + } + + private: + size_t m_major; + size_t m_minor; + std::string_view m_name; + }; +} // namespace devices + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/storage/ram_disk/ram_disk_controller.hpp b/kernel/include/kernel/devices/storage/ram_disk/ram_disk_controller.hpp new file mode 100644 index 0000000..6f022e3 --- /dev/null +++ b/kernel/include/kernel/devices/storage/ram_disk/ram_disk_controller.hpp @@ -0,0 +1,31 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP +#define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP + +#include "kapi/boot_module/boot_module_registry.hpp" + +#include "kernel/devices/storage/storage_controller.hpp" + +namespace devices::storage::ram_disk +{ + /** + * @brief Storage controller that exposes boot modules as RAM-disk devices. + */ + struct ram_disk_controller : storage_controller + { + /** + * @brief Create a RAM-disk controller. + * @param registry Boot module registry as device source. + */ + explicit ram_disk_controller(kapi::boot_modules::boot_module_registry const * registry); + + /** + * @brief Probe boot modules and create RAM-disk devices. + */ + auto probe() -> void override; + + private: + kapi::boot_modules::boot_module_registry const * m_boot_module_registry; + }; +} // namespace devices::storage::ram_disk + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/storage/ram_disk/ram_disk_device.hpp b/kernel/include/kernel/devices/storage/ram_disk/ram_disk_device.hpp new file mode 100644 index 0000000..c323f4b --- /dev/null +++ b/kernel/include/kernel/devices/storage/ram_disk/ram_disk_device.hpp @@ -0,0 +1,52 @@ +#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 "kernel/devices/block_device.hpp" + +#include + +namespace devices::storage::ram_disk +{ + /** + * @brief Block device for a boot module. + */ + struct ram_disk_device : block_device + { + /** + * @brief Create a RAM disk for the @p module. + * @param module Boot module providing the memory region. + * @param major Device major number. + * @param minor Device minor number. + */ + ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor); + + /** + * @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 -> void 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) -> void override; + + private: + /** + * @brief Return module size in bytes. + */ + [[nodiscard]] auto size() const -> size_t override; + + kapi::boot_modules::boot_module m_boot_module{}; + }; +} // namespace devices::storage::ram_disk + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/storage/storage_controller.hpp b/kernel/include/kernel/devices/storage/storage_controller.hpp new file mode 100644 index 0000000..58585fa --- /dev/null +++ b/kernel/include/kernel/devices/storage/storage_controller.hpp @@ -0,0 +1,71 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP +#define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP + +#include "kernel/devices/device.hpp" + +#include +#include + +#include + +namespace devices::storage +{ + /** + * @brief Base interface for storage controllers. + * + * A storage controller probes for devices and resolves devices by major/minor + * numbers. + */ + struct storage_controller + { + /** + * @brief Virtual destructor. + */ + virtual ~storage_controller() = default; + + /** + * @brief Probe the controller and register discovered devices. + */ + virtual auto probe() -> void = 0; + + /** + * @brief Assign the major number and minor stride for this controller. + * @param major Major number assigned to this controller. + * @param minors_per_dev Minor number stride between devices. + */ + auto set_ids(size_t major, size_t minors_per_dev) -> void; + + /** + * @brief Return the assigned major number. + * @return Assigned major number. + */ + [[nodiscard]] auto major() const -> size_t; + + /** + * @brief Return the number of devices managed by this controller. + * @return Number of managed devices. + */ + [[nodiscard]] auto devices_count() const -> size_t; + + /** + * @brief Return all devices managed by this controller. + * @return Vector of all managed devices. + */ + [[nodiscard]] auto all_devices() const -> kstd::vector> const &; + + /** + * @brief Find a managed device by major/minor numbers. + * @param major Device major number. + * @param minor Device minor number. + * @return Matching block device, or nullptr if no device matches. + */ + [[nodiscard]] auto device_by_minor(size_t minor) const -> kstd::shared_ptr; + + protected: + size_t m_major{}; + size_t m_minors_per_device{}; + kstd::vector> m_devices{}; + }; +} // namespace devices::storage + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/storage/storage_management.hpp b/kernel/include/kernel/devices/storage/storage_management.hpp new file mode 100644 index 0000000..413820e --- /dev/null +++ b/kernel/include/kernel/devices/storage/storage_management.hpp @@ -0,0 +1,77 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP +#define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP + +#include "kernel/devices/device.hpp" +#include "kernel/devices/storage/storage_controller.hpp" + +#include +#include + +#include + +namespace devices::storage +{ + /** + * @brief Global storage subsystem manager. + * + * Owns registered storage controllers and provides device lookup by + * major/minor numbers. + */ + struct storage_management + { + /** + * @brief Initialize global storage management. + * + * Creates the singleton instance, registers controllers and probes + * them for devices. + * + * @warning Panics if called more than once. + */ + auto static init() -> void; + + /** + * @brief Return the active storage manager singleton. + * @return Reference to the active storage manager. + * @warning Panics if storage management has not been initialized. + */ + auto static get() -> storage_management &; + + /** + * @brief Register a storage controller. + * @param controller Controller to register. + * + * Assigns controller IDs (major number range and minors per device). + */ + auto add_controller(kstd::shared_ptr const & controller) -> void; + + /** + * @brief Return all registered storage controllers. + * @return Vector of all registered storage controllers. + */ + [[nodiscard]] auto all_controllers() const -> kstd::vector> const &; + + /** + * @brief Find a device by major/minor numbers. + * @param major Device major number. + * @param minor Device minor number. + * @return Matching device, or nullptr if no device matches. + */ + auto device_by_major_minor(size_t major, size_t minor) -> kstd::shared_ptr; + + /** + * @brief Determine the boot device. + * @return Boot device, or nullptr if it cannot be determined. + */ + auto determine_boot_device() -> kstd::shared_ptr; + + private: + /** + * @brief Private default constructor for storage management singleton. + */ + storage_management() = default; + + kstd::vector> m_controllers{}; + }; +} // namespace devices::storage + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/custody.hpp b/kernel/include/kernel/filesystem/custody.hpp new file mode 100644 index 0000000..8a0e09a --- /dev/null +++ b/kernel/include/kernel/filesystem/custody.hpp @@ -0,0 +1,23 @@ +#ifndef TEACH_OS_KERNEL_CUSTODY_HPP +#define TEACH_OS_KERNEL_CUSTODY_HPP + +#include "kernel/filesystem/inode.hpp" + +#include + +namespace filesystem +{ + struct custody + { + custody(kstd::shared_ptr const & parent, kstd::shared_ptr const & node); + + [[nodiscard]] auto get_inode() const -> kstd::shared_ptr const &; + [[nodiscard]] auto get_parent() const -> kstd::shared_ptr const &; + + private: + kstd::shared_ptr m_parent; + kstd::shared_ptr m_inode; + }; +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/device_file.hpp b/kernel/include/kernel/filesystem/device_file.hpp new file mode 100644 index 0000000..06aa9b2 --- /dev/null +++ b/kernel/include/kernel/filesystem/device_file.hpp @@ -0,0 +1,32 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVICE_FILE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_FILE_HPP + +#include "kernel/devices/block_device.hpp" +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/file.hpp" + +#include + +#include + +namespace filesystem +{ + struct device_file : file + { + explicit device_file(kstd::shared_ptr const & device); + + auto open() -> void override; + + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + + private: + 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(size_t offset, size_t size, void * buffer, block_op op) const -> size_t; + + kstd::shared_ptr m_device; + }; +} // namespace filesystem + +#endif diff --git a/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp b/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp new file mode 100644 index 0000000..d6f69c8 --- /dev/null +++ b/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp @@ -0,0 +1,24 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/filesystem.hpp" +#include "kernel/filesystem/inode.hpp" + +#include + +#include + +namespace filesystem::ext2 +{ + struct ext2_filesystem : filesystem + { + auto mount(kstd::shared_ptr const & device) -> int override; + auto lookup(inode const & parent, std::string_view name) -> inode * override; + + private: + kstd::shared_ptr m_device{}; + }; +} // namespace filesystem::ext2 + +#endif diff --git a/kernel/include/kernel/filesystem/file.hpp b/kernel/include/kernel/filesystem/file.hpp new file mode 100644 index 0000000..e7e1b12 --- /dev/null +++ b/kernel/include/kernel/filesystem/file.hpp @@ -0,0 +1,19 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_FILE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_FILE_HPP + +#include + +namespace filesystem +{ + struct file + { + virtual ~file() = default; + + virtual auto open() -> void = 0; + + virtual auto read(void * buffer, size_t offset, size_t size) const -> size_t = 0; + virtual auto write(void const * buffer, size_t offset, size_t size) -> size_t = 0; + }; +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/filesystem/file_descriptor_table.hpp new file mode 100644 index 0000000..6d78532 --- /dev/null +++ b/kernel/include/kernel/filesystem/file_descriptor_table.hpp @@ -0,0 +1,31 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP + +#include "open_file_description.hpp" + +#include + +#include + +namespace filesystem +{ + struct file_descriptor_table + { + auto static init() -> void; + auto static get() -> file_descriptor_table &; + + ~file_descriptor_table() = default; + + auto add_file(open_file_description & f) -> int; + [[nodiscard]] auto get_file(int fd) const -> std::optional; + auto remove_file(int fd) -> void; + + private: + file_descriptor_table() = default; + + // TODO BA-FS26 use kstd::shared_ptr when available + kstd::vector> m_open_files{}; + }; +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp new file mode 100644 index 0000000..23924c4 --- /dev/null +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -0,0 +1,28 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/inode.hpp" + +#include + +#include + +namespace filesystem +{ + struct filesystem + { + virtual ~filesystem() = default; + + virtual auto mount(kstd::shared_ptr const & device) -> int = 0; + virtual auto lookup(inode const & parent, std::string_view name) -> inode * = 0; + + [[nodiscard]] auto root_inode() const -> inode const &; + + protected: + inode m_root_inode{}; // TODO BA-FS26 set during mount? + }; + +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp new file mode 100644 index 0000000..a2955f9 --- /dev/null +++ b/kernel/include/kernel/filesystem/inode.hpp @@ -0,0 +1,38 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/inode_metadata.hpp" + +#include + +#include + +namespace filesystem +{ + struct inode + { + inode() = default; + explicit inode(inode_kind kind); + explicit inode(kstd::shared_ptr const & device); + + [[nodiscard]] auto metadata() const -> inode_metadata; + + [[nodiscard]] auto is_directory() const -> bool; + [[nodiscard]] auto is_regular() const -> bool; + [[nodiscard]] auto is_device() const -> bool; + [[nodiscard]] auto is_block_device() const -> bool; + [[nodiscard]] auto major_device() const -> size_t; + [[nodiscard]] auto minor_device() const -> size_t; + [[nodiscard]] auto backing_device() const -> kstd::shared_ptr const &; + + auto read(void * buffer, size_t offset, size_t size) const -> size_t; + auto write(void const * buffer, size_t offset, size_t size) -> size_t; + + private: + inode_kind m_kind{inode_kind::regular}; + kstd::shared_ptr m_device{}; + }; +} // namespace filesystem + +#endif diff --git a/kernel/include/kernel/filesystem/inode_file.hpp b/kernel/include/kernel/filesystem/inode_file.hpp new file mode 100644 index 0000000..ee84eee --- /dev/null +++ b/kernel/include/kernel/filesystem/inode_file.hpp @@ -0,0 +1,27 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_FILE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_INODE_FILE_HPP + +#include "kernel/filesystem/file.hpp" +#include "kernel/filesystem/inode.hpp" + +#include + +#include + +namespace filesystem +{ + struct inode_file : file + { + explicit inode_file(kstd::shared_ptr const & inode); + + auto open() -> void override; + + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + + private: + kstd::shared_ptr m_inode; + }; +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/inode_metadata.hpp b/kernel/include/kernel/filesystem/inode_metadata.hpp new file mode 100644 index 0000000..ed5a09d --- /dev/null +++ b/kernel/include/kernel/filesystem/inode_metadata.hpp @@ -0,0 +1,24 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_METADATA_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_INODE_METADATA_HPP + +#include +#include + +namespace filesystem +{ + enum class inode_kind + { + regular, + directory, + device + }; + + struct inode_metadata + { + inode_kind kind{inode_kind::regular}; + std::optional major{}; + std::optional minor{}; + }; +} // namespace filesystem + +#endif // TEACH_OS_KERNEL_FILESYSTEM_INODE_METADATA_HPP \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp new file mode 100644 index 0000000..232a9be --- /dev/null +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -0,0 +1,25 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_MOUNT_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_MOUNT_HPP + +#include "kernel/filesystem/filesystem.hpp" + +#include + +#include + +namespace filesystem +{ + struct mount + { + mount(std::string_view const & path, kstd::shared_ptr const & fs); + + [[nodiscard]] auto path() const -> std::string_view; + [[nodiscard]] auto get_filesystem() const -> kstd::shared_ptr const &; + + private: + std::string_view m_path; + kstd::shared_ptr m_filesystem{}; + }; +} // namespace filesystem + +#endif diff --git a/kernel/include/kernel/filesystem/open_file_description.hpp b/kernel/include/kernel/filesystem/open_file_description.hpp new file mode 100644 index 0000000..5ff094d --- /dev/null +++ b/kernel/include/kernel/filesystem/open_file_description.hpp @@ -0,0 +1,28 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP + +#include "file.hpp" + +#include + +#include + +namespace filesystem +{ + struct open_file_description + { + open_file_description(kstd::shared_ptr const & file); + + ~open_file_description() = default; + + auto read(void * buffer, size_t size) -> size_t; + auto write(void const * buffer, size_t size) -> size_t; + + private: + kstd::shared_ptr m_file; + size_t m_offset; + }; + +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp new file mode 100644 index 0000000..a2894a6 --- /dev/null +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -0,0 +1,46 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/custody.hpp" +#include "kernel/filesystem/ext2/ext2_filesystem.hpp" +#include "kernel/filesystem/inode.hpp" +#include "kernel/filesystem/mount.hpp" +#include "kernel/filesystem/open_file_description.hpp" + +#include +#include + +#include +#include + +namespace filesystem +{ + struct vfs + { + auto static init() -> void; + auto static get() -> vfs &; + + ~vfs() = default; + + auto open(std::string_view path) -> std::optional; + + private: + struct device_node_entry + { + std::string_view name; + kstd::shared_ptr node; + }; + + vfs() = default; + auto make_device_node(kstd::shared_ptr const & device) -> void; + [[nodiscard]] auto resolve_path(std::string_view path) -> std::optional; + + kstd::shared_ptr m_root_fs; + std::optional m_root_mount; + // kstd::vector m_mounts; // TODO BA-FS26 really needed? + kstd::vector> m_device_nodes; // TODO BA-FS26 remove again, use devtempfs + }; +} // namespace filesystem + +#endif \ No newline at end of file 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 diff --git a/kernel/src/filesystem/custody.cpp b/kernel/src/filesystem/custody.cpp new file mode 100644 index 0000000..a4dd12c --- /dev/null +++ b/kernel/src/filesystem/custody.cpp @@ -0,0 +1,30 @@ +#include "kernel/filesystem/custody.hpp" + +#include "kapi/system.hpp" + +#include "kernel/filesystem/inode.hpp" + +#include + +namespace filesystem +{ + custody::custody(kstd::shared_ptr const & parent, kstd::shared_ptr const & node) + : m_parent(parent) + , m_inode(node) + { + if (!m_inode) + { + kapi::system::panic("[FILESYSTEM] custody constructed with null inode."); + } + } + + auto custody::get_inode() const -> kstd::shared_ptr const & + { + return m_inode; + } + + auto custody::get_parent() const -> kstd::shared_ptr const & + { + return m_parent; + } +} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/device_file.cpp b/kernel/src/filesystem/device_file.cpp new file mode 100644 index 0000000..c6db5af --- /dev/null +++ b/kernel/src/filesystem/device_file.cpp @@ -0,0 +1,124 @@ +#include "kernel/filesystem/device_file.hpp" + +#include "kapi/system.hpp" + +#include "kernel/devices/block_device.hpp" +#include "kernel/devices/device.hpp" + +#include +#include +#include + +#include +#include + +namespace filesystem +{ + device_file::device_file(kstd::shared_ptr const & device) + : m_device(device) + { + if (!m_device) + { + kapi::system::panic("[FILESYSTEM] device_file constructed with null device."); + } + } + + auto device_file::open() -> void + { + // Hook point for permission checks or lazy metadata loading. + } + + auto device_file::read(void * buffer, size_t offset, size_t size) const -> size_t + { + if (m_device->is_block_device()) + { + return process_blocks(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); + } + }); + } + else + { + kapi::system::panic("[FILESYSTEM] device_file::read called on non-block device."); + } + } + + auto device_file::write(void const * buffer, size_t offset, size_t size) -> size_t + { + if (m_device->is_block_device()) + { + return process_blocks(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); + } + }); + } + else + { + kapi::system::panic("[FILESYSTEM] device_file::write called on non-block device."); + } + } + + auto device_file::process_blocks(size_t offset, size_t size, void * buffer, block_op op) const -> size_t + { + if (buffer == nullptr) + { + kapi::system::panic("[FILESYSTEM] device_file::write called with null buffer."); + } + + if (size == 0) + { + return 0; + } + + auto * block_dev = static_cast(m_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; + } +} // namespace filesystem diff --git a/kernel/src/filesystem/ext2/ext2_filesystem.cpp b/kernel/src/filesystem/ext2/ext2_filesystem.cpp new file mode 100644 index 0000000..408b292 --- /dev/null +++ b/kernel/src/filesystem/ext2/ext2_filesystem.cpp @@ -0,0 +1,33 @@ +#include "kernel/filesystem/ext2/ext2_filesystem.hpp" + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/inode.hpp" +#include "kernel/filesystem/inode_metadata.hpp" + +#include + +#include + +namespace filesystem::ext2 +{ + auto ext2_filesystem::mount(kstd::shared_ptr const & device) -> int + { + if (!device) + { + return -1; // TODO BA-FS26 panic or errorcode? + } + + m_device = device; + // TODO BA-FS26 load proper root inode from ext2 metadata + m_root_inode = inode{inode_kind::directory}; + + // TODO BA-FS26 implement + return 0; + } + + auto ext2_filesystem::lookup(inode const & /*parent*/, std::string_view /*name*/) -> inode * + { + // TODO BA-FS26 implement ext2 directory traversal and inode loading + return nullptr; + } +} // namespace filesystem::ext2 diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp new file mode 100644 index 0000000..814322e --- /dev/null +++ b/kernel/src/filesystem/file_descriptor_table.cpp @@ -0,0 +1,82 @@ +#include "kernel/filesystem/file_descriptor_table.hpp" + +#include "kapi/system.hpp" + +#include "kernel/filesystem/open_file_description.hpp" + +#include +#include +#include + +namespace filesystem +{ + namespace + { + constinit auto static global_file_descriptor_table = std::optional{}; + } // namespace + + auto file_descriptor_table::init() -> void + { + if (global_file_descriptor_table) + { + kapi::system::panic("[FILESYSTEM] File descriptor table has already been initialized."); + } + + global_file_descriptor_table.emplace(file_descriptor_table{}); + } + + auto file_descriptor_table::get() -> file_descriptor_table & + { + if (!global_file_descriptor_table) + { + kapi::system::panic("[FILESYSTEM] File descriptor table has not been initialized."); + } + + return *global_file_descriptor_table; + } + + auto file_descriptor_table::add_file(open_file_description & file_description) -> int + { + auto it = std::ranges::find_if(m_open_files, [](auto & open_file) { return !open_file.has_value(); }); + if (it != m_open_files.end()) + { + *it = file_description; + return static_cast(it - m_open_files.begin()); + } + + m_open_files.push_back(file_description); + return static_cast(m_open_files.size() - 1); + } + + auto file_descriptor_table::get_file(int fd) const -> std::optional + { + if (fd < 0) + { + return std::nullopt; + } + + auto const index = static_cast(fd); + if (index >= m_open_files.size() || !m_open_files.at(fd).has_value()) + { + return std::nullopt; + } + + return m_open_files.at(fd); + } + + auto file_descriptor_table::remove_file(int fd) -> void + { + if (fd < 0) + { + return; + } + + auto const index = static_cast(fd); + if (index >= m_open_files.size()) + { + return; + } + + m_open_files.at(fd).reset(); + } +} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp new file mode 100644 index 0000000..86b7940 --- /dev/null +++ b/kernel/src/filesystem/filesystem.cpp @@ -0,0 +1,11 @@ +#include "kernel/filesystem/filesystem.hpp" + +#include "kernel/filesystem/inode.hpp" + +namespace filesystem +{ + auto filesystem::root_inode() const -> inode const & + { + return m_root_inode; + } +} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/inode.cpp b/kernel/src/filesystem/inode.cpp new file mode 100644 index 0000000..af73662 --- /dev/null +++ b/kernel/src/filesystem/inode.cpp @@ -0,0 +1,108 @@ +#include "kernel/filesystem/inode.hpp" + +#include "kapi/system.hpp" + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/inode_metadata.hpp" + +#include + +#include + +namespace filesystem +{ + inode::inode(inode_kind kind) + : m_kind(kind) + {} + + inode::inode(kstd::shared_ptr const & device) + : m_kind(inode_kind::device) + , m_device(device) + { + if (!m_device) + { + kapi::system::panic("[FILESYSTEM] inode constructed with null device."); + } + } + + auto inode::metadata() const -> inode_metadata + { + auto meta = inode_metadata{}; + meta.kind = m_kind; + + if (is_device()) + { + meta.major = m_device->major(); + meta.minor = m_device->minor(); + } + + return meta; + } + + auto inode::is_directory() const -> bool + { + return m_kind == inode_kind::directory; + } + + auto inode::is_regular() const -> bool + { + return m_kind == inode_kind::regular; + } + + auto inode::is_device() const -> bool + { + return m_kind == inode_kind::device; + } + + auto inode::is_block_device() const -> bool + { + return is_device() && m_device->is_block_device(); + } + + auto inode::major_device() const -> size_t + { + if (!is_device()) + { + kapi::system::panic("[FILESYSTEM] inode::major_device called on non-device inode."); + } + + return m_device->major(); + } + + auto inode::minor_device() const -> size_t + { + if (!is_device()) + { + kapi::system::panic("[FILESYSTEM] inode::minor_device called on non-device inode."); + } + + return m_device->minor(); + } + + auto inode::backing_device() const -> kstd::shared_ptr const & + { + return m_device; + } + + auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t + { + if (is_device()) + { + kapi::system::panic("[FILESYSTEM] inode::read called on device inode. Open it as a device file first."); + } + + // TODO BA-FS26 + return 0; + } + + auto inode::write(void const *, size_t, size_t) -> size_t + { + if (is_device()) + { + kapi::system::panic("[FILESYSTEM] inode::write called on device inode. Open it as a device file first."); + } + + kapi::system::panic("[FILESYSTEM] inode::write is not implemented yet"); + return 0; + } +} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/inode_file.cpp b/kernel/src/filesystem/inode_file.cpp new file mode 100644 index 0000000..7abac7b --- /dev/null +++ b/kernel/src/filesystem/inode_file.cpp @@ -0,0 +1,35 @@ +#include "kernel/filesystem/inode_file.hpp" + +#include "kapi/system.hpp" + +#include "kernel/filesystem/inode.hpp" + +#include + +#include + +namespace filesystem +{ + inode_file::inode_file(kstd::shared_ptr const & inode) + : m_inode(inode) + { + if (!m_inode) + { + kapi::system::panic("[FILESYSTEM] inode_file constructed with null inode"); + } + } + + auto inode_file::open() -> void + { + // Hook point for permission checks or lazy metadata loading. + } + + auto inode_file::read(void * buffer, size_t offset, size_t size) const -> size_t + { + return m_inode->read(buffer, offset, size); + } + auto inode_file::write(void const * buffer, size_t offset, size_t size) -> size_t + { + return m_inode->write(buffer, offset, size); + } +} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp new file mode 100644 index 0000000..a2c501f --- /dev/null +++ b/kernel/src/filesystem/mount.cpp @@ -0,0 +1,32 @@ +#include "kernel/filesystem/mount.hpp" + +#include "kapi/system.hpp" + +#include "kernel/filesystem/filesystem.hpp" + +#include + +#include + +namespace filesystem +{ + mount::mount(std::string_view const & path, kstd::shared_ptr const & fs) + : m_path(path) + , m_filesystem(fs) + { + if (!m_filesystem) + { + kapi::system::panic("[FILESYSTEM] mount initialized with null filesystem."); + } + } + + auto mount::path() const -> std::string_view + { + return m_path; + } + + auto mount::get_filesystem() const -> kstd::shared_ptr const & + { + return m_filesystem; + } +} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/open_file_description.cpp b/kernel/src/filesystem/open_file_description.cpp new file mode 100644 index 0000000..ff4d678 --- /dev/null +++ b/kernel/src/filesystem/open_file_description.cpp @@ -0,0 +1,35 @@ +#include "kernel/filesystem/open_file_description.hpp" + +#include "kernel/filesystem/file.hpp" + +#include +#include + +#include + +namespace filesystem +{ + open_file_description::open_file_description(kstd::shared_ptr const & file) + : m_file(file) + , m_offset(0) + { + if (!file) + { + kstd::os::panic("[FILESYSTEM] open_file_description constructed with null file."); + } + } + + auto open_file_description::read(void * buffer, size_t size) -> size_t + { + auto read_bytes = m_file->read(buffer, m_offset, size); + m_offset += read_bytes; + return read_bytes; + } + + auto open_file_description::write(void const * buffer, size_t size) -> size_t + { + auto written_bytes = m_file->write(buffer, m_offset, size); + m_offset += written_bytes; + return written_bytes; + } +} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp new file mode 100644 index 0000000..8d2ed0a --- /dev/null +++ b/kernel/src/filesystem/vfs.cpp @@ -0,0 +1,123 @@ +#include "kernel/filesystem/vfs.hpp" + +#include "kapi/system.hpp" + +#include "kernel/devices/storage/storage_management.hpp" +#include "kernel/filesystem/custody.hpp" +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/device_file.hpp" +#include "kernel/filesystem/ext2/ext2_filesystem.hpp" +#include "kernel/filesystem/inode.hpp" +#include "kernel/filesystem/inode_file.hpp" +#include "kernel/filesystem/mount.hpp" +#include "kernel/filesystem/open_file_description.hpp" + +#include +#include + +#include +#include +#include + +namespace filesystem +{ + namespace + { + constinit auto static active_vfs = std::optional{}; + } // namespace + + auto vfs::init() -> void + { + if (active_vfs) + { + kapi::system::panic("[FILESYSTEM] vfs has already been initialized."); + } + + active_vfs.emplace(vfs{}); + + auto storage_mgmt = devices::storage::storage_management::get(); + if (auto boot_device = storage_mgmt.determine_boot_device()) + { + active_vfs->m_root_fs = kstd::make_shared(); + if (active_vfs->m_root_fs->mount(boot_device) != 0) + { + kapi::system::panic("[FILESYSTEM] Failed to mount root filesystem."); + } + + active_vfs->m_root_mount = mount{"/", active_vfs->m_root_fs}; + + std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto controller) { + std::ranges::for_each(controller->all_devices(), [&](auto device) { active_vfs->make_device_node(device); }); + }); + } + else + { + // TODO BA-FS26 ?? what when no boot_device == no modules loaded?? + } + } + + auto vfs::get() -> vfs & + { + if (!active_vfs) + { + kapi::system::panic("[FILESYSTEM] vfs has not been initialized."); + } + + return *active_vfs; + } + + auto vfs::open(std::string_view path) -> std::optional + { + if (auto custody = resolve_path(path)) + { + auto node = custody->get_inode(); + if (node->is_device()) + { + auto current_device_file = kstd::make_shared(node->backing_device()); + current_device_file->open(); + return open_file_description{current_device_file}; + } + + auto current_inode_file = kstd::make_shared(node); + current_inode_file->open(); + return open_file_description{current_inode_file}; + } + + return std::nullopt; + } + + auto vfs::make_device_node(kstd::shared_ptr const & device) -> void + { + if (!device) + { + kapi::system::panic("[FILESYSTEM] make_device_node called with null device."); + } + + m_device_nodes.push_back(device_node_entry{device->name(), kstd::make_shared(device)}); + } + + auto vfs::resolve_path(std::string_view path) -> std::optional + { + // TODO BA-FS26 implement real path resolution with mounts and directories etc. + // For now, just support device nodes at /dev/. + + constexpr auto device_prefix = std::string_view{"/dev/"}; + if (path.starts_with(device_prefix)) + { + auto const device_name = path.substr(device_prefix.size()); + auto entry = std::ranges::find_if(m_device_nodes, [&](auto const & device_entry) { + return device_entry.has_value() && device_entry->name == device_name; + }); + + if (entry != m_device_nodes.end()) + { + return custody{nullptr, entry->value().node}; + } + + return std::nullopt; + } + + return std::nullopt; + } + +} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index cf3afdf..6ced18c 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -3,11 +3,11 @@ #include "kapi/memory.hpp" #include "kapi/system.hpp" -#include "devices/storage/storage_management.hpp" -#include "filesystem/device_file.hpp" -#include "filesystem/file_descriptor_table.hpp" -#include "filesystem/open_file_description.hpp" -#include "filesystem/vfs.hpp" +#include "kernel/devices/storage/storage_management.hpp" +#include "kernel/filesystem/device_file.hpp" +#include "kernel/filesystem/file_descriptor_table.hpp" +#include "kernel/filesystem/open_file_description.hpp" +#include "kernel/filesystem/vfs.hpp" #include "kernel/memory.hpp" #include -- cgit v1.2.3 From fde097681f96e2c6f23ecd71a5c0037acb3ac79e Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Tue, 17 Mar 2026 19:47:53 +0100 Subject: Fix include order --- kernel/src/filesystem/vfs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 8d2ed0a..2123fc7 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -2,9 +2,9 @@ #include "kapi/system.hpp" +#include "kernel/devices/device.hpp" #include "kernel/devices/storage/storage_management.hpp" #include "kernel/filesystem/custody.hpp" -#include "kernel/devices/device.hpp" #include "kernel/filesystem/device_file.hpp" #include "kernel/filesystem/ext2/ext2_filesystem.hpp" #include "kernel/filesystem/inode.hpp" -- 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/include/kernel/devices/block_device.hpp | 5 ----- kernel/src/devices/storage/ram_disk/ram_disk_controller.cpp | 1 - kernel/src/filesystem/vfs.cpp | 1 - kernel/src/main.cpp | 4 +++- 4 files changed, 3 insertions(+), 8 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/devices/block_device.hpp b/kernel/include/kernel/devices/block_device.hpp index 2a6f061..fb7d104 100644 --- a/kernel/include/kernel/devices/block_device.hpp +++ b/kernel/include/kernel/devices/block_device.hpp @@ -22,11 +22,6 @@ namespace devices */ block_device(size_t major, size_t minor, std::string_view name, size_t block_size); - /** - * @brief Virtual destructor for block device. - */ - virtual ~block_device() = default; - /** * @brief Read data from the block at @p block_index into @p buffer. * @param block_index Zero-based block index. 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 diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 2123fc7..4e0b6bf 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -12,7 +12,6 @@ #include "kernel/filesystem/mount.hpp" #include "kernel/filesystem/open_file_description.hpp" -#include #include #include diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 6ced18c..eb59402 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -51,7 +51,9 @@ auto run_test_code() -> void kstd::println("---"); // write half of the file new - kstd::vector write_buffer{std::byte{0xBB}, std::byte{0xAA}}; + auto const value1 = std::byte{0xAA}; + auto const value2 = std::byte{0xBB}; + kstd::vector write_buffer{value1, value2}; auto written_bytes = fd->write(write_buffer.data(), write_buffer.size()); kstd::println("written bytes: {}", written_bytes); -- cgit v1.2.3 From e7ccb96aecae7b231fb05818d7e45a767aebc31d Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 18 Mar 2026 17:18:37 +0100 Subject: kstd: introduce strong type for memory amounts --- .../include/kernel/memory/block_list_allocator.hpp | 13 +++++----- kernel/include/kernel/memory/heap_allocator.hpp | 5 ++-- kernel/kapi/memory.cpp | 10 +++++--- kernel/src/memory.cpp | 5 ++-- kernel/src/memory/block_list_allocator.cpp | 28 ++++++++++++---------- kernel/src/memory/operators.cpp | 13 ++++++---- 6 files changed, 42 insertions(+), 32 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/memory/block_list_allocator.hpp b/kernel/include/kernel/memory/block_list_allocator.hpp index 5e81c44..f319097 100644 --- a/kernel/include/kernel/memory/block_list_allocator.hpp +++ b/kernel/include/kernel/memory/block_list_allocator.hpp @@ -6,6 +6,7 @@ #include "kernel/memory/heap_allocator.hpp" #include +#include #include #include @@ -32,7 +33,7 @@ namespace kernel::memory //! @param size The size of the block to allocate //! @param alignment The desired alignment of the allocated block //! @return A pointer to the beginning of the block on success, @p nullptr otherwise. - [[nodiscard]] auto allocate(std::size_t size, std::align_val_t alignment) noexcept -> void * override; + [[nodiscard]] auto allocate(kstd::units::bytes size, kstd::units::bytes alignment) noexcept -> void * override; //! Deallocate a block of memory previously allocated. //! @@ -42,7 +43,7 @@ namespace kernel::memory private: struct block_header final { - std::size_t usable_size; + kstd::units::bytes usable_size; bool free; block_header * next; block_header * prev; @@ -52,16 +53,16 @@ namespace kernel::memory //! //! Each allocated block carries a block header, like any unallocated one, but in addition also has a back-pointer //! to the block header to support padding due to alignment. - constexpr auto static allocated_metadata_size = sizeof(block_header) + sizeof(block_header *); + constexpr auto static allocated_metadata_size = kstd::units::bytes{sizeof(block_header) + sizeof(block_header *)}; //! The minimum number of bytes for an allocation. - constexpr auto static minimum_allocation_size = 16uz; + constexpr auto static minimum_allocation_size = kstd::units::bytes{16uz}; //! Try to expand the heap to accommodate the given size. //! //! @param delta The size to expand the heap by. //! @return @p true if the heap was expanded, @p false otherwise. - auto expand(std::size_t delta) noexcept -> bool; + auto expand(kstd::units::bytes delta) noexcept -> bool; //! Split a given free block to accommodate and allocation. //! @@ -70,7 +71,7 @@ namespace kernel::memory //! @param block The block to split. //! @param size The size of the allocation. //! @param padding The amount of padding to apply. - auto split(block_header * block, std::size_t size, std::size_t padding) noexcept -> void; + auto split(block_header * block, kstd::units::bytes size, kstd::units::bytes padding) noexcept -> void; //! Try to coalesce a given block with it's preceding and/or following block. //! diff --git a/kernel/include/kernel/memory/heap_allocator.hpp b/kernel/include/kernel/memory/heap_allocator.hpp index bc771e3..55de7e4 100644 --- a/kernel/include/kernel/memory/heap_allocator.hpp +++ b/kernel/include/kernel/memory/heap_allocator.hpp @@ -1,9 +1,8 @@ #ifndef TEACHOS_KERNEL_MEMORY_HEAP_ALLOCATOR_HPP #define TEACHOS_KERNEL_MEMORY_HEAP_ALLOCATOR_HPP -#include +#include -#include #include namespace kernel::memory @@ -19,7 +18,7 @@ namespace kernel::memory //! @param size The size of the block to allocate //! @param alignment The desired alignment of the allocated block //! @return A pointer to the beginning of the block on success, @p nullptr otherwise. - [[nodiscard]] virtual auto allocate(std::size_t size, std::align_val_t alignment) noexcept -> void * = 0; + [[nodiscard]] virtual auto allocate(kstd::units::bytes size, kstd::units::bytes alignment) noexcept -> void * = 0; //! Deallocate a block of memory previously allocated. //! diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp index d8065d4..2803d76 100644 --- a/kernel/kapi/memory.cpp +++ b/kernel/kapi/memory.cpp @@ -5,6 +5,7 @@ #include "kernel/memory/bitmap_allocator.hpp" #include +#include #include #include @@ -112,8 +113,10 @@ namespace kapi::memory auto init_pmm(std::size_t frame_count, void (&handoff_handler)(frame_allocator &)) -> void { - auto const bitmap_bytes = (frame_count + 7uz) / 8uz; - auto const bitmap_pages = (bitmap_bytes + page::size - 1uz) / page::size; + using namespace kstd::units_literals; + + auto const bitmap_bytes = kstd::units::bytes{(frame_count + 7uz) / 8uz}; + auto const bitmap_pages = (bitmap_bytes + page::size - 1_B) / page::size; auto const bitmap_frames = allocate_many_frames(bitmap_pages); if (!bitmap_frames) @@ -130,7 +133,8 @@ namespace kapi::memory }); auto bitmap_ptr = static_cast(pmm_metadata_base); - auto bitmap = std::span{bitmap_ptr, (bitmap_bytes + sizeof(std::uint64_t) - 1uz) / sizeof(std::uint64_t)}; + auto bitmap = + std::span{bitmap_ptr, (bitmap_bytes + kstd::type_size - 1_B) / kstd::type_size}; allocator.emplace(bitmap, frame_count); diff --git a/kernel/src/memory.cpp b/kernel/src/memory.cpp index 0f614f0..4a8e203 100644 --- a/kernel/src/memory.cpp +++ b/kernel/src/memory.cpp @@ -7,10 +7,9 @@ #include "kernel/memory/heap_allocator.hpp" #include +#include #include -#include -#include #include namespace kernel::memory @@ -22,7 +21,7 @@ namespace kernel::memory { null_allocator static instance; - [[nodiscard]] auto allocate(std::size_t, std::align_val_t) noexcept -> void * override + [[nodiscard]] auto allocate(kstd::units::bytes, kstd::units::bytes) noexcept -> void * override { kstd::print(kstd::print_sink::stderr, "Tried to allocate memory without an active heap!"); return nullptr; diff --git a/kernel/src/memory/block_list_allocator.cpp b/kernel/src/memory/block_list_allocator.cpp index 5d870d8..fbc5945 100644 --- a/kernel/src/memory/block_list_allocator.cpp +++ b/kernel/src/memory/block_list_allocator.cpp @@ -6,19 +6,21 @@ #include "kernel/memory/heap_allocator.hpp" #include +#include #include #include #include #include -#include + +using namespace kstd::units_literals; namespace kernel::memory { namespace { - [[nodiscard]] constexpr auto align_up(std::byte * pointer, std::align_val_t alignment) noexcept -> std::byte * + [[nodiscard]] constexpr auto align_up(std::byte * pointer, kstd::units::bytes alignment) noexcept -> std::byte * { auto const remainder = std::bit_cast(pointer) % static_cast(alignment); return remainder == 0 ? pointer : pointer + static_cast(alignment) - remainder; @@ -33,7 +35,7 @@ namespace kernel::memory , m_lock{} {} - auto block_list_allocator::allocate(std::size_t size, std::align_val_t alignment) noexcept -> void * + auto block_list_allocator::allocate(kstd::units::bytes size, kstd::units::bytes alignment) noexcept -> void * { kstd::lock_guard guard{m_lock}; @@ -47,13 +49,13 @@ namespace kernel::memory auto const raw_block = reinterpret_cast(current); auto const unaligned_payload = raw_block + allocated_metadata_size; auto const aligned_payload = align_up(unaligned_payload, alignment); - auto const required_padding = static_cast(aligned_payload - unaligned_payload); + auto const required_padding = static_cast(aligned_payload - unaligned_payload); auto const total_required_size = required_padding + allocated_metadata_size + size; if (current->usable_size >= total_required_size) { auto const payload_header = aligned_payload - sizeof(block_header *) - sizeof(block_header); - auto const front_padding = static_cast(payload_header - raw_block); + auto const front_padding = static_cast(payload_header - raw_block); auto payload_block = current; @@ -72,9 +74,10 @@ namespace kernel::memory payload_block->prev = current; } - auto const payload_size = - aligned_payload - reinterpret_cast(payload_block) - allocated_metadata_size + size; - split(payload_block, payload_size, 0uz); + auto const header_size = + static_cast(aligned_payload - reinterpret_cast(payload_block)); + auto const payload_size = header_size - allocated_metadata_size + size; + split(payload_block, payload_size, 0_B); payload_block->free = false; @@ -87,7 +90,7 @@ namespace kernel::memory current = current->next; } - auto const search_size = size + static_cast(alignment); + auto const search_size = size + alignment; if (attempt == 0uz && !expand(search_size)) { return nullptr; @@ -114,10 +117,10 @@ namespace kernel::memory coalesce(block); } - auto block_list_allocator::expand(std::size_t size) noexcept -> bool + auto block_list_allocator::expand(kstd::units::bytes size) noexcept -> bool { auto const total_required_size = size + allocated_metadata_size; - auto const frames_needed = (total_required_size + kapi::memory::frame::size - 1) / kapi::memory::frame::size; + auto const frames_needed = (total_required_size + kapi::memory::frame::size - 1_B) / kapi::memory::frame::size; auto const flags = kapi::memory::page_mapper::flags::writable | kapi::memory::page_mapper::flags::supervisor_only | kapi::memory::page_mapper::flags::global; @@ -187,7 +190,8 @@ namespace kernel::memory } } - auto block_list_allocator::split(block_header * block, std::size_t size, std::size_t padding) noexcept -> void + auto block_list_allocator::split(block_header * block, kstd::units::bytes size, kstd::units::bytes padding) noexcept + -> void { auto const new_block_size = size + padding; diff --git a/kernel/src/memory/operators.cpp b/kernel/src/memory/operators.cpp index 57e31e6..c786b53 100644 --- a/kernel/src/memory/operators.cpp +++ b/kernel/src/memory/operators.cpp @@ -2,13 +2,16 @@ #include "kernel/memory.hpp" +#include + #include #include [[nodiscard]] auto operator new(std::size_t size, std::align_val_t alignment, std::nothrow_t const &) noexcept -> void * { auto & allocator = kernel::memory::get_heap_allocator(); - return allocator.allocate(size, alignment); + return allocator.allocate(static_cast(size), + static_cast(static_cast(alignment))); } [[nodiscard]] auto operator new(std::size_t size, std::align_val_t alignment) -> void * @@ -83,9 +86,9 @@ auto operator delete[](void * pointer) noexcept -> void ::operator delete(pointer); } -auto operator delete[](void * pointer, std::size_t) noexcept -> void +auto operator delete[](void * pointer, std::size_t size) noexcept -> void { - ::operator delete(pointer); + ::operator delete(pointer, size); } auto operator delete[](void * pointer, std::align_val_t) noexcept -> void @@ -93,7 +96,7 @@ auto operator delete[](void * pointer, std::align_val_t) noexcept -> void ::operator delete(pointer); } -auto operator delete[](void * pointer, std::size_t, std::align_val_t) noexcept -> void +auto operator delete[](void * pointer, std::size_t size, std::align_val_t) noexcept -> void { - ::operator delete(pointer); + ::operator delete(pointer, size); } -- cgit v1.2.3 From 584304d99b6bb43cef8aab9c6bfe22d24a5bf5a0 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 19 Mar 2026 13:31:54 +0100 Subject: kernel/memory: fix sized operator delete --- kernel/src/memory/operators.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/src/memory/operators.cpp b/kernel/src/memory/operators.cpp index c786b53..25b5f24 100644 --- a/kernel/src/memory/operators.cpp +++ b/kernel/src/memory/operators.cpp @@ -76,9 +76,9 @@ auto operator delete(void * pointer, std::align_val_t) noexcept -> void ::operator delete(pointer); } -auto operator delete(void * pointer, std::size_t, std::align_val_t) noexcept -> void +auto operator delete(void * pointer, std::size_t size, std::align_val_t) noexcept -> void { - ::operator delete(pointer); + ::operator delete(pointer, size); } auto operator delete[](void * pointer) noexcept -> void -- cgit v1.2.3 From 4f942e014dab44ccb8850c5921b81d4bd777d831 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 20 Mar 2026 11:19:05 +0100 Subject: kstd: rework formatting to be closer to std --- kernel/kstd/print.cpp | 137 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 49 deletions(-) (limited to 'kernel') diff --git a/kernel/kstd/print.cpp b/kernel/kstd/print.cpp index c7d26ba..44f80a7 100644 --- a/kernel/kstd/print.cpp +++ b/kernel/kstd/print.cpp @@ -70,74 +70,113 @@ namespace kstd::os auto writer = write_buffer{(sink == print_sink::stderr) ? kapi::cio::output_stream::stderr : kapi::cio::output_stream::stdout}; auto context = kstd::format_context{.writer = write_buffer::callback, .user_data = &writer}; + auto parse_context = kstd::format_parse_context{format, args.size()}; - auto current = format.begin(); - auto end = format.end(); - auto next_automatic_index = 0uz; + auto it = parse_context.begin(); + auto end = parse_context.end(); - while (current != end) + while (it != end) { - if (*current != '{') + if (*it != '{' && *it != '}') { - auto start = current; - while (current != end && *current != '{') + auto start = it; + while (it != end && *it != '{' && *it != '}') { - std::advance(current, 1); + std::advance(it, 1); } - context.push(std::string_view(start, current - start)); + parse_context.advance_to(it); + context.push(std::string_view(start, it - start)); continue; } - if (std::next(current) != end && *(std::next(current)) == '{') + if (*it == '{') { - context.push('{'); - std::advance(current, 2); - continue; - } + std::advance(it, 1); + if (it != end && *it == '{') + { + context.push('{'); + std::advance(it, 1); + parse_context.advance_to(it); + continue; + } - std::advance(current, 1); + parse_context.advance_to(it); + auto index = 0uz; - auto index = 0uz; - if (current != end && *current >= '0' && *current <= '9') - { - while (current != end && *current >= '0' && *current <= '9') + if (it != end && *it >= '0' && *it <= '9') { - index = index * 10 + static_cast(*current - '0'); - std::advance(current, 1); + while (it != end && *it >= '0' && *it <= '9') + { + index = index * 10 + static_cast(*it - '0'); + std::advance(it, 1); + } + parse_context.check_arg_id(index); + } + else + { + index = parse_context.next_arg_id(); } - } - else - { - index = next_automatic_index++; - } - auto remaining_fmt = std::string_view{current, static_cast(std::distance(current, end))}; + if (it != end && *it == ':') + { + std::advance(it, 1); + } - auto const arg = args.get(index); - if (arg.format) - { - auto const after_specs = arg.format(arg.value, remaining_fmt, context); - auto const consumed = remaining_fmt.size() - after_specs.size(); - std::advance(current, consumed); - } - else - { - context.push("{?}"); - while (current != end && *current != '}') - std::advance(current, 1); - } + parse_context.advance_to(it); - if (current != end && *current == '}') - { - std::advance(current, 1); + if (index < args.size()) + { + auto const & arg = args[index]; + if (arg.format_function) + { + arg.format_function(arg.value_pointer, parse_context, context); + } + else + { + context.push("{?}"); + } + } + else + { + context.push("{fmt-err: bound}"); + } + + it = parse_context.begin(); + + if (it != end && *it == '}') + { + std::advance(it, 1); + parse_context.advance_to(it); + } + else + { + context.push("{fmt-err: unconsumed}"); + while (it != end && *it != '}') + { + std::advance(it, 1); + } + + if (it != end) + { + std::advance(it, 1); + parse_context.advance_to(it); + } + } } - else + else if (*it == '}') { - context.push("{fmt-err}"); - while (current != end && *current != '}') - std::advance(current, 1); - if (current != end) - std::advance(current, 1); + std::advance(it, 1); + if (it != end && *it == '}') + { + context.push('}'); + std::advance(it, 1); + parse_context.advance_to(it); + } + else + { + context.push("{fmt-err: unescaped}"); + parse_context.advance_to(it); + } } } } -- cgit v1.2.3 From d7147ddd7416a6cce874d290d1615527f4d7cdb9 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 20 Mar 2026 12:01:22 +0100 Subject: kstd/format: implement dynamic width support --- kernel/kstd/print.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/kstd/print.cpp b/kernel/kstd/print.cpp index 44f80a7..db03816 100644 --- a/kernel/kstd/print.cpp +++ b/kernel/kstd/print.cpp @@ -69,7 +69,7 @@ namespace kstd::os { auto writer = write_buffer{(sink == print_sink::stderr) ? kapi::cio::output_stream::stderr : kapi::cio::output_stream::stdout}; - auto context = kstd::format_context{.writer = write_buffer::callback, .user_data = &writer}; + auto context = kstd::format_context{.writer = write_buffer::callback, .user_data = &writer, .args = args}; auto parse_context = kstd::format_parse_context{format, args.size()}; auto it = parse_context.begin(); -- cgit v1.2.3 From 8ae0f5a9a83aa58f2bd9eacfb51369b0bf966809 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 20 Mar 2026 15:22:37 +0100 Subject: kstd/format: use tagged union to reduce template bloat --- kernel/kstd/print.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/kstd/print.cpp b/kernel/kstd/print.cpp index db03816..beee2e5 100644 --- a/kernel/kstd/print.cpp +++ b/kernel/kstd/print.cpp @@ -127,13 +127,81 @@ namespace kstd::os if (index < args.size()) { auto const & arg = args[index]; - if (arg.format_function) + switch (arg.type) { - arg.format_function(arg.value_pointer, parse_context, context); - } - else - { - context.push("{?}"); + case kstd::bits::format::arg_type::boolean: + { + auto fmt = kstd::formatter{}; + auto const parsed = fmt.parse(parse_context); + parse_context.advance_to(parsed); + fmt.format(arg.value.boolean, context); + break; + } + case kstd::bits::format::arg_type::character: + { + auto fmt = kstd::formatter{}; + auto const parsed = fmt.parse(parse_context); + parse_context.advance_to(parsed); + fmt.format(arg.value.character, context); + break; + } + case kstd::bits::format::arg_type::integer: + { + auto fmt = kstd::formatter{}; + auto const parsed = fmt.parse(parse_context); + parse_context.advance_to(parsed); + fmt.format(arg.value.integer, context); + break; + } + case kstd::bits::format::arg_type::unsigned_integer: + { + auto fmt = kstd::formatter{}; + auto const parsed = fmt.parse(parse_context); + parse_context.advance_to(parsed); + fmt.format(arg.value.unsigned_integer, context); + break; + } + case kstd::bits::format::arg_type::string_view: + { + auto fmt = kstd::formatter{}; + auto const parsed = fmt.parse(parse_context); + parse_context.advance_to(parsed); + fmt.format(arg.value.string_view, context); + break; + } + case kstd::bits::format::arg_type::c_string: + { + auto fmt = kstd::formatter{}; + auto const parsed = fmt.parse(parse_context); + parse_context.advance_to(parsed); + fmt.format(arg.value.c_string, context); + break; + } + case kstd::bits::format::arg_type::pointer: + { + auto fmt = kstd::formatter{}; + auto const parsed = fmt.parse(parse_context); + parse_context.advance_to(parsed); + fmt.format(arg.value.pointer, context); + break; + } + case kstd::bits::format::arg_type::user_defined: + { + if (arg.value.user_defined.format) + { + arg.value.user_defined.format(arg.value.user_defined.pointer, parse_context, context); + } + else + { + context.push("{?}"); + } + break; + } + default: + { + context.push("{fmt-err: unknown-type}"); + break; + } } } else -- cgit v1.2.3 From 98b6633ea8e961f8668259dbd4970330494408d5 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 19 Mar 2026 21:32:38 +0100 Subject: prepare files for new inode structure --- kernel/CMakeLists.txt | 2 ++ kernel/include/kernel/filesystem/device_inode.hpp | 14 ++++++++++++++ kernel/include/kernel/filesystem/ext2/ext2_inode.hpp | 14 ++++++++++++++ kernel/src/filesystem/device_inode.cpp | 6 ++++++ kernel/src/filesystem/ext2/ext2_inode.cpp | 6 ++++++ 5 files changed, 42 insertions(+) create mode 100644 kernel/include/kernel/filesystem/device_inode.hpp create mode 100644 kernel/include/kernel/filesystem/ext2/ext2_inode.hpp create mode 100644 kernel/src/filesystem/device_inode.cpp create mode 100644 kernel/src/filesystem/ext2/ext2_inode.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 398022c..a36eac0 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -22,8 +22,10 @@ add_executable("kernel" "src/devices/storage/ram_disk/ram_disk_controller.cpp" "src/devices/storage/ram_disk/ram_disk_device.cpp" "src/filesystem/ext2/ext2_filesystem.cpp" + "src/filesystem/ext2/ext2_inode.cpp" "src/filesystem/custody.cpp" "src/filesystem/device_file.cpp" + "src/filesystem/device_inode.cpp" "src/filesystem/file_descriptor_table.cpp" "src/filesystem/filesystem.cpp" "src/filesystem/inode_file.cpp" diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp new file mode 100644 index 0000000..a99e5d1 --- /dev/null +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -0,0 +1,14 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP + +#include "kernel/filesystem/inode.hpp" + +namespace filesystem +{ + struct device_inode : inode + { + // TODO BA-FS26 + }; +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp new file mode 100644 index 0000000..7cd6f8f --- /dev/null +++ b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp @@ -0,0 +1,14 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP + +#include "kernel/filesystem/inode.hpp" + +namespace filesystem::ext2 +{ + struct ext2_inode : inode + { + // TODO BA-FS26 + }; +} // namespace filesystem::ext2 + +#endif \ No newline at end of file diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp new file mode 100644 index 0000000..b9018b1 --- /dev/null +++ b/kernel/src/filesystem/device_inode.cpp @@ -0,0 +1,6 @@ +#include "kernel/filesystem/device_inode.hpp" + +namespace filesystem +{ + // TODO BA-FS26: Implement device inode +} \ No newline at end of file diff --git a/kernel/src/filesystem/ext2/ext2_inode.cpp b/kernel/src/filesystem/ext2/ext2_inode.cpp new file mode 100644 index 0000000..ec68ee9 --- /dev/null +++ b/kernel/src/filesystem/ext2/ext2_inode.cpp @@ -0,0 +1,6 @@ +#include "kernel/filesystem/ext2/ext2_inode.hpp" + +namespace filesystem::ext2 +{ + // TODO BA-FS26: Implement ext2 inode +} \ No newline at end of file -- cgit v1.2.3 From 8d3471f1d160d301f9d990455bd8c63450df1cf3 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 19 Mar 2026 21:59:31 +0100 Subject: remove inode metadata --- kernel/include/kernel/filesystem/device_inode.hpp | 15 +++- kernel/include/kernel/filesystem/filesystem.hpp | 4 +- kernel/include/kernel/filesystem/inode.hpp | 23 +++--- .../include/kernel/filesystem/inode_metadata.hpp | 24 ------ kernel/src/filesystem/device_inode.cpp | 50 ++++++++++++- kernel/src/filesystem/ext2/ext2_filesystem.cpp | 3 +- kernel/src/filesystem/filesystem.cpp | 4 +- kernel/src/filesystem/inode.cpp | 85 ---------------------- kernel/src/filesystem/vfs.cpp | 6 +- 9 files changed, 82 insertions(+), 132 deletions(-) delete mode 100644 kernel/include/kernel/filesystem/inode_metadata.hpp (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index a99e5d1..0287875 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -1,13 +1,26 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP +#include "kernel/devices/device.hpp" #include "kernel/filesystem/inode.hpp" +#include + +#include + namespace filesystem { struct device_inode : inode { - // TODO BA-FS26 + explicit device_inode(kstd::shared_ptr const & device); + + [[nodiscard]] auto backing_device() const -> kstd::shared_ptr const &; + + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + + private: + kstd::shared_ptr m_device{}; }; } // namespace filesystem diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index 23924c4..035f49d 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -17,10 +17,10 @@ namespace filesystem virtual auto mount(kstd::shared_ptr const & device) -> int = 0; virtual auto lookup(inode const & parent, std::string_view name) -> inode * = 0; - [[nodiscard]] auto root_inode() const -> inode const &; + [[nodiscard]] auto root_inode() const -> kstd::shared_ptr const &; protected: - inode m_root_inode{}; // TODO BA-FS26 set during mount? + kstd::shared_ptr m_root_inode{}; }; } // namespace filesystem diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp index a2955f9..dcf83b9 100644 --- a/kernel/include/kernel/filesystem/inode.hpp +++ b/kernel/include/kernel/filesystem/inode.hpp @@ -1,9 +1,6 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP -#include "kernel/devices/device.hpp" -#include "kernel/filesystem/inode_metadata.hpp" - #include #include @@ -12,26 +9,26 @@ namespace filesystem { struct inode { - inode() = default; + enum class inode_kind + { + regular, + directory, + device + }; + explicit inode(inode_kind kind); - explicit inode(kstd::shared_ptr const & device); - [[nodiscard]] auto metadata() const -> inode_metadata; + virtual ~inode() = default; [[nodiscard]] auto is_directory() const -> bool; [[nodiscard]] auto is_regular() const -> bool; [[nodiscard]] auto is_device() const -> bool; - [[nodiscard]] auto is_block_device() const -> bool; - [[nodiscard]] auto major_device() const -> size_t; - [[nodiscard]] auto minor_device() const -> size_t; - [[nodiscard]] auto backing_device() const -> kstd::shared_ptr const &; - auto read(void * buffer, size_t offset, size_t size) const -> size_t; - auto write(void const * buffer, size_t offset, size_t size) -> size_t; + virtual auto read(void * buffer, size_t offset, size_t size) const -> size_t = 0; + virtual auto write(void const * buffer, size_t offset, size_t size) -> size_t = 0; private: inode_kind m_kind{inode_kind::regular}; - kstd::shared_ptr m_device{}; }; } // namespace filesystem diff --git a/kernel/include/kernel/filesystem/inode_metadata.hpp b/kernel/include/kernel/filesystem/inode_metadata.hpp deleted file mode 100644 index ed5a09d..0000000 --- a/kernel/include/kernel/filesystem/inode_metadata.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_METADATA_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_INODE_METADATA_HPP - -#include -#include - -namespace filesystem -{ - enum class inode_kind - { - regular, - directory, - device - }; - - struct inode_metadata - { - inode_kind kind{inode_kind::regular}; - std::optional major{}; - std::optional minor{}; - }; -} // namespace filesystem - -#endif // TEACH_OS_KERNEL_FILESYSTEM_INODE_METADATA_HPP \ No newline at end of file diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp index b9018b1..18e3b24 100644 --- a/kernel/src/filesystem/device_inode.cpp +++ b/kernel/src/filesystem/device_inode.cpp @@ -1,6 +1,52 @@ #include "kernel/filesystem/device_inode.hpp" +#include "kapi/system.hpp" + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/inode.hpp" + +#include + +#include + namespace filesystem { - // TODO BA-FS26: Implement device inode -} \ No newline at end of file + device_inode::device_inode(kstd::shared_ptr const & device) + : inode(inode_kind::device) + , m_device(device) + { + if (!device) + { + kapi::system::panic("[FILESYSTEM] device_inode constructed with null device."); + } + } + + auto device_inode::backing_device() const -> kstd::shared_ptr const & + { + return m_device; + } + + auto device_inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t + { + if (!m_device) + { + kapi::system::panic("[FILESYSTEM] device_inode has null device."); + } + + // TODO BA-FS26 use device file? + // return m_device->read(buffer, offset, size); + return 0; + } + + auto device_inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t + { + if (!m_device) + { + kapi::system::panic("[FILESYSTEM] device_inode has null device."); + } + + // TODO BA-FS26 use device file? + // return m_device->write(buffer, offset, size); + return 0; + } +} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/ext2/ext2_filesystem.cpp b/kernel/src/filesystem/ext2/ext2_filesystem.cpp index 408b292..87845d5 100644 --- a/kernel/src/filesystem/ext2/ext2_filesystem.cpp +++ b/kernel/src/filesystem/ext2/ext2_filesystem.cpp @@ -2,7 +2,6 @@ #include "kernel/devices/device.hpp" #include "kernel/filesystem/inode.hpp" -#include "kernel/filesystem/inode_metadata.hpp" #include @@ -19,7 +18,7 @@ namespace filesystem::ext2 m_device = device; // TODO BA-FS26 load proper root inode from ext2 metadata - m_root_inode = inode{inode_kind::directory}; + // m_root_inode = inode{inode_kind::directory}; // TODO BA-FS26 implement return 0; diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index 86b7940..50b5587 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -2,9 +2,11 @@ #include "kernel/filesystem/inode.hpp" +#include + namespace filesystem { - auto filesystem::root_inode() const -> inode const & + auto filesystem::root_inode() const -> kstd::shared_ptr const & { return m_root_inode; } diff --git a/kernel/src/filesystem/inode.cpp b/kernel/src/filesystem/inode.cpp index af73662..de3282f 100644 --- a/kernel/src/filesystem/inode.cpp +++ b/kernel/src/filesystem/inode.cpp @@ -1,44 +1,11 @@ #include "kernel/filesystem/inode.hpp" -#include "kapi/system.hpp" - -#include "kernel/devices/device.hpp" -#include "kernel/filesystem/inode_metadata.hpp" - -#include - -#include - namespace filesystem { inode::inode(inode_kind kind) : m_kind(kind) {} - inode::inode(kstd::shared_ptr const & device) - : m_kind(inode_kind::device) - , m_device(device) - { - if (!m_device) - { - kapi::system::panic("[FILESYSTEM] inode constructed with null device."); - } - } - - auto inode::metadata() const -> inode_metadata - { - auto meta = inode_metadata{}; - meta.kind = m_kind; - - if (is_device()) - { - meta.major = m_device->major(); - meta.minor = m_device->minor(); - } - - return meta; - } - auto inode::is_directory() const -> bool { return m_kind == inode_kind::directory; @@ -53,56 +20,4 @@ namespace filesystem { return m_kind == inode_kind::device; } - - auto inode::is_block_device() const -> bool - { - return is_device() && m_device->is_block_device(); - } - - auto inode::major_device() const -> size_t - { - if (!is_device()) - { - kapi::system::panic("[FILESYSTEM] inode::major_device called on non-device inode."); - } - - return m_device->major(); - } - - auto inode::minor_device() const -> size_t - { - if (!is_device()) - { - kapi::system::panic("[FILESYSTEM] inode::minor_device called on non-device inode."); - } - - return m_device->minor(); - } - - auto inode::backing_device() const -> kstd::shared_ptr const & - { - return m_device; - } - - auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t - { - if (is_device()) - { - kapi::system::panic("[FILESYSTEM] inode::read called on device inode. Open it as a device file first."); - } - - // TODO BA-FS26 - return 0; - } - - auto inode::write(void const *, size_t, size_t) -> size_t - { - if (is_device()) - { - kapi::system::panic("[FILESYSTEM] inode::write called on device inode. Open it as a device file first."); - } - - kapi::system::panic("[FILESYSTEM] inode::write is not implemented yet"); - return 0; - } } // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 4e0b6bf..188da6d 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -6,6 +6,7 @@ #include "kernel/devices/storage/storage_management.hpp" #include "kernel/filesystem/custody.hpp" #include "kernel/filesystem/device_file.hpp" +#include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/ext2/ext2_filesystem.hpp" #include "kernel/filesystem/inode.hpp" #include "kernel/filesystem/inode_file.hpp" @@ -72,7 +73,8 @@ namespace filesystem auto node = custody->get_inode(); if (node->is_device()) { - auto current_device_file = kstd::make_shared(node->backing_device()); + auto device_node = static_cast(node.get()); + auto current_device_file = kstd::make_shared(device_node->backing_device()); current_device_file->open(); return open_file_description{current_device_file}; } @@ -92,7 +94,7 @@ namespace filesystem kapi::system::panic("[FILESYSTEM] make_device_node called with null device."); } - m_device_nodes.push_back(device_node_entry{device->name(), kstd::make_shared(device)}); + m_device_nodes.push_back(device_node_entry{device->name(), kstd::make_shared(device)}); } auto vfs::resolve_path(std::string_view path) -> std::optional -- cgit v1.2.3 From 09e3d0cb2272e7eabd79a320c17c58124515d427 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 19 Mar 2026 22:58:31 +0100 Subject: first try to simplify the architecture (remove redundant inode_file and open() methods), add ext2_file placeholder struct --- kernel/CMakeLists.txt | 2 +- kernel/include/kernel/filesystem/device_file.hpp | 2 -- kernel/include/kernel/filesystem/device_inode.hpp | 8 ++--- .../include/kernel/filesystem/ext2/ext2_file.hpp | 17 +++++++++++ .../include/kernel/filesystem/ext2/ext2_inode.hpp | 10 ++++++- kernel/include/kernel/filesystem/file.hpp | 2 -- kernel/include/kernel/filesystem/inode.hpp | 7 ++--- kernel/include/kernel/filesystem/inode_file.hpp | 27 ----------------- kernel/src/filesystem/device_file.cpp | 5 ---- kernel/src/filesystem/device_inode.cpp | 32 +++----------------- kernel/src/filesystem/ext2/ext2_file.cpp | 20 +++++++++++++ kernel/src/filesystem/ext2/ext2_inode.cpp | 17 +++++++++-- kernel/src/filesystem/inode_file.cpp | 35 ---------------------- kernel/src/filesystem/vfs.cpp | 14 +++------ 14 files changed, 75 insertions(+), 123 deletions(-) create mode 100644 kernel/include/kernel/filesystem/ext2/ext2_file.hpp delete mode 100644 kernel/include/kernel/filesystem/inode_file.hpp create mode 100644 kernel/src/filesystem/ext2/ext2_file.cpp delete mode 100644 kernel/src/filesystem/inode_file.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index a36eac0..a8287ba 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -21,6 +21,7 @@ add_executable("kernel" "src/devices/storage/storage_management.cpp" "src/devices/storage/ram_disk/ram_disk_controller.cpp" "src/devices/storage/ram_disk/ram_disk_device.cpp" + "src/filesystem/ext2/ext2_file.cpp" "src/filesystem/ext2/ext2_filesystem.cpp" "src/filesystem/ext2/ext2_inode.cpp" "src/filesystem/custody.cpp" @@ -28,7 +29,6 @@ add_executable("kernel" "src/filesystem/device_inode.cpp" "src/filesystem/file_descriptor_table.cpp" "src/filesystem/filesystem.cpp" - "src/filesystem/inode_file.cpp" "src/filesystem/inode.cpp" "src/filesystem/mount.cpp" "src/filesystem/open_file_description.cpp" diff --git a/kernel/include/kernel/filesystem/device_file.hpp b/kernel/include/kernel/filesystem/device_file.hpp index 06aa9b2..ff803f8 100644 --- a/kernel/include/kernel/filesystem/device_file.hpp +++ b/kernel/include/kernel/filesystem/device_file.hpp @@ -15,8 +15,6 @@ namespace filesystem { explicit device_file(kstd::shared_ptr const & device); - auto open() -> void override; - auto read(void * buffer, size_t offset, size_t size) const -> size_t override; auto write(void const * buffer, size_t offset, size_t size) -> size_t override; diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index 0287875..c38c75b 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -2,22 +2,18 @@ #define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP #include "kernel/devices/device.hpp" +#include "kernel/filesystem/file.hpp" #include "kernel/filesystem/inode.hpp" #include -#include - namespace filesystem { struct device_inode : inode { explicit device_inode(kstd::shared_ptr const & device); - [[nodiscard]] auto backing_device() const -> kstd::shared_ptr const &; - - auto read(void * buffer, size_t offset, size_t size) const -> size_t override; - auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + [[nodiscard]] auto open_file() const -> kstd::shared_ptr override; private: kstd::shared_ptr m_device{}; diff --git a/kernel/include/kernel/filesystem/ext2/ext2_file.hpp b/kernel/include/kernel/filesystem/ext2/ext2_file.hpp new file mode 100644 index 0000000..b5708d8 --- /dev/null +++ b/kernel/include/kernel/filesystem/ext2/ext2_file.hpp @@ -0,0 +1,17 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILE_HPP + +#include "kernel/filesystem/file.hpp" + +#include + +namespace filesystem::ext2 +{ + struct ext2_file : file + { + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + }; +} // namespace filesystem::ext2 + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp index 7cd6f8f..f103877 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp @@ -1,13 +1,21 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP +#include "kernel/filesystem/file.hpp" #include "kernel/filesystem/inode.hpp" +#include + namespace filesystem::ext2 { struct ext2_inode : inode { - // TODO BA-FS26 + ext2_inode(); + + [[nodiscard]] auto open_file() const -> kstd::shared_ptr override; + + private: + // TODO BA-FS26 add ext2-specific inode metadata here (e.g. block pointers, size, permissions, etc.) }; } // namespace filesystem::ext2 diff --git a/kernel/include/kernel/filesystem/file.hpp b/kernel/include/kernel/filesystem/file.hpp index e7e1b12..5a41fab 100644 --- a/kernel/include/kernel/filesystem/file.hpp +++ b/kernel/include/kernel/filesystem/file.hpp @@ -9,8 +9,6 @@ namespace filesystem { virtual ~file() = default; - virtual auto open() -> void = 0; - virtual auto read(void * buffer, size_t offset, size_t size) const -> size_t = 0; virtual auto write(void const * buffer, size_t offset, size_t size) -> size_t = 0; }; diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp index dcf83b9..79cbcf9 100644 --- a/kernel/include/kernel/filesystem/inode.hpp +++ b/kernel/include/kernel/filesystem/inode.hpp @@ -1,9 +1,9 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP -#include +#include "kernel/filesystem/file.hpp" -#include +#include namespace filesystem { @@ -24,8 +24,7 @@ namespace filesystem [[nodiscard]] auto is_regular() const -> bool; [[nodiscard]] auto is_device() const -> bool; - virtual auto read(void * buffer, size_t offset, size_t size) const -> size_t = 0; - virtual auto write(void const * buffer, size_t offset, size_t size) -> size_t = 0; + [[nodiscard]] virtual auto open_file() const -> kstd::shared_ptr = 0; private: inode_kind m_kind{inode_kind::regular}; diff --git a/kernel/include/kernel/filesystem/inode_file.hpp b/kernel/include/kernel/filesystem/inode_file.hpp deleted file mode 100644 index ee84eee..0000000 --- a/kernel/include/kernel/filesystem/inode_file.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_FILE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_INODE_FILE_HPP - -#include "kernel/filesystem/file.hpp" -#include "kernel/filesystem/inode.hpp" - -#include - -#include - -namespace filesystem -{ - struct inode_file : file - { - explicit inode_file(kstd::shared_ptr const & inode); - - auto open() -> void override; - - auto read(void * buffer, size_t offset, size_t size) const -> size_t override; - auto write(void const * buffer, size_t offset, size_t size) -> size_t override; - - private: - kstd::shared_ptr m_inode; - }; -} // namespace filesystem - -#endif \ No newline at end of file diff --git a/kernel/src/filesystem/device_file.cpp b/kernel/src/filesystem/device_file.cpp index c6db5af..48ed20d 100644 --- a/kernel/src/filesystem/device_file.cpp +++ b/kernel/src/filesystem/device_file.cpp @@ -23,11 +23,6 @@ namespace filesystem } } - auto device_file::open() -> void - { - // Hook point for permission checks or lazy metadata loading. - } - auto device_file::read(void * buffer, size_t offset, size_t size) const -> size_t { if (m_device->is_block_device()) diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp index 18e3b24..592637d 100644 --- a/kernel/src/filesystem/device_inode.cpp +++ b/kernel/src/filesystem/device_inode.cpp @@ -3,12 +3,12 @@ #include "kapi/system.hpp" #include "kernel/devices/device.hpp" +#include "kernel/filesystem/device_file.hpp" +#include "kernel/filesystem/file.hpp" #include "kernel/filesystem/inode.hpp" #include -#include - namespace filesystem { device_inode::device_inode(kstd::shared_ptr const & device) @@ -21,32 +21,8 @@ namespace filesystem } } - auto device_inode::backing_device() const -> kstd::shared_ptr const & - { - return m_device; - } - - auto device_inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t + auto device_inode::open_file() const -> kstd::shared_ptr { - if (!m_device) - { - kapi::system::panic("[FILESYSTEM] device_inode has null device."); - } - - // TODO BA-FS26 use device file? - // return m_device->read(buffer, offset, size); - return 0; - } - - auto device_inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t - { - if (!m_device) - { - kapi::system::panic("[FILESYSTEM] device_inode has null device."); - } - - // TODO BA-FS26 use device file? - // return m_device->write(buffer, offset, size); - return 0; + return kstd::make_shared(m_device); } } // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/ext2/ext2_file.cpp b/kernel/src/filesystem/ext2/ext2_file.cpp new file mode 100644 index 0000000..7217c77 --- /dev/null +++ b/kernel/src/filesystem/ext2/ext2_file.cpp @@ -0,0 +1,20 @@ +#include "kernel/filesystem/ext2/ext2_file.hpp" + +#include "kapi/system.hpp" + +#include + +namespace filesystem::ext2 +{ + auto ext2_file::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t + { + kapi::system::panic("[FILESYSTEM] ext2_file::read is not implemented yet."); + return 0; + } + + auto ext2_file::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t + { + kapi::system::panic("[FILESYSTEM] ext2_file::write is not implemented yet."); + return 0; + } +} // namespace filesystem::ext2 diff --git a/kernel/src/filesystem/ext2/ext2_inode.cpp b/kernel/src/filesystem/ext2/ext2_inode.cpp index ec68ee9..1522387 100644 --- a/kernel/src/filesystem/ext2/ext2_inode.cpp +++ b/kernel/src/filesystem/ext2/ext2_inode.cpp @@ -1,6 +1,19 @@ #include "kernel/filesystem/ext2/ext2_inode.hpp" +#include "kernel/filesystem/ext2/ext2_file.hpp" +#include "kernel/filesystem/file.hpp" +#include "kernel/filesystem/inode.hpp" + +#include + namespace filesystem::ext2 { - // TODO BA-FS26: Implement ext2 inode -} \ No newline at end of file + ext2_inode::ext2_inode() + : inode(inode_kind::regular) + {} + + auto ext2_inode::open_file() const -> kstd::shared_ptr + { + return kstd::make_shared(); + } +} // namespace filesystem::ext2 \ No newline at end of file diff --git a/kernel/src/filesystem/inode_file.cpp b/kernel/src/filesystem/inode_file.cpp deleted file mode 100644 index 7abac7b..0000000 --- a/kernel/src/filesystem/inode_file.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "kernel/filesystem/inode_file.hpp" - -#include "kapi/system.hpp" - -#include "kernel/filesystem/inode.hpp" - -#include - -#include - -namespace filesystem -{ - inode_file::inode_file(kstd::shared_ptr const & inode) - : m_inode(inode) - { - if (!m_inode) - { - kapi::system::panic("[FILESYSTEM] inode_file constructed with null inode"); - } - } - - auto inode_file::open() -> void - { - // Hook point for permission checks or lazy metadata loading. - } - - auto inode_file::read(void * buffer, size_t offset, size_t size) const -> size_t - { - return m_inode->read(buffer, offset, size); - } - auto inode_file::write(void const * buffer, size_t offset, size_t size) -> size_t - { - return m_inode->write(buffer, offset, size); - } -} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 188da6d..4b0c7d7 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -5,11 +5,8 @@ #include "kernel/devices/device.hpp" #include "kernel/devices/storage/storage_management.hpp" #include "kernel/filesystem/custody.hpp" -#include "kernel/filesystem/device_file.hpp" #include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/ext2/ext2_filesystem.hpp" -#include "kernel/filesystem/inode.hpp" -#include "kernel/filesystem/inode_file.hpp" #include "kernel/filesystem/mount.hpp" #include "kernel/filesystem/open_file_description.hpp" @@ -71,16 +68,13 @@ namespace filesystem if (auto custody = resolve_path(path)) { auto node = custody->get_inode(); - if (node->is_device()) + + auto current_inode_file = node->open_file(); + if (!current_inode_file) { - auto device_node = static_cast(node.get()); - auto current_device_file = kstd::make_shared(device_node->backing_device()); - current_device_file->open(); - return open_file_description{current_device_file}; + kapi::system::panic("[FILESYSTEM] inode::open_file returned null file."); } - auto current_inode_file = kstd::make_shared(node); - current_inode_file->open(); return open_file_description{current_inode_file}; } -- cgit v1.2.3 From f669454966c9fa8cbdbbefb1d9cfdd61026849f9 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 20 Mar 2026 21:47:58 +0100 Subject: improve architecture again -> use same architecture for devices and ext2_files --- kernel/CMakeLists.txt | 1 + kernel/include/kernel/filesystem/disk_file.hpp | 19 +++++++++++++ .../include/kernel/filesystem/ext2/ext2_file.hpp | 4 +-- .../include/kernel/filesystem/ext2/ext2_inode.hpp | 5 ++-- kernel/include/kernel/filesystem/inode_file.hpp | 25 +++++++++++++++++ kernel/src/filesystem/ext2/ext2_inode.cpp | 8 +++--- kernel/src/filesystem/inode_file.cpp | 31 ++++++++++++++++++++++ 7 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 kernel/include/kernel/filesystem/disk_file.hpp create mode 100644 kernel/include/kernel/filesystem/inode_file.hpp create mode 100644 kernel/src/filesystem/inode_file.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index a8287ba..e0b40be 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -29,6 +29,7 @@ add_executable("kernel" "src/filesystem/device_inode.cpp" "src/filesystem/file_descriptor_table.cpp" "src/filesystem/filesystem.cpp" + "src/filesystem/inode_file.cpp" "src/filesystem/inode.cpp" "src/filesystem/mount.cpp" "src/filesystem/open_file_description.cpp" diff --git a/kernel/include/kernel/filesystem/disk_file.hpp b/kernel/include/kernel/filesystem/disk_file.hpp new file mode 100644 index 0000000..c6a7655 --- /dev/null +++ b/kernel/include/kernel/filesystem/disk_file.hpp @@ -0,0 +1,19 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_DISK_FILE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_DISK_FILE_HPP + +#include + +#include + +namespace filesystem +{ + struct disk_file + { + virtual ~disk_file() = default; + + virtual auto read(void * buffer, size_t offset, size_t size) const -> size_t = 0; + virtual auto write(void const * buffer, size_t offset, size_t size) -> size_t = 0; + }; +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/ext2_file.hpp b/kernel/include/kernel/filesystem/ext2/ext2_file.hpp index b5708d8..371507d 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_file.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_file.hpp @@ -1,13 +1,13 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILE_HPP -#include "kernel/filesystem/file.hpp" +#include "kernel/filesystem/disk_file.hpp" #include namespace filesystem::ext2 { - struct ext2_file : file + struct ext2_file : disk_file { auto read(void * buffer, size_t offset, size_t size) const -> size_t override; auto write(void const * buffer, size_t offset, size_t size) -> size_t override; diff --git a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp index f103877..7b5ff3f 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp @@ -1,6 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP +#include "kernel/filesystem/disk_file.hpp" #include "kernel/filesystem/file.hpp" #include "kernel/filesystem/inode.hpp" @@ -10,12 +11,12 @@ namespace filesystem::ext2 { struct ext2_inode : inode { - ext2_inode(); + explicit ext2_inode(kstd::shared_ptr const & disk_file); [[nodiscard]] auto open_file() const -> kstd::shared_ptr override; private: - // TODO BA-FS26 add ext2-specific inode metadata here (e.g. block pointers, size, permissions, etc.) + kstd::shared_ptr m_disk_file{}; }; } // namespace filesystem::ext2 diff --git a/kernel/include/kernel/filesystem/inode_file.hpp b/kernel/include/kernel/filesystem/inode_file.hpp new file mode 100644 index 0000000..3e2b954 --- /dev/null +++ b/kernel/include/kernel/filesystem/inode_file.hpp @@ -0,0 +1,25 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_FILE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_INODE_FILE_HPP + +#include "kernel/filesystem/disk_file.hpp" +#include "kernel/filesystem/file.hpp" + +#include + +#include + +namespace filesystem +{ + struct inode_file : file + { + explicit inode_file(kstd::shared_ptr const & disk_file); + + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + + private: + kstd::shared_ptr m_disk_file; + }; +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/src/filesystem/ext2/ext2_inode.cpp b/kernel/src/filesystem/ext2/ext2_inode.cpp index 1522387..8131f43 100644 --- a/kernel/src/filesystem/ext2/ext2_inode.cpp +++ b/kernel/src/filesystem/ext2/ext2_inode.cpp @@ -1,19 +1,21 @@ #include "kernel/filesystem/ext2/ext2_inode.hpp" -#include "kernel/filesystem/ext2/ext2_file.hpp" +#include "kernel/filesystem/disk_file.hpp" #include "kernel/filesystem/file.hpp" #include "kernel/filesystem/inode.hpp" +#include "kernel/filesystem/inode_file.hpp" #include namespace filesystem::ext2 { - ext2_inode::ext2_inode() + ext2_inode::ext2_inode(kstd::shared_ptr const & disk_file) : inode(inode_kind::regular) + , m_disk_file(disk_file) {} auto ext2_inode::open_file() const -> kstd::shared_ptr { - return kstd::make_shared(); + return kstd::make_shared(m_disk_file); } } // namespace filesystem::ext2 \ No newline at end of file diff --git a/kernel/src/filesystem/inode_file.cpp b/kernel/src/filesystem/inode_file.cpp new file mode 100644 index 0000000..9c351da --- /dev/null +++ b/kernel/src/filesystem/inode_file.cpp @@ -0,0 +1,31 @@ +#include "kernel/filesystem/inode_file.hpp" + +#include "kapi/system.hpp" + +#include "kernel/filesystem/disk_file.hpp" + +#include + +#include + +namespace filesystem +{ + inode_file::inode_file(kstd::shared_ptr const & disk_file) + : m_disk_file(disk_file) + { + if (!m_disk_file) + { + kapi::system::panic("[FILESYSTEM] inode_file constructed with null disk_file."); + } + } + + auto inode_file::read(void * buffer, size_t offset, size_t size) const -> size_t + { + return m_disk_file->read(buffer, offset, size); + } + + auto inode_file::write(void const * buffer, size_t offset, size_t size) -> size_t + { + return m_disk_file->write(buffer, offset, size); + } +} // namespace filesystem \ No newline at end of file -- cgit v1.2.3 From 91feb8a2a70af1915c8cfa4ee7d95b6e276f5c02 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 20 Mar 2026 21:51:51 +0100 Subject: small refactoring --- kernel/src/filesystem/vfs.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 4b0c7d7..1bc9ae6 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -69,13 +69,12 @@ namespace filesystem { auto node = custody->get_inode(); - auto current_inode_file = node->open_file(); - if (!current_inode_file) + if (auto current_inode_file = node->open_file();) { - kapi::system::panic("[FILESYSTEM] inode::open_file returned null file."); + return open_file_description{current_inode_file}; } - return open_file_description{current_inode_file}; + kapi::system::panic("[FILESYSTEM] inode::open_file returned null file."); } return std::nullopt; -- cgit v1.2.3 From b02b90f21de5954aef34eb37a17775f194b8de39 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 20 Mar 2026 22:11:33 +0100 Subject: prepare test code for a further test function --- kernel/src/main.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index eb59402..e719164 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -18,7 +18,7 @@ #include #include -auto run_test_code() -> void +auto test_file_description_manually() -> void { // setup auto fd_table = filesystem::file_descriptor_table::get(); @@ -85,6 +85,17 @@ auto run_test_code() -> void kstd::println("---"); } +auto test_device_with_vfs() -> void +{ + // TODO BA-FS26 +} + +auto run_test_code() -> void +{ + test_file_description_manually(); + test_device_with_vfs(); +} + auto main() -> int { kapi::cio::init(); -- cgit v1.2.3 From a396b71827a24f9d6c8010fd85b9afd9d86b6e2a Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 20 Mar 2026 22:13:36 +0100 Subject: implement first draft of a do_mount function --- kernel/include/kernel/filesystem/vfs.hpp | 10 ++++--- kernel/src/filesystem/vfs.cpp | 49 +++++++++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 8 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index a2894a6..2ad570b 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -3,7 +3,7 @@ #include "kernel/devices/device.hpp" #include "kernel/filesystem/custody.hpp" -#include "kernel/filesystem/ext2/ext2_filesystem.hpp" +#include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" #include "kernel/filesystem/mount.hpp" #include "kernel/filesystem/open_file_description.hpp" @@ -24,22 +24,24 @@ namespace filesystem ~vfs() = default; auto open(std::string_view path) -> std::optional; + auto do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> int; private: + // TODO BA-FS26 remove again and use devtempfs struct device_node_entry { std::string_view name; kstd::shared_ptr node; }; + kstd::vector> m_device_nodes; // TODO BA-FS26 remove again, use devtempfs vfs() = default; auto make_device_node(kstd::shared_ptr const & device) -> void; [[nodiscard]] auto resolve_path(std::string_view path) -> std::optional; - kstd::shared_ptr m_root_fs; + kstd::shared_ptr m_root_fs; std::optional m_root_mount; - // kstd::vector m_mounts; // TODO BA-FS26 really needed? - kstd::vector> m_device_nodes; // TODO BA-FS26 remove again, use devtempfs + kstd::vector m_mounts; }; } // namespace filesystem diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 1bc9ae6..febb844 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -36,13 +36,12 @@ namespace filesystem if (auto boot_device = storage_mgmt.determine_boot_device()) { active_vfs->m_root_fs = kstd::make_shared(); - if (active_vfs->m_root_fs->mount(boot_device) != 0) + if (active_vfs->do_mount("/", active_vfs->m_root_fs) != 0) { kapi::system::panic("[FILESYSTEM] Failed to mount root filesystem."); } - active_vfs->m_root_mount = mount{"/", active_vfs->m_root_fs}; - + // TODO BA-FS26 use do_mount when tempdevfs is implemented -> just call /dev/ with all devices in devtempfs std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto controller) { std::ranges::for_each(controller->all_devices(), [&](auto device) { active_vfs->make_device_node(device); }); }); @@ -69,8 +68,9 @@ namespace filesystem { auto node = custody->get_inode(); - if (auto current_inode_file = node->open_file();) + if (auto current_inode_file = node->open_file()) { + // TODO BA-FS26 return shared_ptr? return open_file_description{current_inode_file}; } @@ -80,6 +80,45 @@ namespace filesystem return std::nullopt; } + auto vfs::do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> int + { + if (!filesystem) + { + return -1; // TODO BA-FS26 panic or errorcode? + } + + if (path.empty() || path.front() != '/') + { + return -1; // TODO BA-FS26 panic or errorcode? + } + + // TODO BA-FS26 better path validation + if ((path.size() > 1 && path.back() == '/') || path.find("//") != std::string_view::npos) + { + return -1; // TODO BA-FS26 panic or errorcode? + } + + if (path == "/") + { + m_root_fs = filesystem; + m_root_mount = mount{"/", filesystem}; + return 0; + } + + auto existing_mount = + std::ranges::find_if(m_mounts, [&](auto const & existing) { return existing.path() == path; }); + if (existing_mount != m_mounts.end()) + { + *existing_mount = mount{path, filesystem}; + } + else + { + m_mounts.push_back(mount{path, filesystem}); + } + + return 0; + } + auto vfs::make_device_node(kstd::shared_ptr const & device) -> void { if (!device) @@ -94,6 +133,8 @@ namespace filesystem { // TODO BA-FS26 implement real path resolution with mounts and directories etc. // For now, just support device nodes at /dev/. + // TODO BA-FS26 better path validation + // TODO BA-FS26 implement a path parser (maybe in libs?) and use it here and in do_mount constexpr auto device_prefix = std::string_view{"/dev/"}; if (path.starts_with(device_prefix)) -- cgit v1.2.3 From be44d4b778bb7c3a947af4cae610ecc3b8851672 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 20 Mar 2026 22:27:26 +0100 Subject: use kstd::shared_ptr instead of std::optional for open_file_descriptions --- .../kernel/filesystem/file_descriptor_table.hpp | 10 ++++----- kernel/include/kernel/filesystem/vfs.hpp | 2 +- kernel/src/filesystem/file_descriptor_table.cpp | 24 ++++++++++++++-------- kernel/src/filesystem/vfs.cpp | 8 ++++---- kernel/src/main.cpp | 4 ++-- 5 files changed, 27 insertions(+), 21 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/filesystem/file_descriptor_table.hpp index 6d78532..bc6fb24 100644 --- a/kernel/include/kernel/filesystem/file_descriptor_table.hpp +++ b/kernel/include/kernel/filesystem/file_descriptor_table.hpp @@ -3,10 +3,9 @@ #include "open_file_description.hpp" +#include #include -#include - namespace filesystem { struct file_descriptor_table @@ -16,15 +15,14 @@ namespace filesystem ~file_descriptor_table() = default; - auto add_file(open_file_description & f) -> int; - [[nodiscard]] auto get_file(int fd) const -> std::optional; + auto add_file(kstd::shared_ptr const & f) -> int; + [[nodiscard]] auto get_file(int fd) const -> kstd::shared_ptr; auto remove_file(int fd) -> void; private: file_descriptor_table() = default; - // TODO BA-FS26 use kstd::shared_ptr when available - kstd::vector> m_open_files{}; + kstd::vector> m_open_files{}; }; } // namespace filesystem diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 2ad570b..ca51d90 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -23,7 +23,7 @@ namespace filesystem ~vfs() = default; - auto open(std::string_view path) -> std::optional; + auto open(std::string_view path) -> kstd::shared_ptr; auto do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> int; private: diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp index 814322e..6eb3845 100644 --- a/kernel/src/filesystem/file_descriptor_table.cpp +++ b/kernel/src/filesystem/file_descriptor_table.cpp @@ -4,6 +4,8 @@ #include "kernel/filesystem/open_file_description.hpp" +#include + #include #include #include @@ -35,9 +37,15 @@ namespace filesystem return *global_file_descriptor_table; } - auto file_descriptor_table::add_file(open_file_description & file_description) -> int + auto file_descriptor_table::add_file(kstd::shared_ptr const & file_description) -> int { - auto it = std::ranges::find_if(m_open_files, [](auto & open_file) { return !open_file.has_value(); }); + if (!file_description) + { + // TODO BA-FS26 panic or errorcode? + return -1; + } + + auto it = std::ranges::find_if(m_open_files, [](auto const & open_file) { return open_file == nullptr; }); if (it != m_open_files.end()) { *it = file_description; @@ -48,20 +56,20 @@ namespace filesystem return static_cast(m_open_files.size() - 1); } - auto file_descriptor_table::get_file(int fd) const -> std::optional + auto file_descriptor_table::get_file(int fd) const -> kstd::shared_ptr { if (fd < 0) { - return std::nullopt; + return nullptr; } auto const index = static_cast(fd); - if (index >= m_open_files.size() || !m_open_files.at(fd).has_value()) + if (index >= m_open_files.size()) { - return std::nullopt; + return nullptr; } - return m_open_files.at(fd); + return m_open_files.at(index); } auto file_descriptor_table::remove_file(int fd) -> void @@ -77,6 +85,6 @@ namespace filesystem return; } - m_open_files.at(fd).reset(); + m_open_files.at(index) = nullptr; } } // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index febb844..a3e554e 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -7,6 +7,7 @@ #include "kernel/filesystem/custody.hpp" #include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/ext2/ext2_filesystem.hpp" +#include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/mount.hpp" #include "kernel/filesystem/open_file_description.hpp" @@ -62,7 +63,7 @@ namespace filesystem return *active_vfs; } - auto vfs::open(std::string_view path) -> std::optional + auto vfs::open(std::string_view path) -> kstd::shared_ptr { if (auto custody = resolve_path(path)) { @@ -70,14 +71,13 @@ namespace filesystem if (auto current_inode_file = node->open_file()) { - // TODO BA-FS26 return shared_ptr? - return open_file_description{current_inode_file}; + return kstd::make_shared(current_inode_file); } kapi::system::panic("[FILESYSTEM] inode::open_file returned null file."); } - return std::nullopt; + return nullptr; } auto vfs::do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> int diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index e719164..31133a5 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -26,7 +26,7 @@ auto test_file_description_manually() -> void auto device = storage_mgmt.device_by_major_minor(1, 0); auto dev_file = kstd::make_shared(device); - filesystem::open_file_description ofd(dev_file); + auto ofd = kstd::make_shared(dev_file); auto fd_index = fd_table.add_file(ofd); // use: read two bytes and write two again @@ -61,7 +61,7 @@ auto test_file_description_manually() -> void fd_table.remove_file(fd_index); // use: read four bytes again -> two old bytes two new bytes - filesystem::open_file_description ofd1(dev_file); + auto ofd1 = kstd::make_shared(dev_file); fd_index = fd_table.add_file(ofd1); auto fd1 = fd_table.get_file(fd_index); -- cgit v1.2.3 From 90452b752688110db2edc8d5dccdf0d6e0face5f Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 20 Mar 2026 23:17:11 +0100 Subject: fix build --- kernel/src/filesystem/vfs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index a3e554e..ee5fd9b 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -93,7 +93,7 @@ namespace filesystem } // TODO BA-FS26 better path validation - if ((path.size() > 1 && path.back() == '/') || path.find("//") != std::string_view::npos) + if ((path.size() > 1 && path.back() == '/')) { return -1; // TODO BA-FS26 panic or errorcode? } -- cgit v1.2.3 From ba63fbfc2bb43a6f0f05b6b49fd51fd6c89a0861 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 21 Mar 2026 00:28:17 +0100 Subject: refactor file and inode architecture again --- kernel/CMakeLists.txt | 1 + kernel/include/kernel/filesystem/device_file.hpp | 6 ++++-- kernel/include/kernel/filesystem/device_inode.hpp | 7 ++++-- kernel/include/kernel/filesystem/disk_file.hpp | 19 ---------------- .../include/kernel/filesystem/ext2/ext2_file.hpp | 8 +++---- .../include/kernel/filesystem/ext2/ext2_inode.hpp | 9 ++++---- kernel/include/kernel/filesystem/file.hpp | 8 +++++++ kernel/include/kernel/filesystem/inode.hpp | 8 +++---- kernel/include/kernel/filesystem/inode_file.hpp | 9 ++++---- kernel/src/filesystem/device_file.cpp | 25 +++++++++++++++------- kernel/src/filesystem/device_inode.cpp | 14 ++++++++++-- kernel/src/filesystem/ext2/ext2_inode.cpp | 15 ++++++++----- kernel/src/filesystem/file.cpp | 20 +++++++++++++++++ kernel/src/filesystem/inode_file.cpp | 21 ++++++++++-------- kernel/src/filesystem/vfs.cpp | 5 +++-- kernel/src/main.cpp | 5 ++++- 16 files changed, 112 insertions(+), 68 deletions(-) delete mode 100644 kernel/include/kernel/filesystem/disk_file.hpp create mode 100644 kernel/src/filesystem/file.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index e0b40be..ec0d4e2 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -27,6 +27,7 @@ add_executable("kernel" "src/filesystem/custody.cpp" "src/filesystem/device_file.cpp" "src/filesystem/device_inode.cpp" + "src/filesystem/file.cpp" "src/filesystem/file_descriptor_table.cpp" "src/filesystem/filesystem.cpp" "src/filesystem/inode_file.cpp" diff --git a/kernel/include/kernel/filesystem/device_file.hpp b/kernel/include/kernel/filesystem/device_file.hpp index ff803f8..22ddb49 100644 --- a/kernel/include/kernel/filesystem/device_file.hpp +++ b/kernel/include/kernel/filesystem/device_file.hpp @@ -11,9 +11,11 @@ namespace filesystem { + struct inode; + struct device_file : file { - explicit device_file(kstd::shared_ptr const & device); + explicit device_file(kstd::shared_ptr const & inode); auto read(void * buffer, size_t offset, size_t size) const -> size_t override; auto write(void const * buffer, size_t offset, size_t size) -> size_t override; @@ -23,7 +25,7 @@ namespace filesystem std::byte * scratch, void * buffer); auto process_blocks(size_t offset, size_t size, void * buffer, block_op op) const -> size_t; - kstd::shared_ptr m_device; + [[nodiscard]] auto device() const -> kstd::shared_ptr const &; }; } // namespace filesystem diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index c38c75b..af2a51b 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -2,18 +2,21 @@ #define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP #include "kernel/devices/device.hpp" -#include "kernel/filesystem/file.hpp" #include "kernel/filesystem/inode.hpp" #include namespace filesystem { + struct file; + struct device_inode : inode { explicit device_inode(kstd::shared_ptr const & device); - [[nodiscard]] auto open_file() const -> kstd::shared_ptr override; + [[nodiscard]] auto open_file(kstd::shared_ptr const & self) const -> kstd::shared_ptr override; + + [[nodiscard]] auto device() const -> kstd::shared_ptr const &; private: kstd::shared_ptr m_device{}; diff --git a/kernel/include/kernel/filesystem/disk_file.hpp b/kernel/include/kernel/filesystem/disk_file.hpp deleted file mode 100644 index c6a7655..0000000 --- a/kernel/include/kernel/filesystem/disk_file.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_DISK_FILE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_DISK_FILE_HPP - -#include - -#include - -namespace filesystem -{ - struct disk_file - { - virtual ~disk_file() = default; - - virtual auto read(void * buffer, size_t offset, size_t size) const -> size_t = 0; - virtual auto write(void const * buffer, size_t offset, size_t size) -> size_t = 0; - }; -} // namespace filesystem - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/ext2_file.hpp b/kernel/include/kernel/filesystem/ext2/ext2_file.hpp index 371507d..e5357e3 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_file.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_file.hpp @@ -1,16 +1,14 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILE_HPP -#include "kernel/filesystem/disk_file.hpp" - #include namespace filesystem::ext2 { - struct ext2_file : disk_file + struct ext2_file { - auto read(void * buffer, size_t offset, size_t size) const -> size_t override; - auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + auto read(void * buffer, size_t offset, size_t size) const -> size_t; + auto write(void const * buffer, size_t offset, size_t size) -> size_t; }; } // namespace filesystem::ext2 diff --git a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp index 7b5ff3f..b57d267 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP -#include "kernel/filesystem/disk_file.hpp" +#include "kernel/filesystem/ext2/ext2_file.hpp" #include "kernel/filesystem/file.hpp" #include "kernel/filesystem/inode.hpp" @@ -11,12 +11,13 @@ namespace filesystem::ext2 { struct ext2_inode : inode { - explicit ext2_inode(kstd::shared_ptr const & disk_file); + explicit ext2_inode(); - [[nodiscard]] auto open_file() const -> kstd::shared_ptr override; + [[nodiscard]] auto open_file(kstd::shared_ptr const & self) const + -> kstd::shared_ptr override; private: - kstd::shared_ptr m_disk_file{}; + kstd::shared_ptr m_file{}; }; } // namespace filesystem::ext2 diff --git a/kernel/include/kernel/filesystem/file.hpp b/kernel/include/kernel/filesystem/file.hpp index 5a41fab..522f078 100644 --- a/kernel/include/kernel/filesystem/file.hpp +++ b/kernel/include/kernel/filesystem/file.hpp @@ -1,16 +1,24 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_FILE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_FILE_HPP +#include + #include namespace filesystem { + struct inode; + struct file { + explicit file(kstd::shared_ptr const & inode); virtual ~file() = default; virtual auto read(void * buffer, size_t offset, size_t size) const -> size_t = 0; virtual auto write(void const * buffer, size_t offset, size_t size) -> size_t = 0; + + protected: + kstd::shared_ptr m_inode; }; } // namespace filesystem diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp index 79cbcf9..8c9f75e 100644 --- a/kernel/include/kernel/filesystem/inode.hpp +++ b/kernel/include/kernel/filesystem/inode.hpp @@ -1,12 +1,12 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP -#include "kernel/filesystem/file.hpp" - #include namespace filesystem { + struct file; + struct inode { enum class inode_kind @@ -20,12 +20,12 @@ namespace filesystem virtual ~inode() = default; + [[nodiscard]] virtual auto open_file(kstd::shared_ptr const & self) const -> kstd::shared_ptr = 0; + [[nodiscard]] auto is_directory() const -> bool; [[nodiscard]] auto is_regular() const -> bool; [[nodiscard]] auto is_device() const -> bool; - [[nodiscard]] virtual auto open_file() const -> kstd::shared_ptr = 0; - private: inode_kind m_kind{inode_kind::regular}; }; diff --git a/kernel/include/kernel/filesystem/inode_file.hpp b/kernel/include/kernel/filesystem/inode_file.hpp index 3e2b954..f87b77c 100644 --- a/kernel/include/kernel/filesystem/inode_file.hpp +++ b/kernel/include/kernel/filesystem/inode_file.hpp @@ -1,8 +1,8 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_FILE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_INODE_FILE_HPP -#include "kernel/filesystem/disk_file.hpp" #include "kernel/filesystem/file.hpp" +#include "kernel/filesystem/inode.hpp" #include @@ -10,15 +10,14 @@ namespace filesystem { + struct inode; + struct inode_file : file { - explicit inode_file(kstd::shared_ptr const & disk_file); + explicit inode_file(kstd::shared_ptr const & inode); auto read(void * buffer, size_t offset, size_t size) const -> size_t override; auto write(void const * buffer, size_t offset, size_t size) -> size_t override; - - private: - kstd::shared_ptr m_disk_file; }; } // namespace filesystem diff --git a/kernel/src/filesystem/device_file.cpp b/kernel/src/filesystem/device_file.cpp index 48ed20d..26c7511 100644 --- a/kernel/src/filesystem/device_file.cpp +++ b/kernel/src/filesystem/device_file.cpp @@ -4,6 +4,9 @@ #include "kernel/devices/block_device.hpp" #include "kernel/devices/device.hpp" +#include "kernel/filesystem/device_inode.hpp" +#include "kernel/filesystem/file.hpp" +#include "kernel/filesystem/inode.hpp" #include #include @@ -14,18 +17,18 @@ namespace filesystem { - device_file::device_file(kstd::shared_ptr const & device) - : m_device(device) + device_file::device_file(kstd::shared_ptr const & inode) + : file(inode) { - if (!m_device) + if (!m_inode->is_device()) { - kapi::system::panic("[FILESYSTEM] device_file constructed with null device."); + kapi::system::panic("[FILESYSTEM] device_file constructed with non-device inode."); } } auto device_file::read(void * buffer, size_t offset, size_t size) const -> size_t { - if (m_device->is_block_device()) + if (device()->is_block_device()) { return process_blocks(offset, size, buffer, [](size_t idx, size_t off, size_t len, size_t done, devices::block_device * device, @@ -50,7 +53,7 @@ namespace filesystem auto device_file::write(void const * buffer, size_t offset, size_t size) -> size_t { - if (m_device->is_block_device()) + if (device()->is_block_device()) { return process_blocks(offset, size, const_cast(buffer), [](size_t idx, size_t off, size_t len, size_t done, devices::block_device * device, @@ -78,7 +81,7 @@ namespace filesystem { if (buffer == nullptr) { - kapi::system::panic("[FILESYSTEM] device_file::write called with null buffer."); + kapi::system::panic("[FILESYSTEM] device_file::process_blocks called with null buffer."); } if (size == 0) @@ -86,7 +89,7 @@ namespace filesystem return 0; } - auto * block_dev = static_cast(m_device.get()); + auto * block_dev = static_cast(device().get()); if (block_dev == nullptr) { kapi::system::panic("[FILESYSTEM] device_file: expected block_device."); @@ -116,4 +119,10 @@ namespace filesystem return processed; } + + auto device_file::device() const -> kstd::shared_ptr const & + { + auto inode = static_cast(m_inode.get()); + return inode->device(); + } } // namespace filesystem diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp index 592637d..65dd9a3 100644 --- a/kernel/src/filesystem/device_inode.cpp +++ b/kernel/src/filesystem/device_inode.cpp @@ -21,8 +21,18 @@ namespace filesystem } } - auto device_inode::open_file() const -> kstd::shared_ptr + auto device_inode::open_file(kstd::shared_ptr const & self) const -> kstd::shared_ptr { - return kstd::make_shared(m_device); + if (!self) + { + kapi::system::panic("[FILESYSTEM] device_inode::open_file called with null inode."); + } + + return kstd::make_shared(self); + } + + auto device_inode::device() const -> kstd::shared_ptr const & + { + return m_device; } } // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/ext2/ext2_inode.cpp b/kernel/src/filesystem/ext2/ext2_inode.cpp index 8131f43..0a1994b 100644 --- a/kernel/src/filesystem/ext2/ext2_inode.cpp +++ b/kernel/src/filesystem/ext2/ext2_inode.cpp @@ -1,6 +1,7 @@ #include "kernel/filesystem/ext2/ext2_inode.hpp" -#include "kernel/filesystem/disk_file.hpp" +#include "kapi/system.hpp" + #include "kernel/filesystem/file.hpp" #include "kernel/filesystem/inode.hpp" #include "kernel/filesystem/inode_file.hpp" @@ -9,13 +10,17 @@ namespace filesystem::ext2 { - ext2_inode::ext2_inode(kstd::shared_ptr const & disk_file) + ext2_inode::ext2_inode() : inode(inode_kind::regular) - , m_disk_file(disk_file) {} - auto ext2_inode::open_file() const -> kstd::shared_ptr + auto ext2_inode::open_file(kstd::shared_ptr const & self) const -> kstd::shared_ptr { - return kstd::make_shared(m_disk_file); + if (!self) + { + kapi::system::panic("[FILESYSTEM] ext2_inode::open_file called with null inode."); + } + + return kstd::make_shared(self); } } // namespace filesystem::ext2 \ No newline at end of file diff --git a/kernel/src/filesystem/file.cpp b/kernel/src/filesystem/file.cpp new file mode 100644 index 0000000..a147863 --- /dev/null +++ b/kernel/src/filesystem/file.cpp @@ -0,0 +1,20 @@ +#include "kernel/filesystem/file.hpp" + +#include "kapi/system.hpp" + +#include "kernel/filesystem/inode.hpp" + +#include + +namespace filesystem +{ + + file::file(kstd::shared_ptr const & inode) + : m_inode(inode) + { + if (!m_inode) + { + kapi::system::panic("[FILESYSTEM] file constructed with null inode."); + } + } +} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/inode_file.cpp b/kernel/src/filesystem/inode_file.cpp index 9c351da..8b2fcba 100644 --- a/kernel/src/filesystem/inode_file.cpp +++ b/kernel/src/filesystem/inode_file.cpp @@ -2,7 +2,8 @@ #include "kapi/system.hpp" -#include "kernel/filesystem/disk_file.hpp" +#include "kernel/filesystem/file.hpp" +#include "kernel/filesystem/inode.hpp" #include @@ -10,22 +11,24 @@ namespace filesystem { - inode_file::inode_file(kstd::shared_ptr const & disk_file) - : m_disk_file(disk_file) + inode_file::inode_file(kstd::shared_ptr const & inode) + : file(inode) { - if (!m_disk_file) + if (m_inode->is_device()) { - kapi::system::panic("[FILESYSTEM] inode_file constructed with null disk_file."); + kapi::system::panic("[FILESYSTEM] inode_file constructed with device inode."); } } - auto inode_file::read(void * buffer, size_t offset, size_t size) const -> size_t + auto inode_file::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t { - return m_disk_file->read(buffer, offset, size); + // TODO BA-FS26 + return 0; } - auto inode_file::write(void const * buffer, size_t offset, size_t size) -> size_t + auto inode_file::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t { - return m_disk_file->write(buffer, offset, size); + // TODO BA-FS26 + return 0; } } // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index ee5fd9b..5330b82 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -34,6 +34,7 @@ namespace filesystem active_vfs.emplace(vfs{}); auto storage_mgmt = devices::storage::storage_management::get(); + // TODO BA-FS26 fix mounting boot_device if (auto boot_device = storage_mgmt.determine_boot_device()) { active_vfs->m_root_fs = kstd::make_shared(); @@ -69,9 +70,9 @@ namespace filesystem { auto node = custody->get_inode(); - if (auto current_inode_file = node->open_file()) + if (auto opened_file = node->open_file(node)) { - return kstd::make_shared(current_inode_file); + return kstd::make_shared(opened_file); } kapi::system::panic("[FILESYSTEM] inode::open_file returned null file."); diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 31133a5..8d7308b 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -5,6 +5,7 @@ #include "kernel/devices/storage/storage_management.hpp" #include "kernel/filesystem/device_file.hpp" +#include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/file_descriptor_table.hpp" #include "kernel/filesystem/open_file_description.hpp" #include "kernel/filesystem/vfs.hpp" @@ -25,7 +26,9 @@ auto test_file_description_manually() -> void auto storage_mgmt = devices::storage::storage_management::get(); auto device = storage_mgmt.device_by_major_minor(1, 0); - auto dev_file = kstd::make_shared(device); + auto dev_node = kstd::make_shared(device); + + auto dev_file = kstd::make_shared(dev_node); auto ofd = kstd::make_shared(dev_file); auto fd_index = fd_table.add_file(ofd); -- cgit v1.2.3 From ffb2accb09a013d8da16acd824c846bc1acfd8e4 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 21 Mar 2026 10:52:46 +0100 Subject: use enable_shared_from_this instead of self invocation method --- kernel/include/kernel/filesystem/device_inode.hpp | 4 ++-- kernel/include/kernel/filesystem/ext2/ext2_inode.hpp | 5 ++--- kernel/include/kernel/filesystem/inode.hpp | 4 ++-- kernel/src/filesystem/device_inode.cpp | 9 ++------- kernel/src/filesystem/ext2/ext2_inode.cpp | 11 ++--------- kernel/src/filesystem/vfs.cpp | 2 +- 6 files changed, 11 insertions(+), 24 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index af2a51b..10e40b3 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -14,12 +14,12 @@ namespace filesystem { explicit device_inode(kstd::shared_ptr const & device); - [[nodiscard]] auto open_file(kstd::shared_ptr const & self) const -> kstd::shared_ptr override; + [[nodiscard]] auto open_file() -> kstd::shared_ptr override; [[nodiscard]] auto device() const -> kstd::shared_ptr const &; private: - kstd::shared_ptr m_device{}; + kstd::shared_ptr m_device; }; } // namespace filesystem diff --git a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp index b57d267..e6e8e99 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp @@ -13,11 +13,10 @@ namespace filesystem::ext2 { explicit ext2_inode(); - [[nodiscard]] auto open_file(kstd::shared_ptr const & self) const - -> kstd::shared_ptr override; + [[nodiscard]] auto open_file() -> kstd::shared_ptr override; private: - kstd::shared_ptr m_file{}; + kstd::shared_ptr m_file; }; } // namespace filesystem::ext2 diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp index 8c9f75e..1083d13 100644 --- a/kernel/include/kernel/filesystem/inode.hpp +++ b/kernel/include/kernel/filesystem/inode.hpp @@ -7,7 +7,7 @@ namespace filesystem { struct file; - struct inode + struct inode : kstd::enable_shared_from_this { enum class inode_kind { @@ -20,7 +20,7 @@ namespace filesystem virtual ~inode() = default; - [[nodiscard]] virtual auto open_file(kstd::shared_ptr const & self) const -> kstd::shared_ptr = 0; + [[nodiscard]] virtual auto open_file() -> kstd::shared_ptr = 0; [[nodiscard]] auto is_directory() const -> bool; [[nodiscard]] auto is_regular() const -> bool; diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp index 65dd9a3..b9ccd6d 100644 --- a/kernel/src/filesystem/device_inode.cpp +++ b/kernel/src/filesystem/device_inode.cpp @@ -21,14 +21,9 @@ namespace filesystem } } - auto device_inode::open_file(kstd::shared_ptr const & self) const -> kstd::shared_ptr + auto device_inode::open_file() -> kstd::shared_ptr { - if (!self) - { - kapi::system::panic("[FILESYSTEM] device_inode::open_file called with null inode."); - } - - return kstd::make_shared(self); + return kstd::make_shared(shared_from_this()); } auto device_inode::device() const -> kstd::shared_ptr const & diff --git a/kernel/src/filesystem/ext2/ext2_inode.cpp b/kernel/src/filesystem/ext2/ext2_inode.cpp index 0a1994b..0760cb1 100644 --- a/kernel/src/filesystem/ext2/ext2_inode.cpp +++ b/kernel/src/filesystem/ext2/ext2_inode.cpp @@ -1,7 +1,5 @@ #include "kernel/filesystem/ext2/ext2_inode.hpp" -#include "kapi/system.hpp" - #include "kernel/filesystem/file.hpp" #include "kernel/filesystem/inode.hpp" #include "kernel/filesystem/inode_file.hpp" @@ -14,13 +12,8 @@ namespace filesystem::ext2 : inode(inode_kind::regular) {} - auto ext2_inode::open_file(kstd::shared_ptr const & self) const -> kstd::shared_ptr + auto ext2_inode::open_file() -> kstd::shared_ptr { - if (!self) - { - kapi::system::panic("[FILESYSTEM] ext2_inode::open_file called with null inode."); - } - - return kstd::make_shared(self); + return kstd::make_shared(shared_from_this()); } } // namespace filesystem::ext2 \ No newline at end of file diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 5330b82..2316de0 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -70,7 +70,7 @@ namespace filesystem { auto node = custody->get_inode(); - if (auto opened_file = node->open_file(node)) + if (auto opened_file = node->open_file()) { return kstd::make_shared(opened_file); } -- cgit v1.2.3 From 6c172389b562a08a6540574d6fbdf6a5bdce37b8 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 21 Mar 2026 16:22:23 +0100 Subject: simplify architecture again --- kernel/CMakeLists.txt | 3 - kernel/include/kernel/filesystem/device_file.hpp | 32 ------ kernel/include/kernel/filesystem/device_inode.hpp | 14 ++- .../include/kernel/filesystem/ext2/ext2_inode.hpp | 6 +- kernel/include/kernel/filesystem/file.hpp | 25 ---- kernel/include/kernel/filesystem/inode.hpp | 7 +- kernel/include/kernel/filesystem/inode_file.hpp | 24 ---- .../kernel/filesystem/open_file_description.hpp | 6 +- kernel/src/filesystem/device_file.cpp | 128 --------------------- kernel/src/filesystem/device_inode.cpp | 100 +++++++++++++++- kernel/src/filesystem/ext2/ext2_inode.cpp | 15 ++- kernel/src/filesystem/file.cpp | 20 ---- kernel/src/filesystem/inode_file.cpp | 34 ------ kernel/src/filesystem/open_file_description.cpp | 14 +-- kernel/src/filesystem/vfs.cpp | 6 +- kernel/src/main.cpp | 9 +- 16 files changed, 138 insertions(+), 305 deletions(-) delete mode 100644 kernel/include/kernel/filesystem/device_file.hpp delete mode 100644 kernel/include/kernel/filesystem/file.hpp delete mode 100644 kernel/include/kernel/filesystem/inode_file.hpp delete mode 100644 kernel/src/filesystem/device_file.cpp delete mode 100644 kernel/src/filesystem/file.cpp delete mode 100644 kernel/src/filesystem/inode_file.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index ec0d4e2..16ebb8b 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -25,12 +25,9 @@ add_executable("kernel" "src/filesystem/ext2/ext2_filesystem.cpp" "src/filesystem/ext2/ext2_inode.cpp" "src/filesystem/custody.cpp" - "src/filesystem/device_file.cpp" "src/filesystem/device_inode.cpp" - "src/filesystem/file.cpp" "src/filesystem/file_descriptor_table.cpp" "src/filesystem/filesystem.cpp" - "src/filesystem/inode_file.cpp" "src/filesystem/inode.cpp" "src/filesystem/mount.cpp" "src/filesystem/open_file_description.cpp" diff --git a/kernel/include/kernel/filesystem/device_file.hpp b/kernel/include/kernel/filesystem/device_file.hpp deleted file mode 100644 index 22ddb49..0000000 --- a/kernel/include/kernel/filesystem/device_file.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVICE_FILE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_FILE_HPP - -#include "kernel/devices/block_device.hpp" -#include "kernel/devices/device.hpp" -#include "kernel/filesystem/file.hpp" - -#include - -#include - -namespace filesystem -{ - struct inode; - - struct device_file : file - { - explicit device_file(kstd::shared_ptr const & inode); - - auto read(void * buffer, size_t offset, size_t size) const -> size_t override; - auto write(void const * buffer, size_t offset, size_t size) -> size_t override; - - private: - 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(size_t offset, size_t size, void * buffer, block_op op) const -> size_t; - - [[nodiscard]] auto device() const -> kstd::shared_ptr const &; - }; -} // namespace filesystem - -#endif diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index 10e40b3..ce0f91c 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -1,24 +1,28 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP +#include "kernel/devices/block_device.hpp" #include "kernel/devices/device.hpp" #include "kernel/filesystem/inode.hpp" #include +#include + namespace filesystem { - struct file; - struct device_inode : inode { explicit device_inode(kstd::shared_ptr const & device); - [[nodiscard]] auto open_file() -> kstd::shared_ptr override; - - [[nodiscard]] auto device() const -> kstd::shared_ptr const &; + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; private: + 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(size_t offset, size_t size, void * buffer, block_op op) const -> size_t; + kstd::shared_ptr m_device; }; } // namespace filesystem diff --git a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp index e6e8e99..5f4d16a 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp @@ -2,18 +2,20 @@ #define TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP #include "kernel/filesystem/ext2/ext2_file.hpp" -#include "kernel/filesystem/file.hpp" #include "kernel/filesystem/inode.hpp" #include +#include + namespace filesystem::ext2 { struct ext2_inode : inode { explicit ext2_inode(); - [[nodiscard]] auto open_file() -> kstd::shared_ptr override; + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; private: kstd::shared_ptr m_file; diff --git a/kernel/include/kernel/filesystem/file.hpp b/kernel/include/kernel/filesystem/file.hpp deleted file mode 100644 index 522f078..0000000 --- a/kernel/include/kernel/filesystem/file.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_FILE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_FILE_HPP - -#include - -#include - -namespace filesystem -{ - struct inode; - - struct file - { - explicit file(kstd::shared_ptr const & inode); - virtual ~file() = default; - - virtual auto read(void * buffer, size_t offset, size_t size) const -> size_t = 0; - virtual auto write(void const * buffer, size_t offset, size_t size) -> size_t = 0; - - protected: - kstd::shared_ptr m_inode; - }; -} // namespace filesystem - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp index 1083d13..94ccd89 100644 --- a/kernel/include/kernel/filesystem/inode.hpp +++ b/kernel/include/kernel/filesystem/inode.hpp @@ -3,10 +3,10 @@ #include +#include + namespace filesystem { - struct file; - struct inode : kstd::enable_shared_from_this { enum class inode_kind @@ -20,7 +20,8 @@ namespace filesystem virtual ~inode() = default; - [[nodiscard]] virtual auto open_file() -> kstd::shared_ptr = 0; + virtual auto read(void * buffer, size_t offset, size_t size) const -> size_t = 0; + virtual auto write(void const * buffer, size_t offset, size_t size) -> size_t = 0; [[nodiscard]] auto is_directory() const -> bool; [[nodiscard]] auto is_regular() const -> bool; diff --git a/kernel/include/kernel/filesystem/inode_file.hpp b/kernel/include/kernel/filesystem/inode_file.hpp deleted file mode 100644 index f87b77c..0000000 --- a/kernel/include/kernel/filesystem/inode_file.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_FILE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_INODE_FILE_HPP - -#include "kernel/filesystem/file.hpp" -#include "kernel/filesystem/inode.hpp" - -#include - -#include - -namespace filesystem -{ - struct inode; - - struct inode_file : file - { - explicit inode_file(kstd::shared_ptr const & inode); - - auto read(void * buffer, size_t offset, size_t size) const -> size_t override; - auto write(void const * buffer, size_t offset, size_t size) -> size_t override; - }; -} // namespace filesystem - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/open_file_description.hpp b/kernel/include/kernel/filesystem/open_file_description.hpp index 5ff094d..3c97d50 100644 --- a/kernel/include/kernel/filesystem/open_file_description.hpp +++ b/kernel/include/kernel/filesystem/open_file_description.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP #define TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP -#include "file.hpp" +#include "kernel/filesystem/inode.hpp" #include @@ -11,7 +11,7 @@ namespace filesystem { struct open_file_description { - open_file_description(kstd::shared_ptr const & file); + open_file_description(kstd::shared_ptr const & inode); ~open_file_description() = default; @@ -19,7 +19,7 @@ namespace filesystem auto write(void const * buffer, size_t size) -> size_t; private: - kstd::shared_ptr m_file; + kstd::shared_ptr m_inode; size_t m_offset; }; diff --git a/kernel/src/filesystem/device_file.cpp b/kernel/src/filesystem/device_file.cpp deleted file mode 100644 index 26c7511..0000000 --- a/kernel/src/filesystem/device_file.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include "kernel/filesystem/device_file.hpp" - -#include "kapi/system.hpp" - -#include "kernel/devices/block_device.hpp" -#include "kernel/devices/device.hpp" -#include "kernel/filesystem/device_inode.hpp" -#include "kernel/filesystem/file.hpp" -#include "kernel/filesystem/inode.hpp" - -#include -#include -#include - -#include -#include - -namespace filesystem -{ - device_file::device_file(kstd::shared_ptr const & inode) - : file(inode) - { - if (!m_inode->is_device()) - { - kapi::system::panic("[FILESYSTEM] device_file constructed with non-device inode."); - } - } - - auto device_file::read(void * buffer, size_t offset, size_t size) const -> size_t - { - if (device()->is_block_device()) - { - return process_blocks(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); - } - }); - } - else - { - kapi::system::panic("[FILESYSTEM] device_file::read called on non-block device."); - } - } - - auto device_file::write(void const * buffer, size_t offset, size_t size) -> size_t - { - if (device()->is_block_device()) - { - return process_blocks(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); - } - }); - } - else - { - kapi::system::panic("[FILESYSTEM] device_file::write called on non-block device."); - } - } - - auto device_file::process_blocks(size_t offset, size_t size, void * buffer, block_op op) const -> 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 device_file::device() const -> kstd::shared_ptr const & - { - auto inode = static_cast(m_inode.get()); - return inode->device(); - } -} // namespace filesystem diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp index b9ccd6d..812b43a 100644 --- a/kernel/src/filesystem/device_inode.cpp +++ b/kernel/src/filesystem/device_inode.cpp @@ -2,12 +2,16 @@ #include "kapi/system.hpp" +#include "kernel/devices/block_device.hpp" #include "kernel/devices/device.hpp" -#include "kernel/filesystem/device_file.hpp" -#include "kernel/filesystem/file.hpp" #include "kernel/filesystem/inode.hpp" +#include #include +#include + +#include +#include namespace filesystem { @@ -21,13 +25,97 @@ namespace filesystem } } - auto device_inode::open_file() -> kstd::shared_ptr + auto device_inode::read(void * buffer, size_t offset, size_t size) const -> size_t { - return kstd::make_shared(shared_from_this()); + if (m_device->is_block_device()) + { + return process_blocks(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); + } + }); + } + else + { + kapi::system::panic("[FILESYSTEM] device_file::read called on non-block device."); + } } - auto device_inode::device() const -> kstd::shared_ptr const & + auto device_inode::write(void const * buffer, size_t offset, size_t size) -> size_t { - return m_device; + if (m_device->is_block_device()) + { + return process_blocks(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); + } + }); + } + else + { + kapi::system::panic("[FILESYSTEM] device_file::write called on non-block device."); + } + } + + auto device_inode::process_blocks(size_t offset, size_t size, void * buffer, block_op op) const -> 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(m_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; } } // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/ext2/ext2_inode.cpp b/kernel/src/filesystem/ext2/ext2_inode.cpp index 0760cb1..3cc0fb2 100644 --- a/kernel/src/filesystem/ext2/ext2_inode.cpp +++ b/kernel/src/filesystem/ext2/ext2_inode.cpp @@ -1,10 +1,8 @@ #include "kernel/filesystem/ext2/ext2_inode.hpp" -#include "kernel/filesystem/file.hpp" #include "kernel/filesystem/inode.hpp" -#include "kernel/filesystem/inode_file.hpp" -#include +#include namespace filesystem::ext2 { @@ -12,8 +10,15 @@ namespace filesystem::ext2 : inode(inode_kind::regular) {} - auto ext2_inode::open_file() -> kstd::shared_ptr + auto ext2_inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t { - return kstd::make_shared(shared_from_this()); + // TODO BA-FS26 implement + return 0; + } + + auto ext2_inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t + { + // TODO BA-FS26 implement + return 0; } } // namespace filesystem::ext2 \ No newline at end of file diff --git a/kernel/src/filesystem/file.cpp b/kernel/src/filesystem/file.cpp deleted file mode 100644 index a147863..0000000 --- a/kernel/src/filesystem/file.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "kernel/filesystem/file.hpp" - -#include "kapi/system.hpp" - -#include "kernel/filesystem/inode.hpp" - -#include - -namespace filesystem -{ - - file::file(kstd::shared_ptr const & inode) - : m_inode(inode) - { - if (!m_inode) - { - kapi::system::panic("[FILESYSTEM] file constructed with null inode."); - } - } -} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/inode_file.cpp b/kernel/src/filesystem/inode_file.cpp deleted file mode 100644 index 8b2fcba..0000000 --- a/kernel/src/filesystem/inode_file.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "kernel/filesystem/inode_file.hpp" - -#include "kapi/system.hpp" - -#include "kernel/filesystem/file.hpp" -#include "kernel/filesystem/inode.hpp" - -#include - -#include - -namespace filesystem -{ - inode_file::inode_file(kstd::shared_ptr const & inode) - : file(inode) - { - if (m_inode->is_device()) - { - kapi::system::panic("[FILESYSTEM] inode_file constructed with device inode."); - } - } - - auto inode_file::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t - { - // TODO BA-FS26 - return 0; - } - - auto inode_file::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t - { - // TODO BA-FS26 - return 0; - } -} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/open_file_description.cpp b/kernel/src/filesystem/open_file_description.cpp index ff4d678..93c38ac 100644 --- a/kernel/src/filesystem/open_file_description.cpp +++ b/kernel/src/filesystem/open_file_description.cpp @@ -1,6 +1,6 @@ #include "kernel/filesystem/open_file_description.hpp" -#include "kernel/filesystem/file.hpp" +#include "kernel/filesystem/inode.hpp" #include #include @@ -9,26 +9,26 @@ namespace filesystem { - open_file_description::open_file_description(kstd::shared_ptr const & file) - : m_file(file) + open_file_description::open_file_description(kstd::shared_ptr const & inode) + : m_inode(inode) , m_offset(0) { - if (!file) + if (!inode) { - kstd::os::panic("[FILESYSTEM] open_file_description constructed with null file."); + kstd::os::panic("[FILESYSTEM] open_file_description constructed with null inode."); } } auto open_file_description::read(void * buffer, size_t size) -> size_t { - auto read_bytes = m_file->read(buffer, m_offset, size); + auto read_bytes = m_inode->read(buffer, m_offset, size); m_offset += read_bytes; return read_bytes; } auto open_file_description::write(void const * buffer, size_t size) -> size_t { - auto written_bytes = m_file->write(buffer, m_offset, size); + auto written_bytes = m_inode->write(buffer, m_offset, size); m_offset += written_bytes; return written_bytes; } diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 2316de0..86991ea 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -68,11 +68,9 @@ namespace filesystem { if (auto custody = resolve_path(path)) { - auto node = custody->get_inode(); - - if (auto opened_file = node->open_file()) + if (auto node = custody->get_inode()) { - return kstd::make_shared(opened_file); + return kstd::make_shared(node); } kapi::system::panic("[FILESYSTEM] inode::open_file returned null file."); diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 8d7308b..eb699bd 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -4,7 +4,6 @@ #include "kapi/system.hpp" #include "kernel/devices/storage/storage_management.hpp" -#include "kernel/filesystem/device_file.hpp" #include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/file_descriptor_table.hpp" #include "kernel/filesystem/open_file_description.hpp" @@ -28,8 +27,7 @@ auto test_file_description_manually() -> void auto dev_node = kstd::make_shared(device); - auto dev_file = kstd::make_shared(dev_node); - auto ofd = kstd::make_shared(dev_file); + auto ofd = kstd::make_shared(dev_node); auto fd_index = fd_table.add_file(ofd); // use: read two bytes and write two again @@ -64,7 +62,7 @@ auto test_file_description_manually() -> void fd_table.remove_file(fd_index); // use: read four bytes again -> two old bytes two new bytes - auto ofd1 = kstd::make_shared(dev_file); + auto ofd1 = kstd::make_shared(dev_node); fd_index = fd_table.add_file(ofd1); auto fd1 = fd_table.get_file(fd_index); @@ -91,6 +89,9 @@ auto test_file_description_manually() -> void auto test_device_with_vfs() -> void { // TODO BA-FS26 + + auto vfs = filesystem::vfs::get(); + vfs.open("/"); } auto run_test_code() -> void -- cgit v1.2.3 From 9d23a9fb6ae774bf3b1345d0b7adcb88f9627dc0 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 21 Mar 2026 16:35:01 +0100 Subject: refactoring, node cannot be null --- kernel/src/filesystem/vfs.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 86991ea..c448618 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -68,12 +68,7 @@ namespace filesystem { if (auto custody = resolve_path(path)) { - if (auto node = custody->get_inode()) - { - return kstd::make_shared(node); - } - - kapi::system::panic("[FILESYSTEM] inode::open_file returned null file."); + return kstd::make_shared(custody->get_inode()); } return nullptr; -- 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/include/kernel/devices/block_device.hpp | 5 +++-- kernel/include/kernel/devices/device.hpp | 9 +++++---- kernel/src/devices/block_device.cpp | 5 +++-- kernel/src/devices/device.cpp | 7 ++++--- kernel/src/devices/storage/ram_disk/ram_disk_device.cpp | 15 ++------------- kernel/src/filesystem/vfs.cpp | 2 +- kernel/src/main.cpp | 13 +++++++++++++ 7 files changed, 31 insertions(+), 25 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/devices/block_device.hpp b/kernel/include/kernel/devices/block_device.hpp index fb7d104..e2026dd 100644 --- a/kernel/include/kernel/devices/block_device.hpp +++ b/kernel/include/kernel/devices/block_device.hpp @@ -3,8 +3,9 @@ #include "kernel/devices/device.hpp" +#include + #include -#include namespace devices { @@ -20,7 +21,7 @@ namespace devices * @param name Device name. * @param block_size Size of one logical block in bytes. */ - block_device(size_t major, size_t minor, std::string_view name, size_t block_size); + block_device(size_t major, size_t minor, kstd::string const & name, size_t block_size); /** * @brief Read data from the block at @p block_index into @p buffer. diff --git a/kernel/include/kernel/devices/device.hpp b/kernel/include/kernel/devices/device.hpp index d6f520f..66cb7f8 100644 --- a/kernel/include/kernel/devices/device.hpp +++ b/kernel/include/kernel/devices/device.hpp @@ -1,8 +1,9 @@ #ifndef TEACH_OS_KERNEL_DEVICES_DEVICE_HPP #define TEACH_OS_KERNEL_DEVICES_DEVICE_HPP +#include + #include -#include namespace devices { @@ -17,7 +18,7 @@ namespace devices * @param minor Device minor number. * @param name Device name. */ - device(size_t major, size_t minor, std::string_view name); + device(size_t major, size_t minor, kstd::string const & name); /** * @brief Virtual destructor for device. @@ -40,7 +41,7 @@ namespace devices * @brief Returns the name of the device. * @return Device name. */ - [[nodiscard]] auto name() const -> std::string_view; + [[nodiscard]] auto name() const -> kstd::string const &; /** * @brief Check if the device is a block device. @@ -54,7 +55,7 @@ namespace devices private: size_t m_major; size_t m_minor; - std::string_view m_name; + kstd::string m_name; }; } // namespace 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) {} diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index c448618..1bd6fb5 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -120,7 +120,7 @@ namespace filesystem kapi::system::panic("[FILESYSTEM] make_device_node called with null device."); } - m_device_nodes.push_back(device_node_entry{device->name(), kstd::make_shared(device)}); + m_device_nodes.push_back(device_node_entry{device->name().view(), kstd::make_shared(device)}); } auto vfs::resolve_path(std::string_view path) -> std::optional diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index eb699bd..1043c81 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -10,14 +10,26 @@ #include "kernel/filesystem/vfs.hpp" #include "kernel/memory.hpp" +#include #include #include #include +#include #include +#include #include #include +auto test_device_names() -> void +{ + auto storage_mgmt = devices::storage::storage_management::get(); + std::ranges::for_each(storage_mgmt.all_controllers(), [](auto const & controller) { + std::ranges::for_each(controller->all_devices(), + [](auto const & device) { kstd::println("{}", device->name().view()); }); + }); +} + auto test_file_description_manually() -> void { // setup @@ -96,6 +108,7 @@ auto test_device_with_vfs() -> void auto run_test_code() -> void { + test_device_names(); test_file_description_manually(); test_device_with_vfs(); } -- cgit v1.2.3 From fde90dcc551b35ea03fef1231fafac9faea2c5b5 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 22 Mar 2026 09:31:03 +0100 Subject: add tests, use better println for vectors --- kernel/src/main.cpp | 57 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 24 deletions(-) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 1043c81..3ba240d 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -19,7 +19,6 @@ #include #include -#include auto test_device_names() -> void { @@ -51,17 +50,8 @@ auto test_file_description_manually() -> void kstd::vector buffer{2}; auto number_of_read_bytes = fd->read(buffer.data(), buffer.size()); - - for (size_t i = 0; i < number_of_read_bytes; ++i) - { - kstd::print("{:02x} ", static_cast(buffer[i])); - - if ((i + 1) % 16 == 0) - { - kstd::println(""); - } - } - kstd::println("---"); + kstd::println("read bytes: {}", number_of_read_bytes); + kstd::println("buffer: {::#04x}", buffer); // write half of the file new auto const value1 = std::byte{0xAA}; @@ -85,17 +75,8 @@ auto test_file_description_manually() -> void kstd::vector buffer1{4}; number_of_read_bytes = fd1->read(buffer1.data(), buffer1.size()); - - for (size_t i = 0; i < number_of_read_bytes; ++i) - { - kstd::print("{:02x} ", static_cast(buffer1[i])); - - if ((i + 1) % 16 == 0) - { - kstd::println(""); - } - } - kstd::println("---"); + kstd::println("read bytes: {}", number_of_read_bytes); + kstd::println("buffer: {::#04x}", buffer1); } auto test_device_with_vfs() -> void @@ -103,14 +84,41 @@ auto test_device_with_vfs() -> void // TODO BA-FS26 auto vfs = filesystem::vfs::get(); - vfs.open("/"); + auto ofd = vfs.open("/dev/ram0"); + if (!ofd) + { + kstd::os::panic("test code failed"); + } + + auto fd_table = filesystem::file_descriptor_table::get(); + auto fd = fd_table.add_file(ofd); + kstd::vector buffer{2}; + auto file = fd_table.get_file(fd); + if (!file) + { + kstd::os::panic("test code failed"); + } + + auto number_of_read_bytes = file->read(buffer.data(), buffer.size()); + kstd::println("read bytes: {}", number_of_read_bytes); + kstd::println("buffer: {::#04x}", buffer); } auto run_test_code() -> void { + kstd::println("[TEST] Running test code..."); + + kstd::println("[TEST] device names"); test_device_names(); + kstd::println("---------------------------------"); + + kstd::println("[TEST] file description manually"); test_file_description_manually(); + kstd::println("---------------------------------"); + + kstd::println("[TEST] device with VFS"); test_device_with_vfs(); + kstd::println("---------------------------------"); } auto main() -> int @@ -136,6 +144,7 @@ auto main() -> int kstd::println("[OS] Virtual filesystem initialized."); run_test_code(); + kstd::println("[TEST] All tests completed."); kapi::system::panic("Returning from kernel main!"); } -- cgit v1.2.3 From 840c7fec926e7fa8a9d9b64b23167f269096b59b Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sun, 22 Mar 2026 15:08:42 +0100 Subject: Remove unneeded enable_shared_from_this in inode --- kernel/include/kernel/filesystem/inode.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp index 94ccd89..6d8f0d4 100644 --- a/kernel/include/kernel/filesystem/inode.hpp +++ b/kernel/include/kernel/filesystem/inode.hpp @@ -1,13 +1,11 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP -#include - #include namespace filesystem { - struct inode : kstd::enable_shared_from_this + struct inode { enum class inode_kind { -- cgit v1.2.3 From f90cbdaa91b1b7a4752db3f159ce2524696cff9f Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Mon, 23 Mar 2026 09:03:27 +0100 Subject: Rename custody to dentry and add children --- kernel/CMakeLists.txt | 2 +- kernel/include/kernel/filesystem/custody.hpp | 23 --------------------- kernel/include/kernel/filesystem/dentry.hpp | 25 +++++++++++++++++++++++ kernel/include/kernel/filesystem/vfs.hpp | 6 +++--- kernel/src/filesystem/custody.cpp | 30 ---------------------------- kernel/src/filesystem/dentry.cpp | 30 ++++++++++++++++++++++++++++ kernel/src/filesystem/vfs.cpp | 16 +++++++-------- 7 files changed, 67 insertions(+), 65 deletions(-) delete mode 100644 kernel/include/kernel/filesystem/custody.hpp create mode 100644 kernel/include/kernel/filesystem/dentry.hpp delete mode 100644 kernel/src/filesystem/custody.cpp create mode 100644 kernel/src/filesystem/dentry.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 16ebb8b..01fee74 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -24,7 +24,7 @@ add_executable("kernel" "src/filesystem/ext2/ext2_file.cpp" "src/filesystem/ext2/ext2_filesystem.cpp" "src/filesystem/ext2/ext2_inode.cpp" - "src/filesystem/custody.cpp" + "src/filesystem/dentry.cpp" "src/filesystem/device_inode.cpp" "src/filesystem/file_descriptor_table.cpp" "src/filesystem/filesystem.cpp" diff --git a/kernel/include/kernel/filesystem/custody.hpp b/kernel/include/kernel/filesystem/custody.hpp deleted file mode 100644 index 8a0e09a..0000000 --- a/kernel/include/kernel/filesystem/custody.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef TEACH_OS_KERNEL_CUSTODY_HPP -#define TEACH_OS_KERNEL_CUSTODY_HPP - -#include "kernel/filesystem/inode.hpp" - -#include - -namespace filesystem -{ - struct custody - { - custody(kstd::shared_ptr const & parent, kstd::shared_ptr const & node); - - [[nodiscard]] auto get_inode() const -> kstd::shared_ptr const &; - [[nodiscard]] auto get_parent() const -> kstd::shared_ptr const &; - - private: - kstd::shared_ptr m_parent; - kstd::shared_ptr m_inode; - }; -} // namespace filesystem - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp new file mode 100644 index 0000000..1532880 --- /dev/null +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -0,0 +1,25 @@ +#ifndef TEACH_OS_KERNEL_DENTRY_HPP +#define TEACH_OS_KERNEL_DENTRY_HPP + +#include "kernel/filesystem/inode.hpp" + +#include +#include + +namespace filesystem +{ + struct dentry + { + dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & node); + + [[nodiscard]] auto get_inode() const -> kstd::shared_ptr const &; + [[nodiscard]] auto get_parent() const -> kstd::shared_ptr const &; + + private: + kstd::shared_ptr m_parent; + kstd::vector> m_children; + kstd::shared_ptr m_inode; + }; +} // namespace filesystem + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index ca51d90..bcf06f7 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -2,7 +2,7 @@ #define TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP #include "kernel/devices/device.hpp" -#include "kernel/filesystem/custody.hpp" +#include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" #include "kernel/filesystem/mount.hpp" @@ -37,11 +37,11 @@ namespace filesystem vfs() = default; auto make_device_node(kstd::shared_ptr const & device) -> void; - [[nodiscard]] auto resolve_path(std::string_view path) -> std::optional; + [[nodiscard]] auto resolve_path(std::string_view path) -> std::optional; kstd::shared_ptr m_root_fs; std::optional m_root_mount; - kstd::vector m_mounts; + kstd::vector m_mount_table; }; } // namespace filesystem diff --git a/kernel/src/filesystem/custody.cpp b/kernel/src/filesystem/custody.cpp deleted file mode 100644 index a4dd12c..0000000 --- a/kernel/src/filesystem/custody.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "kernel/filesystem/custody.hpp" - -#include "kapi/system.hpp" - -#include "kernel/filesystem/inode.hpp" - -#include - -namespace filesystem -{ - custody::custody(kstd::shared_ptr const & parent, kstd::shared_ptr const & node) - : m_parent(parent) - , m_inode(node) - { - if (!m_inode) - { - kapi::system::panic("[FILESYSTEM] custody constructed with null inode."); - } - } - - auto custody::get_inode() const -> kstd::shared_ptr const & - { - return m_inode; - } - - auto custody::get_parent() const -> kstd::shared_ptr const & - { - return m_parent; - } -} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp new file mode 100644 index 0000000..08f0b25 --- /dev/null +++ b/kernel/src/filesystem/dentry.cpp @@ -0,0 +1,30 @@ +#include "kernel/filesystem/dentry.hpp" + +#include "kapi/system.hpp" + +#include "kernel/filesystem/inode.hpp" + +#include + +namespace filesystem +{ + dentry::dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & node) + : m_parent(parent) + , m_inode(node) + { + if (!m_inode) + { + kapi::system::panic("[FILESYSTEM] dentry constructed with null inode."); + } + } + + auto dentry::get_inode() const -> kstd::shared_ptr const & + { + return m_inode; + } + + auto dentry::get_parent() const -> kstd::shared_ptr const & + { + return m_parent; + } +} // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 1bd6fb5..a111f23 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -4,7 +4,7 @@ #include "kernel/devices/device.hpp" #include "kernel/devices/storage/storage_management.hpp" -#include "kernel/filesystem/custody.hpp" +#include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/ext2/ext2_filesystem.hpp" #include "kernel/filesystem/filesystem.hpp" @@ -66,9 +66,9 @@ namespace filesystem auto vfs::open(std::string_view path) -> kstd::shared_ptr { - if (auto custody = resolve_path(path)) + if (auto dentry = resolve_path(path)) { - return kstd::make_shared(custody->get_inode()); + return kstd::make_shared(dentry->get_inode()); } return nullptr; @@ -100,14 +100,14 @@ namespace filesystem } auto existing_mount = - std::ranges::find_if(m_mounts, [&](auto const & existing) { return existing.path() == path; }); - if (existing_mount != m_mounts.end()) + std::ranges::find_if(m_mount_table, [&](auto const & existing) { return existing.path() == path; }); + if (existing_mount != m_mount_table.end()) { *existing_mount = mount{path, filesystem}; } else { - m_mounts.push_back(mount{path, filesystem}); + m_mount_table.push_back(mount{path, filesystem}); } return 0; @@ -123,7 +123,7 @@ namespace filesystem m_device_nodes.push_back(device_node_entry{device->name().view(), kstd::make_shared(device)}); } - auto vfs::resolve_path(std::string_view path) -> std::optional + auto vfs::resolve_path(std::string_view path) -> std::optional { // TODO BA-FS26 implement real path resolution with mounts and directories etc. // For now, just support device nodes at /dev/. @@ -140,7 +140,7 @@ namespace filesystem if (entry != m_device_nodes.end()) { - return custody{nullptr, entry->value().node}; + return dentry{nullptr, entry->value().node}; } return std::nullopt; -- cgit v1.2.3 From d70e2df0885a844d47b6498bf2c710fb9730b364 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Mon, 23 Mar 2026 09:49:10 +0100 Subject: Add dentry structure --- kernel/include/kernel/filesystem/dentry.hpp | 14 ++++++++++++++ kernel/include/kernel/filesystem/vfs.hpp | 2 +- kernel/src/filesystem/dentry.cpp | 17 +++++++++++++++++ kernel/src/filesystem/vfs.cpp | 21 +++++++++++---------- 4 files changed, 43 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index 1532880..db15b48 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -4,21 +4,35 @@ #include "kernel/filesystem/inode.hpp" #include +#include #include +#include + namespace filesystem { struct dentry { + enum class dentry_flags : uint32_t + { + dcache_mounted = 1 << 15 + }; + dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & node); [[nodiscard]] auto get_inode() const -> kstd::shared_ptr const &; [[nodiscard]] auto get_parent() const -> kstd::shared_ptr const &; + auto set_flag(dentry_flags flag) -> void; + auto unset_flag(dentry_flags flag) -> void; + [[nodiscard]] auto has_flag(dentry_flags flag) const -> bool; + private: + kstd::string m_name; kstd::shared_ptr m_parent; kstd::vector> m_children; kstd::shared_ptr m_inode; + uint32_t m_flags{0}; }; } // namespace filesystem diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index bcf06f7..01cd2ea 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -40,7 +40,7 @@ namespace filesystem [[nodiscard]] auto resolve_path(std::string_view path) -> std::optional; kstd::shared_ptr m_root_fs; - std::optional m_root_mount; + kstd::shared_ptr m_root_dentry; kstd::vector m_mount_table; }; } // namespace filesystem diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index 08f0b25..e498b52 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -6,6 +6,8 @@ #include +#include + namespace filesystem { dentry::dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & node) @@ -27,4 +29,19 @@ namespace filesystem { return m_parent; } + + auto dentry::set_flag(dentry_flags flag) -> void + { + m_flags |= static_cast(flag); + } + + auto dentry::unset_flag(dentry_flags flag) -> void + { + m_flags &= ~static_cast(flag); + } + + auto dentry::has_flag(dentry_flags flag) const -> bool + { + return (m_flags & static_cast(flag)) != 0; + } } // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index a111f23..2c4a4d5 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -38,10 +38,11 @@ namespace filesystem if (auto boot_device = storage_mgmt.determine_boot_device()) { active_vfs->m_root_fs = kstd::make_shared(); - if (active_vfs->do_mount("/", active_vfs->m_root_fs) != 0) - { - kapi::system::panic("[FILESYSTEM] Failed to mount root filesystem."); - } + active_vfs->m_root_dentry = kstd::make_shared(nullptr, active_vfs->m_root_fs->root_inode()); + // if (active_vfs->do_mount("/", active_vfs->m_root_fs) != 0) + // { + // kapi::system::panic("[FILESYSTEM] Failed to mount root filesystem."); + // } // TODO BA-FS26 use do_mount when tempdevfs is implemented -> just call /dev/ with all devices in devtempfs std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto controller) { @@ -92,12 +93,12 @@ namespace filesystem return -1; // TODO BA-FS26 panic or errorcode? } - if (path == "/") - { - m_root_fs = filesystem; - m_root_mount = mount{"/", filesystem}; - return 0; - } + // if (path == "/") + // { + // m_root_fs = filesystem; + // m_root_mount = mount{"/", filesystem}; + // return 0; + // } auto existing_mount = std::ranges::find_if(m_mount_table, [&](auto const & existing) { return existing.path() == path; }); -- cgit v1.2.3 From bcb4f8a76dea2443c1597716e27b7c2d268bfc44 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Mon, 23 Mar 2026 09:49:32 +0100 Subject: Refactor filesystem --- kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp | 1 - kernel/include/kernel/filesystem/filesystem.hpp | 5 ++++- kernel/src/filesystem/ext2/ext2_filesystem.cpp | 8 ++------ kernel/src/filesystem/filesystem.cpp | 11 +++++++++++ 4 files changed, 17 insertions(+), 8 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp b/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp index d6f69c8..92e05c8 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp @@ -17,7 +17,6 @@ namespace filesystem::ext2 auto lookup(inode const & parent, std::string_view name) -> inode * override; private: - kstd::shared_ptr m_device{}; }; } // namespace filesystem::ext2 diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index 035f49d..733c51a 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -5,6 +5,7 @@ #include "kernel/filesystem/inode.hpp" #include +#include #include @@ -14,13 +15,15 @@ namespace filesystem { virtual ~filesystem() = default; - virtual auto mount(kstd::shared_ptr const & device) -> int = 0; + virtual auto mount(kstd::shared_ptr const & device) -> int; virtual auto lookup(inode const & parent, std::string_view name) -> inode * = 0; [[nodiscard]] auto root_inode() const -> kstd::shared_ptr const &; protected: kstd::shared_ptr m_root_inode{}; + kstd::shared_ptr m_device{}; + kstd::vector> m_inodes{}; }; } // namespace filesystem diff --git a/kernel/src/filesystem/ext2/ext2_filesystem.cpp b/kernel/src/filesystem/ext2/ext2_filesystem.cpp index 87845d5..ea692ee 100644 --- a/kernel/src/filesystem/ext2/ext2_filesystem.cpp +++ b/kernel/src/filesystem/ext2/ext2_filesystem.cpp @@ -1,6 +1,7 @@ #include "kernel/filesystem/ext2/ext2_filesystem.hpp" #include "kernel/devices/device.hpp" +#include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" #include @@ -11,12 +12,7 @@ namespace filesystem::ext2 { auto ext2_filesystem::mount(kstd::shared_ptr const & device) -> int { - if (!device) - { - return -1; // TODO BA-FS26 panic or errorcode? - } - - m_device = device; + filesystem::mount(device); // TODO BA-FS26 error handling? // TODO BA-FS26 load proper root inode from ext2 metadata // m_root_inode = inode{inode_kind::directory}; diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index 50b5587..0e33d95 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -1,11 +1,22 @@ #include "kernel/filesystem/filesystem.hpp" +#include "kernel/devices/device.hpp" #include "kernel/filesystem/inode.hpp" #include namespace filesystem { + auto filesystem::mount(kstd::shared_ptr const & device) -> int + { + if (!device) + { + return -1; // TODO BA-FS26 panic or errorcode? + } + m_device = device; + return 0; + } + auto filesystem::root_inode() const -> kstd::shared_ptr const & { return m_root_inode; -- cgit v1.2.3 From fdcf1c7d2b47d418916e311cea8b87affaf63f90 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Mon, 23 Mar 2026 20:12:29 +0100 Subject: Small refactoring use shared pointer --- kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp | 2 +- kernel/include/kernel/filesystem/filesystem.hpp | 2 +- kernel/src/filesystem/ext2/ext2_filesystem.cpp | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp b/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp index 92e05c8..1445e5a 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp @@ -14,7 +14,7 @@ namespace filesystem::ext2 struct ext2_filesystem : filesystem { auto mount(kstd::shared_ptr const & device) -> int override; - auto lookup(inode const & parent, std::string_view name) -> inode * override; + auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; private: }; diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index 733c51a..e069ced 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -16,7 +16,7 @@ namespace filesystem virtual ~filesystem() = default; virtual auto mount(kstd::shared_ptr const & device) -> int; - virtual auto lookup(inode const & parent, std::string_view name) -> inode * = 0; + virtual auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr = 0; [[nodiscard]] auto root_inode() const -> kstd::shared_ptr const &; diff --git a/kernel/src/filesystem/ext2/ext2_filesystem.cpp b/kernel/src/filesystem/ext2/ext2_filesystem.cpp index ea692ee..536e328 100644 --- a/kernel/src/filesystem/ext2/ext2_filesystem.cpp +++ b/kernel/src/filesystem/ext2/ext2_filesystem.cpp @@ -20,7 +20,8 @@ namespace filesystem::ext2 return 0; } - auto ext2_filesystem::lookup(inode const & /*parent*/, std::string_view /*name*/) -> inode * + auto ext2_filesystem::lookup(kstd::shared_ptr const & /*parent*/, std::string_view /*name*/) + -> kstd::shared_ptr { // TODO BA-FS26 implement ext2 directory traversal and inode loading return nullptr; -- cgit v1.2.3 From 7173e5ba354dccc4b5d5fea119b946f28bc5b08f Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Mon, 23 Mar 2026 20:22:43 +0100 Subject: Refactor move init logic into member function --- kernel/include/kernel/filesystem/vfs.hpp | 2 ++ kernel/src/filesystem/vfs.cpp | 15 +++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 01cd2ea..b6d4c4c 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -36,6 +36,8 @@ namespace filesystem kstd::vector> m_device_nodes; // TODO BA-FS26 remove again, use devtempfs vfs() = default; + auto init_internal() -> void; + auto make_device_node(kstd::shared_ptr const & device) -> void; [[nodiscard]] auto resolve_path(std::string_view path) -> std::optional; diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 2c4a4d5..ece3080 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -32,21 +32,28 @@ namespace filesystem } active_vfs.emplace(vfs{}); + active_vfs->init_internal(); + } + auto vfs::init_internal() -> void + { auto storage_mgmt = devices::storage::storage_management::get(); // TODO BA-FS26 fix mounting boot_device if (auto boot_device = storage_mgmt.determine_boot_device()) { - active_vfs->m_root_fs = kstd::make_shared(); - active_vfs->m_root_dentry = kstd::make_shared(nullptr, active_vfs->m_root_fs->root_inode()); - // if (active_vfs->do_mount("/", active_vfs->m_root_fs) != 0) + m_root_fs = kstd::make_shared(); + + m_root_fs->mount(boot_device); + + m_root_dentry = kstd::make_shared(nullptr, m_root_fs->root_inode()); + // if (do_mount("/", m_root_fs) != 0) // { // kapi::system::panic("[FILESYSTEM] Failed to mount root filesystem."); // } // TODO BA-FS26 use do_mount when tempdevfs is implemented -> just call /dev/ with all devices in devtempfs std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto controller) { - std::ranges::for_each(controller->all_devices(), [&](auto device) { active_vfs->make_device_node(device); }); + std::ranges::for_each(controller->all_devices(), [&](auto device) { make_device_node(device); }); }); } else -- cgit v1.2.3 From fbb4eefce7bf825b0406f6fa63de318153a3b95a Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Mon, 23 Mar 2026 21:41:37 +0100 Subject: Implement resolve_path --- kernel/include/kernel/filesystem/dentry.hpp | 6 ++- .../kernel/filesystem/open_file_description.hpp | 2 +- kernel/include/kernel/filesystem/vfs.hpp | 2 +- kernel/src/filesystem/dentry.cpp | 18 ++++++++- kernel/src/filesystem/vfs.cpp | 46 +++++++++++++++++++--- 5 files changed, 64 insertions(+), 10 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index db15b48..ca7ca95 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -8,6 +8,7 @@ #include #include +#include namespace filesystem { @@ -18,11 +19,14 @@ namespace filesystem dcache_mounted = 1 << 15 }; - dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & node); + dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & node, std::string_view name = {}); [[nodiscard]] auto get_inode() const -> kstd::shared_ptr const &; [[nodiscard]] auto get_parent() const -> kstd::shared_ptr const &; + auto add_child(kstd::shared_ptr const & child) -> void; + [[nodiscard]] auto find_child(std::string_view name) const -> kstd::shared_ptr; + auto set_flag(dentry_flags flag) -> void; auto unset_flag(dentry_flags flag) -> void; [[nodiscard]] auto has_flag(dentry_flags flag) const -> bool; diff --git a/kernel/include/kernel/filesystem/open_file_description.hpp b/kernel/include/kernel/filesystem/open_file_description.hpp index 3c97d50..e17f9fe 100644 --- a/kernel/include/kernel/filesystem/open_file_description.hpp +++ b/kernel/include/kernel/filesystem/open_file_description.hpp @@ -11,7 +11,7 @@ namespace filesystem { struct open_file_description { - open_file_description(kstd::shared_ptr const & inode); + explicit open_file_description(kstd::shared_ptr const & inode); ~open_file_description() = default; diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index b6d4c4c..317f2d1 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -39,7 +39,7 @@ namespace filesystem auto init_internal() -> void; auto make_device_node(kstd::shared_ptr const & device) -> void; - [[nodiscard]] auto resolve_path(std::string_view path) -> std::optional; + [[nodiscard]] auto resolve_path(std::string_view path) -> kstd::shared_ptr; kstd::shared_ptr m_root_fs; kstd::shared_ptr m_root_dentry; diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index e498b52..76949f2 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -6,12 +6,15 @@ #include +#include #include +#include namespace filesystem { - dentry::dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & node) - : m_parent(parent) + dentry::dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & node, std::string_view name) + : m_name(name) + , m_parent(parent) , m_inode(node) { if (!m_inode) @@ -30,6 +33,17 @@ namespace filesystem return m_parent; } + auto dentry::add_child(kstd::shared_ptr const & child) -> void + { + m_children.push_back(child); + } + + auto dentry::find_child(std::string_view name) const -> kstd::shared_ptr + { + auto it = std::ranges::find_if(m_children, [&](auto const & child) { return child->m_name == name; }); + return (it != m_children.end()) ? *it : nullptr; + } + auto dentry::set_flag(dentry_flags flag) -> void { m_flags |= static_cast(flag); diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index ece3080..0e8a76d 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -15,6 +15,7 @@ #include #include +#include #include namespace filesystem @@ -42,7 +43,6 @@ namespace filesystem if (auto boot_device = storage_mgmt.determine_boot_device()) { m_root_fs = kstd::make_shared(); - m_root_fs->mount(boot_device); m_root_dentry = kstd::make_shared(nullptr, m_root_fs->root_inode()); @@ -131,7 +131,7 @@ namespace filesystem m_device_nodes.push_back(device_node_entry{device->name().view(), kstd::make_shared(device)}); } - auto vfs::resolve_path(std::string_view path) -> std::optional + auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr { // TODO BA-FS26 implement real path resolution with mounts and directories etc. // For now, just support device nodes at /dev/. @@ -148,13 +148,49 @@ namespace filesystem if (entry != m_device_nodes.end()) { - return dentry{nullptr, entry->value().node}; + return kstd::make_shared(nullptr, entry->value().node); } - return std::nullopt; + return nullptr; } + else if (!path.empty() && path.front() == '/') + { + auto path_parts = + std::views::split(path, '/') | std::views::filter([](auto const & part) { return !part.empty(); }); + auto parent = m_root_dentry; - return std::nullopt; + for (auto const & part : path_parts) + { + if (auto child = parent->find_child(std::string_view{part})) + { + parent = child; + } + else if (auto found_inode = m_root_fs->lookup(parent->get_inode(), std::string_view{part})) + { + auto next_dentry = kstd::make_shared(parent, found_inode, std::string_view{part}); + parent->add_child(next_dentry); + parent = next_dentry; + } + else + { + return nullptr; + } + } + // | std::views::transform([this](auto const & part) { + // // TODO BA-FS26 implement real path resolution with mounts and directories etc. + // // For now, just return null for any non-device-node path. + // return std::optional>{}; + // }) + // | std::views::filter([](auto const & opt) { return opt.has_value(); }) + // | std::views::transform([](auto const & opt) { return opt.value(); }) + // | std::ranges::find_if(m_mount_table, [&](auto const & mount) { + // // TODO BA-FS26 implement real path resolution with mounts and directories etc. + // // For now, just check if the first path component matches a mount point. + // return part == mount.path(); + // }); + } + + return nullptr; } } // namespace filesystem \ No newline at end of file -- cgit v1.2.3 From b3cb1d0f8864bf54362f1da2b7a65ca693778cff Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Mon, 23 Mar 2026 22:18:54 +0100 Subject: Add test for resolve_path --- kernel/src/filesystem/ext2/ext2_filesystem.cpp | 5 ++++- kernel/src/main.cpp | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/ext2/ext2_filesystem.cpp b/kernel/src/filesystem/ext2/ext2_filesystem.cpp index 536e328..3f5774c 100644 --- a/kernel/src/filesystem/ext2/ext2_filesystem.cpp +++ b/kernel/src/filesystem/ext2/ext2_filesystem.cpp @@ -1,6 +1,7 @@ #include "kernel/filesystem/ext2/ext2_filesystem.hpp" #include "kernel/devices/device.hpp" +#include "kernel/filesystem/ext2/ext2_inode.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" @@ -17,6 +18,7 @@ namespace filesystem::ext2 // m_root_inode = inode{inode_kind::directory}; // TODO BA-FS26 implement + m_root_inode = kstd::make_shared(); return 0; } @@ -24,6 +26,7 @@ namespace filesystem::ext2 -> kstd::shared_ptr { // TODO BA-FS26 implement ext2 directory traversal and inode loading - return nullptr; + // return nullptr; + return kstd::make_shared(); } } // namespace filesystem::ext2 diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 3ba240d..a575be2 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -104,6 +104,16 @@ auto test_device_with_vfs() -> void kstd::println("buffer: {::#04x}", buffer); } +auto test_file_lookup() -> void +{ + // TODO BA-FS26 implement a more complete test with multiple files and directories and mounts etc. + + auto vfs = filesystem::vfs::get(); + vfs.open("/a/b/c"); + vfs.open("/a/d/e"); + vfs.open("x/y/z"); +} + auto run_test_code() -> void { kstd::println("[TEST] Running test code..."); @@ -119,6 +129,10 @@ auto run_test_code() -> void kstd::println("[TEST] device with VFS"); test_device_with_vfs(); kstd::println("---------------------------------"); + + kstd::println("[TEST] file lookup"); + test_file_lookup(); + kstd::println("---------------------------------"); } auto main() -> int -- cgit v1.2.3 From 444810121f9c89285da1ec118828640f0445b2a7 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Tue, 24 Mar 2026 16:50:27 +0100 Subject: Add mount_table --- kernel/CMakeLists.txt | 1 + kernel/include/kernel/filesystem/mount_table.hpp | 23 +++++++++++++++++++ kernel/src/filesystem/mount_table.cpp | 29 ++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 kernel/include/kernel/filesystem/mount_table.hpp create mode 100644 kernel/src/filesystem/mount_table.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 01fee74..ee1f585 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -29,6 +29,7 @@ add_executable("kernel" "src/filesystem/file_descriptor_table.cpp" "src/filesystem/filesystem.cpp" "src/filesystem/inode.cpp" + "src/filesystem/mount_table.cpp" "src/filesystem/mount.cpp" "src/filesystem/open_file_description.cpp" "src/filesystem/vfs.cpp" diff --git a/kernel/include/kernel/filesystem/mount_table.hpp b/kernel/include/kernel/filesystem/mount_table.hpp new file mode 100644 index 0000000..14d6d08 --- /dev/null +++ b/kernel/include/kernel/filesystem/mount_table.hpp @@ -0,0 +1,23 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_MOUNT_TABLE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_MOUNT_TABLE_HPP + +#include "kernel/filesystem/dentry.hpp" +#include "kernel/filesystem/mount.hpp" + +#include +#include + +namespace filesystem +{ + struct mount_table + { + public: + void add_mount(kstd::shared_ptr); + auto find_mount_by_dentry(kstd::shared_ptr const & dentry) -> kstd::shared_ptr; + + private: + kstd::vector> m_mounts; + }; +} // namespace filesystem + +#endif diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp new file mode 100644 index 0000000..0e9a53d --- /dev/null +++ b/kernel/src/filesystem/mount_table.cpp @@ -0,0 +1,29 @@ +#include "kernel/filesystem/mount_table.hpp" + +#include "kapi/system.hpp" + +#include "kernel/filesystem/dentry.hpp" +#include "kernel/filesystem/mount.hpp" + +#include + +#include + +namespace filesystem +{ + void mount_table::add_mount(kstd::shared_ptr mount) + { + m_mounts.push_back(mount); + } + + auto mount_table::find_mount_by_dentry(kstd::shared_ptr const & dentry) -> kstd::shared_ptr + { + auto found = + std::ranges::find_if(m_mounts, [&](auto const & mount) { return mount->get_dentry().get() == dentry.get(); }); + if (found != m_mounts.end()) + { + return *found; + } + kapi::system::panic("[FILESYSTEM] dentry has mount flag set but no corresponding mount found."); + } +} // namespace filesystem \ No newline at end of file -- cgit v1.2.3 From 6110774495a10d1dd8766f8fa8597fb3bdc4aabd Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Tue, 24 Mar 2026 16:51:28 +0100 Subject: Fix dentry header guards --- kernel/include/kernel/filesystem/dentry.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index ca7ca95..c28246f 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -1,5 +1,5 @@ -#ifndef TEACH_OS_KERNEL_DENTRY_HPP -#define TEACH_OS_KERNEL_DENTRY_HPP +#ifndef TEACH_OS_KERNEL_FILESYSTEM_DENTRY_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_DENTRY_HPP #include "kernel/filesystem/inode.hpp" -- cgit v1.2.3 From b742349ba039d1a864462332bb7ae5a071afdec1 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Tue, 24 Mar 2026 16:53:21 +0100 Subject: Refactor mount_table entry (mount) to use dentry as key instead of path --- kernel/include/kernel/filesystem/mount.hpp | 9 ++++----- kernel/src/filesystem/mount.cpp | 9 +++++---- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index 232a9be..dd47ce7 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -1,23 +1,22 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_MOUNT_HPP #define TEACH_OS_KERNEL_FILESYSTEM_MOUNT_HPP +#include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/filesystem.hpp" #include -#include - namespace filesystem { struct mount { - mount(std::string_view const & path, kstd::shared_ptr const & fs); + mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & fs); - [[nodiscard]] auto path() const -> std::string_view; + [[nodiscard]] auto get_dentry() const -> kstd::shared_ptr; [[nodiscard]] auto get_filesystem() const -> kstd::shared_ptr const &; private: - std::string_view m_path; + kstd::shared_ptr m_dentry; kstd::shared_ptr m_filesystem{}; }; } // namespace filesystem diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index a2c501f..b65f331 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -2,6 +2,7 @@ #include "kapi/system.hpp" +#include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/filesystem.hpp" #include @@ -10,8 +11,8 @@ namespace filesystem { - mount::mount(std::string_view const & path, kstd::shared_ptr const & fs) - : m_path(path) + mount::mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & fs) + : m_dentry(mount_dentry) , m_filesystem(fs) { if (!m_filesystem) @@ -20,9 +21,9 @@ namespace filesystem } } - auto mount::path() const -> std::string_view + auto mount::get_dentry() const -> kstd::shared_ptr { - return m_path; + return m_dentry; } auto mount::get_filesystem() const -> kstd::shared_ptr const & -- cgit v1.2.3 From 70229b88ad195a6e945b4cc75e1248685cda0951 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Tue, 24 Mar 2026 17:05:57 +0100 Subject: Add root_dentry to filesystem --- kernel/include/kernel/filesystem/filesystem.hpp | 5 +++++ kernel/src/filesystem/filesystem.cpp | 11 +++++++++++ 2 files changed, 16 insertions(+) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index e069ced..362242f 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -2,6 +2,7 @@ #define TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP #include "kernel/devices/device.hpp" +#include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/inode.hpp" #include @@ -19,11 +20,15 @@ namespace filesystem virtual auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr = 0; [[nodiscard]] auto root_inode() const -> kstd::shared_ptr const &; + [[nodiscard]] auto root_dentry() const -> kstd::shared_ptr const &; + + auto set_root_dentry(kstd::shared_ptr dentry) -> void; protected: kstd::shared_ptr m_root_inode{}; kstd::shared_ptr m_device{}; kstd::vector> m_inodes{}; + kstd::shared_ptr m_root_dentry; }; } // namespace filesystem diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index 0e33d95..8ebe58f 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -1,6 +1,7 @@ #include "kernel/filesystem/filesystem.hpp" #include "kernel/devices/device.hpp" +#include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/inode.hpp" #include @@ -21,4 +22,14 @@ namespace filesystem { return m_root_inode; } + + auto filesystem::root_dentry() const -> kstd::shared_ptr const & + { + return m_root_dentry; + } + + auto filesystem::set_root_dentry(kstd::shared_ptr dentry) -> void + { + m_root_dentry = dentry; + } } // namespace filesystem \ No newline at end of file -- cgit v1.2.3 From a2ac8770937a28d0d4c674e25c9b3c77802a5c9e Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Tue, 24 Mar 2026 17:22:55 +0100 Subject: Refactor mounting of new filesystems and path resolving in vfs --- kernel/include/kernel/filesystem/vfs.hpp | 3 +- kernel/src/filesystem/vfs.cpp | 53 ++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 24 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 317f2d1..55bf6a4 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -6,6 +6,7 @@ #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" #include "kernel/filesystem/mount.hpp" +#include "kernel/filesystem/mount_table.hpp" #include "kernel/filesystem/open_file_description.hpp" #include @@ -43,7 +44,7 @@ namespace filesystem kstd::shared_ptr m_root_fs; kstd::shared_ptr m_root_dentry; - kstd::vector m_mount_table; + mount_table m_mount_table; }; } // namespace filesystem diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 0e8a76d..c77736a 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -82,9 +82,9 @@ namespace filesystem return nullptr; } - auto vfs::do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> int + auto vfs::do_mount(std::string_view path, kstd::shared_ptr const & new_filesystem) -> int { - if (!filesystem) + if (!new_filesystem) { return -1; // TODO BA-FS26 panic or errorcode? } @@ -100,24 +100,21 @@ namespace filesystem return -1; // TODO BA-FS26 panic or errorcode? } - // if (path == "/") - // { - // m_root_fs = filesystem; - // m_root_mount = mount{"/", filesystem}; - // return 0; - // } + auto mount_dentry = resolve_path(path); - auto existing_mount = - std::ranges::find_if(m_mount_table, [&](auto const & existing) { return existing.path() == path; }); - if (existing_mount != m_mount_table.end()) + if (!mount_dentry) { - *existing_mount = mount{path, filesystem}; - } - else - { - m_mount_table.push_back(mount{path, filesystem}); + return -1; // mount point path doesn't exist } + // TODO BA-FS26 check if mount point is already mounted and handle it (unmount old fs, fail, etc.) + + mount_dentry->set_flag(dentry::dentry_flags::dcache_mounted); + m_mount_table.add_mount(kstd::make_shared(mount_dentry, new_filesystem)); + + new_filesystem->set_root_dentry( + kstd::make_shared(mount_dentry->get_parent(), new_filesystem->root_inode())); + return 0; } @@ -157,19 +154,29 @@ namespace filesystem { auto path_parts = std::views::split(path, '/') | std::views::filter([](auto const & part) { return !part.empty(); }); - auto parent = m_root_dentry; + auto current_parent = m_root_dentry; + auto current_fs = m_root_fs; for (auto const & part : path_parts) { - if (auto child = parent->find_child(std::string_view{part})) + if (auto child = current_parent->find_child(std::string_view{part})) { - parent = child; + if (child->has_flag(dentry::dentry_flags::dcache_mounted)) // found dentry is a mounted fs + { + auto found_mount = m_mount_table.find_mount_by_dentry(child); + current_fs = found_mount->get_filesystem(); + current_parent = current_fs->root_dentry(); + } + else + { // found dentry is NOT a mounted fs -> continue path resolution in current fs + current_parent = child; + } } - else if (auto found_inode = m_root_fs->lookup(parent->get_inode(), std::string_view{part})) + else if (auto found_inode = m_root_fs->lookup(current_parent->get_inode(), std::string_view{part})) { - auto next_dentry = kstd::make_shared(parent, found_inode, std::string_view{part}); - parent->add_child(next_dentry); - parent = next_dentry; + auto next_dentry = kstd::make_shared(current_parent, found_inode, std::string_view{part}); + current_parent->add_child(next_dentry); + current_parent = next_dentry; } else { -- cgit v1.2.3 From 7351349f296f100f10db62b5a834a971fbe51473 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 24 Mar 2026 18:52:41 +0100 Subject: small refactoring --- kernel/src/filesystem/mount_table.cpp | 6 +++--- kernel/src/filesystem/vfs.cpp | 36 ++++++++++------------------------- 2 files changed, 13 insertions(+), 29 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 0e9a53d..b4a906b 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -18,11 +18,11 @@ namespace filesystem auto mount_table::find_mount_by_dentry(kstd::shared_ptr const & dentry) -> kstd::shared_ptr { - auto found = + auto it = std::ranges::find_if(m_mounts, [&](auto const & mount) { return mount->get_dentry().get() == dentry.get(); }); - if (found != m_mounts.end()) + if (it != m_mounts.end()) { - return *found; + return *it; } kapi::system::panic("[FILESYSTEM] dentry has mount flag set but no corresponding mount found."); } diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index c77736a..78dec77 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -39,7 +39,6 @@ namespace filesystem auto vfs::init_internal() -> void { auto storage_mgmt = devices::storage::storage_management::get(); - // TODO BA-FS26 fix mounting boot_device if (auto boot_device = storage_mgmt.determine_boot_device()) { m_root_fs = kstd::make_shared(); @@ -82,9 +81,9 @@ namespace filesystem return nullptr; } - auto vfs::do_mount(std::string_view path, kstd::shared_ptr const & new_filesystem) -> int + auto vfs::do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> int { - if (!new_filesystem) + if (!filesystem) { return -1; // TODO BA-FS26 panic or errorcode? } @@ -100,22 +99,19 @@ namespace filesystem return -1; // TODO BA-FS26 panic or errorcode? } - auto mount_dentry = resolve_path(path); - - if (!mount_dentry) + if (auto mount_dentry = resolve_path(path)) { - return -1; // mount point path doesn't exist - } + // TODO BA-FS26 check if mount point is already mounted and handle it (unmount old fs, fail, etc.) - // TODO BA-FS26 check if mount point is already mounted and handle it (unmount old fs, fail, etc.) + mount_dentry->set_flag(dentry::dentry_flags::dcache_mounted); + m_mount_table.add_mount(kstd::make_shared(mount_dentry, filesystem)); - mount_dentry->set_flag(dentry::dentry_flags::dcache_mounted); - m_mount_table.add_mount(kstd::make_shared(mount_dentry, new_filesystem)); + filesystem->set_root_dentry(kstd::make_shared(mount_dentry->get_parent(), filesystem->root_inode())); - new_filesystem->set_root_dentry( - kstd::make_shared(mount_dentry->get_parent(), new_filesystem->root_inode())); + return 0; + } - return 0; + return -1; } auto vfs::make_device_node(kstd::shared_ptr const & device) -> void @@ -183,18 +179,6 @@ namespace filesystem return nullptr; } } - // | std::views::transform([this](auto const & part) { - // // TODO BA-FS26 implement real path resolution with mounts and directories etc. - // // For now, just return null for any non-device-node path. - // return std::optional>{}; - // }) - // | std::views::filter([](auto const & opt) { return opt.has_value(); }) - // | std::views::transform([](auto const & opt) { return opt.value(); }) - // | std::ranges::find_if(m_mount_table, [&](auto const & mount) { - // // TODO BA-FS26 implement real path resolution with mounts and directories etc. - // // For now, just check if the first path component matches a mount point. - // return part == mount.path(); - // }); } return nullptr; -- cgit v1.2.3 From 2eb086d516f20a0b5cef9881a3459adb389c6ee8 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 24 Mar 2026 19:06:50 +0100 Subject: implement == and <=> operator in shared_ptr --- kernel/src/filesystem/mount_table.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index b4a906b..3176d6d 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -18,8 +18,7 @@ namespace filesystem auto mount_table::find_mount_by_dentry(kstd::shared_ptr const & dentry) -> kstd::shared_ptr { - auto it = - std::ranges::find_if(m_mounts, [&](auto const & mount) { return mount->get_dentry().get() == dentry.get(); }); + auto it = std::ranges::find_if(m_mounts, [&](auto const & mount) { return mount->get_dentry() == dentry; }); if (it != m_mounts.end()) { return *it; -- cgit v1.2.3 From 76de81de1e12694bf6bec1edd3e3409092a92d09 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 24 Mar 2026 20:41:32 +0100 Subject: refactoring, add root_mount into the root_table --- kernel/include/kernel/filesystem/mount_table.hpp | 2 + kernel/include/kernel/filesystem/vfs.hpp | 3 -- kernel/src/filesystem/mount_table.cpp | 7 ++++ kernel/src/filesystem/vfs.cpp | 53 ++++++++++++++---------- kernel/src/main.cpp | 1 - 5 files changed, 40 insertions(+), 26 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount_table.hpp b/kernel/include/kernel/filesystem/mount_table.hpp index 14d6d08..cf523c1 100644 --- a/kernel/include/kernel/filesystem/mount_table.hpp +++ b/kernel/include/kernel/filesystem/mount_table.hpp @@ -13,6 +13,8 @@ namespace filesystem { public: void add_mount(kstd::shared_ptr); + + [[nodiscard]] auto get_root_mount() const -> kstd::shared_ptr; auto find_mount_by_dentry(kstd::shared_ptr const & dentry) -> kstd::shared_ptr; private: diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 55bf6a4..cf268a3 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -5,7 +5,6 @@ #include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" -#include "kernel/filesystem/mount.hpp" #include "kernel/filesystem/mount_table.hpp" #include "kernel/filesystem/open_file_description.hpp" @@ -42,8 +41,6 @@ namespace filesystem auto make_device_node(kstd::shared_ptr const & device) -> void; [[nodiscard]] auto resolve_path(std::string_view path) -> kstd::shared_ptr; - kstd::shared_ptr m_root_fs; - kstd::shared_ptr m_root_dentry; mount_table m_mount_table; }; } // namespace filesystem diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 3176d6d..debb9ab 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -16,6 +16,13 @@ namespace filesystem m_mounts.push_back(mount); } + auto mount_table::get_root_mount() const -> kstd::shared_ptr + { + auto it = + std::ranges::find_if(m_mounts, [](auto const & mount) { return mount->get_dentry()->get_parent() == nullptr; }); + return it != m_mounts.end() ? *it : nullptr; + } + auto mount_table::find_mount_by_dentry(kstd::shared_ptr const & dentry) -> kstd::shared_ptr { auto it = std::ranges::find_if(m_mounts, [&](auto const & mount) { return mount->get_dentry() == dentry; }); diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 78dec77..c8e5bc5 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -41,14 +41,13 @@ namespace filesystem auto storage_mgmt = devices::storage::storage_management::get(); if (auto boot_device = storage_mgmt.determine_boot_device()) { - m_root_fs = kstd::make_shared(); - m_root_fs->mount(boot_device); + auto root_fs = kstd::make_shared(); + root_fs->mount(boot_device); - m_root_dentry = kstd::make_shared(nullptr, m_root_fs->root_inode()); - // if (do_mount("/", m_root_fs) != 0) - // { - // kapi::system::panic("[FILESYSTEM] Failed to mount root filesystem."); - // } + auto root_dentry = kstd::make_shared(nullptr, root_fs->root_inode(), "/"); + root_fs->set_root_dentry(root_dentry); + + m_mount_table.add_mount(kstd::make_shared(nullptr, root_fs)); // TODO BA-FS26 use do_mount when tempdevfs is implemented -> just call /dev/ with all devices in devtempfs std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto controller) { @@ -148,37 +147,47 @@ namespace filesystem } else if (!path.empty() && path.front() == '/') { + auto root_mount = m_mount_table.get_root_mount(); + if (!root_mount) + { + kapi::system::panic("[FILESYSTEM] no root mount found."); + } + + auto current_dentry = root_mount->get_dentry(); + auto current_fs = root_mount->get_filesystem(); + auto path_parts = std::views::split(path, '/') | std::views::filter([](auto const & part) { return !part.empty(); }); - auto current_parent = m_root_dentry; - auto current_fs = m_root_fs; - for (auto const & part : path_parts) { - if (auto child = current_parent->find_child(std::string_view{part})) + auto next_dentry = current_dentry->find_child(std::string_view{part}); + + if (!next_dentry) { - if (child->has_flag(dentry::dentry_flags::dcache_mounted)) // found dentry is a mounted fs + if (auto found_inode = current_fs->lookup(current_dentry->get_inode(), std::string_view{part})) { - auto found_mount = m_mount_table.find_mount_by_dentry(child); - current_fs = found_mount->get_filesystem(); - current_parent = current_fs->root_dentry(); + next_dentry = kstd::make_shared(current_dentry, found_inode, std::string_view{part}); + current_dentry->add_child(next_dentry); } else - { // found dentry is NOT a mounted fs -> continue path resolution in current fs - current_parent = child; + { + return nullptr; } } - else if (auto found_inode = m_root_fs->lookup(current_parent->get_inode(), std::string_view{part})) + + if (next_dentry->has_flag(dentry::dentry_flags::dcache_mounted)) { - auto next_dentry = kstd::make_shared(current_parent, found_inode, std::string_view{part}); - current_parent->add_child(next_dentry); - current_parent = next_dentry; + auto found_mount = m_mount_table.find_mount_by_dentry(next_dentry); + current_fs = found_mount->get_filesystem(); + current_dentry = current_fs->root_dentry(); } else { - return nullptr; + current_dentry = next_dentry; } } + + return current_dentry; } return nullptr; diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index a575be2..9571a0d 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3 From 84d4476650b31dbfc52becf2ff65ddce9d31c9ec Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 24 Mar 2026 23:54:28 +0100 Subject: implement a rootfs to handle / mounts correctly --- kernel/CMakeLists.txt | 2 + kernel/include/kernel/filesystem/filesystem.hpp | 5 --- kernel/include/kernel/filesystem/mount.hpp | 10 +++-- .../kernel/filesystem/rootfs/rootfs_filesystem.hpp | 21 +++++++++++ .../kernel/filesystem/rootfs/rootfs_inode.hpp | 19 ++++++++++ kernel/src/filesystem/filesystem.cpp | 11 ------ kernel/src/filesystem/mount.cpp | 15 ++++++-- kernel/src/filesystem/mount_table.cpp | 14 ++----- kernel/src/filesystem/rootfs/rootfs_filesystem.cpp | 24 ++++++++++++ kernel/src/filesystem/rootfs/rootfs_inode.cpp | 22 +++++++++++ kernel/src/filesystem/vfs.cpp | 43 +++++++++++++++------- kernel/src/main.cpp | 10 +++++ 12 files changed, 149 insertions(+), 47 deletions(-) create mode 100644 kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp create mode 100644 kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp create mode 100644 kernel/src/filesystem/rootfs/rootfs_filesystem.cpp create mode 100644 kernel/src/filesystem/rootfs/rootfs_inode.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index ee1f585..406ac54 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -32,6 +32,8 @@ add_executable("kernel" "src/filesystem/mount_table.cpp" "src/filesystem/mount.cpp" "src/filesystem/open_file_description.cpp" + "src/filesystem/rootfs/rootfs_filesystem.cpp" + "src/filesystem/rootfs/rootfs_inode.cpp" "src/filesystem/vfs.cpp" ) diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index 362242f..e069ced 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -2,7 +2,6 @@ #define TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP #include "kernel/devices/device.hpp" -#include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/inode.hpp" #include @@ -20,15 +19,11 @@ namespace filesystem virtual auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr = 0; [[nodiscard]] auto root_inode() const -> kstd::shared_ptr const &; - [[nodiscard]] auto root_dentry() const -> kstd::shared_ptr const &; - - auto set_root_dentry(kstd::shared_ptr dentry) -> void; protected: kstd::shared_ptr m_root_inode{}; kstd::shared_ptr m_device{}; kstd::vector> m_inodes{}; - kstd::shared_ptr m_root_dentry; }; } // namespace filesystem diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index dd47ce7..0cd30b4 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -10,13 +10,17 @@ namespace filesystem { struct mount { - mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & fs); + mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & root_dentry, + kstd::shared_ptr const & fs); + + [[nodiscard]] auto get_mount_dentry() const -> kstd::shared_ptr; + [[nodiscard]] auto root_dentry() const -> kstd::shared_ptr const &; - [[nodiscard]] auto get_dentry() const -> kstd::shared_ptr; [[nodiscard]] auto get_filesystem() const -> kstd::shared_ptr const &; private: - kstd::shared_ptr m_dentry; + kstd::shared_ptr m_mount_dentry; + kstd::shared_ptr m_root_dentry; kstd::shared_ptr m_filesystem{}; }; } // namespace filesystem diff --git a/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp new file mode 100644 index 0000000..949ac83 --- /dev/null +++ b/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp @@ -0,0 +1,21 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_ROOTFS_FILESYSTEM_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_ROOTFS_FILESYSTEM_HPP + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/filesystem.hpp" +#include "kernel/filesystem/inode.hpp" + +#include + +#include + +namespace filesystem::rootfs +{ + struct rootfs_filesystem : filesystem + { + auto mount(kstd::shared_ptr const & device) -> int override; + auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; + }; +} // namespace filesystem::rootfs + +#endif diff --git a/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp b/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp new file mode 100644 index 0000000..d533e8e --- /dev/null +++ b/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp @@ -0,0 +1,19 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_ROOTFS_INODE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_ROOTFS_INODE_HPP + +#include "kernel/filesystem/inode.hpp" + +#include + +namespace filesystem::rootfs +{ + struct rootfs_inode : inode + { + rootfs_inode(); + + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + }; +} // namespace filesystem::rootfs + +#endif diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index 8ebe58f..0e33d95 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -1,7 +1,6 @@ #include "kernel/filesystem/filesystem.hpp" #include "kernel/devices/device.hpp" -#include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/inode.hpp" #include @@ -22,14 +21,4 @@ namespace filesystem { return m_root_inode; } - - auto filesystem::root_dentry() const -> kstd::shared_ptr const & - { - return m_root_dentry; - } - - auto filesystem::set_root_dentry(kstd::shared_ptr dentry) -> void - { - m_root_dentry = dentry; - } } // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index b65f331..d9937dc 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -11,8 +11,10 @@ namespace filesystem { - mount::mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & fs) - : m_dentry(mount_dentry) + mount::mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & root_dentry, + kstd::shared_ptr const & fs) + : m_mount_dentry(mount_dentry) + , m_root_dentry(root_dentry) , m_filesystem(fs) { if (!m_filesystem) @@ -21,13 +23,18 @@ namespace filesystem } } - auto mount::get_dentry() const -> kstd::shared_ptr + auto mount::get_mount_dentry() const -> kstd::shared_ptr { - return m_dentry; + return m_mount_dentry; } auto mount::get_filesystem() const -> kstd::shared_ptr const & { return m_filesystem; } + + auto mount::root_dentry() const -> kstd::shared_ptr const & + { + return m_root_dentry; + } } // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index debb9ab..681c2b9 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -1,7 +1,5 @@ #include "kernel/filesystem/mount_table.hpp" -#include "kapi/system.hpp" - #include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/mount.hpp" @@ -18,18 +16,14 @@ namespace filesystem auto mount_table::get_root_mount() const -> kstd::shared_ptr { - auto it = - std::ranges::find_if(m_mounts, [](auto const & mount) { return mount->get_dentry()->get_parent() == nullptr; }); + auto it = std::ranges::find_if(m_mounts, [](auto const & mount) { return mount->get_mount_dentry() == nullptr; }); return it != m_mounts.end() ? *it : nullptr; } auto mount_table::find_mount_by_dentry(kstd::shared_ptr const & dentry) -> kstd::shared_ptr { - auto it = std::ranges::find_if(m_mounts, [&](auto const & mount) { return mount->get_dentry() == dentry; }); - if (it != m_mounts.end()) - { - return *it; - } - kapi::system::panic("[FILESYSTEM] dentry has mount flag set but no corresponding mount found."); + auto it = std::ranges::find_if(m_mounts, [&](auto const & mnt) { return mnt->get_mount_dentry() == dentry; }); + + return it != m_mounts.end() ? *it : nullptr; } } // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp b/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp new file mode 100644 index 0000000..22b1962 --- /dev/null +++ b/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp @@ -0,0 +1,24 @@ +#include "kernel/filesystem/rootfs/rootfs_filesystem.hpp" + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/inode.hpp" +#include "kernel/filesystem/rootfs/rootfs_inode.hpp" + +#include + +#include + +namespace filesystem::rootfs +{ + auto rootfs_filesystem::mount(kstd::shared_ptr const & /*device*/) -> int + { + m_root_inode = kstd::make_shared(); + return 0; + } + + auto rootfs_filesystem::lookup(kstd::shared_ptr const & /*parent*/, std::string_view /*name*/) + -> kstd::shared_ptr + { + return nullptr; + } +} // namespace filesystem::rootfs diff --git a/kernel/src/filesystem/rootfs/rootfs_inode.cpp b/kernel/src/filesystem/rootfs/rootfs_inode.cpp new file mode 100644 index 0000000..ed057f7 --- /dev/null +++ b/kernel/src/filesystem/rootfs/rootfs_inode.cpp @@ -0,0 +1,22 @@ +#include "kernel/filesystem/rootfs/rootfs_inode.hpp" + +#include "kernel/filesystem/inode.hpp" + +#include + +namespace filesystem::rootfs +{ + rootfs_inode::rootfs_inode() + : inode(inode_kind::directory) + {} + + auto rootfs_inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t + { + return 0; + } + + auto rootfs_inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t + { + return 0; + } +} // namespace filesystem::rootfs diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index c8e5bc5..1c4dd8b 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -10,6 +10,7 @@ #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/mount.hpp" #include "kernel/filesystem/open_file_description.hpp" +#include "kernel/filesystem/rootfs/rootfs_filesystem.hpp" #include @@ -38,16 +39,20 @@ namespace filesystem auto vfs::init_internal() -> void { + auto virtual_fs = kstd::make_shared(); + virtual_fs->mount(nullptr); + + auto virtual_root_dentry = kstd::make_shared(nullptr, virtual_fs->root_inode(), "/"); + m_mount_table.add_mount(kstd::make_shared(nullptr, virtual_root_dentry, virtual_fs)); + auto storage_mgmt = devices::storage::storage_management::get(); if (auto boot_device = storage_mgmt.determine_boot_device()) { - auto root_fs = kstd::make_shared(); - root_fs->mount(boot_device); + // TODO BA-FS26 detect fs type from boot device and load corresponding fs, for now just assume ext2 + auto boot_root_fs = kstd::make_shared(); + boot_root_fs->mount(boot_device); - auto root_dentry = kstd::make_shared(nullptr, root_fs->root_inode(), "/"); - root_fs->set_root_dentry(root_dentry); - - m_mount_table.add_mount(kstd::make_shared(nullptr, root_fs)); + do_mount("/", boot_root_fs); // TODO BA-FS26 use do_mount when tempdevfs is implemented -> just call /dev/ with all devices in devtempfs std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto controller) { @@ -102,10 +107,10 @@ namespace filesystem { // TODO BA-FS26 check if mount point is already mounted and handle it (unmount old fs, fail, etc.) + auto new_fs_root = kstd::make_shared(mount_dentry, filesystem->root_inode()); + auto new_mount = kstd::make_shared(mount_dentry, new_fs_root, filesystem); + m_mount_table.add_mount(new_mount); mount_dentry->set_flag(dentry::dentry_flags::dcache_mounted); - m_mount_table.add_mount(kstd::make_shared(mount_dentry, filesystem)); - - filesystem->set_root_dentry(kstd::make_shared(mount_dentry->get_parent(), filesystem->root_inode())); return 0; } @@ -153,20 +158,30 @@ namespace filesystem kapi::system::panic("[FILESYSTEM] no root mount found."); } - auto current_dentry = root_mount->get_dentry(); + auto current_dentry = root_mount->root_dentry(); auto current_fs = root_mount->get_filesystem(); + while (current_dentry->has_flag(dentry::dentry_flags::dcache_mounted)) + { + auto mnt = m_mount_table.find_mount_by_dentry(current_dentry); + if (!mnt) + kapi::system::panic("[FILESYSTEM] dcache_mounted set but no covering mount found."); + current_dentry = mnt->root_dentry(); + current_fs = mnt->get_filesystem(); + } + auto path_parts = std::views::split(path, '/') | std::views::filter([](auto const & part) { return !part.empty(); }); for (auto const & part : path_parts) { - auto next_dentry = current_dentry->find_child(std::string_view{part}); + std::string_view part_view{part}; + auto next_dentry = current_dentry->find_child(part_view); if (!next_dentry) { - if (auto found_inode = current_fs->lookup(current_dentry->get_inode(), std::string_view{part})) + if (auto found_inode = current_fs->lookup(current_dentry->get_inode(), part_view)) { - next_dentry = kstd::make_shared(current_dentry, found_inode, std::string_view{part}); + next_dentry = kstd::make_shared(current_dentry, found_inode, part_view); current_dentry->add_child(next_dentry); } else @@ -179,7 +194,7 @@ namespace filesystem { auto found_mount = m_mount_table.find_mount_by_dentry(next_dentry); current_fs = found_mount->get_filesystem(); - current_dentry = current_fs->root_dentry(); + current_dentry = found_mount->root_dentry(); } else { diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 9571a0d..19a0992 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -5,6 +5,7 @@ #include "kernel/devices/storage/storage_management.hpp" #include "kernel/filesystem/device_inode.hpp" +#include "kernel/filesystem/ext2/ext2_filesystem.hpp" #include "kernel/filesystem/file_descriptor_table.hpp" #include "kernel/filesystem/open_file_description.hpp" #include "kernel/filesystem/vfs.hpp" @@ -108,8 +109,17 @@ auto test_file_lookup() -> void // TODO BA-FS26 implement a more complete test with multiple files and directories and mounts etc. auto vfs = filesystem::vfs::get(); + auto storage_mgmt = devices::storage::storage_management::get(); + vfs.open("/a/b/c"); vfs.open("/a/d/e"); + + auto new_filesystem = kstd::make_shared(); + auto device = storage_mgmt.device_by_major_minor(1, 16); + new_filesystem->mount(device); + vfs.do_mount("/a/b", new_filesystem); + vfs.open("/a/b/c"); + vfs.open("x/y/z"); } -- cgit v1.2.3 From 74351bbcd440189bafa79c806dd3ae8255f42c11 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 25 Mar 2026 07:47:24 +0100 Subject: currently do not support stacked mounts --- kernel/src/filesystem/vfs.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 1c4dd8b..483bae5 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -161,7 +161,8 @@ namespace filesystem auto current_dentry = root_mount->root_dentry(); auto current_fs = root_mount->get_filesystem(); - while (current_dentry->has_flag(dentry::dentry_flags::dcache_mounted)) + // TODO BA-FS26 use while to allow stacked mounts? + if (current_dentry->has_flag(dentry::dentry_flags::dcache_mounted)) { auto mnt = m_mount_table.find_mount_by_dentry(current_dentry); if (!mnt) @@ -190,6 +191,7 @@ namespace filesystem } } + // TODO BA-FS26 use while to allow stacked mounts? if (next_dentry->has_flag(dentry::dentry_flags::dcache_mounted)) { auto found_mount = m_mount_table.find_mount_by_dentry(next_dentry); -- cgit v1.2.3 From 31ac3e6ffff00b7ac3b3dbb3db38c44409251b34 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 26 Mar 2026 20:09:37 +0100 Subject: first draft of an devfs implementation --- kernel/CMakeLists.txt | 2 + .../kernel/filesystem/devfs/devfs_filesystem.hpp | 25 ++++++++++ .../kernel/filesystem/devfs/devfs_root_inode.hpp | 19 ++++++++ kernel/include/kernel/filesystem/device_inode.hpp | 2 + kernel/include/kernel/filesystem/vfs.hpp | 13 ----- kernel/src/filesystem/devfs/devfs_filesystem.cpp | 57 ++++++++++++++++++++++ kernel/src/filesystem/devfs/devfs_root_inode.cpp | 22 +++++++++ kernel/src/filesystem/device_inode.cpp | 5 ++ kernel/src/filesystem/vfs.cpp | 50 ++++++------------- 9 files changed, 146 insertions(+), 49 deletions(-) create mode 100644 kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp create mode 100644 kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp create mode 100644 kernel/src/filesystem/devfs/devfs_filesystem.cpp create mode 100644 kernel/src/filesystem/devfs/devfs_root_inode.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 406ac54..eb762ac 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -21,6 +21,8 @@ add_executable("kernel" "src/devices/storage/storage_management.cpp" "src/devices/storage/ram_disk/ram_disk_controller.cpp" "src/devices/storage/ram_disk/ram_disk_device.cpp" + "src/filesystem/devfs/devfs_filesystem.cpp" + "src/filesystem/devfs/devfs_root_inode.cpp" "src/filesystem/ext2/ext2_file.cpp" "src/filesystem/ext2/ext2_filesystem.cpp" "src/filesystem/ext2/ext2_inode.cpp" diff --git a/kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp b/kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp new file mode 100644 index 0000000..5559c2a --- /dev/null +++ b/kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp @@ -0,0 +1,25 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVFS_DEVFS_FILESYSTEM_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_DEVFS_FILESYSTEM_HPP + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/filesystem.hpp" +#include "kernel/filesystem/inode.hpp" + +#include +#include + +#include + +namespace filesystem::devfs +{ + struct devfs_filesystem : filesystem + { + auto mount(kstd::shared_ptr const & device) -> int override; + auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; + + private: + auto build_device_inode_table() -> void; + }; +} // namespace filesystem::devfs + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp b/kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp new file mode 100644 index 0000000..b1d37ab --- /dev/null +++ b/kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp @@ -0,0 +1,19 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVFS_DEVFS_ROOT_INODE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_DEVFS_ROOT_INODE_HPP + +#include "kernel/filesystem/inode.hpp" + +#include + +namespace filesystem::devfs +{ + struct devfs_root_inode : inode + { + devfs_root_inode(); + + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + }; +} // namespace filesystem::devfs + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index ce0f91c..1cf08d4 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -18,6 +18,8 @@ namespace filesystem auto read(void * buffer, size_t offset, size_t size) const -> size_t override; auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + [[nodiscard]] auto device() const -> kstd::shared_ptr const &; + private: 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); diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index cf268a3..f301b7a 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -1,17 +1,13 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP #define TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP -#include "kernel/devices/device.hpp" #include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/filesystem.hpp" -#include "kernel/filesystem/inode.hpp" #include "kernel/filesystem/mount_table.hpp" #include "kernel/filesystem/open_file_description.hpp" #include -#include -#include #include namespace filesystem @@ -27,18 +23,9 @@ namespace filesystem auto do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> int; private: - // TODO BA-FS26 remove again and use devtempfs - struct device_node_entry - { - std::string_view name; - kstd::shared_ptr node; - }; - kstd::vector> m_device_nodes; // TODO BA-FS26 remove again, use devtempfs - vfs() = default; auto init_internal() -> void; - auto make_device_node(kstd::shared_ptr const & device) -> void; [[nodiscard]] auto resolve_path(std::string_view path) -> kstd::shared_ptr; mount_table m_mount_table; diff --git a/kernel/src/filesystem/devfs/devfs_filesystem.cpp b/kernel/src/filesystem/devfs/devfs_filesystem.cpp new file mode 100644 index 0000000..cfd2d88 --- /dev/null +++ b/kernel/src/filesystem/devfs/devfs_filesystem.cpp @@ -0,0 +1,57 @@ +#include "kernel/filesystem/devfs/devfs_filesystem.hpp" + +#include "kernel/devices/device.hpp" +#include "kernel/devices/storage/storage_management.hpp" +#include "kernel/filesystem/devfs/devfs_root_inode.hpp" +#include "kernel/filesystem/device_inode.hpp" +#include "kernel/filesystem/inode.hpp" + +#include + +#include +#include + +namespace filesystem::devfs +{ + auto devfs_filesystem::mount(kstd::shared_ptr const & /*device*/) -> int + { + m_root_inode = kstd::make_shared(); + build_device_inode_table(); + return 0; + } + + auto devfs_filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) + -> kstd::shared_ptr + { + if (!parent || !parent->is_directory()) + { + return nullptr; + } + + if (parent.get() != m_root_inode.get()) + { + return nullptr; + } + + auto it = std::ranges::find_if(m_inodes, [&](auto const & dev_node) { + auto device_inode_ptr = static_cast(dev_node.get()); + if (!device_inode_ptr) + { + return false; + } + return device_inode_ptr->device()->name() == name; + }); + return (it != m_inodes.end()) ? *it : nullptr; + } + + auto devfs_filesystem::build_device_inode_table() -> void + { + m_inodes.clear(); + + auto storage_mgmt = devices::storage::storage_management::get(); + std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto const & controller) { + std::ranges::for_each(controller->all_devices(), + [&](auto const & device) { m_inodes.push_back(kstd::make_shared(device)); }); + }); + } +} // namespace filesystem::devfs \ No newline at end of file diff --git a/kernel/src/filesystem/devfs/devfs_root_inode.cpp b/kernel/src/filesystem/devfs/devfs_root_inode.cpp new file mode 100644 index 0000000..53441b0 --- /dev/null +++ b/kernel/src/filesystem/devfs/devfs_root_inode.cpp @@ -0,0 +1,22 @@ +#include "kernel/filesystem/devfs/devfs_root_inode.hpp" + +#include "kernel/filesystem/inode.hpp" + +#include + +namespace filesystem::devfs +{ + devfs_root_inode::devfs_root_inode() + : inode(inode_kind::directory) + {} + + auto devfs_root_inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t + { + return 0; + } + + auto devfs_root_inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t + { + return 0; + } +} // namespace filesystem::devfs \ No newline at end of file diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp index 812b43a..64cd6e9 100644 --- a/kernel/src/filesystem/device_inode.cpp +++ b/kernel/src/filesystem/device_inode.cpp @@ -76,6 +76,11 @@ namespace filesystem } } + auto device_inode::device() const -> kstd::shared_ptr const & + { + return m_device; + } + auto device_inode::process_blocks(size_t offset, size_t size, void * buffer, block_op op) const -> size_t { if (buffer == nullptr) diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 483bae5..368d994 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -2,10 +2,9 @@ #include "kapi/system.hpp" -#include "kernel/devices/device.hpp" #include "kernel/devices/storage/storage_management.hpp" #include "kernel/filesystem/dentry.hpp" -#include "kernel/filesystem/device_inode.hpp" +#include "kernel/filesystem/devfs/devfs_filesystem.hpp" #include "kernel/filesystem/ext2/ext2_filesystem.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/mount.hpp" @@ -14,7 +13,6 @@ #include -#include #include #include #include @@ -52,12 +50,18 @@ namespace filesystem auto boot_root_fs = kstd::make_shared(); boot_root_fs->mount(boot_device); - do_mount("/", boot_root_fs); + if (do_mount("/", boot_root_fs) != 0) + { + kapi::system::panic("[FILESYSTEM] failed to mount root filesystem."); + } + + auto device_fs = kstd::make_shared(); + device_fs->mount(nullptr); - // TODO BA-FS26 use do_mount when tempdevfs is implemented -> just call /dev/ with all devices in devtempfs - std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto controller) { - std::ranges::for_each(controller->all_devices(), [&](auto device) { make_device_node(device); }); - }); + if (do_mount("/dev", device_fs) != 0) + { + kapi::system::panic("[FILESYSTEM] failed to mount devfs at /dev."); + } } else { @@ -118,39 +122,13 @@ namespace filesystem return -1; } - auto vfs::make_device_node(kstd::shared_ptr const & device) -> void - { - if (!device) - { - kapi::system::panic("[FILESYSTEM] make_device_node called with null device."); - } - - m_device_nodes.push_back(device_node_entry{device->name().view(), kstd::make_shared(device)}); - } - auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr { - // TODO BA-FS26 implement real path resolution with mounts and directories etc. - // For now, just support device nodes at /dev/. + // TODO BA-FS26 implement full path resolution semantics. // TODO BA-FS26 better path validation // TODO BA-FS26 implement a path parser (maybe in libs?) and use it here and in do_mount - constexpr auto device_prefix = std::string_view{"/dev/"}; - if (path.starts_with(device_prefix)) - { - auto const device_name = path.substr(device_prefix.size()); - auto entry = std::ranges::find_if(m_device_nodes, [&](auto const & device_entry) { - return device_entry.has_value() && device_entry->name == device_name; - }); - - if (entry != m_device_nodes.end()) - { - return kstd::make_shared(nullptr, entry->value().node); - } - - return nullptr; - } - else if (!path.empty() && path.front() == '/') + if (!path.empty() && path.front() == '/') { auto root_mount = m_mount_table.get_root_mount(); if (!root_mount) -- cgit v1.2.3 From e97b668f82ad1a51e1e9352073a3ae51cedfdd34 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 26 Mar 2026 20:27:23 +0100 Subject: mount /dev in the rootfs --- .../kernel/filesystem/rootfs/rootfs_filesystem.hpp | 4 ++++ .../include/kernel/filesystem/rootfs/rootfs_inode.hpp | 12 ++++++++++++ kernel/src/filesystem/rootfs/rootfs_filesystem.cpp | 9 +++++++-- kernel/src/filesystem/rootfs/rootfs_inode.cpp | 17 +++++++++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp index 949ac83..cb07111 100644 --- a/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp +++ b/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp @@ -4,10 +4,14 @@ #include "kernel/devices/device.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" +#include "kernel/filesystem/rootfs/rootfs_inode.hpp" #include +#include +#include #include +#include namespace filesystem::rootfs { diff --git a/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp b/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp index d533e8e..de4fb7c 100644 --- a/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp +++ b/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp @@ -3,7 +3,13 @@ #include "kernel/filesystem/inode.hpp" +#include +#include +#include + #include +#include +#include namespace filesystem::rootfs { @@ -13,6 +19,12 @@ namespace filesystem::rootfs auto read(void * buffer, size_t offset, size_t size) const -> size_t override; auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + + auto add_child(std::string_view name) -> void; + auto lookup_child(std::string_view name) -> kstd::shared_ptr; + + private: + kstd::vector>> m_children; }; } // namespace filesystem::rootfs diff --git a/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp b/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp index 22b1962..e819fc7 100644 --- a/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp +++ b/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp @@ -12,13 +12,18 @@ namespace filesystem::rootfs { auto rootfs_filesystem::mount(kstd::shared_ptr const & /*device*/) -> int { - m_root_inode = kstd::make_shared(); + auto rfs_inode = kstd::make_shared(); + rfs_inode->add_child("dev"); + m_root_inode = rfs_inode; + return 0; } - auto rootfs_filesystem::lookup(kstd::shared_ptr const & /*parent*/, std::string_view /*name*/) + auto rootfs_filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr { + if (auto * rfs_inode = static_cast(parent.get())) + return rfs_inode->lookup_child(name); return nullptr; } } // namespace filesystem::rootfs diff --git a/kernel/src/filesystem/rootfs/rootfs_inode.cpp b/kernel/src/filesystem/rootfs/rootfs_inode.cpp index ed057f7..9bbfbce 100644 --- a/kernel/src/filesystem/rootfs/rootfs_inode.cpp +++ b/kernel/src/filesystem/rootfs/rootfs_inode.cpp @@ -2,7 +2,13 @@ #include "kernel/filesystem/inode.hpp" +#include +#include + +#include #include +#include +#include namespace filesystem::rootfs { @@ -19,4 +25,15 @@ namespace filesystem::rootfs { return 0; } + + auto rootfs_inode::add_child(std::string_view name) -> void + { + m_children.push_back(std::make_pair(kstd::string{name}, kstd::make_shared())); + } + + auto rootfs_inode::lookup_child(std::string_view name) -> kstd::shared_ptr + { + auto it = std::ranges::find_if(m_children, [&](auto const & pair) { return pair.first == name; }); + return (it != m_children.end()) ? it->second : nullptr; + } } // namespace filesystem::rootfs -- cgit v1.2.3 From 372148a1379d7f14cbe641272f8f28766925f3aa Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 26 Mar 2026 21:13:59 +0100 Subject: mock filesystem correctly for tests with /dev --- kernel/src/filesystem/ext2/ext2_filesystem.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/ext2/ext2_filesystem.cpp b/kernel/src/filesystem/ext2/ext2_filesystem.cpp index 3f5774c..373c6a2 100644 --- a/kernel/src/filesystem/ext2/ext2_filesystem.cpp +++ b/kernel/src/filesystem/ext2/ext2_filesystem.cpp @@ -22,11 +22,16 @@ namespace filesystem::ext2 return 0; } - auto ext2_filesystem::lookup(kstd::shared_ptr const & /*parent*/, std::string_view /*name*/) + auto ext2_filesystem::lookup(kstd::shared_ptr const & /*parent*/, std::string_view name) -> kstd::shared_ptr { // TODO BA-FS26 implement ext2 directory traversal and inode loading - // return nullptr; + if (name == "dev") + { + // TODO BA-FS26 just for testing + return nullptr; + } + return kstd::make_shared(); } } // namespace filesystem::ext2 -- cgit v1.2.3 From c3e80174faa2db9e6674af995aaa95b59ec53fec Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 26 Mar 2026 21:15:40 +0100 Subject: fix resolve_path -> first traverse rootfs before jumping into the mounted root filesystem --- kernel/src/filesystem/vfs.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 368d994..40c97f8 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -139,16 +139,6 @@ namespace filesystem auto current_dentry = root_mount->root_dentry(); auto current_fs = root_mount->get_filesystem(); - // TODO BA-FS26 use while to allow stacked mounts? - if (current_dentry->has_flag(dentry::dentry_flags::dcache_mounted)) - { - auto mnt = m_mount_table.find_mount_by_dentry(current_dentry); - if (!mnt) - kapi::system::panic("[FILESYSTEM] dcache_mounted set but no covering mount found."); - current_dentry = mnt->root_dentry(); - current_fs = mnt->get_filesystem(); - } - auto path_parts = std::views::split(path, '/') | std::views::filter([](auto const & part) { return !part.empty(); }); for (auto const & part : path_parts) @@ -173,6 +163,8 @@ namespace filesystem if (next_dentry->has_flag(dentry::dentry_flags::dcache_mounted)) { auto found_mount = m_mount_table.find_mount_by_dentry(next_dentry); + if (!found_mount) + kapi::system::panic("[FILESYSTEM] dcache_mounted set but no covering mount found."); current_fs = found_mount->get_filesystem(); current_dentry = found_mount->root_dentry(); } -- cgit v1.2.3 From cb60cdebdc36dd2358fe1ce06eec197e213af491 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 24 Mar 2026 17:35:54 +0100 Subject: kapi/cpu: introduce CPU API --- kernel/CMakeLists.txt | 2 ++ kernel/include/kernel/cpu.hpp | 14 +++++++++++++ kernel/kapi/cpu.cpp | 30 ++++++++++++++++++++++++++++ kernel/src/cpu.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++ kernel/src/main.cpp | 5 +++++ 5 files changed, 97 insertions(+) create mode 100644 kernel/include/kernel/cpu.hpp create mode 100644 kernel/kapi/cpu.cpp create mode 100644 kernel/src/cpu.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 398022c..d9a5c75 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -2,6 +2,7 @@ add_executable("kernel" # Platform-independent KAPI implementation "kapi/boot_modules.cpp" "kapi/cio.cpp" + "kapi/cpu.cpp" "kapi/memory.cpp" "kapi/system.cpp" @@ -10,6 +11,7 @@ add_executable("kernel" "kstd/print.cpp" # Kernel Implementation + "src/cpu.cpp" "src/main.cpp" "src/memory/bitmap_allocator.cpp" "src/memory/block_list_allocator.cpp" diff --git a/kernel/include/kernel/cpu.hpp b/kernel/include/kernel/cpu.hpp new file mode 100644 index 0000000..d4e1ced --- /dev/null +++ b/kernel/include/kernel/cpu.hpp @@ -0,0 +1,14 @@ +#ifndef TEACHOS_KERNEL_CPU_HPP +#define TEACHOS_KERNEL_CPU_HPP + +namespace kernel::cpu +{ + + //! Initialize the kernel heap. + auto init() -> void; + + //! + +} // namespace kernel::cpu + +#endif \ No newline at end of file diff --git a/kernel/kapi/cpu.cpp b/kernel/kapi/cpu.cpp new file mode 100644 index 0000000..2089098 --- /dev/null +++ b/kernel/kapi/cpu.cpp @@ -0,0 +1,30 @@ +#include "kapi/cpu.hpp" + +namespace kapi::cpu +{ + + namespace + { + struct null_exception_handler : exception_handler + { + auto handle(exception const &) -> bool override + { + return false; + } + } static constinit default_exception_handler; + + exception_handler * current_handler = &default_exception_handler; + + } // namespace + + auto get_exception_handler() -> exception_handler & + { + return *current_handler; + } + + auto set_exception_handler(exception_handler & handler) -> void + { + current_handler = &handler; + } + +} // namespace kapi::cpu \ No newline at end of file diff --git a/kernel/src/cpu.cpp b/kernel/src/cpu.cpp new file mode 100644 index 0000000..fc460c9 --- /dev/null +++ b/kernel/src/cpu.cpp @@ -0,0 +1,46 @@ +#include "kernel/cpu.hpp" + +#include "kapi/cpu.hpp" +#include "kapi/system.hpp" + +#include + +namespace kernel::cpu +{ + + namespace + { + struct exception_handler : kapi::cpu::exception_handler + { + auto handle(kapi::cpu::exception const & context) -> bool override + { + switch (context.type) + { + case kapi::cpu::exception::type::page_fault: + return handle_page_fault(context); + default: + return false; + } + } + + private: + auto handle_page_fault(kapi::cpu::exception const & context) -> bool + { + kstd::println(kstd::print_sink::stderr, "[OS:CPU] PAGE FAULT!"); + kstd::println(kstd::print_sink::stderr, "\tFault address: {:#018x}", context.access_address); + kstd::println(kstd::print_sink::stderr, "\tPresent: {}", context.is_present); + kstd::println(kstd::print_sink::stderr, "\tWrite: {}", context.is_write_access); + kstd::println(kstd::print_sink::stderr, "\tUser: {}", context.is_user_mode); + kstd::println(kstd::print_sink::stderr, "\tRIP: {:#018x}", context.instruction_pointer); + + kapi::system::panic("Halting the system due to an unrecoverable page fault."); + } + } static constinit handler; + } // namespace + + auto init() -> void + { + kapi::cpu::set_exception_handler(handler); + } + +} // namespace kernel::cpu \ No newline at end of file diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index eb59402..0416ee9 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,8 +1,10 @@ #include "kapi/boot_modules.hpp" #include "kapi/cio.hpp" +#include "kapi/cpu.hpp" #include "kapi/memory.hpp" #include "kapi/system.hpp" +#include "kernel/cpu.hpp" #include "kernel/devices/storage/storage_management.hpp" #include "kernel/filesystem/device_file.hpp" #include "kernel/filesystem/file_descriptor_table.hpp" @@ -90,6 +92,9 @@ auto main() -> int kapi::cio::init(); kstd::println("[OS] IO subsystem initialized."); + kapi::cpu::init(); + kernel::cpu::init(); + kapi::memory::init(); kernel::memory::init_heap(kapi::memory::heap_base); kstd::println("[OS] Memory subsystem initialized."); -- cgit v1.2.3 From 42895684b631380c8aca94f82209297ac0c0e5f2 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 24 Mar 2026 17:44:21 +0100 Subject: kapi: extract interrupt enablement --- kernel/src/main.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 0416ee9..6bd168c 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -94,6 +94,7 @@ auto main() -> int kapi::cpu::init(); kernel::cpu::init(); + kapi::cpu::enable_interrupts(); kapi::memory::init(); kernel::memory::init_heap(kapi::memory::heap_base); -- cgit v1.2.3 From fd1c5a50bb35f772b8e37125188640447d4b3b2a Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 25 Mar 2026 13:24:03 +0100 Subject: kapi/cpu: enable formatting of exception types --- kernel/src/cpu.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/src/cpu.cpp b/kernel/src/cpu.cpp index fc460c9..11b6551 100644 --- a/kernel/src/cpu.cpp +++ b/kernel/src/cpu.cpp @@ -14,6 +14,7 @@ namespace kernel::cpu { auto handle(kapi::cpu::exception const & context) -> bool override { + kstd::println(kstd::print_sink::stderr, "[OS:CPU] {} @ {:#018x}", context.type, context.instruction_pointer); switch (context.type) { case kapi::cpu::exception::type::page_fault: @@ -26,12 +27,10 @@ namespace kernel::cpu private: auto handle_page_fault(kapi::cpu::exception const & context) -> bool { - kstd::println(kstd::print_sink::stderr, "[OS:CPU] PAGE FAULT!"); kstd::println(kstd::print_sink::stderr, "\tFault address: {:#018x}", context.access_address); kstd::println(kstd::print_sink::stderr, "\tPresent: {}", context.is_present); kstd::println(kstd::print_sink::stderr, "\tWrite: {}", context.is_write_access); kstd::println(kstd::print_sink::stderr, "\tUser: {}", context.is_user_mode); - kstd::println(kstd::print_sink::stderr, "\tRIP: {:#018x}", context.instruction_pointer); kapi::system::panic("Halting the system due to an unrecoverable page fault."); } -- cgit v1.2.3 From 8d06763f47e7b7c93af2a55f6bd2dbc4aa9abfa2 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 16:10:50 +0100 Subject: kapi/cpu: simplify exception handling --- kernel/CMakeLists.txt | 1 - kernel/include/kernel/cpu.hpp | 14 -------------- kernel/kapi/cpu.cpp | 35 ++++++++++++++++++--------------- kernel/src/cpu.cpp | 45 ------------------------------------------- kernel/src/main.cpp | 2 -- 5 files changed, 20 insertions(+), 77 deletions(-) delete mode 100644 kernel/include/kernel/cpu.hpp delete mode 100644 kernel/src/cpu.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index d9a5c75..9b1e2ad 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -11,7 +11,6 @@ add_executable("kernel" "kstd/print.cpp" # Kernel Implementation - "src/cpu.cpp" "src/main.cpp" "src/memory/bitmap_allocator.cpp" "src/memory/block_list_allocator.cpp" diff --git a/kernel/include/kernel/cpu.hpp b/kernel/include/kernel/cpu.hpp deleted file mode 100644 index d4e1ced..0000000 --- a/kernel/include/kernel/cpu.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef TEACHOS_KERNEL_CPU_HPP -#define TEACHOS_KERNEL_CPU_HPP - -namespace kernel::cpu -{ - - //! Initialize the kernel heap. - auto init() -> void; - - //! - -} // namespace kernel::cpu - -#endif \ No newline at end of file diff --git a/kernel/kapi/cpu.cpp b/kernel/kapi/cpu.cpp index 2089098..13de584 100644 --- a/kernel/kapi/cpu.cpp +++ b/kernel/kapi/cpu.cpp @@ -1,30 +1,35 @@ #include "kapi/cpu.hpp" +#include "kapi/system.hpp" + +#include + namespace kapi::cpu { namespace { - struct null_exception_handler : exception_handler + auto handle_page_fault(kapi::cpu::exception const & context) -> bool { - auto handle(exception const &) -> bool override - { - return false; - } - } static constinit default_exception_handler; - - exception_handler * current_handler = &default_exception_handler; + kstd::println(kstd::print_sink::stderr, "\tFault address: {:#018x}", context.access_address); + kstd::println(kstd::print_sink::stderr, "\tPresent: {}", context.is_present); + kstd::println(kstd::print_sink::stderr, "\tWrite: {}", context.is_write_access); + kstd::println(kstd::print_sink::stderr, "\tUser: {}", context.is_user_mode); + kapi::system::panic("Halting the system due to an unrecoverable page fault."); + } } // namespace - auto get_exception_handler() -> exception_handler & + auto dispatch(exception const & context) -> bool { - return *current_handler; - } - - auto set_exception_handler(exception_handler & handler) -> void - { - current_handler = &handler; + kstd::println(kstd::print_sink::stderr, "[OS:CPU] {} @ {:#018x}", context.type, context.instruction_pointer); + switch (context.type) + { + case kapi::cpu::exception::type::page_fault: + return handle_page_fault(context); + default: + return false; + } } } // namespace kapi::cpu \ No newline at end of file diff --git a/kernel/src/cpu.cpp b/kernel/src/cpu.cpp deleted file mode 100644 index 11b6551..0000000 --- a/kernel/src/cpu.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "kernel/cpu.hpp" - -#include "kapi/cpu.hpp" -#include "kapi/system.hpp" - -#include - -namespace kernel::cpu -{ - - namespace - { - struct exception_handler : kapi::cpu::exception_handler - { - auto handle(kapi::cpu::exception const & context) -> bool override - { - kstd::println(kstd::print_sink::stderr, "[OS:CPU] {} @ {:#018x}", context.type, context.instruction_pointer); - switch (context.type) - { - case kapi::cpu::exception::type::page_fault: - return handle_page_fault(context); - default: - return false; - } - } - - private: - auto handle_page_fault(kapi::cpu::exception const & context) -> bool - { - kstd::println(kstd::print_sink::stderr, "\tFault address: {:#018x}", context.access_address); - kstd::println(kstd::print_sink::stderr, "\tPresent: {}", context.is_present); - kstd::println(kstd::print_sink::stderr, "\tWrite: {}", context.is_write_access); - kstd::println(kstd::print_sink::stderr, "\tUser: {}", context.is_user_mode); - - kapi::system::panic("Halting the system due to an unrecoverable page fault."); - } - } static constinit handler; - } // namespace - - auto init() -> void - { - kapi::cpu::set_exception_handler(handler); - } - -} // namespace kernel::cpu \ No newline at end of file diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 6bd168c..45a4aae 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -4,7 +4,6 @@ #include "kapi/memory.hpp" #include "kapi/system.hpp" -#include "kernel/cpu.hpp" #include "kernel/devices/storage/storage_management.hpp" #include "kernel/filesystem/device_file.hpp" #include "kernel/filesystem/file_descriptor_table.hpp" @@ -93,7 +92,6 @@ auto main() -> int kstd::println("[OS] IO subsystem initialized."); kapi::cpu::init(); - kernel::cpu::init(); kapi::cpu::enable_interrupts(); kapi::memory::init(); -- cgit v1.2.3 From 00a77644192642e06462c11479a5c0e9bd859e9a Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 16:35:32 +0100 Subject: kapi: extract interrupts API --- kernel/src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 45a4aae..6434045 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/interrupts.hpp" #include "kapi/memory.hpp" #include "kapi/system.hpp" @@ -92,7 +93,7 @@ auto main() -> int kstd::println("[OS] IO subsystem initialized."); kapi::cpu::init(); - kapi::cpu::enable_interrupts(); + kapi::interrupts::enable(); kapi::memory::init(); kernel::memory::init_heap(kapi::memory::heap_base); -- cgit v1.2.3 From f4dc64976049761a6f56dd55d9d0b651f1e9475f Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 16:47:41 +0100 Subject: kapi: move interrupt handling to kernel --- kernel/CMakeLists.txt | 1 + kernel/kapi/interrupts.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 kernel/kapi/interrupts.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 9b1e2ad..535c441 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -3,6 +3,7 @@ add_executable("kernel" "kapi/boot_modules.cpp" "kapi/cio.cpp" "kapi/cpu.cpp" + "kapi/interrupts.cpp" "kapi/memory.cpp" "kapi/system.cpp" diff --git a/kernel/kapi/interrupts.cpp b/kernel/kapi/interrupts.cpp new file mode 100644 index 0000000..e79453a --- /dev/null +++ b/kernel/kapi/interrupts.cpp @@ -0,0 +1,45 @@ +#include "kapi/interrupts.hpp" + +#include +#include + +#include +#include + +namespace kapi::interrupts +{ + + namespace + { + auto constinit handlers = std::array, 256>{}; + } // namespace + + auto register_handler(std::uint32_t irq_number, handler & handler) -> void + { + auto & handler_list = handlers.at(irq_number); + handler_list.push_back(&handler); + } + + auto unregister_handler(std::uint32_t irq_number, handler & handler) -> void + { + static_cast(irq_number); + static_cast(handler); + kstd::println("[OS:interrupts] TODO: support erasure from vector."); + } + + auto dispatch(std::uint32_t irq_number) -> status + { + auto & handler_list = handlers.at(irq_number); + + for (auto handler : handler_list) + { + if (handler && handler->handle_interrupt(irq_number) == status::handled) + { + return status::handled; + } + } + + return status::unhandled; + } + +} // namespace kapi::interrupts \ No newline at end of file -- cgit v1.2.3 From a2834cc22b096e848448bb681ab7b517ecbe70b9 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 16:54:07 +0100 Subject: build: simplify header scanning --- kernel/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 535c441..3d3c7e2 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -56,6 +56,15 @@ set_property(TARGET "kernel" "${KERNEL_LINKER_SCRIPT}" ) +file(GLOB_RECURSE KERNEL_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "include/**.hpp") + +target_sources("kernel" PUBLIC + FILE_SET HEADERS + BASE_DIRS "include" + FILES + ${KERNEL_HEADERS} +) + target_disassemble("kernel") target_extract_debug_symbols("kernel") target_strip("kernel") -- cgit v1.2.3 From aa68f53d2502e0ea81c8e9c95e37d9847cb6cb16 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 17:15:26 +0100 Subject: arch/cpu: fix interrupt dispatch --- kernel/kapi/interrupts.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'kernel') diff --git a/kernel/kapi/interrupts.cpp b/kernel/kapi/interrupts.cpp index e79453a..27427bb 100644 --- a/kernel/kapi/interrupts.cpp +++ b/kernel/kapi/interrupts.cpp @@ -31,6 +31,12 @@ namespace kapi::interrupts { auto & handler_list = handlers.at(irq_number); + if (handler_list.empty()) + { + kstd::println(kstd::print_sink::stderr, "[OS:interrupts] No handler for IRQ{}", irq_number); + return status::unhandled; + } + for (auto handler : handler_list) { if (handler && handler->handle_interrupt(irq_number) == status::handled) -- cgit v1.2.3 From 11c6d57e013832983bcd9bb965d470bf4c282ab6 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 18:40:39 +0100 Subject: kstd/vector: implement range erase --- kernel/kapi/interrupts.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/interrupts.cpp b/kernel/kapi/interrupts.cpp index 27427bb..e172e70 100644 --- a/kernel/kapi/interrupts.cpp +++ b/kernel/kapi/interrupts.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -22,9 +23,9 @@ namespace kapi::interrupts auto unregister_handler(std::uint32_t irq_number, handler & handler) -> void { - static_cast(irq_number); - static_cast(handler); - kstd::println("[OS:interrupts] TODO: support erasure from vector."); + auto & handler_list = handlers.at(irq_number); + auto [first, last] = std::ranges::remove(handler_list, &handler); + handler_list.erase(first, last); } auto dispatch(std::uint32_t irq_number) -> status -- cgit v1.2.3 From 3070bb45b9741165d786b2c5a018ee55c1a82db8 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 27 Mar 2026 07:05:05 +0100 Subject: kernel/interrupts: switch to flat_map for dispatch --- kernel/kapi/interrupts.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/interrupts.cpp b/kernel/kapi/interrupts.cpp index e172e70..0e37bc3 100644 --- a/kernel/kapi/interrupts.cpp +++ b/kernel/kapi/interrupts.cpp @@ -1,10 +1,10 @@ #include "kapi/interrupts.hpp" +#include #include #include #include -#include #include namespace kapi::interrupts @@ -12,13 +12,20 @@ namespace kapi::interrupts namespace { - auto constinit handlers = std::array, 256>{}; + auto constinit handlers = kstd::flat_map>{}; } // namespace auto register_handler(std::uint32_t irq_number, handler & handler) -> void { - auto & handler_list = handlers.at(irq_number); - handler_list.push_back(&handler); + if (handlers.contains(irq_number)) + { + auto & handler_list = handlers.at(irq_number); + handler_list.push_back(&handler); + } + else + { + handlers.emplace(irq_number, kstd::vector{&handler}); + } } auto unregister_handler(std::uint32_t irq_number, handler & handler) -> void @@ -30,6 +37,12 @@ namespace kapi::interrupts auto dispatch(std::uint32_t irq_number) -> status { + if (!handlers.contains(irq_number)) + { + kstd::println(kstd::print_sink::stderr, "[OS:interrupts] No handler for IRQ{}", irq_number); + return status::unhandled; + } + auto & handler_list = handlers.at(irq_number); if (handler_list.empty()) -- cgit v1.2.3 From a6f93bf8df0dbfa7d19aa1168bfc8b052e41c42f Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 28 Mar 2026 17:28:32 +0100 Subject: fix vfs mount with /dev & /a and rootfs & devfs --- kernel/include/kernel/filesystem/mount.hpp | 7 +- kernel/include/kernel/filesystem/mount_table.hpp | 6 +- .../kernel/filesystem/rootfs/rootfs_filesystem.hpp | 2 - kernel/include/kernel/filesystem/vfs.hpp | 2 + kernel/src/filesystem/devfs/devfs_filesystem.cpp | 3 +- kernel/src/filesystem/mount.cpp | 11 +- kernel/src/filesystem/mount_table.cpp | 29 +++-- kernel/src/filesystem/rootfs/rootfs_filesystem.cpp | 2 +- kernel/src/filesystem/vfs.cpp | 122 +++++++++------------ 9 files changed, 93 insertions(+), 91 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index 0cd30b4..0f37687 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -5,20 +5,25 @@ #include "kernel/filesystem/filesystem.hpp" #include +#include + +#include namespace filesystem { struct mount { mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & root_dentry, - kstd::shared_ptr const & fs); + kstd::shared_ptr const & fs, std::string_view mount_path); [[nodiscard]] auto get_mount_dentry() const -> kstd::shared_ptr; [[nodiscard]] auto root_dentry() const -> kstd::shared_ptr const &; [[nodiscard]] auto get_filesystem() const -> kstd::shared_ptr const &; + [[nodiscard]] auto get_mount_path() const -> std::string_view; private: + kstd::string m_mount_path; kstd::shared_ptr m_mount_dentry; kstd::shared_ptr m_root_dentry; kstd::shared_ptr m_filesystem{}; diff --git a/kernel/include/kernel/filesystem/mount_table.hpp b/kernel/include/kernel/filesystem/mount_table.hpp index cf523c1..2cd66ea 100644 --- a/kernel/include/kernel/filesystem/mount_table.hpp +++ b/kernel/include/kernel/filesystem/mount_table.hpp @@ -1,12 +1,13 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_MOUNT_TABLE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_MOUNT_TABLE_HPP -#include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/mount.hpp" #include #include +#include + namespace filesystem { struct mount_table @@ -14,8 +15,7 @@ namespace filesystem public: void add_mount(kstd::shared_ptr); - [[nodiscard]] auto get_root_mount() const -> kstd::shared_ptr; - auto find_mount_by_dentry(kstd::shared_ptr const & dentry) -> kstd::shared_ptr; + [[nodiscard]] auto find_longest_prefix_mount(std::string_view path) const -> kstd::shared_ptr; private: kstd::vector> m_mounts; diff --git a/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp index cb07111..b3e03a9 100644 --- a/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp +++ b/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp @@ -4,14 +4,12 @@ #include "kernel/devices/device.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" -#include "kernel/filesystem/rootfs/rootfs_inode.hpp" #include #include #include #include -#include namespace filesystem::rootfs { diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index f301b7a..9bee104 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -27,6 +27,8 @@ namespace filesystem auto init_internal() -> void; [[nodiscard]] auto resolve_path(std::string_view path) -> kstd::shared_ptr; + auto do_mount_internal(std::string_view path, kstd::shared_ptr const & mount_point_dentry, + kstd::shared_ptr const & fs) -> void; mount_table m_mount_table; }; diff --git a/kernel/src/filesystem/devfs/devfs_filesystem.cpp b/kernel/src/filesystem/devfs/devfs_filesystem.cpp index cfd2d88..c4cd81a 100644 --- a/kernel/src/filesystem/devfs/devfs_filesystem.cpp +++ b/kernel/src/filesystem/devfs/devfs_filesystem.cpp @@ -13,10 +13,11 @@ namespace filesystem::devfs { - auto devfs_filesystem::mount(kstd::shared_ptr const & /*device*/) -> int + auto devfs_filesystem::mount(kstd::shared_ptr const &) -> int { m_root_inode = kstd::make_shared(); build_device_inode_table(); + return 0; } diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index d9937dc..afc07fa 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -6,14 +6,16 @@ #include "kernel/filesystem/filesystem.hpp" #include +#include #include namespace filesystem { mount::mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & root_dentry, - kstd::shared_ptr const & fs) - : m_mount_dentry(mount_dentry) + kstd::shared_ptr const & fs, std::string_view mount_path) + : m_mount_path(mount_path) + , m_mount_dentry(mount_dentry) , m_root_dentry(root_dentry) , m_filesystem(fs) { @@ -37,4 +39,9 @@ namespace filesystem { return m_root_dentry; } + + auto mount::get_mount_path() const -> std::string_view + { + return m_mount_path.view(); + } } // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 681c2b9..b9e57d4 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -1,11 +1,11 @@ #include "kernel/filesystem/mount_table.hpp" -#include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/mount.hpp" #include -#include +#include +#include namespace filesystem { @@ -14,16 +14,25 @@ namespace filesystem m_mounts.push_back(mount); } - auto mount_table::get_root_mount() const -> kstd::shared_ptr + auto mount_table::find_longest_prefix_mount(std::string_view path) const -> kstd::shared_ptr { - auto it = std::ranges::find_if(m_mounts, [](auto const & mount) { return mount->get_mount_dentry() == nullptr; }); - return it != m_mounts.end() ? *it : nullptr; - } + kstd::shared_ptr mount_with_longest_prefix = nullptr; + std::size_t best_len = 0; - auto mount_table::find_mount_by_dentry(kstd::shared_ptr const & dentry) -> kstd::shared_ptr - { - auto it = std::ranges::find_if(m_mounts, [&](auto const & mnt) { return mnt->get_mount_dentry() == dentry; }); + for (auto const & mount : m_mounts) + { + auto mp = mount->get_mount_path(); + + // /a/b/c should match /a/b but not /a/bb or /a/b/c/d, / should match everything + bool is_prefix = path.starts_with(mp) && (mp == "/" || path.size() == mp.size() || path[mp.size()] == '/'); + + if (is_prefix && mp.size() >= best_len) + { + mount_with_longest_prefix = mount; + best_len = mp.size(); + } + } - return it != m_mounts.end() ? *it : nullptr; + return mount_with_longest_prefix; } } // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp b/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp index e819fc7..22502aa 100644 --- a/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp +++ b/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp @@ -10,7 +10,7 @@ namespace filesystem::rootfs { - auto rootfs_filesystem::mount(kstd::shared_ptr const & /*device*/) -> int + auto rootfs_filesystem::mount(kstd::shared_ptr const &) -> int { auto rfs_inode = kstd::make_shared(); rfs_inode->add_child("dev"); diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 40c97f8..da7fa05 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -37,11 +37,11 @@ namespace filesystem auto vfs::init_internal() -> void { - auto virtual_fs = kstd::make_shared(); - virtual_fs->mount(nullptr); + auto root_fs = kstd::make_shared(); + root_fs->mount(nullptr); - auto virtual_root_dentry = kstd::make_shared(nullptr, virtual_fs->root_inode(), "/"); - m_mount_table.add_mount(kstd::make_shared(nullptr, virtual_root_dentry, virtual_fs)); + auto root_fs_root_dentry = kstd::make_shared(nullptr, root_fs->root_inode()); + m_mount_table.add_mount(kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, "")); auto storage_mgmt = devices::storage::storage_management::get(); if (auto boot_device = storage_mgmt.determine_boot_device()) @@ -49,24 +49,12 @@ namespace filesystem // TODO BA-FS26 detect fs type from boot device and load corresponding fs, for now just assume ext2 auto boot_root_fs = kstd::make_shared(); boot_root_fs->mount(boot_device); - - if (do_mount("/", boot_root_fs) != 0) - { - kapi::system::panic("[FILESYSTEM] failed to mount root filesystem."); - } - - auto device_fs = kstd::make_shared(); - device_fs->mount(nullptr); - - if (do_mount("/dev", device_fs) != 0) - { - kapi::system::panic("[FILESYSTEM] failed to mount devfs at /dev."); - } - } - else - { - // TODO BA-FS26 ?? what when no boot_device == no modules loaded?? + do_mount_internal("/", root_fs_root_dentry, boot_root_fs); } + + auto device_fs = kstd::make_shared(); + device_fs->mount(nullptr); + do_mount_internal("/dev", root_fs_root_dentry, device_fs); } auto vfs::get() -> vfs & @@ -107,77 +95,69 @@ namespace filesystem return -1; // TODO BA-FS26 panic or errorcode? } - if (auto mount_dentry = resolve_path(path)) + if (auto mount_point_dentry = resolve_path(path)) { - // TODO BA-FS26 check if mount point is already mounted and handle it (unmount old fs, fail, etc.) - - auto new_fs_root = kstd::make_shared(mount_dentry, filesystem->root_inode()); - auto new_mount = kstd::make_shared(mount_dentry, new_fs_root, filesystem); - m_mount_table.add_mount(new_mount); - mount_dentry->set_flag(dentry::dentry_flags::dcache_mounted); - + do_mount_internal(path, mount_point_dentry, filesystem); return 0; } return -1; } + auto vfs::do_mount_internal(std::string_view path, kstd::shared_ptr const & mount_point_dentry, + kstd::shared_ptr const & fs) -> void + { + // TODO BA-FS26 check if mount point is already mounted and handle it (unmount old fs, fail, etc.) + auto new_fs_root = kstd::make_shared(mount_point_dentry, fs->root_inode()); + auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, path); + m_mount_table.add_mount(new_mount); + } + auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr { // TODO BA-FS26 implement full path resolution semantics. // TODO BA-FS26 better path validation // TODO BA-FS26 implement a path parser (maybe in libs?) and use it here and in do_mount - if (!path.empty() && path.front() == '/') + if (path.empty() || path.front() != '/') + return nullptr; + + // TODO BA-FS26 longest match in mount_table -> jump into final fs directly + // TODO BA-FS26 performance optimization first check mounted_flag O(1) then check mount_table O(n) + + auto best_mount = m_mount_table.find_longest_prefix_mount(path); + if (!best_mount) { - auto root_mount = m_mount_table.get_root_mount(); - if (!root_mount) - { - kapi::system::panic("[FILESYSTEM] no root mount found."); - } + kapi::system::panic("[FILESYSTEM] no root mount found."); + } - auto current_dentry = root_mount->root_dentry(); - auto current_fs = root_mount->get_filesystem(); + auto current_dentry = best_mount->root_dentry(); + auto current_fs = best_mount->get_filesystem(); - auto path_parts = - std::views::split(path, '/') | std::views::filter([](auto const & part) { return !part.empty(); }); - for (auto const & part : path_parts) + std::string_view remaining = path.substr(best_mount->get_mount_path().size()); + + auto path_parts = + std::views::split(remaining, '/') | std::views::filter([](auto const & part) { return !part.empty(); }); + + for (auto const & part : path_parts) + { + std::string_view part_view{part}; + + auto next_dentry = current_dentry->find_child(part_view); + if (!next_dentry) { - std::string_view part_view{part}; - auto next_dentry = current_dentry->find_child(part_view); - - if (!next_dentry) - { - if (auto found_inode = current_fs->lookup(current_dentry->get_inode(), part_view)) - { - next_dentry = kstd::make_shared(current_dentry, found_inode, part_view); - current_dentry->add_child(next_dentry); - } - else - { - return nullptr; - } - } - - // TODO BA-FS26 use while to allow stacked mounts? - if (next_dentry->has_flag(dentry::dentry_flags::dcache_mounted)) - { - auto found_mount = m_mount_table.find_mount_by_dentry(next_dentry); - if (!found_mount) - kapi::system::panic("[FILESYSTEM] dcache_mounted set but no covering mount found."); - current_fs = found_mount->get_filesystem(); - current_dentry = found_mount->root_dentry(); - } - else - { - current_dentry = next_dentry; - } + auto found_inode = current_fs->lookup(current_dentry->get_inode(), part_view); + if (!found_inode) + return nullptr; + + next_dentry = kstd::make_shared(current_dentry, found_inode, part_view); + current_dentry->add_child(next_dentry); } - return current_dentry; + current_dentry = next_dentry; } - return nullptr; + return current_dentry; } } // namespace filesystem \ No newline at end of file -- cgit v1.2.3 From 09300635a916b67c027f8b6c1823db944f578669 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 28 Mar 2026 17:34:08 +0100 Subject: improve open and mount tests --- kernel/src/main.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 19a0992..4510240 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -111,16 +111,32 @@ auto test_file_lookup() -> void auto vfs = filesystem::vfs::get(); auto storage_mgmt = devices::storage::storage_management::get(); - vfs.open("/a/b/c"); - vfs.open("/a/d/e"); + auto ofd1 = vfs.open("/a/b/c"); + auto ofd2 = vfs.open("/dev/ram0"); + auto ofd3 = vfs.open("/a/d/e"); + if (!ofd1 || !ofd2 || !ofd3) + { + kstd::os::panic("test code failed"); + } + + if (auto ofd4 = vfs.open("/dev/xxx")) + { + kstd::os::panic("test code failed"); + } auto new_filesystem = kstd::make_shared(); auto device = storage_mgmt.device_by_major_minor(1, 16); new_filesystem->mount(device); - vfs.do_mount("/a/b", new_filesystem); - vfs.open("/a/b/c"); + if (vfs.do_mount("/a/b", new_filesystem) != 0) + { + kstd::os::panic("test code failed"); + } + auto ofd5 = vfs.open("/a/b/c"); - vfs.open("x/y/z"); + if (auto ofd6 = vfs.open("x/y/z")) + { + kstd::os::panic("test code failed"); + } } auto run_test_code() -> void -- cgit v1.2.3 From fe964c2c9d3fb29223060f99c07ae1ce4e69daae Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 28 Mar 2026 19:14:02 +0100 Subject: set flag (currently not needed) --- kernel/src/filesystem/vfs.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index da7fa05..7a90531 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -111,6 +111,7 @@ namespace filesystem auto new_fs_root = kstd::make_shared(mount_point_dentry, fs->root_inode()); auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, path); m_mount_table.add_mount(new_mount); + mount_point_dentry->set_flag(dentry::dentry_flags::dcache_mounted); } auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr -- cgit v1.2.3 From 8a9bf5a90b7f46d5c615b55a3fc418b419db4926 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 28 Mar 2026 19:14:26 +0100 Subject: improve test --- kernel/src/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 4510240..98c88f2 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -132,6 +132,10 @@ auto test_file_lookup() -> void kstd::os::panic("test code failed"); } auto ofd5 = vfs.open("/a/b/c"); + if (!ofd5) + { + kstd::os::panic("test code failed"); + } if (auto ofd6 = vfs.open("x/y/z")) { -- cgit v1.2.3 From 8c0488fb8df8742740eb8464a7ad51d71a24e416 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 29 Mar 2026 13:29:23 +0200 Subject: remove redundant ext2_file class --- kernel/CMakeLists.txt | 1 - kernel/include/kernel/filesystem/ext2/ext2_file.hpp | 15 --------------- kernel/include/kernel/filesystem/ext2/ext2_inode.hpp | 4 ---- kernel/src/filesystem/ext2/ext2_file.cpp | 20 -------------------- 4 files changed, 40 deletions(-) delete mode 100644 kernel/include/kernel/filesystem/ext2/ext2_file.hpp delete mode 100644 kernel/src/filesystem/ext2/ext2_file.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index eb762ac..1a8eb99 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -23,7 +23,6 @@ add_executable("kernel" "src/devices/storage/ram_disk/ram_disk_device.cpp" "src/filesystem/devfs/devfs_filesystem.cpp" "src/filesystem/devfs/devfs_root_inode.cpp" - "src/filesystem/ext2/ext2_file.cpp" "src/filesystem/ext2/ext2_filesystem.cpp" "src/filesystem/ext2/ext2_inode.cpp" "src/filesystem/dentry.cpp" diff --git a/kernel/include/kernel/filesystem/ext2/ext2_file.hpp b/kernel/include/kernel/filesystem/ext2/ext2_file.hpp deleted file mode 100644 index e5357e3..0000000 --- a/kernel/include/kernel/filesystem/ext2/ext2_file.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILE_HPP - -#include - -namespace filesystem::ext2 -{ - struct ext2_file - { - auto read(void * buffer, size_t offset, size_t size) const -> size_t; - auto write(void const * buffer, size_t offset, size_t size) -> size_t; - }; -} // namespace filesystem::ext2 - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp index 5f4d16a..b697c93 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp @@ -1,7 +1,6 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP -#include "kernel/filesystem/ext2/ext2_file.hpp" #include "kernel/filesystem/inode.hpp" #include @@ -16,9 +15,6 @@ namespace filesystem::ext2 auto read(void * buffer, size_t offset, size_t size) const -> size_t override; auto write(void const * buffer, size_t offset, size_t size) -> size_t override; - - private: - kstd::shared_ptr m_file; }; } // namespace filesystem::ext2 diff --git a/kernel/src/filesystem/ext2/ext2_file.cpp b/kernel/src/filesystem/ext2/ext2_file.cpp deleted file mode 100644 index 7217c77..0000000 --- a/kernel/src/filesystem/ext2/ext2_file.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "kernel/filesystem/ext2/ext2_file.hpp" - -#include "kapi/system.hpp" - -#include - -namespace filesystem::ext2 -{ - auto ext2_file::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t - { - kapi::system::panic("[FILESYSTEM] ext2_file::read is not implemented yet."); - return 0; - } - - auto ext2_file::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t - { - kapi::system::panic("[FILESYSTEM] ext2_file::write is not implemented yet."); - return 0; - } -} // namespace filesystem::ext2 -- cgit v1.2.3 From fd6e5899f6e0dc238a7944772e35d0ec6b738a38 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sun, 29 Mar 2026 16:56:30 +0200 Subject: Refactor --- kernel/include/kernel/filesystem/ext2/ext2_inode.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp index b697c93..3f6a3b0 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp @@ -11,7 +11,7 @@ namespace filesystem::ext2 { struct ext2_inode : inode { - explicit ext2_inode(); + ext2_inode(); auto read(void * buffer, size_t offset, size_t size) const -> size_t override; auto write(void const * buffer, size_t offset, size_t size) -> size_t override; -- cgit v1.2.3 From a64b9daefeee0f91fe74d6df394944b71ecc7d80 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sun, 29 Mar 2026 16:57:19 +0200 Subject: Add ext2_superblock definiton --- .../kernel/filesystem/ext2/ext2_superblock.hpp | 76 ++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 kernel/include/kernel/filesystem/ext2/ext2_superblock.hpp (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/ext2_superblock.hpp b/kernel/include/kernel/filesystem/ext2/ext2_superblock.hpp new file mode 100644 index 0000000..cd77cd4 --- /dev/null +++ b/kernel/include/kernel/filesystem/ext2/ext2_superblock.hpp @@ -0,0 +1,76 @@ +#ifndef EXT2_SUPERBLOCK_HPP +#define EXT2_SUPERBLOCK_HPP + +#include +#include + +namespace filesystem::ext2 +{ + struct ext2_superblock + { + uint32_t inodes_count; + uint32_t blocks_count; + uint32_t reserved_blocks_count; + uint32_t free_blocks_count; + uint32_t free_inodes_count; + uint32_t first_data_block; + uint32_t log_block_size; + uint32_t log_frag_size; + uint32_t blocks_per_group; + uint32_t frags_per_group; + uint32_t inodes_per_group; + uint32_t mtime; + uint32_t wtime; + uint16_t mnt_count; + uint16_t max_mnt_count; + uint16_t magic; + uint16_t state; + uint16_t errors; + uint16_t minor_rev_level; + uint32_t lastcheck; + uint32_t checkinterval; + uint32_t creator_os; + uint32_t rev_level; + uint16_t def_resuid; + uint16_t def_resgid; + + // EXT2_DYNAMIC_REV superblock only + uint32_t first_ino; + uint16_t inode_size; + uint16_t block_group_nr; + uint32_t feature_compat; + uint32_t feature_incompat; + uint32_t feature_ro_compat; + // uint8_t uuid[16]; // TODO BA-FS26 really correct? + std::array uuid; + // uint8_t volume_name[16]; // TODO BA-FS26 really correct? + std::array volume_name; + // uint8_t last_mounted[64]; // TODO BA-FS26 really correct? + std::array last_mounted; + uint32_t algorithm_usage_bitmap; + + // Performance Hints + uint8_t prealloc_blocks; + uint8_t prealloc_dir_blocks; + uint16_t padding1; + + // Journaling Support + // uint8_t journal_uuid[16]; // TODO BA-FS26 really correct? + std::array journal_uuid; + uint32_t journal_inum; + uint32_t journal_dev; + uint32_t last_orphan; + + // Directory Indexing Support + // uint32_t hash_seed[4]; // TODO BA-FS26 really correct? + std::array hash_seed; + uint8_t def_hash_version; + std::array padding2; + + // Other options + uint32_t default_mount_options; + uint32_t first_meta_bg; + std::array unused; // NOLINT(readability-magic-numbers) + }; +} // namespace filesystem::ext2 +#endif \ No newline at end of file -- cgit v1.2.3 From b03b6b851082d91ca374fed3e8a070d278eb93ab Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sun, 29 Mar 2026 17:22:55 +0200 Subject: Add ext2 block_group_descriptor, inode and linked_directory_entry definitions --- .../ext2/ext2_block_group_descriptor.hpp | 21 ++++++++++++++++++++ .../include/kernel/filesystem/ext2/ext2_inode.hpp | 23 ++++++++++++++++++++++ .../ext2/ext2_linked_directory_entry.hpp | 20 +++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 kernel/include/kernel/filesystem/ext2/ext2_block_group_descriptor.hpp create mode 100644 kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/ext2_block_group_descriptor.hpp b/kernel/include/kernel/filesystem/ext2/ext2_block_group_descriptor.hpp new file mode 100644 index 0000000..b0966da --- /dev/null +++ b/kernel/include/kernel/filesystem/ext2/ext2_block_group_descriptor.hpp @@ -0,0 +1,21 @@ +#ifndef EXT2_BLOCK_GROUP_DESCRIPTOR_HPP +#define EXT2_BLOCK_GROUP_DESCRIPTOR_HPP + +#include +#include + +namespace filesystem::ext2 +{ + struct ext2_block_group_descriptor + { + uint32_t block_bitmap; + uint32_t inode_bitmap; + uint32_t inode_table; + uint16_t free_blocks_count; + uint16_t free_inodes_count; + uint16_t used_dirs_count; + std::array padding; + std::array reserved; // NOLINT(readability-magic-numbers) + }; +} // namespace filesystem::ext2 +#endif // EXT2_BLOCK_GROUP_DESCRIPTOR_HPP \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp index 3f6a3b0..c35f84c 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp @@ -5,7 +5,9 @@ #include +#include #include +#include namespace filesystem::ext2 { @@ -15,6 +17,27 @@ namespace filesystem::ext2 auto read(void * buffer, size_t offset, size_t size) const -> size_t override; auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + + uint16_t mode; + uint16_t uid; + uint32_t size; + uint32_t atime; + uint32_t ctime; + uint32_t mtime; + uint32_t dtime; + uint16_t gid; + uint16_t links_count; + uint32_t blocks; + uint32_t flags; + uint32_t osd1; + // uint32_t block[15]; // TODO BA-FS26 really correct? + std::array block; // NOLINT(readability-magic-numbers) + uint32_t generation; + uint32_t file_acl; + uint32_t dir_acl; + uint32_t faddr; + // uint8_t osd2[12]; // TODO BA-FS26 really correct? + std::array osd2; // NOLINT(readability-magic-numbers) }; } // namespace filesystem::ext2 diff --git a/kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp b/kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp new file mode 100644 index 0000000..2a8872b --- /dev/null +++ b/kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp @@ -0,0 +1,20 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_LINKED_DIRECTORY_ENTRY_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_LINKED_DIRECTORY_ENTRY_HPP + +#include +#include + +namespace filesystem::ext2 +{ + struct ext2_linked_directory_entry + { + uint32_t inode; + uint16_t rec_len; + uint8_t name_len; + uint8_t file_type; + uint8_t pad; + std::array name; + }; +} // namespace filesystem::ext2 + +#endif \ No newline at end of file -- cgit v1.2.3 From 3888a9f90301003780fc02ce317fde29e1c20c1f Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sun, 29 Mar 2026 18:36:53 +0200 Subject: Fix name length --- kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp b/kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp index 2a8872b..3128617 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp @@ -13,7 +13,7 @@ namespace filesystem::ext2 uint8_t name_len; uint8_t file_type; uint8_t pad; - std::array name; + std::array name; // NOLINT(readability-magic-numbers) }; } // namespace filesystem::ext2 -- 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/CMakeLists.txt | 1 + .../include/kernel/devices/block_device_utils.hpp | 17 ++++ kernel/include/kernel/filesystem/device_inode.hpp | 5 - kernel/src/devices/block_device_utils.cpp | 103 +++++++++++++++++++++ kernel/src/filesystem/device_inode.cpp | 76 +-------------- kernel/src/filesystem/ext2/ext2_filesystem.cpp | 2 + 6 files changed, 126 insertions(+), 78 deletions(-) create mode 100644 kernel/include/kernel/devices/block_device_utils.hpp create mode 100644 kernel/src/devices/block_device_utils.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 1a8eb99..5f9a019 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -17,6 +17,7 @@ add_executable("kernel" "src/memory.cpp" "src/devices/device.cpp" "src/devices/block_device.cpp" + "src/devices/block_device_utils.cpp" "src/devices/storage/storage_controller.cpp" "src/devices/storage/storage_management.cpp" "src/devices/storage/ram_disk/ram_disk_controller.cpp" diff --git a/kernel/include/kernel/devices/block_device_utils.hpp b/kernel/include/kernel/devices/block_device_utils.hpp new file mode 100644 index 0000000..5ec69d1 --- /dev/null +++ b/kernel/include/kernel/devices/block_device_utils.hpp @@ -0,0 +1,17 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_UTILS_HPP +#define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_UTILS_HPP + +#include "kernel/devices/device.hpp" + +#include + +#include + +namespace devices::block_device_utils +{ + auto read(kstd::shared_ptr const & device, void * buffer, size_t offset, size_t size) -> size_t; + auto write(kstd::shared_ptr const & device, void const * buffer, size_t offset, size_t size) + -> size_t; +} // namespace devices::block_device_utils + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index 1cf08d4..0477969 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -1,7 +1,6 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP -#include "kernel/devices/block_device.hpp" #include "kernel/devices/device.hpp" #include "kernel/filesystem/inode.hpp" @@ -21,10 +20,6 @@ namespace filesystem [[nodiscard]] auto device() const -> kstd::shared_ptr const &; private: - 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(size_t offset, size_t size, void * buffer, block_op op) const -> size_t; - kstd::shared_ptr m_device; }; } // namespace filesystem 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 diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp index 64cd6e9..da062fc 100644 --- a/kernel/src/filesystem/device_inode.cpp +++ b/kernel/src/filesystem/device_inode.cpp @@ -2,7 +2,7 @@ #include "kapi/system.hpp" -#include "kernel/devices/block_device.hpp" +#include "kernel/devices/block_device_utils.hpp" #include "kernel/devices/device.hpp" #include "kernel/filesystem/inode.hpp" @@ -10,7 +10,6 @@ #include #include -#include #include namespace filesystem @@ -29,20 +28,7 @@ namespace filesystem { if (m_device->is_block_device()) { - return process_blocks(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); - } - }); + return devices::block_device_utils::read(m_device, buffer, offset, size); } else { @@ -54,21 +40,7 @@ namespace filesystem { if (m_device->is_block_device()) { - return process_blocks(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); - } - }); + return devices::block_device_utils::write(m_device, buffer, offset, size); } else { @@ -81,46 +53,4 @@ namespace filesystem return m_device; } - auto device_inode::process_blocks(size_t offset, size_t size, void * buffer, block_op op) const -> 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(m_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; - } } // namespace filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/ext2/ext2_filesystem.cpp b/kernel/src/filesystem/ext2/ext2_filesystem.cpp index 373c6a2..19f1014 100644 --- a/kernel/src/filesystem/ext2/ext2_filesystem.cpp +++ b/kernel/src/filesystem/ext2/ext2_filesystem.cpp @@ -1,5 +1,6 @@ #include "kernel/filesystem/ext2/ext2_filesystem.hpp" +#include "kernel/devices/block_device_utils.hpp" #include "kernel/devices/device.hpp" #include "kernel/filesystem/ext2/ext2_inode.hpp" #include "kernel/filesystem/filesystem.hpp" @@ -19,6 +20,7 @@ namespace filesystem::ext2 // TODO BA-FS26 implement m_root_inode = kstd::make_shared(); + // devices::block_device_utils::read(device, nullptr, 0, 0); // TODO BA-FS26 just for testing return 0; } -- cgit v1.2.3 From ea578b348f63939bb07bd669ad86d3fe1b6d5f65 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Sun, 29 Mar 2026 21:30:32 +0200 Subject: Save WIP add some definitions and helper functions --- kernel/src/filesystem/ext2/ext2_filesystem.cpp | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'kernel') diff --git a/kernel/src/filesystem/ext2/ext2_filesystem.cpp b/kernel/src/filesystem/ext2/ext2_filesystem.cpp index 19f1014..e176ade 100644 --- a/kernel/src/filesystem/ext2/ext2_filesystem.cpp +++ b/kernel/src/filesystem/ext2/ext2_filesystem.cpp @@ -3,15 +3,48 @@ #include "kernel/devices/block_device_utils.hpp" #include "kernel/devices/device.hpp" #include "kernel/filesystem/ext2/ext2_inode.hpp" +#include "kernel/filesystem/ext2/ext2_superblock.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" #include +#include +#include #include namespace filesystem::ext2 { + namespace + { + constexpr size_t SUPERBLOCK_OFFSET = 1024; + constexpr uint16_t EXT2_MAGIC = 0xEF53; + + // Mode bits + constexpr uint16_t S_IFMT = 0xF000; + constexpr uint16_t S_IFREG = 0x8000; + constexpr uint16_t S_IFDIR = 0x4000; + + auto S_ISREG(uint16_t mode) -> bool + { + return (mode & S_IFMT) == S_IFREG; + } + auto S_ISDIR(uint16_t mode) -> bool + { + return (mode & S_IFMT) == S_IFDIR; + } + + auto get_block_size(ext2_superblock const & superblock) -> size_t + { + return 1024U << superblock.log_block_size; + } + + auto get_inode_size(ext2_superblock const & superblock) -> size_t + { + return superblock.rev_level == 0 ? 128 : superblock.inode_size; + } + } // namespace + auto ext2_filesystem::mount(kstd::shared_ptr const & device) -> int { filesystem::mount(device); // TODO BA-FS26 error handling? -- cgit v1.2.3 From 7ad07a735759dc93b668ec92896f57c0c0df0025 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Mon, 30 Mar 2026 19:26:48 +0200 Subject: Fix linter warnings --- kernel/src/filesystem/ext2/ext2_filesystem.cpp | 44 +++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/ext2/ext2_filesystem.cpp b/kernel/src/filesystem/ext2/ext2_filesystem.cpp index e176ade..ea6fe0d 100644 --- a/kernel/src/filesystem/ext2/ext2_filesystem.cpp +++ b/kernel/src/filesystem/ext2/ext2_filesystem.cpp @@ -17,32 +17,32 @@ namespace filesystem::ext2 { namespace { - constexpr size_t SUPERBLOCK_OFFSET = 1024; - constexpr uint16_t EXT2_MAGIC = 0xEF53; + // constexpr size_t SUPERBLOCK_OFFSET = 1024; + // constexpr uint16_t EXT2_MAGIC = 0xEF53; - // Mode bits - constexpr uint16_t S_IFMT = 0xF000; - constexpr uint16_t S_IFREG = 0x8000; - constexpr uint16_t S_IFDIR = 0x4000; + // // Mode bits + // constexpr uint16_t S_IFMT = 0xF000; + // constexpr uint16_t S_IFREG = 0x8000; + // constexpr uint16_t S_IFDIR = 0x4000; - auto S_ISREG(uint16_t mode) -> bool - { - return (mode & S_IFMT) == S_IFREG; - } - auto S_ISDIR(uint16_t mode) -> bool - { - return (mode & S_IFMT) == S_IFDIR; - } + // auto S_ISREG(uint16_t mode) -> bool + // { + // return (mode & S_IFMT) == S_IFREG; + // } + // auto S_ISDIR(uint16_t mode) -> bool + // { + // return (mode & S_IFMT) == S_IFDIR; + // } - auto get_block_size(ext2_superblock const & superblock) -> size_t - { - return 1024U << superblock.log_block_size; - } + // auto get_block_size(ext2_superblock const & superblock) -> size_t + // { + // return 1024U << superblock.log_block_size; + // } - auto get_inode_size(ext2_superblock const & superblock) -> size_t - { - return superblock.rev_level == 0 ? 128 : superblock.inode_size; - } + // auto get_inode_size(ext2_superblock const & superblock) -> size_t + // { + // return superblock.rev_level == 0 ? 128 : superblock.inode_size; + // } } // namespace auto ext2_filesystem::mount(kstd::shared_ptr const & device) -> int -- 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/include/kernel/devices/block_device.hpp | 4 ++-- .../include/kernel/devices/block_device_utils.hpp | 4 ++-- kernel/include/kernel/devices/device.hpp | 4 ++-- .../storage/ram_disk/ram_disk_controller.hpp | 4 ++-- .../devices/storage/ram_disk/ram_disk_device.hpp | 4 ++-- .../kernel/devices/storage/storage_controller.hpp | 4 ++-- .../kernel/devices/storage/storage_management.hpp | 4 ++-- kernel/include/kernel/filesystem/dentry.hpp | 4 ++-- .../kernel/filesystem/devfs/devfs_filesystem.hpp | 4 ++-- .../kernel/filesystem/devfs/devfs_root_inode.hpp | 4 ++-- kernel/include/kernel/filesystem/device_inode.hpp | 4 ++-- .../ext2/ext2_block_group_descriptor.hpp | 4 ++-- .../kernel/filesystem/ext2/ext2_filesystem.hpp | 4 ++-- .../include/kernel/filesystem/ext2/ext2_inode.hpp | 4 ++-- .../ext2/ext2_linked_directory_entry.hpp | 4 ++-- .../kernel/filesystem/ext2/ext2_superblock.hpp | 4 ++-- .../kernel/filesystem/file_descriptor_table.hpp | 4 ++-- kernel/include/kernel/filesystem/filesystem.hpp | 4 ++-- kernel/include/kernel/filesystem/inode.hpp | 4 ++-- kernel/include/kernel/filesystem/mount.hpp | 4 ++-- kernel/include/kernel/filesystem/mount_table.hpp | 4 ++-- .../kernel/filesystem/open_file_description.hpp | 4 ++-- .../kernel/filesystem/rootfs/rootfs_filesystem.hpp | 4 ++-- .../kernel/filesystem/rootfs/rootfs_inode.hpp | 4 ++-- kernel/include/kernel/filesystem/vfs.hpp | 4 ++-- kernel/include/kernel/memory/heap_allocator.hpp | 2 -- kernel/src/devices/block_device.cpp | 4 ++-- kernel/src/devices/block_device_utils.cpp | 4 ++-- kernel/src/devices/device.cpp | 4 ++-- .../storage/ram_disk/ram_disk_controller.cpp | 4 ++-- .../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 ++-- kernel/src/filesystem/dentry.cpp | 4 ++-- kernel/src/filesystem/devfs/devfs_filesystem.cpp | 4 ++-- kernel/src/filesystem/devfs/devfs_root_inode.cpp | 4 ++-- kernel/src/filesystem/device_inode.cpp | 4 ++-- kernel/src/filesystem/ext2/ext2_filesystem.cpp | 4 ++-- kernel/src/filesystem/ext2/ext2_inode.cpp | 4 ++-- kernel/src/filesystem/file_descriptor_table.cpp | 4 ++-- kernel/src/filesystem/filesystem.cpp | 4 ++-- kernel/src/filesystem/inode.cpp | 4 ++-- kernel/src/filesystem/mount.cpp | 4 ++-- kernel/src/filesystem/mount_table.cpp | 4 ++-- kernel/src/filesystem/open_file_description.cpp | 4 ++-- kernel/src/filesystem/rootfs/rootfs_filesystem.cpp | 4 ++-- kernel/src/filesystem/rootfs/rootfs_inode.cpp | 4 ++-- kernel/src/filesystem/vfs.cpp | 4 ++-- kernel/src/main.cpp | 28 +++++++++++----------- 49 files changed, 108 insertions(+), 110 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/devices/block_device.hpp b/kernel/include/kernel/devices/block_device.hpp index e2026dd..619b815 100644 --- a/kernel/include/kernel/devices/block_device.hpp +++ b/kernel/include/kernel/devices/block_device.hpp @@ -7,7 +7,7 @@ #include -namespace devices +namespace kernel::devices { /** * @brief Base interface for block-addressable devices. @@ -92,6 +92,6 @@ namespace devices size_t m_block_size; }; -} // namespace devices +} // namespace kernel::devices #endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/block_device_utils.hpp b/kernel/include/kernel/devices/block_device_utils.hpp index 5ec69d1..bb49d04 100644 --- a/kernel/include/kernel/devices/block_device_utils.hpp +++ b/kernel/include/kernel/devices/block_device_utils.hpp @@ -7,11 +7,11 @@ #include -namespace devices::block_device_utils +namespace kernel::devices::block_device_utils { auto read(kstd::shared_ptr const & device, void * buffer, size_t offset, size_t size) -> size_t; auto write(kstd::shared_ptr const & device, void const * buffer, size_t offset, size_t size) -> size_t; -} // namespace devices::block_device_utils +} // namespace kernel::devices::block_device_utils #endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/device.hpp b/kernel/include/kernel/devices/device.hpp index 66cb7f8..67fa5ad 100644 --- a/kernel/include/kernel/devices/device.hpp +++ b/kernel/include/kernel/devices/device.hpp @@ -5,7 +5,7 @@ #include -namespace devices +namespace kernel::devices { /** * @brief Base device identified by a major, minor number and name. @@ -57,6 +57,6 @@ namespace devices size_t m_minor; kstd::string m_name; }; -} // namespace devices +} // namespace kernel::devices #endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/storage/ram_disk/ram_disk_controller.hpp b/kernel/include/kernel/devices/storage/ram_disk/ram_disk_controller.hpp index 6f022e3..40763bf 100644 --- a/kernel/include/kernel/devices/storage/ram_disk/ram_disk_controller.hpp +++ b/kernel/include/kernel/devices/storage/ram_disk/ram_disk_controller.hpp @@ -5,7 +5,7 @@ #include "kernel/devices/storage/storage_controller.hpp" -namespace devices::storage::ram_disk +namespace kernel::devices::storage::ram_disk { /** * @brief Storage controller that exposes boot modules as RAM-disk devices. @@ -26,6 +26,6 @@ namespace devices::storage::ram_disk private: kapi::boot_modules::boot_module_registry const * m_boot_module_registry; }; -} // namespace devices::storage::ram_disk +} // namespace kernel::devices::storage::ram_disk #endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/storage/ram_disk/ram_disk_device.hpp b/kernel/include/kernel/devices/storage/ram_disk/ram_disk_device.hpp index c323f4b..75ff50b 100644 --- a/kernel/include/kernel/devices/storage/ram_disk/ram_disk_device.hpp +++ b/kernel/include/kernel/devices/storage/ram_disk/ram_disk_device.hpp @@ -7,7 +7,7 @@ #include -namespace devices::storage::ram_disk +namespace kernel::devices::storage::ram_disk { /** * @brief Block device for a boot module. @@ -47,6 +47,6 @@ namespace devices::storage::ram_disk kapi::boot_modules::boot_module m_boot_module{}; }; -} // namespace devices::storage::ram_disk +} // namespace kernel::devices::storage::ram_disk #endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/storage/storage_controller.hpp b/kernel/include/kernel/devices/storage/storage_controller.hpp index 58585fa..5639160 100644 --- a/kernel/include/kernel/devices/storage/storage_controller.hpp +++ b/kernel/include/kernel/devices/storage/storage_controller.hpp @@ -8,7 +8,7 @@ #include -namespace devices::storage +namespace kernel::devices::storage { /** * @brief Base interface for storage controllers. @@ -66,6 +66,6 @@ namespace devices::storage size_t m_minors_per_device{}; kstd::vector> m_devices{}; }; -} // namespace devices::storage +} // namespace kernel::devices::storage #endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/storage/storage_management.hpp b/kernel/include/kernel/devices/storage/storage_management.hpp index 413820e..b6d1318 100644 --- a/kernel/include/kernel/devices/storage/storage_management.hpp +++ b/kernel/include/kernel/devices/storage/storage_management.hpp @@ -9,7 +9,7 @@ #include -namespace devices::storage +namespace kernel::devices::storage { /** * @brief Global storage subsystem manager. @@ -72,6 +72,6 @@ namespace devices::storage kstd::vector> m_controllers{}; }; -} // namespace devices::storage +} // namespace kernel::devices::storage #endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index c28246f..fc85a7d 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -10,7 +10,7 @@ #include #include -namespace filesystem +namespace kernel::filesystem { struct dentry { @@ -38,6 +38,6 @@ namespace filesystem kstd::shared_ptr m_inode; uint32_t m_flags{0}; }; -} // namespace filesystem +} // namespace kernel::filesystem #endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp b/kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp index 5559c2a..2330915 100644 --- a/kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp +++ b/kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp @@ -10,7 +10,7 @@ #include -namespace filesystem::devfs +namespace kernel::filesystem::devfs { struct devfs_filesystem : filesystem { @@ -20,6 +20,6 @@ namespace filesystem::devfs private: auto build_device_inode_table() -> void; }; -} // namespace filesystem::devfs +} // namespace kernel::filesystem::devfs #endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp b/kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp index b1d37ab..206fc13 100644 --- a/kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp +++ b/kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp @@ -5,7 +5,7 @@ #include -namespace filesystem::devfs +namespace kernel::filesystem::devfs { struct devfs_root_inode : inode { @@ -14,6 +14,6 @@ namespace filesystem::devfs auto read(void * buffer, size_t offset, size_t size) const -> size_t override; auto write(void const * buffer, size_t offset, size_t size) -> size_t override; }; -} // namespace filesystem::devfs +} // namespace kernel::filesystem::devfs #endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index 0477969..7f044b0 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -8,7 +8,7 @@ #include -namespace filesystem +namespace kernel::filesystem { struct device_inode : inode { @@ -22,6 +22,6 @@ namespace filesystem private: kstd::shared_ptr m_device; }; -} // namespace filesystem +} // namespace kernel::filesystem #endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/ext2_block_group_descriptor.hpp b/kernel/include/kernel/filesystem/ext2/ext2_block_group_descriptor.hpp index b0966da..0de7428 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_block_group_descriptor.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_block_group_descriptor.hpp @@ -4,7 +4,7 @@ #include #include -namespace filesystem::ext2 +namespace kernel::filesystem::ext2 { struct ext2_block_group_descriptor { @@ -17,5 +17,5 @@ namespace filesystem::ext2 std::array padding; std::array reserved; // NOLINT(readability-magic-numbers) }; -} // namespace filesystem::ext2 +} // namespace kernel::filesystem::ext2 #endif // EXT2_BLOCK_GROUP_DESCRIPTOR_HPP \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp b/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp index 1445e5a..753aea1 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp @@ -9,7 +9,7 @@ #include -namespace filesystem::ext2 +namespace kernel::filesystem::ext2 { struct ext2_filesystem : filesystem { @@ -18,6 +18,6 @@ namespace filesystem::ext2 private: }; -} // namespace filesystem::ext2 +} // namespace kernel::filesystem::ext2 #endif diff --git a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp index c35f84c..2054227 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp @@ -9,7 +9,7 @@ #include #include -namespace filesystem::ext2 +namespace kernel::filesystem::ext2 { struct ext2_inode : inode { @@ -39,6 +39,6 @@ namespace filesystem::ext2 // uint8_t osd2[12]; // TODO BA-FS26 really correct? std::array osd2; // NOLINT(readability-magic-numbers) }; -} // namespace filesystem::ext2 +} // namespace kernel::filesystem::ext2 #endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp b/kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp index 3128617..84e47e8 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp @@ -4,7 +4,7 @@ #include #include -namespace filesystem::ext2 +namespace kernel::filesystem::ext2 { struct ext2_linked_directory_entry { @@ -15,6 +15,6 @@ namespace filesystem::ext2 uint8_t pad; std::array name; // NOLINT(readability-magic-numbers) }; -} // namespace filesystem::ext2 +} // namespace kernel::filesystem::ext2 #endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/ext2_superblock.hpp b/kernel/include/kernel/filesystem/ext2/ext2_superblock.hpp index cd77cd4..aa93e68 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_superblock.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_superblock.hpp @@ -4,7 +4,7 @@ #include #include -namespace filesystem::ext2 +namespace kernel::filesystem::ext2 { struct ext2_superblock { @@ -72,5 +72,5 @@ namespace filesystem::ext2 uint32_t first_meta_bg; std::array unused; // NOLINT(readability-magic-numbers) }; -} // namespace filesystem::ext2 +} // namespace kernel::filesystem::ext2 #endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/filesystem/file_descriptor_table.hpp index bc6fb24..91e2960 100644 --- a/kernel/include/kernel/filesystem/file_descriptor_table.hpp +++ b/kernel/include/kernel/filesystem/file_descriptor_table.hpp @@ -6,7 +6,7 @@ #include #include -namespace filesystem +namespace kernel::filesystem { struct file_descriptor_table { @@ -24,6 +24,6 @@ namespace filesystem kstd::vector> m_open_files{}; }; -} // namespace filesystem +} // namespace kernel::filesystem #endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index e069ced..c50a86c 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -9,7 +9,7 @@ #include -namespace filesystem +namespace kernel::filesystem { struct filesystem { @@ -26,6 +26,6 @@ namespace filesystem kstd::vector> m_inodes{}; }; -} // namespace filesystem +} // namespace kernel::filesystem #endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp index 6d8f0d4..d97b5ab 100644 --- a/kernel/include/kernel/filesystem/inode.hpp +++ b/kernel/include/kernel/filesystem/inode.hpp @@ -3,7 +3,7 @@ #include -namespace filesystem +namespace kernel::filesystem { struct inode { @@ -28,6 +28,6 @@ namespace filesystem private: inode_kind m_kind{inode_kind::regular}; }; -} // namespace filesystem +} // namespace kernel::filesystem #endif diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index 0f37687..a054750 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -9,7 +9,7 @@ #include -namespace filesystem +namespace kernel::filesystem { struct mount { @@ -28,6 +28,6 @@ namespace filesystem kstd::shared_ptr m_root_dentry; kstd::shared_ptr m_filesystem{}; }; -} // namespace filesystem +} // namespace kernel::filesystem #endif diff --git a/kernel/include/kernel/filesystem/mount_table.hpp b/kernel/include/kernel/filesystem/mount_table.hpp index 2cd66ea..6dc2218 100644 --- a/kernel/include/kernel/filesystem/mount_table.hpp +++ b/kernel/include/kernel/filesystem/mount_table.hpp @@ -8,7 +8,7 @@ #include -namespace filesystem +namespace kernel::filesystem { struct mount_table { @@ -20,6 +20,6 @@ namespace filesystem private: kstd::vector> m_mounts; }; -} // namespace filesystem +} // namespace kernel::filesystem #endif diff --git a/kernel/include/kernel/filesystem/open_file_description.hpp b/kernel/include/kernel/filesystem/open_file_description.hpp index e17f9fe..45719cf 100644 --- a/kernel/include/kernel/filesystem/open_file_description.hpp +++ b/kernel/include/kernel/filesystem/open_file_description.hpp @@ -7,7 +7,7 @@ #include -namespace filesystem +namespace kernel::filesystem { struct open_file_description { @@ -23,6 +23,6 @@ namespace filesystem size_t m_offset; }; -} // namespace filesystem +} // namespace kernel::filesystem #endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp index b3e03a9..b91f728 100644 --- a/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp +++ b/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp @@ -11,13 +11,13 @@ #include -namespace filesystem::rootfs +namespace kernel::filesystem::rootfs { struct rootfs_filesystem : filesystem { auto mount(kstd::shared_ptr const & device) -> int override; auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; }; -} // namespace filesystem::rootfs +} // namespace kernel::filesystem::rootfs #endif diff --git a/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp b/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp index de4fb7c..26e7f88 100644 --- a/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp +++ b/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp @@ -11,7 +11,7 @@ #include #include -namespace filesystem::rootfs +namespace kernel::filesystem::rootfs { struct rootfs_inode : inode { @@ -26,6 +26,6 @@ namespace filesystem::rootfs private: kstd::vector>> m_children; }; -} // namespace filesystem::rootfs +} // namespace kernel::filesystem::rootfs #endif diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 9bee104..5823a83 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -10,7 +10,7 @@ #include -namespace filesystem +namespace kernel::filesystem { struct vfs { @@ -32,6 +32,6 @@ namespace filesystem mount_table m_mount_table; }; -} // namespace filesystem +} // namespace kernel::filesystem #endif \ No newline at end of file diff --git a/kernel/include/kernel/memory/heap_allocator.hpp b/kernel/include/kernel/memory/heap_allocator.hpp index 55de7e4..fd39bef 100644 --- a/kernel/include/kernel/memory/heap_allocator.hpp +++ b/kernel/include/kernel/memory/heap_allocator.hpp @@ -3,8 +3,6 @@ #include -#include - namespace kernel::memory { 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 diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index 76949f2..2f99e91 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -10,7 +10,7 @@ #include #include -namespace filesystem +namespace kernel::filesystem { dentry::dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & node, std::string_view name) : m_name(name) @@ -58,4 +58,4 @@ namespace filesystem { return (m_flags & static_cast(flag)) != 0; } -} // namespace filesystem \ No newline at end of file +} // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/devfs/devfs_filesystem.cpp b/kernel/src/filesystem/devfs/devfs_filesystem.cpp index c4cd81a..df977b8 100644 --- a/kernel/src/filesystem/devfs/devfs_filesystem.cpp +++ b/kernel/src/filesystem/devfs/devfs_filesystem.cpp @@ -11,7 +11,7 @@ #include #include -namespace filesystem::devfs +namespace kernel::filesystem::devfs { auto devfs_filesystem::mount(kstd::shared_ptr const &) -> int { @@ -55,4 +55,4 @@ namespace filesystem::devfs [&](auto const & device) { m_inodes.push_back(kstd::make_shared(device)); }); }); } -} // namespace filesystem::devfs \ No newline at end of file +} // namespace kernel::filesystem::devfs \ No newline at end of file diff --git a/kernel/src/filesystem/devfs/devfs_root_inode.cpp b/kernel/src/filesystem/devfs/devfs_root_inode.cpp index 53441b0..a7308dc 100644 --- a/kernel/src/filesystem/devfs/devfs_root_inode.cpp +++ b/kernel/src/filesystem/devfs/devfs_root_inode.cpp @@ -4,7 +4,7 @@ #include -namespace filesystem::devfs +namespace kernel::filesystem::devfs { devfs_root_inode::devfs_root_inode() : inode(inode_kind::directory) @@ -19,4 +19,4 @@ namespace filesystem::devfs { return 0; } -} // namespace filesystem::devfs \ No newline at end of file +} // namespace kernel::filesystem::devfs \ No newline at end of file diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp index da062fc..d574d8f 100644 --- a/kernel/src/filesystem/device_inode.cpp +++ b/kernel/src/filesystem/device_inode.cpp @@ -12,7 +12,7 @@ #include -namespace filesystem +namespace kernel::filesystem { device_inode::device_inode(kstd::shared_ptr const & device) : inode(inode_kind::device) @@ -53,4 +53,4 @@ namespace filesystem return m_device; } -} // namespace filesystem \ No newline at end of file +} // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/ext2/ext2_filesystem.cpp b/kernel/src/filesystem/ext2/ext2_filesystem.cpp index ea6fe0d..036b80e 100644 --- a/kernel/src/filesystem/ext2/ext2_filesystem.cpp +++ b/kernel/src/filesystem/ext2/ext2_filesystem.cpp @@ -13,7 +13,7 @@ #include #include -namespace filesystem::ext2 +namespace kernel::filesystem::ext2 { namespace { @@ -69,4 +69,4 @@ namespace filesystem::ext2 return kstd::make_shared(); } -} // namespace filesystem::ext2 +} // namespace kernel::filesystem::ext2 diff --git a/kernel/src/filesystem/ext2/ext2_inode.cpp b/kernel/src/filesystem/ext2/ext2_inode.cpp index 3cc0fb2..142502e 100644 --- a/kernel/src/filesystem/ext2/ext2_inode.cpp +++ b/kernel/src/filesystem/ext2/ext2_inode.cpp @@ -4,7 +4,7 @@ #include -namespace filesystem::ext2 +namespace kernel::filesystem::ext2 { ext2_inode::ext2_inode() : inode(inode_kind::regular) @@ -21,4 +21,4 @@ namespace filesystem::ext2 // TODO BA-FS26 implement return 0; } -} // namespace filesystem::ext2 \ No newline at end of file +} // namespace kernel::filesystem::ext2 \ No newline at end of file diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp index 6eb3845..287aea2 100644 --- a/kernel/src/filesystem/file_descriptor_table.cpp +++ b/kernel/src/filesystem/file_descriptor_table.cpp @@ -10,7 +10,7 @@ #include #include -namespace filesystem +namespace kernel::filesystem { namespace { @@ -87,4 +87,4 @@ namespace filesystem m_open_files.at(index) = nullptr; } -} // namespace filesystem \ No newline at end of file +} // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index 0e33d95..c891d00 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -5,7 +5,7 @@ #include -namespace filesystem +namespace kernel::filesystem { auto filesystem::mount(kstd::shared_ptr const & device) -> int { @@ -21,4 +21,4 @@ namespace filesystem { return m_root_inode; } -} // namespace filesystem \ No newline at end of file +} // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/inode.cpp b/kernel/src/filesystem/inode.cpp index de3282f..1cbead8 100644 --- a/kernel/src/filesystem/inode.cpp +++ b/kernel/src/filesystem/inode.cpp @@ -1,6 +1,6 @@ #include "kernel/filesystem/inode.hpp" -namespace filesystem +namespace kernel::filesystem { inode::inode(inode_kind kind) : m_kind(kind) @@ -20,4 +20,4 @@ namespace filesystem { return m_kind == inode_kind::device; } -} // namespace filesystem \ No newline at end of file +} // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index afc07fa..f9e709c 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -10,7 +10,7 @@ #include -namespace filesystem +namespace kernel::filesystem { mount::mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & root_dentry, kstd::shared_ptr const & fs, std::string_view mount_path) @@ -44,4 +44,4 @@ namespace filesystem { return m_mount_path.view(); } -} // namespace filesystem \ No newline at end of file +} // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index b9e57d4..737434e 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -7,7 +7,7 @@ #include #include -namespace filesystem +namespace kernel::filesystem { void mount_table::add_mount(kstd::shared_ptr mount) { @@ -35,4 +35,4 @@ namespace filesystem return mount_with_longest_prefix; } -} // namespace filesystem \ No newline at end of file +} // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/open_file_description.cpp b/kernel/src/filesystem/open_file_description.cpp index 93c38ac..8c04225 100644 --- a/kernel/src/filesystem/open_file_description.cpp +++ b/kernel/src/filesystem/open_file_description.cpp @@ -7,7 +7,7 @@ #include -namespace filesystem +namespace kernel::filesystem { open_file_description::open_file_description(kstd::shared_ptr const & inode) : m_inode(inode) @@ -32,4 +32,4 @@ namespace filesystem m_offset += written_bytes; return written_bytes; } -} // namespace filesystem \ No newline at end of file +} // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp b/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp index 22502aa..804e211 100644 --- a/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp +++ b/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp @@ -8,7 +8,7 @@ #include -namespace filesystem::rootfs +namespace kernel::filesystem::rootfs { auto rootfs_filesystem::mount(kstd::shared_ptr const &) -> int { @@ -26,4 +26,4 @@ namespace filesystem::rootfs return rfs_inode->lookup_child(name); return nullptr; } -} // namespace filesystem::rootfs +} // namespace kernel::filesystem::rootfs diff --git a/kernel/src/filesystem/rootfs/rootfs_inode.cpp b/kernel/src/filesystem/rootfs/rootfs_inode.cpp index 9bbfbce..f44f06c 100644 --- a/kernel/src/filesystem/rootfs/rootfs_inode.cpp +++ b/kernel/src/filesystem/rootfs/rootfs_inode.cpp @@ -10,7 +10,7 @@ #include #include -namespace filesystem::rootfs +namespace kernel::filesystem::rootfs { rootfs_inode::rootfs_inode() : inode(inode_kind::directory) @@ -36,4 +36,4 @@ namespace filesystem::rootfs auto it = std::ranges::find_if(m_children, [&](auto const & pair) { return pair.first == name; }); return (it != m_children.end()) ? it->second : nullptr; } -} // namespace filesystem::rootfs +} // namespace kernel::filesystem::rootfs diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 7a90531..2dbdb12 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -17,7 +17,7 @@ #include #include -namespace filesystem +namespace kernel::filesystem { namespace { @@ -161,4 +161,4 @@ namespace filesystem return current_dentry; } -} // namespace filesystem \ No newline at end of file +} // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index bb6d57d..2dd9fd9 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -24,7 +24,7 @@ auto test_device_names() -> void { - auto storage_mgmt = devices::storage::storage_management::get(); + auto storage_mgmt = kernel::devices::storage::storage_management::get(); std::ranges::for_each(storage_mgmt.all_controllers(), [](auto const & controller) { std::ranges::for_each(controller->all_devices(), [](auto const & device) { kstd::println("{}", device->name().view()); }); @@ -34,13 +34,13 @@ auto test_device_names() -> void auto test_file_description_manually() -> void { // setup - auto fd_table = filesystem::file_descriptor_table::get(); - auto storage_mgmt = devices::storage::storage_management::get(); + auto fd_table = kernel::filesystem::file_descriptor_table::get(); + auto storage_mgmt = kernel::devices::storage::storage_management::get(); auto device = storage_mgmt.device_by_major_minor(1, 0); - auto dev_node = kstd::make_shared(device); + auto dev_node = kstd::make_shared(device); - auto ofd = kstd::make_shared(dev_node); + auto ofd = kstd::make_shared(dev_node); auto fd_index = fd_table.add_file(ofd); // use: read two bytes and write two again @@ -66,7 +66,7 @@ auto test_file_description_manually() -> void fd_table.remove_file(fd_index); // use: read four bytes again -> two old bytes two new bytes - auto ofd1 = kstd::make_shared(dev_node); + auto ofd1 = kstd::make_shared(dev_node); fd_index = fd_table.add_file(ofd1); auto fd1 = fd_table.get_file(fd_index); @@ -85,14 +85,14 @@ auto test_device_with_vfs() -> void { // TODO BA-FS26 - auto vfs = filesystem::vfs::get(); + auto vfs = kernel::filesystem::vfs::get(); auto ofd = vfs.open("/dev/ram0"); if (!ofd) { kstd::os::panic("test code failed"); } - auto fd_table = filesystem::file_descriptor_table::get(); + auto fd_table = kernel::filesystem::file_descriptor_table::get(); auto fd = fd_table.add_file(ofd); kstd::vector buffer{2}; auto file = fd_table.get_file(fd); @@ -110,8 +110,8 @@ auto test_file_lookup() -> void { // TODO BA-FS26 implement a more complete test with multiple files and directories and mounts etc. - auto vfs = filesystem::vfs::get(); - auto storage_mgmt = devices::storage::storage_management::get(); + auto vfs = kernel::filesystem::vfs::get(); + auto storage_mgmt = kernel::devices::storage::storage_management::get(); auto ofd1 = vfs.open("/a/b/c"); auto ofd2 = vfs.open("/dev/ram0"); @@ -126,7 +126,7 @@ auto test_file_lookup() -> void kstd::os::panic("test code failed"); } - auto new_filesystem = kstd::make_shared(); + auto new_filesystem = kstd::make_shared(); auto device = storage_mgmt.device_by_major_minor(1, 16); new_filesystem->mount(device); if (vfs.do_mount("/a/b", new_filesystem) != 0) @@ -182,13 +182,13 @@ auto main() -> int kapi::boot_modules::init(); kstd::println("[OS] Boot module registry initialized."); - devices::storage::storage_management::init(); + kernel::devices::storage::storage_management::init(); kstd::println("[OS] Storage management initialized."); - filesystem::file_descriptor_table::init(); + kernel::filesystem::file_descriptor_table::init(); kstd::println("[OS] Global file descriptor table initialized."); - filesystem::vfs::init(); + kernel::filesystem::vfs::init(); kstd::println("[OS] Virtual filesystem initialized."); run_test_code(); -- cgit v1.2.3 From 55e37a219fc953d1675bc2edb8573c6d47df7647 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Mon, 30 Mar 2026 21:23:02 +0200 Subject: Rename ext2 filesystem files --- kernel/CMakeLists.txt | 4 +- .../filesystem/ext2/block_group_descriptor.hpp | 21 ++++++ .../ext2/ext2_block_group_descriptor.hpp | 21 ------ .../kernel/filesystem/ext2/ext2_filesystem.hpp | 23 ------- .../include/kernel/filesystem/ext2/ext2_inode.hpp | 44 ------------- .../ext2/ext2_linked_directory_entry.hpp | 20 ------ .../kernel/filesystem/ext2/ext2_superblock.hpp | 76 ---------------------- .../include/kernel/filesystem/ext2/filesystem.hpp | 22 +++++++ kernel/include/kernel/filesystem/ext2/inode.hpp | 44 +++++++++++++ .../filesystem/ext2/linked_directory_entry.hpp | 20 ++++++ .../include/kernel/filesystem/ext2/superblock.hpp | 76 ++++++++++++++++++++++ kernel/src/filesystem/ext2/ext2_filesystem.cpp | 72 -------------------- kernel/src/filesystem/ext2/ext2_inode.cpp | 24 ------- kernel/src/filesystem/ext2/filesystem.cpp | 72 ++++++++++++++++++++ kernel/src/filesystem/ext2/inode.cpp | 24 +++++++ kernel/src/filesystem/vfs.cpp | 4 +- kernel/src/main.cpp | 4 +- 17 files changed, 285 insertions(+), 286 deletions(-) create mode 100644 kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp delete mode 100644 kernel/include/kernel/filesystem/ext2/ext2_block_group_descriptor.hpp delete mode 100644 kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp delete mode 100644 kernel/include/kernel/filesystem/ext2/ext2_inode.hpp delete mode 100644 kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp delete mode 100644 kernel/include/kernel/filesystem/ext2/ext2_superblock.hpp create mode 100644 kernel/include/kernel/filesystem/ext2/filesystem.hpp create mode 100644 kernel/include/kernel/filesystem/ext2/inode.hpp create mode 100644 kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp create mode 100644 kernel/include/kernel/filesystem/ext2/superblock.hpp delete mode 100644 kernel/src/filesystem/ext2/ext2_filesystem.cpp delete mode 100644 kernel/src/filesystem/ext2/ext2_inode.cpp create mode 100644 kernel/src/filesystem/ext2/filesystem.cpp create mode 100644 kernel/src/filesystem/ext2/inode.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 5cc6f2d..93ac322 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -26,8 +26,8 @@ add_executable("kernel" "src/devices/storage/ram_disk/ram_disk_device.cpp" "src/filesystem/devfs/devfs_filesystem.cpp" "src/filesystem/devfs/devfs_root_inode.cpp" - "src/filesystem/ext2/ext2_filesystem.cpp" - "src/filesystem/ext2/ext2_inode.cpp" + "src/filesystem/ext2/filesystem.cpp" + "src/filesystem/ext2/inode.cpp" "src/filesystem/dentry.cpp" "src/filesystem/device_inode.cpp" "src/filesystem/file_descriptor_table.cpp" diff --git a/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp b/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp new file mode 100644 index 0000000..a23c045 --- /dev/null +++ b/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp @@ -0,0 +1,21 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_BLOCK_GROUP_DESCRIPTOR_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_BLOCK_GROUP_DESCRIPTOR_HPP + +#include +#include + +namespace kernel::filesystem::ext2 +{ + struct block_group_descriptor + { + uint32_t block_bitmap; + uint32_t inode_bitmap; + uint32_t inode_table; + uint16_t free_blocks_count; + uint16_t free_inodes_count; + uint16_t used_dirs_count; + std::array padding; + std::array reserved; // NOLINT(readability-magic-numbers) + }; +} // namespace kernel::filesystem::ext2 +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/ext2_block_group_descriptor.hpp b/kernel/include/kernel/filesystem/ext2/ext2_block_group_descriptor.hpp deleted file mode 100644 index 0de7428..0000000 --- a/kernel/include/kernel/filesystem/ext2/ext2_block_group_descriptor.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef EXT2_BLOCK_GROUP_DESCRIPTOR_HPP -#define EXT2_BLOCK_GROUP_DESCRIPTOR_HPP - -#include -#include - -namespace kernel::filesystem::ext2 -{ - struct ext2_block_group_descriptor - { - uint32_t block_bitmap; - uint32_t inode_bitmap; - uint32_t inode_table; - uint16_t free_blocks_count; - uint16_t free_inodes_count; - uint16_t used_dirs_count; - std::array padding; - std::array reserved; // NOLINT(readability-magic-numbers) - }; -} // namespace kernel::filesystem::ext2 -#endif // EXT2_BLOCK_GROUP_DESCRIPTOR_HPP \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp b/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp deleted file mode 100644 index 753aea1..0000000 --- a/kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP - -#include "kernel/devices/device.hpp" -#include "kernel/filesystem/filesystem.hpp" -#include "kernel/filesystem/inode.hpp" - -#include - -#include - -namespace kernel::filesystem::ext2 -{ - struct ext2_filesystem : filesystem - { - auto mount(kstd::shared_ptr const & device) -> int override; - auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; - - private: - }; -} // namespace kernel::filesystem::ext2 - -#endif diff --git a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp deleted file mode 100644 index 2054227..0000000 --- a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP - -#include "kernel/filesystem/inode.hpp" - -#include - -#include -#include -#include - -namespace kernel::filesystem::ext2 -{ - struct ext2_inode : inode - { - ext2_inode(); - - auto read(void * buffer, size_t offset, size_t size) const -> size_t override; - auto write(void const * buffer, size_t offset, size_t size) -> size_t override; - - uint16_t mode; - uint16_t uid; - uint32_t size; - uint32_t atime; - uint32_t ctime; - uint32_t mtime; - uint32_t dtime; - uint16_t gid; - uint16_t links_count; - uint32_t blocks; - uint32_t flags; - uint32_t osd1; - // uint32_t block[15]; // TODO BA-FS26 really correct? - std::array block; // NOLINT(readability-magic-numbers) - uint32_t generation; - uint32_t file_acl; - uint32_t dir_acl; - uint32_t faddr; - // uint8_t osd2[12]; // TODO BA-FS26 really correct? - std::array osd2; // NOLINT(readability-magic-numbers) - }; -} // namespace kernel::filesystem::ext2 - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp b/kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp deleted file mode 100644 index 84e47e8..0000000 --- a/kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_LINKED_DIRECTORY_ENTRY_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_LINKED_DIRECTORY_ENTRY_HPP - -#include -#include - -namespace kernel::filesystem::ext2 -{ - struct ext2_linked_directory_entry - { - uint32_t inode; - uint16_t rec_len; - uint8_t name_len; - uint8_t file_type; - uint8_t pad; - std::array name; // NOLINT(readability-magic-numbers) - }; -} // namespace kernel::filesystem::ext2 - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/ext2_superblock.hpp b/kernel/include/kernel/filesystem/ext2/ext2_superblock.hpp deleted file mode 100644 index aa93e68..0000000 --- a/kernel/include/kernel/filesystem/ext2/ext2_superblock.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef EXT2_SUPERBLOCK_HPP -#define EXT2_SUPERBLOCK_HPP - -#include -#include - -namespace kernel::filesystem::ext2 -{ - struct ext2_superblock - { - uint32_t inodes_count; - uint32_t blocks_count; - uint32_t reserved_blocks_count; - uint32_t free_blocks_count; - uint32_t free_inodes_count; - uint32_t first_data_block; - uint32_t log_block_size; - uint32_t log_frag_size; - uint32_t blocks_per_group; - uint32_t frags_per_group; - uint32_t inodes_per_group; - uint32_t mtime; - uint32_t wtime; - uint16_t mnt_count; - uint16_t max_mnt_count; - uint16_t magic; - uint16_t state; - uint16_t errors; - uint16_t minor_rev_level; - uint32_t lastcheck; - uint32_t checkinterval; - uint32_t creator_os; - uint32_t rev_level; - uint16_t def_resuid; - uint16_t def_resgid; - - // EXT2_DYNAMIC_REV superblock only - uint32_t first_ino; - uint16_t inode_size; - uint16_t block_group_nr; - uint32_t feature_compat; - uint32_t feature_incompat; - uint32_t feature_ro_compat; - // uint8_t uuid[16]; // TODO BA-FS26 really correct? - std::array uuid; - // uint8_t volume_name[16]; // TODO BA-FS26 really correct? - std::array volume_name; - // uint8_t last_mounted[64]; // TODO BA-FS26 really correct? - std::array last_mounted; - uint32_t algorithm_usage_bitmap; - - // Performance Hints - uint8_t prealloc_blocks; - uint8_t prealloc_dir_blocks; - uint16_t padding1; - - // Journaling Support - // uint8_t journal_uuid[16]; // TODO BA-FS26 really correct? - std::array journal_uuid; - uint32_t journal_inum; - uint32_t journal_dev; - uint32_t last_orphan; - - // Directory Indexing Support - // uint32_t hash_seed[4]; // TODO BA-FS26 really correct? - std::array hash_seed; - uint8_t def_hash_version; - std::array padding2; - - // Other options - uint32_t default_mount_options; - uint32_t first_meta_bg; - std::array unused; // NOLINT(readability-magic-numbers) - }; -} // namespace kernel::filesystem::ext2 -#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp new file mode 100644 index 0000000..763cd1d --- /dev/null +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -0,0 +1,22 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/filesystem.hpp" +#include "kernel/filesystem/inode.hpp" + +#include + +#include + +namespace kernel::filesystem::ext2 +{ + struct filesystem : kernel::filesystem::filesystem + { + auto mount(kstd::shared_ptr const & device) -> int override; + auto lookup(kstd::shared_ptr const & parent, std::string_view name) + -> kstd::shared_ptr override; + }; +} // namespace kernel::filesystem::ext2 + +#endif diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp new file mode 100644 index 0000000..2c27c17 --- /dev/null +++ b/kernel/include/kernel/filesystem/ext2/inode.hpp @@ -0,0 +1,44 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP + +#include "kernel/filesystem/inode.hpp" + +#include + +#include +#include +#include + +namespace kernel::filesystem::ext2 +{ + struct inode : kernel::filesystem::inode + { + inode(); + + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + + uint16_t mode; + uint16_t uid; + uint32_t size; + uint32_t atime; + uint32_t ctime; + uint32_t mtime; + uint32_t dtime; + uint16_t gid; + uint16_t links_count; + uint32_t blocks; + uint32_t flags; + uint32_t osd1; + // uint32_t block[15]; // TODO BA-FS26 really correct? + std::array block; // NOLINT(readability-magic-numbers) + uint32_t generation; + uint32_t file_acl; + uint32_t dir_acl; + uint32_t faddr; + // uint8_t osd2[12]; // TODO BA-FS26 really correct? + std::array osd2; // NOLINT(readability-magic-numbers) + }; +} // namespace kernel::filesystem::ext2 + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp b/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp new file mode 100644 index 0000000..8dd42a1 --- /dev/null +++ b/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp @@ -0,0 +1,20 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_LINKED_DIRECTORY_ENTRY_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_LINKED_DIRECTORY_ENTRY_HPP + +#include +#include + +namespace kernel::filesystem::ext2 +{ + struct linked_directory_entry + { + uint32_t inode; + uint16_t rec_len; + uint8_t name_len; + uint8_t file_type; + uint8_t pad; + std::array name; // NOLINT(readability-magic-numbers) + }; +} // namespace kernel::filesystem::ext2 + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/superblock.hpp b/kernel/include/kernel/filesystem/ext2/superblock.hpp new file mode 100644 index 0000000..8600b4c --- /dev/null +++ b/kernel/include/kernel/filesystem/ext2/superblock.hpp @@ -0,0 +1,76 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_SUPERBLOCK_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_SUPERBLOCK_HPP + +#include +#include + +namespace kernel::filesystem::ext2 +{ + struct superblock + { + uint32_t inodes_count; + uint32_t blocks_count; + uint32_t reserved_blocks_count; + uint32_t free_blocks_count; + uint32_t free_inodes_count; + uint32_t first_data_block; + uint32_t log_block_size; + uint32_t log_frag_size; + uint32_t blocks_per_group; + uint32_t frags_per_group; + uint32_t inodes_per_group; + uint32_t mtime; + uint32_t wtime; + uint16_t mnt_count; + uint16_t max_mnt_count; + uint16_t magic; + uint16_t state; + uint16_t errors; + uint16_t minor_rev_level; + uint32_t lastcheck; + uint32_t checkinterval; + uint32_t creator_os; + uint32_t rev_level; + uint16_t def_resuid; + uint16_t def_resgid; + + // EXT2_DYNAMIC_REV superblock only + uint32_t first_ino; + uint16_t inode_size; + uint16_t block_group_nr; + uint32_t feature_compat; + uint32_t feature_incompat; + uint32_t feature_ro_compat; + // uint8_t uuid[16]; // TODO BA-FS26 really correct? + std::array uuid; + // uint8_t volume_name[16]; // TODO BA-FS26 really correct? + std::array volume_name; + // uint8_t last_mounted[64]; // TODO BA-FS26 really correct? + std::array last_mounted; + uint32_t algorithm_usage_bitmap; + + // Performance Hints + uint8_t prealloc_blocks; + uint8_t prealloc_dir_blocks; + uint16_t padding1; + + // Journaling Support + // uint8_t journal_uuid[16]; // TODO BA-FS26 really correct? + std::array journal_uuid; + uint32_t journal_inum; + uint32_t journal_dev; + uint32_t last_orphan; + + // Directory Indexing Support + // uint32_t hash_seed[4]; // TODO BA-FS26 really correct? + std::array hash_seed; + uint8_t def_hash_version; + std::array padding2; + + // Other options + uint32_t default_mount_options; + uint32_t first_meta_bg; + std::array unused; // NOLINT(readability-magic-numbers) + }; +} // namespace kernel::filesystem::ext2 +#endif \ No newline at end of file diff --git a/kernel/src/filesystem/ext2/ext2_filesystem.cpp b/kernel/src/filesystem/ext2/ext2_filesystem.cpp deleted file mode 100644 index 036b80e..0000000 --- a/kernel/src/filesystem/ext2/ext2_filesystem.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "kernel/filesystem/ext2/ext2_filesystem.hpp" - -#include "kernel/devices/block_device_utils.hpp" -#include "kernel/devices/device.hpp" -#include "kernel/filesystem/ext2/ext2_inode.hpp" -#include "kernel/filesystem/ext2/ext2_superblock.hpp" -#include "kernel/filesystem/filesystem.hpp" -#include "kernel/filesystem/inode.hpp" - -#include - -#include -#include -#include - -namespace kernel::filesystem::ext2 -{ - namespace - { - // constexpr size_t SUPERBLOCK_OFFSET = 1024; - // constexpr uint16_t EXT2_MAGIC = 0xEF53; - - // // Mode bits - // constexpr uint16_t S_IFMT = 0xF000; - // constexpr uint16_t S_IFREG = 0x8000; - // constexpr uint16_t S_IFDIR = 0x4000; - - // auto S_ISREG(uint16_t mode) -> bool - // { - // return (mode & S_IFMT) == S_IFREG; - // } - // auto S_ISDIR(uint16_t mode) -> bool - // { - // return (mode & S_IFMT) == S_IFDIR; - // } - - // auto get_block_size(ext2_superblock const & superblock) -> size_t - // { - // return 1024U << superblock.log_block_size; - // } - - // auto get_inode_size(ext2_superblock const & superblock) -> size_t - // { - // return superblock.rev_level == 0 ? 128 : superblock.inode_size; - // } - } // namespace - - auto ext2_filesystem::mount(kstd::shared_ptr const & device) -> int - { - filesystem::mount(device); // TODO BA-FS26 error handling? - // TODO BA-FS26 load proper root inode from ext2 metadata - // m_root_inode = inode{inode_kind::directory}; - - // TODO BA-FS26 implement - m_root_inode = kstd::make_shared(); - // devices::block_device_utils::read(device, nullptr, 0, 0); // TODO BA-FS26 just for testing - return 0; - } - - auto ext2_filesystem::lookup(kstd::shared_ptr const & /*parent*/, std::string_view name) - -> kstd::shared_ptr - { - // TODO BA-FS26 implement ext2 directory traversal and inode loading - if (name == "dev") - { - // TODO BA-FS26 just for testing - return nullptr; - } - - return kstd::make_shared(); - } -} // namespace kernel::filesystem::ext2 diff --git a/kernel/src/filesystem/ext2/ext2_inode.cpp b/kernel/src/filesystem/ext2/ext2_inode.cpp deleted file mode 100644 index 142502e..0000000 --- a/kernel/src/filesystem/ext2/ext2_inode.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "kernel/filesystem/ext2/ext2_inode.hpp" - -#include "kernel/filesystem/inode.hpp" - -#include - -namespace kernel::filesystem::ext2 -{ - ext2_inode::ext2_inode() - : inode(inode_kind::regular) - {} - - auto ext2_inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t - { - // TODO BA-FS26 implement - return 0; - } - - auto ext2_inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t - { - // TODO BA-FS26 implement - return 0; - } -} // namespace kernel::filesystem::ext2 \ No newline at end of file diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp new file mode 100644 index 0000000..d951158 --- /dev/null +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -0,0 +1,72 @@ +#include "kernel/filesystem/ext2/filesystem.hpp" + +#include "kernel/devices/block_device_utils.hpp" +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/ext2/inode.hpp" +#include "kernel/filesystem/ext2/superblock.hpp" +#include "kernel/filesystem/filesystem.hpp" +#include "kernel/filesystem/inode.hpp" + +#include + +#include +#include +#include + +namespace kernel::filesystem::ext2 +{ + namespace + { + // constexpr size_t SUPERBLOCK_OFFSET = 1024; + // constexpr uint16_t EXT2_MAGIC = 0xEF53; + + // // Mode bits + // constexpr uint16_t S_IFMT = 0xF000; + // constexpr uint16_t S_IFREG = 0x8000; + // constexpr uint16_t S_IFDIR = 0x4000; + + // auto S_ISREG(uint16_t mode) -> bool + // { + // return (mode & S_IFMT) == S_IFREG; + // } + // auto S_ISDIR(uint16_t mode) -> bool + // { + // return (mode & S_IFMT) == S_IFDIR; + // } + + // auto get_block_size(superblock const & superblock) -> size_t + // { + // return 1024U << superblock.log_block_size; + // } + + // auto get_inode_size(superblock const & superblock) -> size_t + // { + // return superblock.rev_level == 0 ? 128 : superblock.inode_size; + // } + } // namespace + + auto filesystem::mount(kstd::shared_ptr const & device) -> int + { + kernel::filesystem::filesystem::mount(device); // TODO BA-FS26 error handling? + // TODO BA-FS26 load proper root inode from ext2 metadata + // m_root_inode = inode{inode_kind::directory}; + + // TODO BA-FS26 implement + m_root_inode = kstd::make_shared(); + // devices::block_device_utils::read(device, nullptr, 0, 0); // TODO BA-FS26 just for testing + return 0; + } + + auto filesystem::lookup(kstd::shared_ptr const & /*parent*/, std::string_view name) + -> kstd::shared_ptr + { + // TODO BA-FS26 implement ext2 directory traversal and inode loading + if (name == "dev") + { + // TODO BA-FS26 just for testing + return nullptr; + } + + return kstd::make_shared(); + } +} // namespace kernel::filesystem::ext2 diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp new file mode 100644 index 0000000..b75969a --- /dev/null +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -0,0 +1,24 @@ +#include "kernel/filesystem/ext2/inode.hpp" + +#include "kernel/filesystem/inode.hpp" + +#include + +namespace kernel::filesystem::ext2 +{ + inode::inode() + : kernel::filesystem::inode(inode_kind::regular) + {} + + auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t + { + // TODO BA-FS26 implement + return 0; + } + + auto inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t + { + // TODO BA-FS26 implement + return 0; + } +} // namespace kernel::filesystem::ext2 \ No newline at end of file diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 2dbdb12..69740c3 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -5,7 +5,7 @@ #include "kernel/devices/storage/storage_management.hpp" #include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/devfs/devfs_filesystem.hpp" -#include "kernel/filesystem/ext2/ext2_filesystem.hpp" +#include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/mount.hpp" #include "kernel/filesystem/open_file_description.hpp" @@ -47,7 +47,7 @@ namespace kernel::filesystem if (auto boot_device = storage_mgmt.determine_boot_device()) { // TODO BA-FS26 detect fs type from boot device and load corresponding fs, for now just assume ext2 - auto boot_root_fs = kstd::make_shared(); + auto boot_root_fs = kstd::make_shared(); boot_root_fs->mount(boot_device); do_mount_internal("/", root_fs_root_dentry, boot_root_fs); } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 2dd9fd9..ff73985 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -7,7 +7,7 @@ #include "kernel/devices/storage/storage_management.hpp" #include "kernel/filesystem/device_inode.hpp" -#include "kernel/filesystem/ext2/ext2_filesystem.hpp" +#include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/filesystem/file_descriptor_table.hpp" #include "kernel/filesystem/open_file_description.hpp" #include "kernel/filesystem/vfs.hpp" @@ -126,7 +126,7 @@ auto test_file_lookup() -> void kstd::os::panic("test code failed"); } - auto new_filesystem = kstd::make_shared(); + auto new_filesystem = kstd::make_shared(); auto device = storage_mgmt.device_by_major_minor(1, 16); new_filesystem->mount(device); if (vfs.do_mount("/a/b", new_filesystem) != 0) -- cgit v1.2.3 From 0b5084780e4a89dcaccbda5823495c9cdd62b006 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Mon, 30 Mar 2026 20:52:25 +0200 Subject: Rename devfs filesystem files --- kernel/CMakeLists.txt | 4 +- .../kernel/filesystem/devfs/devfs_filesystem.hpp | 25 ---------- .../kernel/filesystem/devfs/devfs_root_inode.hpp | 19 ------- .../include/kernel/filesystem/devfs/filesystem.hpp | 26 ++++++++++ kernel/include/kernel/filesystem/devfs/inode.hpp | 19 +++++++ kernel/src/filesystem/devfs/devfs_filesystem.cpp | 58 ---------------------- kernel/src/filesystem/devfs/devfs_root_inode.cpp | 22 -------- kernel/src/filesystem/devfs/filesystem.cpp | 58 ++++++++++++++++++++++ kernel/src/filesystem/devfs/inode.cpp | 22 ++++++++ kernel/src/filesystem/vfs.cpp | 4 +- 10 files changed, 129 insertions(+), 128 deletions(-) delete mode 100644 kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp delete mode 100644 kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp create mode 100644 kernel/include/kernel/filesystem/devfs/filesystem.hpp create mode 100644 kernel/include/kernel/filesystem/devfs/inode.hpp delete mode 100644 kernel/src/filesystem/devfs/devfs_filesystem.cpp delete mode 100644 kernel/src/filesystem/devfs/devfs_root_inode.cpp create mode 100644 kernel/src/filesystem/devfs/filesystem.cpp create mode 100644 kernel/src/filesystem/devfs/inode.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 93ac322..f9e4a70 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -24,8 +24,8 @@ add_executable("kernel" "src/devices/storage/storage_management.cpp" "src/devices/storage/ram_disk/ram_disk_controller.cpp" "src/devices/storage/ram_disk/ram_disk_device.cpp" - "src/filesystem/devfs/devfs_filesystem.cpp" - "src/filesystem/devfs/devfs_root_inode.cpp" + "src/filesystem/devfs/filesystem.cpp" + "src/filesystem/devfs/inode.cpp" "src/filesystem/ext2/filesystem.cpp" "src/filesystem/ext2/inode.cpp" "src/filesystem/dentry.cpp" diff --git a/kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp b/kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp deleted file mode 100644 index 2330915..0000000 --- a/kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVFS_DEVFS_FILESYSTEM_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_DEVFS_FILESYSTEM_HPP - -#include "kernel/devices/device.hpp" -#include "kernel/filesystem/filesystem.hpp" -#include "kernel/filesystem/inode.hpp" - -#include -#include - -#include - -namespace kernel::filesystem::devfs -{ - struct devfs_filesystem : filesystem - { - auto mount(kstd::shared_ptr const & device) -> int override; - auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; - - private: - auto build_device_inode_table() -> void; - }; -} // namespace kernel::filesystem::devfs - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp b/kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp deleted file mode 100644 index 206fc13..0000000 --- a/kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVFS_DEVFS_ROOT_INODE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_DEVFS_ROOT_INODE_HPP - -#include "kernel/filesystem/inode.hpp" - -#include - -namespace kernel::filesystem::devfs -{ - struct devfs_root_inode : inode - { - devfs_root_inode(); - - auto read(void * buffer, size_t offset, size_t size) const -> size_t override; - auto write(void const * buffer, size_t offset, size_t size) -> size_t override; - }; -} // namespace kernel::filesystem::devfs - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/devfs/filesystem.hpp b/kernel/include/kernel/filesystem/devfs/filesystem.hpp new file mode 100644 index 0000000..5ec6221 --- /dev/null +++ b/kernel/include/kernel/filesystem/devfs/filesystem.hpp @@ -0,0 +1,26 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVFS_FILESYSTEM_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_FILESYSTEM_HPP + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/filesystem.hpp" +#include "kernel/filesystem/inode.hpp" + +#include +#include + +#include + +namespace kernel::filesystem::devfs +{ + struct filesystem : kernel::filesystem::filesystem + { + auto mount(kstd::shared_ptr const & device) -> int override; + auto lookup(kstd::shared_ptr const & parent, std::string_view name) + -> kstd::shared_ptr override; + + private: + auto build_device_inode_table() -> void; + }; +} // namespace kernel::filesystem::devfs + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/devfs/inode.hpp b/kernel/include/kernel/filesystem/devfs/inode.hpp new file mode 100644 index 0000000..9c11edf --- /dev/null +++ b/kernel/include/kernel/filesystem/devfs/inode.hpp @@ -0,0 +1,19 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVFS_INODE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_INODE_HPP + +#include "kernel/filesystem/inode.hpp" + +#include + +namespace kernel::filesystem::devfs +{ + struct inode : kernel::filesystem::inode + { + inode(); + + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + }; +} // namespace kernel::filesystem::devfs + +#endif \ No newline at end of file diff --git a/kernel/src/filesystem/devfs/devfs_filesystem.cpp b/kernel/src/filesystem/devfs/devfs_filesystem.cpp deleted file mode 100644 index df977b8..0000000 --- a/kernel/src/filesystem/devfs/devfs_filesystem.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "kernel/filesystem/devfs/devfs_filesystem.hpp" - -#include "kernel/devices/device.hpp" -#include "kernel/devices/storage/storage_management.hpp" -#include "kernel/filesystem/devfs/devfs_root_inode.hpp" -#include "kernel/filesystem/device_inode.hpp" -#include "kernel/filesystem/inode.hpp" - -#include - -#include -#include - -namespace kernel::filesystem::devfs -{ - auto devfs_filesystem::mount(kstd::shared_ptr const &) -> int - { - m_root_inode = kstd::make_shared(); - build_device_inode_table(); - - return 0; - } - - auto devfs_filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) - -> kstd::shared_ptr - { - if (!parent || !parent->is_directory()) - { - return nullptr; - } - - if (parent.get() != m_root_inode.get()) - { - return nullptr; - } - - auto it = std::ranges::find_if(m_inodes, [&](auto const & dev_node) { - auto device_inode_ptr = static_cast(dev_node.get()); - if (!device_inode_ptr) - { - return false; - } - return device_inode_ptr->device()->name() == name; - }); - return (it != m_inodes.end()) ? *it : nullptr; - } - - auto devfs_filesystem::build_device_inode_table() -> void - { - m_inodes.clear(); - - auto storage_mgmt = devices::storage::storage_management::get(); - std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto const & controller) { - std::ranges::for_each(controller->all_devices(), - [&](auto const & device) { m_inodes.push_back(kstd::make_shared(device)); }); - }); - } -} // namespace kernel::filesystem::devfs \ No newline at end of file diff --git a/kernel/src/filesystem/devfs/devfs_root_inode.cpp b/kernel/src/filesystem/devfs/devfs_root_inode.cpp deleted file mode 100644 index a7308dc..0000000 --- a/kernel/src/filesystem/devfs/devfs_root_inode.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "kernel/filesystem/devfs/devfs_root_inode.hpp" - -#include "kernel/filesystem/inode.hpp" - -#include - -namespace kernel::filesystem::devfs -{ - devfs_root_inode::devfs_root_inode() - : inode(inode_kind::directory) - {} - - auto devfs_root_inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t - { - return 0; - } - - auto devfs_root_inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t - { - return 0; - } -} // namespace kernel::filesystem::devfs \ No newline at end of file diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp new file mode 100644 index 0000000..e7d0e13 --- /dev/null +++ b/kernel/src/filesystem/devfs/filesystem.cpp @@ -0,0 +1,58 @@ +#include "kernel/filesystem/devfs/filesystem.hpp" + +#include "kernel/devices/device.hpp" +#include "kernel/devices/storage/storage_management.hpp" +#include "kernel/filesystem/devfs/inode.hpp" +#include "kernel/filesystem/device_inode.hpp" +#include "kernel/filesystem/inode.hpp" + +#include + +#include +#include + +namespace kernel::filesystem::devfs +{ + auto filesystem::mount(kstd::shared_ptr const &) -> int + { + m_root_inode = kstd::make_shared(); + build_device_inode_table(); + + return 0; + } + + auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) + -> kstd::shared_ptr + { + if (!parent || !parent->is_directory()) + { + return nullptr; + } + + if (parent.get() != m_root_inode.get()) + { + return nullptr; + } + + auto it = std::ranges::find_if(m_inodes, [&](auto const & dev_node) { + auto device_inode_ptr = static_cast(dev_node.get()); + if (!device_inode_ptr) + { + return false; + } + return device_inode_ptr->device()->name() == name; + }); + return (it != m_inodes.end()) ? *it : nullptr; + } + + auto filesystem::build_device_inode_table() -> void + { + m_inodes.clear(); + + auto storage_mgmt = devices::storage::storage_management::get(); + std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto const & controller) { + std::ranges::for_each(controller->all_devices(), + [&](auto const & device) { m_inodes.push_back(kstd::make_shared(device)); }); + }); + } +} // namespace kernel::filesystem::devfs \ No newline at end of file diff --git a/kernel/src/filesystem/devfs/inode.cpp b/kernel/src/filesystem/devfs/inode.cpp new file mode 100644 index 0000000..52cf6fa --- /dev/null +++ b/kernel/src/filesystem/devfs/inode.cpp @@ -0,0 +1,22 @@ +#include "kernel/filesystem/devfs/inode.hpp" + +#include "kernel/filesystem/inode.hpp" + +#include + +namespace kernel::filesystem::devfs +{ + inode::inode() + : kernel::filesystem::inode(inode_kind::directory) + {} + + auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t + { + return 0; + } + + auto inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t + { + return 0; + } +} // namespace kernel::filesystem::devfs \ No newline at end of file diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 69740c3..fdad36c 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -4,7 +4,7 @@ #include "kernel/devices/storage/storage_management.hpp" #include "kernel/filesystem/dentry.hpp" -#include "kernel/filesystem/devfs/devfs_filesystem.hpp" +#include "kernel/filesystem/devfs/filesystem.hpp" #include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/mount.hpp" @@ -52,7 +52,7 @@ namespace kernel::filesystem do_mount_internal("/", root_fs_root_dentry, boot_root_fs); } - auto device_fs = kstd::make_shared(); + auto device_fs = kstd::make_shared(); device_fs->mount(nullptr); do_mount_internal("/dev", root_fs_root_dentry, device_fs); } -- cgit v1.2.3 From 81ab0ba35d724dd465ed870e87047b3bf74cea13 Mon Sep 17 00:00:00 2001 From: "marcel.braun" Date: Mon, 30 Mar 2026 21:01:18 +0200 Subject: Rename rootfs filesystem files --- kernel/CMakeLists.txt | 4 +-- .../kernel/filesystem/rootfs/filesystem.hpp | 24 +++++++++++++ kernel/include/kernel/filesystem/rootfs/inode.hpp | 31 +++++++++++++++++ .../kernel/filesystem/rootfs/rootfs_filesystem.hpp | 23 ------------- .../kernel/filesystem/rootfs/rootfs_inode.hpp | 31 ----------------- kernel/src/filesystem/rootfs/filesystem.cpp | 29 ++++++++++++++++ kernel/src/filesystem/rootfs/inode.cpp | 39 ++++++++++++++++++++++ kernel/src/filesystem/rootfs/rootfs_filesystem.cpp | 29 ---------------- kernel/src/filesystem/rootfs/rootfs_inode.cpp | 39 ---------------------- kernel/src/filesystem/vfs.cpp | 4 +-- 10 files changed, 127 insertions(+), 126 deletions(-) create mode 100644 kernel/include/kernel/filesystem/rootfs/filesystem.hpp create mode 100644 kernel/include/kernel/filesystem/rootfs/inode.hpp delete mode 100644 kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp delete mode 100644 kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp create mode 100644 kernel/src/filesystem/rootfs/filesystem.cpp create mode 100644 kernel/src/filesystem/rootfs/inode.cpp delete mode 100644 kernel/src/filesystem/rootfs/rootfs_filesystem.cpp delete mode 100644 kernel/src/filesystem/rootfs/rootfs_inode.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index f9e4a70..3dbc0f4 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -36,8 +36,8 @@ add_executable("kernel" "src/filesystem/mount_table.cpp" "src/filesystem/mount.cpp" "src/filesystem/open_file_description.cpp" - "src/filesystem/rootfs/rootfs_filesystem.cpp" - "src/filesystem/rootfs/rootfs_inode.cpp" + "src/filesystem/rootfs/filesystem.cpp" + "src/filesystem/rootfs/inode.cpp" "src/filesystem/vfs.cpp" ) diff --git a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp new file mode 100644 index 0000000..b1f33a9 --- /dev/null +++ b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp @@ -0,0 +1,24 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_FILESYSTEM_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_FILESYSTEM_HPP + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/filesystem.hpp" +#include "kernel/filesystem/inode.hpp" + +#include +#include +#include + +#include + +namespace kernel::filesystem::rootfs +{ + struct filesystem : kernel::filesystem::filesystem + { + auto mount(kstd::shared_ptr const & device) -> int override; + auto lookup(kstd::shared_ptr const & parent, std::string_view name) + -> kstd::shared_ptr override; + }; +} // namespace kernel::filesystem::rootfs + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/rootfs/inode.hpp b/kernel/include/kernel/filesystem/rootfs/inode.hpp new file mode 100644 index 0000000..24d3e6b --- /dev/null +++ b/kernel/include/kernel/filesystem/rootfs/inode.hpp @@ -0,0 +1,31 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_INODE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_INODE_HPP + +#include "kernel/filesystem/inode.hpp" + +#include +#include +#include + +#include +#include +#include + +namespace kernel::filesystem::rootfs +{ + struct inode : kernel::filesystem::inode + { + inode(); + + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + + auto add_child(std::string_view name) -> void; + auto lookup_child(std::string_view name) -> kstd::shared_ptr; + + private: + kstd::vector>> m_children; + }; +} // namespace kernel::filesystem::rootfs + +#endif diff --git a/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp deleted file mode 100644 index b91f728..0000000 --- a/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_ROOTFS_FILESYSTEM_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_ROOTFS_FILESYSTEM_HPP - -#include "kernel/devices/device.hpp" -#include "kernel/filesystem/filesystem.hpp" -#include "kernel/filesystem/inode.hpp" - -#include -#include -#include - -#include - -namespace kernel::filesystem::rootfs -{ - struct rootfs_filesystem : filesystem - { - auto mount(kstd::shared_ptr const & device) -> int override; - auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; - }; -} // namespace kernel::filesystem::rootfs - -#endif diff --git a/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp b/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp deleted file mode 100644 index 26e7f88..0000000 --- a/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_ROOTFS_INODE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_ROOTFS_INODE_HPP - -#include "kernel/filesystem/inode.hpp" - -#include -#include -#include - -#include -#include -#include - -namespace kernel::filesystem::rootfs -{ - struct rootfs_inode : inode - { - rootfs_inode(); - - auto read(void * buffer, size_t offset, size_t size) const -> size_t override; - auto write(void const * buffer, size_t offset, size_t size) -> size_t override; - - auto add_child(std::string_view name) -> void; - auto lookup_child(std::string_view name) -> kstd::shared_ptr; - - private: - kstd::vector>> m_children; - }; -} // namespace kernel::filesystem::rootfs - -#endif diff --git a/kernel/src/filesystem/rootfs/filesystem.cpp b/kernel/src/filesystem/rootfs/filesystem.cpp new file mode 100644 index 0000000..0133612 --- /dev/null +++ b/kernel/src/filesystem/rootfs/filesystem.cpp @@ -0,0 +1,29 @@ +#include "kernel/filesystem/rootfs/filesystem.hpp" + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/inode.hpp" +#include "kernel/filesystem/rootfs/inode.hpp" + +#include + +#include + +namespace kernel::filesystem::rootfs +{ + auto filesystem::mount(kstd::shared_ptr const &) -> int + { + auto rfs_inode = kstd::make_shared(); + rfs_inode->add_child("dev"); + m_root_inode = rfs_inode; + + return 0; + } + + auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) + -> kstd::shared_ptr + { + if (auto * rfs_inode = static_cast(parent.get())) + return rfs_inode->lookup_child(name); + return nullptr; + } +} // namespace kernel::filesystem::rootfs diff --git a/kernel/src/filesystem/rootfs/inode.cpp b/kernel/src/filesystem/rootfs/inode.cpp new file mode 100644 index 0000000..3ca9c02 --- /dev/null +++ b/kernel/src/filesystem/rootfs/inode.cpp @@ -0,0 +1,39 @@ +#include "kernel/filesystem/inode.hpp" + +#include "kernel/filesystem/rootfs/inode.hpp" + +#include +#include + +#include +#include +#include +#include + +namespace kernel::filesystem::rootfs +{ + inode::inode() + : kernel::filesystem::inode(inode_kind::directory) + {} + + auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t + { + return 0; + } + + auto inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t + { + return 0; + } + + auto inode::add_child(std::string_view name) -> void + { + m_children.push_back(std::make_pair(kstd::string{name}, kstd::make_shared())); + } + + auto inode::lookup_child(std::string_view name) -> kstd::shared_ptr + { + auto it = std::ranges::find_if(m_children, [&](auto const & pair) { return pair.first == name; }); + return (it != m_children.end()) ? it->second : nullptr; + } +} // namespace kernel::filesystem::rootfs diff --git a/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp b/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp deleted file mode 100644 index 804e211..0000000 --- a/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "kernel/filesystem/rootfs/rootfs_filesystem.hpp" - -#include "kernel/devices/device.hpp" -#include "kernel/filesystem/inode.hpp" -#include "kernel/filesystem/rootfs/rootfs_inode.hpp" - -#include - -#include - -namespace kernel::filesystem::rootfs -{ - auto rootfs_filesystem::mount(kstd::shared_ptr const &) -> int - { - auto rfs_inode = kstd::make_shared(); - rfs_inode->add_child("dev"); - m_root_inode = rfs_inode; - - return 0; - } - - auto rootfs_filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) - -> kstd::shared_ptr - { - if (auto * rfs_inode = static_cast(parent.get())) - return rfs_inode->lookup_child(name); - return nullptr; - } -} // namespace kernel::filesystem::rootfs diff --git a/kernel/src/filesystem/rootfs/rootfs_inode.cpp b/kernel/src/filesystem/rootfs/rootfs_inode.cpp deleted file mode 100644 index f44f06c..0000000 --- a/kernel/src/filesystem/rootfs/rootfs_inode.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "kernel/filesystem/rootfs/rootfs_inode.hpp" - -#include "kernel/filesystem/inode.hpp" - -#include -#include - -#include -#include -#include -#include - -namespace kernel::filesystem::rootfs -{ - rootfs_inode::rootfs_inode() - : inode(inode_kind::directory) - {} - - auto rootfs_inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t - { - return 0; - } - - auto rootfs_inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t - { - return 0; - } - - auto rootfs_inode::add_child(std::string_view name) -> void - { - m_children.push_back(std::make_pair(kstd::string{name}, kstd::make_shared())); - } - - auto rootfs_inode::lookup_child(std::string_view name) -> kstd::shared_ptr - { - auto it = std::ranges::find_if(m_children, [&](auto const & pair) { return pair.first == name; }); - return (it != m_children.end()) ? it->second : nullptr; - } -} // namespace kernel::filesystem::rootfs diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index fdad36c..bee68e6 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -9,7 +9,7 @@ #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/mount.hpp" #include "kernel/filesystem/open_file_description.hpp" -#include "kernel/filesystem/rootfs/rootfs_filesystem.hpp" +#include "kernel/filesystem/rootfs/filesystem.hpp" #include @@ -37,7 +37,7 @@ namespace kernel::filesystem auto vfs::init_internal() -> void { - auto root_fs = kstd::make_shared(); + auto root_fs = kstd::make_shared(); root_fs->mount(nullptr); auto root_fs_root_dentry = kstd::make_shared(nullptr, root_fs->root_inode()); -- 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/CMakeLists.txt | 8 +- .../include/kernel/devices/storage/controller.hpp | 71 ++++++++++++++++++ .../include/kernel/devices/storage/management.hpp | 77 ++++++++++++++++++++ .../kernel/devices/storage/ram_disk/controller.hpp | 31 ++++++++ .../kernel/devices/storage/ram_disk/device.hpp | 52 +++++++++++++ .../storage/ram_disk/ram_disk_controller.hpp | 31 -------- .../devices/storage/ram_disk/ram_disk_device.hpp | 52 ------------- .../kernel/devices/storage/storage_controller.hpp | 71 ------------------ .../kernel/devices/storage/storage_management.hpp | 77 -------------------- 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 ---------------------- kernel/src/filesystem/devfs/filesystem.cpp | 4 +- kernel/src/filesystem/vfs.cpp | 4 +- kernel/src/main.cpp | 10 +-- 20 files changed, 465 insertions(+), 466 deletions(-) create mode 100644 kernel/include/kernel/devices/storage/controller.hpp create mode 100644 kernel/include/kernel/devices/storage/management.hpp create mode 100644 kernel/include/kernel/devices/storage/ram_disk/controller.hpp create mode 100644 kernel/include/kernel/devices/storage/ram_disk/device.hpp delete mode 100644 kernel/include/kernel/devices/storage/ram_disk/ram_disk_controller.hpp delete mode 100644 kernel/include/kernel/devices/storage/ram_disk/ram_disk_device.hpp delete mode 100644 kernel/include/kernel/devices/storage/storage_controller.hpp delete mode 100644 kernel/include/kernel/devices/storage/storage_management.hpp 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') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 3dbc0f4..10bfecb 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -20,10 +20,10 @@ add_executable("kernel" "src/devices/device.cpp" "src/devices/block_device.cpp" "src/devices/block_device_utils.cpp" - "src/devices/storage/storage_controller.cpp" - "src/devices/storage/storage_management.cpp" - "src/devices/storage/ram_disk/ram_disk_controller.cpp" - "src/devices/storage/ram_disk/ram_disk_device.cpp" + "src/devices/storage/controller.cpp" + "src/devices/storage/management.cpp" + "src/devices/storage/ram_disk/controller.cpp" + "src/devices/storage/ram_disk/device.cpp" "src/filesystem/devfs/filesystem.cpp" "src/filesystem/devfs/inode.cpp" "src/filesystem/ext2/filesystem.cpp" diff --git a/kernel/include/kernel/devices/storage/controller.hpp b/kernel/include/kernel/devices/storage/controller.hpp new file mode 100644 index 0000000..e3bfd01 --- /dev/null +++ b/kernel/include/kernel/devices/storage/controller.hpp @@ -0,0 +1,71 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_CONTROLLER_HPP +#define TEACH_OS_KERNEL_DEVICES_STORAGE_CONTROLLER_HPP + +#include "kernel/devices/device.hpp" + +#include +#include + +#include + +namespace kernel::devices::storage +{ + /** + * @brief Base interface for storage controllers. + * + * A storage controller probes for devices and resolves devices by major/minor + * numbers. + */ + struct controller + { + /** + * @brief Virtual destructor. + */ + virtual ~controller() = default; + + /** + * @brief Probe the controller and register discovered devices. + */ + virtual auto probe() -> void = 0; + + /** + * @brief Assign the major number and minor stride for this controller. + * @param major Major number assigned to this controller. + * @param minors_per_dev Minor number stride between devices. + */ + auto set_ids(size_t major, size_t minors_per_dev) -> void; + + /** + * @brief Return the assigned major number. + * @return Assigned major number. + */ + [[nodiscard]] auto major() const -> size_t; + + /** + * @brief Return the number of devices managed by this controller. + * @return Number of managed devices. + */ + [[nodiscard]] auto devices_count() const -> size_t; + + /** + * @brief Return all devices managed by this controller. + * @return Vector of all managed devices. + */ + [[nodiscard]] auto all_devices() const -> kstd::vector> const &; + + /** + * @brief Find a managed device by major/minor numbers. + * @param major Device major number. + * @param minor Device minor number. + * @return Matching block device, or nullptr if no device matches. + */ + [[nodiscard]] auto device_by_minor(size_t minor) const -> kstd::shared_ptr; + + protected: + size_t m_major{}; + size_t m_minors_per_device{}; + kstd::vector> m_devices{}; + }; +} // namespace kernel::devices::storage + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/storage/management.hpp b/kernel/include/kernel/devices/storage/management.hpp new file mode 100644 index 0000000..255d170 --- /dev/null +++ b/kernel/include/kernel/devices/storage/management.hpp @@ -0,0 +1,77 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_MANAGEMENT_HPP +#define TEACH_OS_KERNEL_DEVICES_STORAGE_MANAGEMENT_HPP + +#include "kernel/devices/device.hpp" +#include "kernel/devices/storage/controller.hpp" + +#include +#include + +#include + +namespace kernel::devices::storage +{ + /** + * @brief Global storage subsystem manager. + * + * Owns registered storage controllers and provides device lookup by + * major/minor numbers. + */ + struct management + { + /** + * @brief Initialize global storage management. + * + * Creates the singleton instance, registers controllers and probes + * them for devices. + * + * @warning Panics if called more than once. + */ + auto static init() -> void; + + /** + * @brief Return the active storage manager singleton. + * @return Reference to the active storage manager. + * @warning Panics if storage management has not been initialized. + */ + auto static get() -> management &; + + /** + * @brief Register a storage controller. + * @param controller Controller to register. + * + * Assigns controller IDs (major number range and minors per device). + */ + auto add_controller(kstd::shared_ptr const & controller) -> void; + + /** + * @brief Return all registered storage controllers. + * @return Vector of all registered storage controllers. + */ + [[nodiscard]] auto all_controllers() const -> kstd::vector> const &; + + /** + * @brief Find a device by major/minor numbers. + * @param major Device major number. + * @param minor Device minor number. + * @return Matching device, or nullptr if no device matches. + */ + auto device_by_major_minor(size_t major, size_t minor) -> kstd::shared_ptr; + + /** + * @brief Determine the boot device. + * @return Boot device, or nullptr if it cannot be determined. + */ + auto determine_boot_device() -> kstd::shared_ptr; + + private: + /** + * @brief Private default constructor for storage management singleton. + */ + management() = default; + + kstd::vector> m_controllers{}; + }; +} // namespace kernel::devices::storage + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/storage/ram_disk/controller.hpp b/kernel/include/kernel/devices/storage/ram_disk/controller.hpp new file mode 100644 index 0000000..ad8b29f --- /dev/null +++ b/kernel/include/kernel/devices/storage/ram_disk/controller.hpp @@ -0,0 +1,31 @@ +#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP +#define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP + +#include "kapi/boot_module/boot_module_registry.hpp" + +#include "kernel/devices/storage/controller.hpp" + +namespace kernel::devices::storage::ram_disk +{ + /** + * @brief Storage controller that exposes boot modules as RAM-disk devices. + */ + struct controller : kernel::devices::storage::controller + { + /** + * @brief Create a RAM-disk controller. + * @param registry Boot module registry as device source. + */ + explicit controller(kapi::boot_modules::boot_module_registry const * registry); + + /** + * @brief Probe boot modules and create RAM-disk devices. + */ + auto probe() -> void 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/include/kernel/devices/storage/ram_disk/device.hpp b/kernel/include/kernel/devices/storage/ram_disk/device.hpp new file mode 100644 index 0000000..0777e86 --- /dev/null +++ b/kernel/include/kernel/devices/storage/ram_disk/device.hpp @@ -0,0 +1,52 @@ +#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 "kernel/devices/block_device.hpp" + +#include + +namespace kernel::devices::storage::ram_disk +{ + /** + * @brief Block device for a boot module. + */ + struct device : block_device + { + /** + * @brief Create a RAM disk for the @p module. + * @param module Boot module providing the memory region. + * @param major Device major number. + * @param minor Device minor number. + */ + device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor); + + /** + * @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 -> void 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) -> void override; + + private: + /** + * @brief Return module size in bytes. + */ + [[nodiscard]] auto size() const -> size_t override; + + 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/include/kernel/devices/storage/ram_disk/ram_disk_controller.hpp b/kernel/include/kernel/devices/storage/ram_disk/ram_disk_controller.hpp deleted file mode 100644 index 40763bf..0000000 --- a/kernel/include/kernel/devices/storage/ram_disk/ram_disk_controller.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP -#define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP - -#include "kapi/boot_module/boot_module_registry.hpp" - -#include "kernel/devices/storage/storage_controller.hpp" - -namespace kernel::devices::storage::ram_disk -{ - /** - * @brief Storage controller that exposes boot modules as RAM-disk devices. - */ - struct ram_disk_controller : storage_controller - { - /** - * @brief Create a RAM-disk controller. - * @param registry Boot module registry as device source. - */ - explicit ram_disk_controller(kapi::boot_modules::boot_module_registry const * registry); - - /** - * @brief Probe boot modules and create RAM-disk devices. - */ - auto probe() -> void 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/include/kernel/devices/storage/ram_disk/ram_disk_device.hpp b/kernel/include/kernel/devices/storage/ram_disk/ram_disk_device.hpp deleted file mode 100644 index 75ff50b..0000000 --- a/kernel/include/kernel/devices/storage/ram_disk/ram_disk_device.hpp +++ /dev/null @@ -1,52 +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 "kernel/devices/block_device.hpp" - -#include - -namespace kernel::devices::storage::ram_disk -{ - /** - * @brief Block device for a boot module. - */ - struct ram_disk_device : block_device - { - /** - * @brief Create a RAM disk for the @p module. - * @param module Boot module providing the memory region. - * @param major Device major number. - * @param minor Device minor number. - */ - ram_disk_device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor); - - /** - * @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 -> void 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) -> void override; - - private: - /** - * @brief Return module size in bytes. - */ - [[nodiscard]] auto size() const -> size_t override; - - 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/include/kernel/devices/storage/storage_controller.hpp b/kernel/include/kernel/devices/storage/storage_controller.hpp deleted file mode 100644 index 5639160..0000000 --- a/kernel/include/kernel/devices/storage/storage_controller.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP -#define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_CONTROLLER_HPP - -#include "kernel/devices/device.hpp" - -#include -#include - -#include - -namespace kernel::devices::storage -{ - /** - * @brief Base interface for storage controllers. - * - * A storage controller probes for devices and resolves devices by major/minor - * numbers. - */ - struct storage_controller - { - /** - * @brief Virtual destructor. - */ - virtual ~storage_controller() = default; - - /** - * @brief Probe the controller and register discovered devices. - */ - virtual auto probe() -> void = 0; - - /** - * @brief Assign the major number and minor stride for this controller. - * @param major Major number assigned to this controller. - * @param minors_per_dev Minor number stride between devices. - */ - auto set_ids(size_t major, size_t minors_per_dev) -> void; - - /** - * @brief Return the assigned major number. - * @return Assigned major number. - */ - [[nodiscard]] auto major() const -> size_t; - - /** - * @brief Return the number of devices managed by this controller. - * @return Number of managed devices. - */ - [[nodiscard]] auto devices_count() const -> size_t; - - /** - * @brief Return all devices managed by this controller. - * @return Vector of all managed devices. - */ - [[nodiscard]] auto all_devices() const -> kstd::vector> const &; - - /** - * @brief Find a managed device by major/minor numbers. - * @param major Device major number. - * @param minor Device minor number. - * @return Matching block device, or nullptr if no device matches. - */ - [[nodiscard]] auto device_by_minor(size_t minor) const -> kstd::shared_ptr; - - protected: - size_t m_major{}; - size_t m_minors_per_device{}; - kstd::vector> m_devices{}; - }; -} // namespace kernel::devices::storage - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/storage/storage_management.hpp b/kernel/include/kernel/devices/storage/storage_management.hpp deleted file mode 100644 index b6d1318..0000000 --- a/kernel/include/kernel/devices/storage/storage_management.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP -#define TEACH_OS_KERNEL_DEVICES_STORAGE_STORAGE_MANAGEMENT_HPP - -#include "kernel/devices/device.hpp" -#include "kernel/devices/storage/storage_controller.hpp" - -#include -#include - -#include - -namespace kernel::devices::storage -{ - /** - * @brief Global storage subsystem manager. - * - * Owns registered storage controllers and provides device lookup by - * major/minor numbers. - */ - struct storage_management - { - /** - * @brief Initialize global storage management. - * - * Creates the singleton instance, registers controllers and probes - * them for devices. - * - * @warning Panics if called more than once. - */ - auto static init() -> void; - - /** - * @brief Return the active storage manager singleton. - * @return Reference to the active storage manager. - * @warning Panics if storage management has not been initialized. - */ - auto static get() -> storage_management &; - - /** - * @brief Register a storage controller. - * @param controller Controller to register. - * - * Assigns controller IDs (major number range and minors per device). - */ - auto add_controller(kstd::shared_ptr const & controller) -> void; - - /** - * @brief Return all registered storage controllers. - * @return Vector of all registered storage controllers. - */ - [[nodiscard]] auto all_controllers() const -> kstd::vector> const &; - - /** - * @brief Find a device by major/minor numbers. - * @param major Device major number. - * @param minor Device minor number. - * @return Matching device, or nullptr if no device matches. - */ - auto device_by_major_minor(size_t major, size_t minor) -> kstd::shared_ptr; - - /** - * @brief Determine the boot device. - * @return Boot device, or nullptr if it cannot be determined. - */ - auto determine_boot_device() -> kstd::shared_ptr; - - private: - /** - * @brief Private default constructor for storage management singleton. - */ - storage_management() = default; - - kstd::vector> m_controllers{}; - }; -} // namespace kernel::devices::storage - -#endif \ No newline at end of file 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 diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp index e7d0e13..94c9b05 100644 --- a/kernel/src/filesystem/devfs/filesystem.cpp +++ b/kernel/src/filesystem/devfs/filesystem.cpp @@ -1,7 +1,7 @@ #include "kernel/filesystem/devfs/filesystem.hpp" #include "kernel/devices/device.hpp" -#include "kernel/devices/storage/storage_management.hpp" +#include "kernel/devices/storage/management.hpp" #include "kernel/filesystem/devfs/inode.hpp" #include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/inode.hpp" @@ -49,7 +49,7 @@ namespace kernel::filesystem::devfs { m_inodes.clear(); - auto storage_mgmt = devices::storage::storage_management::get(); + auto storage_mgmt = devices::storage::management::get(); std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto const & controller) { std::ranges::for_each(controller->all_devices(), [&](auto const & device) { m_inodes.push_back(kstd::make_shared(device)); }); diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index bee68e6..06214d2 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -2,7 +2,7 @@ #include "kapi/system.hpp" -#include "kernel/devices/storage/storage_management.hpp" +#include "kernel/devices/storage/management.hpp" #include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/devfs/filesystem.hpp" #include "kernel/filesystem/ext2/filesystem.hpp" @@ -43,7 +43,7 @@ namespace kernel::filesystem auto root_fs_root_dentry = kstd::make_shared(nullptr, root_fs->root_inode()); m_mount_table.add_mount(kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, "")); - auto storage_mgmt = devices::storage::storage_management::get(); + auto storage_mgmt = devices::storage::management::get(); if (auto boot_device = storage_mgmt.determine_boot_device()) { // TODO BA-FS26 detect fs type from boot device and load corresponding fs, for now just assume ext2 diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index ff73985..37b4c5b 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -5,7 +5,7 @@ #include "kapi/memory.hpp" #include "kapi/system.hpp" -#include "kernel/devices/storage/storage_management.hpp" +#include "kernel/devices/storage/management.hpp" #include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/filesystem/file_descriptor_table.hpp" @@ -24,7 +24,7 @@ auto test_device_names() -> void { - auto storage_mgmt = kernel::devices::storage::storage_management::get(); + auto storage_mgmt = kernel::devices::storage::management::get(); std::ranges::for_each(storage_mgmt.all_controllers(), [](auto const & controller) { std::ranges::for_each(controller->all_devices(), [](auto const & device) { kstd::println("{}", device->name().view()); }); @@ -35,7 +35,7 @@ auto test_file_description_manually() -> void { // setup auto fd_table = kernel::filesystem::file_descriptor_table::get(); - auto storage_mgmt = kernel::devices::storage::storage_management::get(); + auto storage_mgmt = kernel::devices::storage::management::get(); auto device = storage_mgmt.device_by_major_minor(1, 0); auto dev_node = kstd::make_shared(device); @@ -111,7 +111,7 @@ auto test_file_lookup() -> void // TODO BA-FS26 implement a more complete test with multiple files and directories and mounts etc. auto vfs = kernel::filesystem::vfs::get(); - auto storage_mgmt = kernel::devices::storage::storage_management::get(); + auto storage_mgmt = kernel::devices::storage::management::get(); auto ofd1 = vfs.open("/a/b/c"); auto ofd2 = vfs.open("/dev/ram0"); @@ -182,7 +182,7 @@ auto main() -> int kapi::boot_modules::init(); kstd::println("[OS] Boot module registry initialized."); - kernel::devices::storage::storage_management::init(); + kernel::devices::storage::management::init(); kstd::println("[OS] Storage management initialized."); kernel::filesystem::file_descriptor_table::init(); -- 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/CMakeLists.txt | 1 - kernel/include/kernel/devices/block_device.hpp | 4 +- .../include/kernel/devices/block_device_utils.hpp | 6 +-- kernel/include/kernel/devices/device.hpp | 62 ---------------------- .../include/kernel/devices/storage/controller.hpp | 8 +-- .../include/kernel/devices/storage/management.hpp | 6 +-- .../kernel/devices/storage/ram_disk/device.hpp | 6 +++ .../include/kernel/filesystem/devfs/filesystem.hpp | 4 +- kernel/include/kernel/filesystem/device_inode.hpp | 8 +-- .../include/kernel/filesystem/ext2/filesystem.hpp | 4 +- kernel/include/kernel/filesystem/filesystem.hpp | 6 +-- .../kernel/filesystem/rootfs/filesystem.hpp | 4 +- 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 ++- kernel/src/filesystem/devfs/filesystem.cpp | 4 +- kernel/src/filesystem/device_inode.cpp | 6 +-- kernel/src/filesystem/ext2/filesystem.cpp | 4 +- kernel/src/filesystem/filesystem.cpp | 4 +- kernel/src/filesystem/rootfs/filesystem.cpp | 4 +- 23 files changed, 62 insertions(+), 142 deletions(-) delete mode 100644 kernel/include/kernel/devices/device.hpp delete mode 100644 kernel/src/devices/device.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 10bfecb..cb3d8a5 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -17,7 +17,6 @@ add_executable("kernel" "src/memory/block_list_allocator.cpp" "src/memory/operators.cpp" "src/memory.cpp" - "src/devices/device.cpp" "src/devices/block_device.cpp" "src/devices/block_device_utils.cpp" "src/devices/storage/controller.cpp" diff --git a/kernel/include/kernel/devices/block_device.hpp b/kernel/include/kernel/devices/block_device.hpp index 619b815..43e6511 100644 --- a/kernel/include/kernel/devices/block_device.hpp +++ b/kernel/include/kernel/devices/block_device.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP #define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include @@ -12,7 +12,7 @@ namespace kernel::devices /** * @brief Base interface for block-addressable devices. */ - struct block_device : device + struct block_device : kapi::devices::device { /** * @brief Create a block device descriptor. diff --git a/kernel/include/kernel/devices/block_device_utils.hpp b/kernel/include/kernel/devices/block_device_utils.hpp index bb49d04..5e862ba 100644 --- a/kernel/include/kernel/devices/block_device_utils.hpp +++ b/kernel/include/kernel/devices/block_device_utils.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_UTILS_HPP #define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_UTILS_HPP -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include @@ -9,8 +9,8 @@ namespace kernel::devices::block_device_utils { - auto read(kstd::shared_ptr const & device, void * buffer, size_t offset, size_t size) -> size_t; - auto write(kstd::shared_ptr const & device, void const * buffer, size_t offset, size_t size) + auto read(kstd::shared_ptr const & device, void * buffer, size_t offset, size_t size) -> size_t; + auto write(kstd::shared_ptr const & device, void const * buffer, size_t offset, size_t size) -> size_t; } // namespace kernel::devices::block_device_utils diff --git a/kernel/include/kernel/devices/device.hpp b/kernel/include/kernel/devices/device.hpp deleted file mode 100644 index 67fa5ad..0000000 --- a/kernel/include/kernel/devices/device.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef TEACH_OS_KERNEL_DEVICES_DEVICE_HPP -#define TEACH_OS_KERNEL_DEVICES_DEVICE_HPP - -#include - -#include - -namespace kernel::devices -{ - /** - * @brief Base device identified by a major, minor number and name. - */ - struct device - { - /** - * @brief Create a device identifier from @p major, @p minor and @p name. - * @param major Device major number. - * @param minor Device minor number. - * @param name Device name. - */ - device(size_t major, size_t minor, kstd::string const & name); - - /** - * @brief Virtual destructor for device. - */ - virtual ~device() = default; - - /** - * @brief Returns the major number of the device. - * @return Device major number. - */ - [[nodiscard]] auto major() const -> size_t; - - /** - * @brief Returns the minor number of the device. - * @return Device minor number. - */ - [[nodiscard]] auto minor() const -> size_t; - - /** - * @brief Returns the name of the device. - * @return Device name. - */ - [[nodiscard]] auto name() const -> kstd::string const &; - - /** - * @brief Check if the device is a block device. - * @return true if this device is a block device, false otherwise. - */ - [[nodiscard]] virtual auto is_block_device() const -> bool - { - return false; - } - - private: - size_t m_major; - size_t m_minor; - kstd::string m_name; - }; -} // namespace kernel::devices - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/devices/storage/controller.hpp b/kernel/include/kernel/devices/storage/controller.hpp index e3bfd01..a91e452 100644 --- a/kernel/include/kernel/devices/storage/controller.hpp +++ b/kernel/include/kernel/devices/storage/controller.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_CONTROLLER_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_CONTROLLER_HPP -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include #include @@ -51,7 +51,7 @@ namespace kernel::devices::storage * @brief Return all devices managed by this controller. * @return Vector of all managed devices. */ - [[nodiscard]] auto all_devices() const -> kstd::vector> const &; + [[nodiscard]] auto all_devices() const -> kstd::vector> const &; /** * @brief Find a managed device by major/minor numbers. @@ -59,12 +59,12 @@ namespace kernel::devices::storage * @param minor Device minor number. * @return Matching block device, or nullptr if no device matches. */ - [[nodiscard]] auto device_by_minor(size_t minor) const -> kstd::shared_ptr; + [[nodiscard]] auto device_by_minor(size_t minor) const -> kstd::shared_ptr; protected: size_t m_major{}; size_t m_minors_per_device{}; - kstd::vector> m_devices{}; + kstd::vector> m_devices{}; }; } // namespace kernel::devices::storage diff --git a/kernel/include/kernel/devices/storage/management.hpp b/kernel/include/kernel/devices/storage/management.hpp index 255d170..0176ce1 100644 --- a/kernel/include/kernel/devices/storage/management.hpp +++ b/kernel/include/kernel/devices/storage/management.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_MANAGEMENT_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_MANAGEMENT_HPP -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include "kernel/devices/storage/controller.hpp" #include @@ -56,13 +56,13 @@ namespace kernel::devices::storage * @param minor Device minor number. * @return Matching device, or nullptr if no device matches. */ - auto device_by_major_minor(size_t major, size_t minor) -> kstd::shared_ptr; + auto device_by_major_minor(size_t major, size_t minor) -> kstd::shared_ptr; /** * @brief Determine the boot device. * @return Boot device, or nullptr if it cannot be determined. */ - auto determine_boot_device() -> kstd::shared_ptr; + auto determine_boot_device() -> kstd::shared_ptr; private: /** diff --git a/kernel/include/kernel/devices/storage/ram_disk/device.hpp b/kernel/include/kernel/devices/storage/ram_disk/device.hpp index 0777e86..e17416e 100644 --- a/kernel/include/kernel/devices/storage/ram_disk/device.hpp +++ b/kernel/include/kernel/devices/storage/ram_disk/device.hpp @@ -22,6 +22,12 @@ namespace kernel::devices::storage::ram_disk */ device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor); + /** + * @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. diff --git a/kernel/include/kernel/filesystem/devfs/filesystem.hpp b/kernel/include/kernel/filesystem/devfs/filesystem.hpp index 5ec6221..29ae388 100644 --- a/kernel/include/kernel/filesystem/devfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/devfs/filesystem.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVFS_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_FILESYSTEM_HPP -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" @@ -14,7 +14,7 @@ namespace kernel::filesystem::devfs { struct filesystem : kernel::filesystem::filesystem { - auto mount(kstd::shared_ptr const & device) -> int override; + auto mount(kstd::shared_ptr const & device) -> int override; auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index 7f044b0..18a98f5 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include "kernel/filesystem/inode.hpp" #include @@ -12,15 +12,15 @@ namespace kernel::filesystem { struct device_inode : inode { - explicit device_inode(kstd::shared_ptr const & device); + explicit device_inode(kstd::shared_ptr const & device); auto read(void * buffer, size_t offset, size_t size) const -> size_t override; auto write(void const * buffer, size_t offset, size_t size) -> size_t override; - [[nodiscard]] auto device() const -> kstd::shared_ptr const &; + [[nodiscard]] auto device() const -> kstd::shared_ptr const &; private: - kstd::shared_ptr m_device; + kstd::shared_ptr m_device; }; } // namespace kernel::filesystem diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index 763cd1d..078da31 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" @@ -13,7 +13,7 @@ namespace kernel::filesystem::ext2 { struct filesystem : kernel::filesystem::filesystem { - auto mount(kstd::shared_ptr const & device) -> int override; + auto mount(kstd::shared_ptr const & device) -> int override; auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; }; diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index c50a86c..1d86178 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include "kernel/filesystem/inode.hpp" #include @@ -15,14 +15,14 @@ namespace kernel::filesystem { virtual ~filesystem() = default; - virtual auto mount(kstd::shared_ptr const & device) -> int; + virtual auto mount(kstd::shared_ptr const & device) -> int; virtual auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr = 0; [[nodiscard]] auto root_inode() const -> kstd::shared_ptr const &; protected: kstd::shared_ptr m_root_inode{}; - kstd::shared_ptr m_device{}; + kstd::shared_ptr m_device{}; kstd::vector> m_inodes{}; }; diff --git a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp index b1f33a9..5632d86 100644 --- a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_FILESYSTEM_HPP -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" @@ -15,7 +15,7 @@ namespace kernel::filesystem::rootfs { struct filesystem : kernel::filesystem::filesystem { - auto mount(kstd::shared_ptr const & device) -> int override; + auto mount(kstd::shared_ptr const & device) -> int override; auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; }; 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) diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp index 94c9b05..9043ac5 100644 --- a/kernel/src/filesystem/devfs/filesystem.cpp +++ b/kernel/src/filesystem/devfs/filesystem.cpp @@ -1,6 +1,6 @@ #include "kernel/filesystem/devfs/filesystem.hpp" -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include "kernel/devices/storage/management.hpp" #include "kernel/filesystem/devfs/inode.hpp" #include "kernel/filesystem/device_inode.hpp" @@ -13,7 +13,7 @@ namespace kernel::filesystem::devfs { - auto filesystem::mount(kstd::shared_ptr const &) -> int + auto filesystem::mount(kstd::shared_ptr const &) -> int { m_root_inode = kstd::make_shared(); build_device_inode_table(); diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp index d574d8f..af8cecc 100644 --- a/kernel/src/filesystem/device_inode.cpp +++ b/kernel/src/filesystem/device_inode.cpp @@ -3,7 +3,7 @@ #include "kapi/system.hpp" #include "kernel/devices/block_device_utils.hpp" -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include "kernel/filesystem/inode.hpp" #include @@ -14,7 +14,7 @@ namespace kernel::filesystem { - device_inode::device_inode(kstd::shared_ptr const & device) + device_inode::device_inode(kstd::shared_ptr const & device) : inode(inode_kind::device) , m_device(device) { @@ -48,7 +48,7 @@ namespace kernel::filesystem } } - auto device_inode::device() const -> kstd::shared_ptr const & + auto device_inode::device() const -> kstd::shared_ptr const & { return m_device; } diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index d951158..eb9edc4 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -1,7 +1,7 @@ #include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/devices/block_device_utils.hpp" -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include "kernel/filesystem/ext2/inode.hpp" #include "kernel/filesystem/ext2/superblock.hpp" #include "kernel/filesystem/filesystem.hpp" @@ -45,7 +45,7 @@ namespace kernel::filesystem::ext2 // } } // namespace - auto filesystem::mount(kstd::shared_ptr const & device) -> int + auto filesystem::mount(kstd::shared_ptr const & device) -> int { kernel::filesystem::filesystem::mount(device); // TODO BA-FS26 error handling? // TODO BA-FS26 load proper root inode from ext2 metadata diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index c891d00..0ac9cf8 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -1,13 +1,13 @@ #include "kernel/filesystem/filesystem.hpp" -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include "kernel/filesystem/inode.hpp" #include namespace kernel::filesystem { - auto filesystem::mount(kstd::shared_ptr const & device) -> int + auto filesystem::mount(kstd::shared_ptr const & device) -> int { if (!device) { diff --git a/kernel/src/filesystem/rootfs/filesystem.cpp b/kernel/src/filesystem/rootfs/filesystem.cpp index 0133612..37bf588 100644 --- a/kernel/src/filesystem/rootfs/filesystem.cpp +++ b/kernel/src/filesystem/rootfs/filesystem.cpp @@ -1,6 +1,6 @@ #include "kernel/filesystem/rootfs/filesystem.hpp" -#include "kernel/devices/device.hpp" +#include "kapi/devices/device.hpp" #include "kernel/filesystem/inode.hpp" #include "kernel/filesystem/rootfs/inode.hpp" @@ -10,7 +10,7 @@ namespace kernel::filesystem::rootfs { - auto filesystem::mount(kstd::shared_ptr const &) -> int + auto filesystem::mount(kstd::shared_ptr const &) -> int { auto rfs_inode = kstd::make_shared(); rfs_inode->add_child("dev"); -- cgit v1.2.3 From cd70186845c90aaaefbdb21b6d0f3c7caaa90a27 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 08:01:28 +0200 Subject: kernel: split off objects into a library --- kernel/CMakeLists.txt | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index cb3d8a5..206923e 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable("kernel" +add_library("kernel-objs" OBJECT # Platform-independent KAPI implementation "kapi/boot_modules.cpp" "kapi/cio.cpp" @@ -40,13 +40,29 @@ add_executable("kernel" "src/filesystem/vfs.cpp" ) -target_include_directories("kernel" PRIVATE +target_include_directories("kernel-objs" PUBLIC "include" ) +target_link_libraries("kernel-objs" PRIVATE + "os::kapi" +) + +file(GLOB_RECURSE KERNEL_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "include/**.hpp") + +target_sources("kernel-objs" PUBLIC + FILE_SET HEADERS + BASE_DIRS "include" + FILES + ${KERNEL_HEADERS} +) + +add_executable("kernel" + $ +) + target_link_libraries("kernel" PRIVATE "os::arch" - "os::kapi" ) target_link_options("kernel" PRIVATE @@ -61,15 +77,6 @@ set_property(TARGET "kernel" "${KERNEL_LINKER_SCRIPT}" ) -file(GLOB_RECURSE KERNEL_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "include/**.hpp") - -target_sources("kernel" PUBLIC - FILE_SET HEADERS - BASE_DIRS "include" - FILES - ${KERNEL_HEADERS} -) - target_disassemble("kernel") target_extract_debug_symbols("kernel") target_strip("kernel") -- cgit v1.2.3 From 9b80bd2ca528a376c2bb6831020b3d78e4b252d6 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 08:10:10 +0200 Subject: build: fix kernel+arch build --- kernel/CMakeLists.txt | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 206923e..4aa72e1 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -12,7 +12,6 @@ add_library("kernel-objs" OBJECT "kstd/print.cpp" # Kernel Implementation - "src/main.cpp" "src/memory/bitmap_allocator.cpp" "src/memory/block_list_allocator.cpp" "src/memory/operators.cpp" @@ -44,7 +43,7 @@ target_include_directories("kernel-objs" PUBLIC "include" ) -target_link_libraries("kernel-objs" PRIVATE +target_link_libraries("kernel-objs" PUBLIC "os::kapi" ) @@ -57,28 +56,34 @@ target_sources("kernel-objs" PUBLIC ${KERNEL_HEADERS} ) -add_executable("kernel" - $ -) +add_library("os::kernel" ALIAS "kernel-objs") -target_link_libraries("kernel" PRIVATE - "os::arch" -) +if(CMAKE_CROSSCOMPILING) + add_executable("kernel" + "src/main.cpp" + ) -target_link_options("kernel" PRIVATE - "-T${KERNEL_LINKER_SCRIPT}" - "-no-pie" - "-nostdlib" -) + target_link_libraries("kernel" PRIVATE + "os::arch" + "os::kernel" + ) -set_property(TARGET "kernel" - APPEND - PROPERTY LINK_DEPENDS - "${KERNEL_LINKER_SCRIPT}" -) + target_link_options("kernel" PRIVATE + "-T${KERNEL_LINKER_SCRIPT}" + "-no-pie" + "-nostdlib" + ) + + set_property(TARGET "kernel" + APPEND + PROPERTY LINK_DEPENDS + "${KERNEL_LINKER_SCRIPT}" + ) + + target_disassemble("kernel") + target_extract_debug_symbols("kernel") + target_strip("kernel") -target_disassemble("kernel") -target_extract_debug_symbols("kernel") -target_strip("kernel") + target_generate_bootable_iso("kernel") +endif() -target_generate_bootable_iso("kernel") -- cgit v1.2.3 From 5ae03c52fe33882416aa6044993d8422ccb33ab4 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 08:49:21 +0200 Subject: kernel: begin basic bht implementation --- kernel/CMakeLists.txt | 15 ++++++---- kernel/tests/CMakeLists.txt | 49 +++++++++++++++++++++++++++++++ kernel/tests/include/kernel/tests/cpu.hpp | 18 ++++++++++++ kernel/tests/kapi/cpu.cpp | 13 ++++++++ kernel/tests/src/main.cpp | 6 ++++ kernel/tests/src/test_support.cpp | 19 ++++++++++++ 6 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 kernel/tests/CMakeLists.txt create mode 100644 kernel/tests/include/kernel/tests/cpu.hpp create mode 100644 kernel/tests/kapi/cpu.cpp create mode 100644 kernel/tests/src/main.cpp create mode 100644 kernel/tests/src/test_support.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 4aa72e1..854fb33 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,4 +1,4 @@ -add_library("kernel-objs" OBJECT +add_library("kernel_objs" OBJECT # Platform-independent KAPI implementation "kapi/boot_modules.cpp" "kapi/cio.cpp" @@ -14,7 +14,6 @@ add_library("kernel-objs" OBJECT # Kernel Implementation "src/memory/bitmap_allocator.cpp" "src/memory/block_list_allocator.cpp" - "src/memory/operators.cpp" "src/memory.cpp" "src/devices/block_device.cpp" "src/devices/block_device_utils.cpp" @@ -39,28 +38,29 @@ add_library("kernel-objs" OBJECT "src/filesystem/vfs.cpp" ) -target_include_directories("kernel-objs" PUBLIC +target_include_directories("kernel_objs" PUBLIC "include" ) -target_link_libraries("kernel-objs" PUBLIC +target_link_libraries("kernel_objs" PUBLIC "os::kapi" ) file(GLOB_RECURSE KERNEL_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "include/**.hpp") -target_sources("kernel-objs" PUBLIC +target_sources("kernel_objs" PUBLIC FILE_SET HEADERS BASE_DIRS "include" FILES ${KERNEL_HEADERS} ) -add_library("os::kernel" ALIAS "kernel-objs") +add_library("os::kernel" ALIAS "kernel_objs") if(CMAKE_CROSSCOMPILING) add_executable("kernel" "src/main.cpp" + "src/memory/operators.cpp" ) target_link_libraries("kernel" PRIVATE @@ -85,5 +85,8 @@ if(CMAKE_CROSSCOMPILING) target_strip("kernel") target_generate_bootable_iso("kernel") +else() + enable_coverage("kernel_objs") + add_subdirectory("tests") endif() diff --git a/kernel/tests/CMakeLists.txt b/kernel/tests/CMakeLists.txt new file mode 100644 index 0000000..96053f1 --- /dev/null +++ b/kernel/tests/CMakeLists.txt @@ -0,0 +1,49 @@ +#[============================================================================[ +# Kernel Test Support (Fakes, Stubs, Mocks, etc.) +#]============================================================================] + +add_library("kernel_test_support" + "kapi/cpu.cpp" +) + +target_include_directories("kernel_test_support" PUBLIC + "include" +) + +target_link_libraries("kernel_test_support" PUBLIC + "os::kapi" +) + +add_library("os::kernel_test_support" ALIAS "kernel_test_support") + +#[============================================================================[ +# Kernel Tests +#]============================================================================] + +add_executable("kernel_tests" + "src/main.cpp" + "src/test_support.cpp" +) + +target_include_directories("kernel_tests" PRIVATE + "include" +) + +target_link_libraries("kernel_tests" PRIVATE + "os::kernel_test_support" + "os::kernel" + "libs::kstd" + "Catch2::Catch2" +) + +set_target_properties("kernel_tests" PROPERTIES + C_CLANG_TIDY "" + CXX_CLANG_TIDY "" + EXCLUDE_FROM_ALL NO +) + +enable_coverage("kernel_tests") + +add_executable("os::kernel_tests" ALIAS "kernel_tests") + +catch_discover_tests("os::kernel_tests") \ No newline at end of file diff --git a/kernel/tests/include/kernel/tests/cpu.hpp b/kernel/tests/include/kernel/tests/cpu.hpp new file mode 100644 index 0000000..81c0c6f --- /dev/null +++ b/kernel/tests/include/kernel/tests/cpu.hpp @@ -0,0 +1,18 @@ +#ifndef TEACHOS_KERNEL_TESTS_CPU_HPP +#define TEACHOS_KERNEL_TESTS_CPU_HPP + +#include + +namespace kernel::tests::cpu +{ + + struct halt : std::runtime_error + { + halt() + : std::runtime_error{"CPU halt requested!"} + {} + }; + +} // namespace kernel::tests::cpu + +#endif \ No newline at end of file diff --git a/kernel/tests/kapi/cpu.cpp b/kernel/tests/kapi/cpu.cpp new file mode 100644 index 0000000..f03fca0 --- /dev/null +++ b/kernel/tests/kapi/cpu.cpp @@ -0,0 +1,13 @@ +#include "kernel/tests/cpu.hpp" + +#include + +namespace kapi::cpu +{ + + auto halt() -> void + { + throw kernel::tests::cpu::halt{}; + } + +} // namespace kapi::cpu \ No newline at end of file diff --git a/kernel/tests/src/main.cpp b/kernel/tests/src/main.cpp new file mode 100644 index 0000000..89bb1c7 --- /dev/null +++ b/kernel/tests/src/main.cpp @@ -0,0 +1,6 @@ +#include + +auto main(int argc, char ** argv) -> int +{ + return Catch::Session().run(argc, argv); +} \ No newline at end of file diff --git a/kernel/tests/src/test_support.cpp b/kernel/tests/src/test_support.cpp new file mode 100644 index 0000000..bbf5dc0 --- /dev/null +++ b/kernel/tests/src/test_support.cpp @@ -0,0 +1,19 @@ +#include "kapi/cpu.hpp" + +#include "kernel/tests/cpu.hpp" + +#include + +SCENARIO("Kernel test support infrastructure", "[support]") +{ + GIVEN("the test support infrastructure is initialized") + { + WHEN("when a CPU halt is requested") + { + THEN("the correct exception is thrown") + { + REQUIRE_THROWS_AS(kapi::cpu::halt(), kernel::tests::cpu::halt); + } + } + } +} \ No newline at end of file -- cgit v1.2.3 From fa1ea53e6f3dd6b9b5f5f8160776b230184a30bf Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 09:36:31 +0200 Subject: kernel/tests: implement platform CIO kapi --- kernel/tests/CMakeLists.txt | 5 ++- kernel/tests/include/kernel/tests/log_buffer.hpp | 32 +++++++++++++++ kernel/tests/kapi/cio.cpp | 38 ++++++++++++++++++ kernel/tests/src/log_buffer.cpp | 39 ++++++++++++++++++ kernel/tests/src/main.cpp | 4 ++ kernel/tests/src/test_support.cpp | 19 --------- kernel/tests/src/test_support.tests.cpp | 51 ++++++++++++++++++++++++ 7 files changed, 168 insertions(+), 20 deletions(-) create mode 100644 kernel/tests/include/kernel/tests/log_buffer.hpp create mode 100644 kernel/tests/kapi/cio.cpp create mode 100644 kernel/tests/src/log_buffer.cpp delete mode 100644 kernel/tests/src/test_support.cpp create mode 100644 kernel/tests/src/test_support.tests.cpp (limited to 'kernel') diff --git a/kernel/tests/CMakeLists.txt b/kernel/tests/CMakeLists.txt index 96053f1..39ab3b7 100644 --- a/kernel/tests/CMakeLists.txt +++ b/kernel/tests/CMakeLists.txt @@ -3,6 +3,7 @@ #]============================================================================] add_library("kernel_test_support" + "kapi/cio.cpp" "kapi/cpu.cpp" ) @@ -21,8 +22,10 @@ add_library("os::kernel_test_support" ALIAS "kernel_test_support") #]============================================================================] add_executable("kernel_tests" + "src/log_buffer.cpp" "src/main.cpp" - "src/test_support.cpp" + + "src/test_support.tests.cpp" ) target_include_directories("kernel_tests" PRIVATE diff --git a/kernel/tests/include/kernel/tests/log_buffer.hpp b/kernel/tests/include/kernel/tests/log_buffer.hpp new file mode 100644 index 0000000..5f2a1a7 --- /dev/null +++ b/kernel/tests/include/kernel/tests/log_buffer.hpp @@ -0,0 +1,32 @@ +#ifndef KERNEL_TESTS_LOG_BUFFER_HPP +#define KERNEL_TESTS_LOG_BUFFER_HPP + +#include +#include + +namespace kernel::tests::log_buffer +{ + + //! Append a message to the testing log buffer. + //! + //! @param message The message to append. + auto append(std::string const & message) -> void; + + //! Clear the testing log buffer. + auto clear() -> void; + + //! Get the testing log buffer as a single string. + //! + //! @return The testing log buffer as a single string. + auto flat_messages() -> std::string; + + //! Get the testing log buffer. + //! + //! @note Messages may be split across multiple entries if they are longer than the internal kernel print buffer size. + //! + //! @return The testing log buffer. + auto messages() -> std::vector const &; + +} // namespace kernel::tests::log_buffer + +#endif \ No newline at end of file diff --git a/kernel/tests/kapi/cio.cpp b/kernel/tests/kapi/cio.cpp new file mode 100644 index 0000000..6359fa8 --- /dev/null +++ b/kernel/tests/kapi/cio.cpp @@ -0,0 +1,38 @@ +#include + +#include "kernel/tests/log_buffer.hpp" + +#include +#include +#include + +namespace kapi::cio +{ + + namespace + { + + class test_output_device : public output_device + { + public: + test_output_device() = default; + + auto write(output_stream stream, std::string_view text) -> void override + { + auto & standard_stream = stream == output_stream::stdout ? std::cout : std::cerr; + standard_stream << text; + if (text != "\n") + { + kernel::tests::log_buffer::append(std::string{text}); + } + } + } device{}; + + } // namespace + + auto init() -> void + { + set_output_device(device); + } + +} // namespace kapi::cio \ No newline at end of file diff --git a/kernel/tests/src/log_buffer.cpp b/kernel/tests/src/log_buffer.cpp new file mode 100644 index 0000000..9e30afb --- /dev/null +++ b/kernel/tests/src/log_buffer.cpp @@ -0,0 +1,39 @@ +#include "kernel/tests/log_buffer.hpp" + +#include +#include +#include + +namespace kernel::tests::log_buffer +{ + + namespace + { + std::vector recorded_messages{}; + } + + auto append(std::string const & message) -> void + { + recorded_messages.push_back(message); + } + + auto clear() -> void + { + recorded_messages.clear(); + } + + auto flat_messages() -> std::string + { + return std::ranges::fold_left(recorded_messages, std::string{}, + [](std::string accumulator, std::string const & message) { + accumulator += message; + return accumulator; + }); + } + + auto messages() -> std::vector const & + { + return recorded_messages; + } + +} // namespace kernel::tests::log_buffer diff --git a/kernel/tests/src/main.cpp b/kernel/tests/src/main.cpp index 89bb1c7..f1f9bb4 100644 --- a/kernel/tests/src/main.cpp +++ b/kernel/tests/src/main.cpp @@ -1,6 +1,10 @@ +#include + #include auto main(int argc, char ** argv) -> int { + kapi::cio::init(); + return Catch::Session().run(argc, argv); } \ No newline at end of file diff --git a/kernel/tests/src/test_support.cpp b/kernel/tests/src/test_support.cpp deleted file mode 100644 index bbf5dc0..0000000 --- a/kernel/tests/src/test_support.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "kapi/cpu.hpp" - -#include "kernel/tests/cpu.hpp" - -#include - -SCENARIO("Kernel test support infrastructure", "[support]") -{ - GIVEN("the test support infrastructure is initialized") - { - WHEN("when a CPU halt is requested") - { - THEN("the correct exception is thrown") - { - REQUIRE_THROWS_AS(kapi::cpu::halt(), kernel::tests::cpu::halt); - } - } - } -} \ No newline at end of file diff --git a/kernel/tests/src/test_support.tests.cpp b/kernel/tests/src/test_support.tests.cpp new file mode 100644 index 0000000..f835e65 --- /dev/null +++ b/kernel/tests/src/test_support.tests.cpp @@ -0,0 +1,51 @@ +#include "kapi/cpu.hpp" +#include "kapi/system.hpp" + +#include "kernel/tests/cpu.hpp" +#include "kernel/tests/log_buffer.hpp" + +#include + +#include + +SCENARIO("Kernel test support infrastructure", "[support]") +{ + GIVEN("the test support infrastructure is initialized") + { + WHEN("a CPU halt is requested") + { + THEN("the correct exception is thrown") + { + REQUIRE_THROWS_AS(kapi::cpu::halt(), kernel::tests::cpu::halt); + } + } + + WHEN("a the system panics") + { + kernel::tests::log_buffer::clear(); + + THEN("the correct exception is thrown") + { + REQUIRE_THROWS_AS(kapi::system::panic("[kernel:tests] Test Panic"), kernel::tests::cpu::halt); + } + + THEN("the message is appended to the log buffer") + { + CHECK_THROWS(kapi::system::panic("[kernel:tests] Test Panic")); + REQUIRE(kernel::tests::log_buffer::flat_messages().contains("[kernel:tests] Test Panic")); + } + } + + WHEN("a regular print is issued") + { + kernel::tests::log_buffer::clear(); + + kstd::println("[kernel:tests] Test Print"); + + THEN("the message is appended to the log buffer") + { + REQUIRE(kernel::tests::log_buffer::flat_messages().contains("[kernel:tests] Test Print")); + } + } + } +} \ No newline at end of file -- cgit v1.2.3 From 0b139b3c66b340bb560dc608ea3b15a07ec95ee3 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 09:48:12 +0200 Subject: kernel/tests: add kapi::cpu::init stub --- kernel/tests/kapi/cpu.cpp | 16 ++++++++++++++++ kernel/tests/src/main.cpp | 4 +++- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/tests/kapi/cpu.cpp b/kernel/tests/kapi/cpu.cpp index f03fca0..3ecaadc 100644 --- a/kernel/tests/kapi/cpu.cpp +++ b/kernel/tests/kapi/cpu.cpp @@ -2,9 +2,25 @@ #include +#include +#include + namespace kapi::cpu { + auto init() -> void + { + auto static initialized = std::atomic_flag{}; + if (initialized.test_and_set()) + { + throw std::logic_error("kapi::cpu::init() called more than once"); + } + + // TODO: make sure that simulated interrupt can run. + + return; + } + auto halt() -> void { throw kernel::tests::cpu::halt{}; diff --git a/kernel/tests/src/main.cpp b/kernel/tests/src/main.cpp index f1f9bb4..a21aa9d 100644 --- a/kernel/tests/src/main.cpp +++ b/kernel/tests/src/main.cpp @@ -1,10 +1,12 @@ #include +#include #include auto main(int argc, char ** argv) -> int { kapi::cio::init(); + kapi::cpu::init(); return Catch::Session().run(argc, argv); -} \ No newline at end of file +} -- cgit v1.2.3 From b4049de007f9d15c12db227e4745a559359a99e9 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 09:51:42 +0200 Subject: kernel/tests: add kapi::interrupts::init stub --- kernel/tests/CMakeLists.txt | 9 +++++---- kernel/tests/kapi/interrupts.cpp | 11 +++++++++++ kernel/tests/src/main.cpp | 2 ++ 3 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 kernel/tests/kapi/interrupts.cpp (limited to 'kernel') diff --git a/kernel/tests/CMakeLists.txt b/kernel/tests/CMakeLists.txt index 39ab3b7..2fe5ff3 100644 --- a/kernel/tests/CMakeLists.txt +++ b/kernel/tests/CMakeLists.txt @@ -5,6 +5,10 @@ add_library("kernel_test_support" "kapi/cio.cpp" "kapi/cpu.cpp" + "kapi/interrupts.cpp" + + "src/log_buffer.cpp" + "src/main.cpp" ) target_include_directories("kernel_test_support" PUBLIC @@ -13,6 +17,7 @@ target_include_directories("kernel_test_support" PUBLIC target_link_libraries("kernel_test_support" PUBLIC "os::kapi" + "Catch2::Catch2" ) add_library("os::kernel_test_support" ALIAS "kernel_test_support") @@ -22,9 +27,6 @@ add_library("os::kernel_test_support" ALIAS "kernel_test_support") #]============================================================================] add_executable("kernel_tests" - "src/log_buffer.cpp" - "src/main.cpp" - "src/test_support.tests.cpp" ) @@ -36,7 +38,6 @@ target_link_libraries("kernel_tests" PRIVATE "os::kernel_test_support" "os::kernel" "libs::kstd" - "Catch2::Catch2" ) set_target_properties("kernel_tests" PROPERTIES diff --git a/kernel/tests/kapi/interrupts.cpp b/kernel/tests/kapi/interrupts.cpp new file mode 100644 index 0000000..0077266 --- /dev/null +++ b/kernel/tests/kapi/interrupts.cpp @@ -0,0 +1,11 @@ +#include + +namespace kapi::interrupts +{ + + auto enable() -> void + { + // TODO: enable simulated interrupts. + } + +} // namespace kapi::interrupts \ No newline at end of file diff --git a/kernel/tests/src/main.cpp b/kernel/tests/src/main.cpp index a21aa9d..11e88a4 100644 --- a/kernel/tests/src/main.cpp +++ b/kernel/tests/src/main.cpp @@ -1,3 +1,4 @@ +#include "kapi/interrupts.hpp" #include #include @@ -7,6 +8,7 @@ auto main(int argc, char ** argv) -> int { kapi::cio::init(); kapi::cpu::init(); + kapi::interrupts::enable(); return Catch::Session().run(argc, argv); } -- cgit v1.2.3 From c30ba8bc8c1cf80a7e9b46e9f1a66dc1b409fcbd Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 10:04:40 +0200 Subject: kernel/tests: add kapi::memory::init stub --- kernel/tests/CMakeLists.txt | 1 + kernel/tests/kapi/memory.cpp | 11 +++++++++++ kernel/tests/src/main.cpp | 3 +++ 3 files changed, 15 insertions(+) create mode 100644 kernel/tests/kapi/memory.cpp (limited to 'kernel') diff --git a/kernel/tests/CMakeLists.txt b/kernel/tests/CMakeLists.txt index 2fe5ff3..0e2ea36 100644 --- a/kernel/tests/CMakeLists.txt +++ b/kernel/tests/CMakeLists.txt @@ -6,6 +6,7 @@ add_library("kernel_test_support" "kapi/cio.cpp" "kapi/cpu.cpp" "kapi/interrupts.cpp" + "kapi/memory.cpp" "src/log_buffer.cpp" "src/main.cpp" diff --git a/kernel/tests/kapi/memory.cpp b/kernel/tests/kapi/memory.cpp new file mode 100644 index 0000000..4482c74 --- /dev/null +++ b/kernel/tests/kapi/memory.cpp @@ -0,0 +1,11 @@ +#include + +namespace kapi::memory +{ + + auto init() -> void + { + // TODO: initialize simulated memory. + } + +} // namespace kapi::memory \ No newline at end of file diff --git a/kernel/tests/src/main.cpp b/kernel/tests/src/main.cpp index 11e88a4..c0ec12f 100644 --- a/kernel/tests/src/main.cpp +++ b/kernel/tests/src/main.cpp @@ -1,4 +1,5 @@ #include "kapi/interrupts.hpp" +#include "kapi/memory.hpp" #include #include @@ -10,5 +11,7 @@ auto main(int argc, char ** argv) -> int kapi::cpu::init(); kapi::interrupts::enable(); + kapi::memory::init(); + return Catch::Session().run(argc, argv); } -- cgit v1.2.3 From 419f4bebff5745b46bf30092dc7a7ca43449ea2e Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 11:12:20 +0200 Subject: kernel/tests: implement basic simulated memory --- kernel/kapi/memory.cpp | 8 ++- kernel/tests/CMakeLists.txt | 14 +++- .../include/kernel/tests/simulated_memory.hpp | 19 ++++++ kernel/tests/kapi/memory.cpp | 77 +++++++++++++++++++++- kernel/tests/src/main.cpp | 4 ++ kernel/tests/src/simulated_memory.cpp | 33 ++++++++++ 6 files changed, 150 insertions(+), 5 deletions(-) create mode 100644 kernel/tests/include/kernel/tests/simulated_memory.hpp create mode 100644 kernel/tests/src/simulated_memory.cpp (limited to 'kernel') diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp index 2803d76..06a3165 100644 --- a/kernel/kapi/memory.cpp +++ b/kernel/kapi/memory.cpp @@ -125,14 +125,18 @@ namespace kapi::memory } auto const flags = page_mapper::flags::writable | page_mapper::flags::supervisor_only | page_mapper::flags::global; + auto bitmap_ptr = static_cast(nullptr); std::ranges::for_each(std::views::iota(0uz, bitmap_pages), [&](auto index) { auto page = page::containing(pmm_metadata_base + index * page::size); auto frame = memory::frame(bitmap_frames->first.number() + index); - active_page_mapper->map(page, frame, flags); + auto mapped = active_page_mapper->map(page, frame, flags); + if (!bitmap_ptr) + { + bitmap_ptr = reinterpret_cast(mapped); + } }); - auto bitmap_ptr = static_cast(pmm_metadata_base); auto bitmap = std::span{bitmap_ptr, (bitmap_bytes + kstd::type_size - 1_B) / kstd::type_size}; diff --git a/kernel/tests/CMakeLists.txt b/kernel/tests/CMakeLists.txt index 0e2ea36..0855520 100644 --- a/kernel/tests/CMakeLists.txt +++ b/kernel/tests/CMakeLists.txt @@ -7,9 +7,19 @@ add_library("kernel_test_support" "kapi/cpu.cpp" "kapi/interrupts.cpp" "kapi/memory.cpp" - + "src/log_buffer.cpp" "src/main.cpp" + "src/simulated_memory.cpp" +) + +file(GLOB_RECURSE KERNEL_TEST_SUPPORT_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "include/**.hpp") + +target_sources("kernel_test_support" PUBLIC + FILE_SET HEADERS + BASE_DIRS "include" + FILES + ${KERNEL_TEST_SUPPORT_HEADERS} ) target_include_directories("kernel_test_support" PUBLIC @@ -18,6 +28,7 @@ target_include_directories("kernel_test_support" PUBLIC target_link_libraries("kernel_test_support" PUBLIC "os::kapi" + "os::kernel" "Catch2::Catch2" ) @@ -37,7 +48,6 @@ target_include_directories("kernel_tests" PRIVATE target_link_libraries("kernel_tests" PRIVATE "os::kernel_test_support" - "os::kernel" "libs::kstd" ) diff --git a/kernel/tests/include/kernel/tests/simulated_memory.hpp b/kernel/tests/include/kernel/tests/simulated_memory.hpp new file mode 100644 index 0000000..156b1e1 --- /dev/null +++ b/kernel/tests/include/kernel/tests/simulated_memory.hpp @@ -0,0 +1,19 @@ +#ifndef TEACHOS_KERNEL_TESTS_SIMULATED_MEMORY_HPP +#define TEACHOS_KERNEL_TESTS_SIMULATED_MEMORY_HPP + +#include + +#include + +namespace kernel::tests::simulated_memory +{ + + auto init(kstd::units::bytes size) -> void; + + auto pmm_metadata_base() -> std::byte *; + + auto ram_base() -> std::byte *; + +} // namespace kernel::tests::simulated_memory + +#endif \ No newline at end of file diff --git a/kernel/tests/kapi/memory.cpp b/kernel/tests/kapi/memory.cpp index 4482c74..6de2f60 100644 --- a/kernel/tests/kapi/memory.cpp +++ b/kernel/tests/kapi/memory.cpp @@ -1,11 +1,86 @@ +#include "kapi/memory.hpp" + #include +#include "kernel/tests/simulated_memory.hpp" + +#include +#include + +#include +#include +#include +#include + namespace kapi::memory { + namespace + { + //! The size of the simulated RAM. + constexpr auto simulate_memory_size = kstd::units::MiB(32); + + struct test_boostrap_frame_allocator : frame_allocator + { + auto mark_used(frame) -> void override {} + + auto allocate_many(std::size_t count) noexcept -> std::optional> override + { + auto start = next_free_frame; + next_free_frame += count; + return std::pair{frame{start}, count}; + } + + auto release_many(std::pair) -> void override {} + + std::size_t next_free_frame{}; + } boostrap_allocator; + + struct test_page_mapper : page_mapper + { + auto map(page page, frame frame, flags flags) -> std::byte * override + { + kstd::println("mapping page {} onto frame {} with flags {}", page.number(), frame.number(), + static_cast(flags)); + + if ((page.start_address() & pmm_metadata_base.raw()) == pmm_metadata_base.raw()) + { + auto offset = page.start_address() & ~pmm_metadata_base.raw(); + return kernel::tests::simulated_memory::pmm_metadata_base() + offset; + } + + return nullptr; + } + + auto unmap(page page) -> void override + { + kstd::println("unmapping page {}", page.number()); + } + + auto try_unmap(page page) noexcept -> bool override + { + kstd::println("trying to unmap page {}", page.number()); + return false; + } + } test_mapper; + + auto handoff_to_kernel_pmm(frame_allocator & new_allocator) -> void + { + for (auto i = 0uz; i < boostrap_allocator.next_free_frame; ++i) + { + new_allocator.mark_used(frame{i}); + } + } + + } // namespace + auto init() -> void { - // TODO: initialize simulated memory. + kernel::tests::simulated_memory::init(simulate_memory_size); + set_frame_allocator(boostrap_allocator); + set_page_mapper(test_mapper); + + init_pmm(simulate_memory_size / frame::size, handoff_to_kernel_pmm); } } // namespace kapi::memory \ No newline at end of file diff --git a/kernel/tests/src/main.cpp b/kernel/tests/src/main.cpp index c0ec12f..69fd633 100644 --- a/kernel/tests/src/main.cpp +++ b/kernel/tests/src/main.cpp @@ -12,6 +12,10 @@ auto main(int argc, char ** argv) -> int kapi::interrupts::enable(); kapi::memory::init(); + // note: no kernel heap is created, since we are in the test environment. Nonetheless, we still initialize the memory + // subsystem, so that components that rely on it can be tested. No component must ever rely on the heap allocator + // directly, rather they have to go through the new and delete. However, some components may use the frame allocator + // and page mapper in order to perform their tasks. return Catch::Session().run(argc, argv); } diff --git a/kernel/tests/src/simulated_memory.cpp b/kernel/tests/src/simulated_memory.cpp new file mode 100644 index 0000000..9a9b354 --- /dev/null +++ b/kernel/tests/src/simulated_memory.cpp @@ -0,0 +1,33 @@ +#include "kernel/tests/simulated_memory.hpp" + +#include + +#include +#include + +namespace kernel::tests::simulated_memory +{ + + namespace + { + auto constinit ram_storage = std::vector{}; + auto constinit pmm_storage = std::vector{}; + } // namespace + + auto init(kstd::units::bytes size) -> void + { + ram_storage.resize(size / kstd::units::bytes{1}); + pmm_storage.resize(size / kstd::units::bytes{1}); + } + + auto pmm_metadata_base() -> std::byte * + { + return pmm_storage.data(); + } + + auto ram_base() -> std::byte * + { + return ram_storage.data(); + } + +} // namespace kernel::tests::simulated_memory \ No newline at end of file -- cgit v1.2.3 From 0369fb7c4baa543dfb36ebb39ab53ac7560994ba Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 11:37:05 +0200 Subject: kernel/test: only initialize kernel when running tests --- kernel/tests/src/main.cpp | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'kernel') diff --git a/kernel/tests/src/main.cpp b/kernel/tests/src/main.cpp index 69fd633..b3ae142 100644 --- a/kernel/tests/src/main.cpp +++ b/kernel/tests/src/main.cpp @@ -7,15 +7,32 @@ auto main(int argc, char ** argv) -> int { - kapi::cio::init(); - kapi::cpu::init(); - kapi::interrupts::enable(); + auto session = Catch::Session{}; - kapi::memory::init(); - // note: no kernel heap is created, since we are in the test environment. Nonetheless, we still initialize the memory - // subsystem, so that components that rely on it can be tested. No component must ever rely on the heap allocator - // directly, rather they have to go through the new and delete. However, some components may use the frame allocator - // and page mapper in order to perform their tasks. + if (auto result = session.applyCommandLine(argc, argv); result != 0) + { + return result; + } - return Catch::Session().run(argc, argv); + auto const & config = session.configData(); + auto skip_init = config.listTests || // + config.listTags || // + config.listReporters || // + config.listListeners || // + config.showHelp; + + if (!skip_init) + { + kapi::cio::init(); + kapi::cpu::init(); + kapi::interrupts::enable(); + + kapi::memory::init(); + // note: no kernel heap is created, since we are in the test environment. Nonetheless, we still initialize the + // memory subsystem, so that components that rely on it can be tested. No component must ever rely on the heap + // allocator directly, rather they have to go through the new and delete. However, some components may use the frame + // allocator and page mapper in order to perform their tasks. + } + + return session.run(); } -- cgit v1.2.3 From 1f652b8b5ca5dbea588975466801cb1479f3dda8 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 12:15:25 +0200 Subject: kernel/tests: dissolve tests into source tree --- kernel/CMakeLists.txt | 42 ++++++++++- kernel/include/kernel/tests/cpu.hpp | 18 +++++ kernel/include/kernel/tests/log_buffer.hpp | 32 ++++++++ kernel/include/kernel/tests/simulated_memory.hpp | 19 +++++ kernel/kapi/cpu.tests.cpp | 19 +++++ kernel/kapi/system.tests.cpp | 30 ++++++++ kernel/kstd/print.tests.cpp | 23 ++++++ kernel/src/main.tests.cpp | 38 ++++++++++ kernel/src/test_support/kapi/cio.cpp | 38 ++++++++++ kernel/src/test_support/kapi/cpu.cpp | 29 ++++++++ kernel/src/test_support/kapi/interrupts.cpp | 11 +++ kernel/src/test_support/kapi/memory.cpp | 86 ++++++++++++++++++++++ kernel/src/test_support/log_buffer.cpp | 39 ++++++++++ kernel/src/test_support/simulated_memory.cpp | 33 +++++++++ kernel/tests/CMakeLists.txt | 64 ---------------- kernel/tests/include/kernel/tests/cpu.hpp | 18 ----- kernel/tests/include/kernel/tests/log_buffer.hpp | 32 -------- .../include/kernel/tests/simulated_memory.hpp | 19 ----- kernel/tests/kapi/cio.cpp | 38 ---------- kernel/tests/kapi/cpu.cpp | 29 -------- kernel/tests/kapi/interrupts.cpp | 11 --- kernel/tests/kapi/memory.cpp | 86 ---------------------- kernel/tests/src/log_buffer.cpp | 39 ---------- kernel/tests/src/main.cpp | 38 ---------- kernel/tests/src/simulated_memory.cpp | 33 --------- kernel/tests/src/test_support.tests.cpp | 51 ------------- 26 files changed, 456 insertions(+), 459 deletions(-) create mode 100644 kernel/include/kernel/tests/cpu.hpp create mode 100644 kernel/include/kernel/tests/log_buffer.hpp create mode 100644 kernel/include/kernel/tests/simulated_memory.hpp create mode 100644 kernel/kapi/cpu.tests.cpp create mode 100644 kernel/kapi/system.tests.cpp create mode 100644 kernel/kstd/print.tests.cpp create mode 100644 kernel/src/main.tests.cpp create mode 100644 kernel/src/test_support/kapi/cio.cpp create mode 100644 kernel/src/test_support/kapi/cpu.cpp create mode 100644 kernel/src/test_support/kapi/interrupts.cpp create mode 100644 kernel/src/test_support/kapi/memory.cpp create mode 100644 kernel/src/test_support/log_buffer.cpp create mode 100644 kernel/src/test_support/simulated_memory.cpp delete mode 100644 kernel/tests/CMakeLists.txt delete mode 100644 kernel/tests/include/kernel/tests/cpu.hpp delete mode 100644 kernel/tests/include/kernel/tests/log_buffer.hpp delete mode 100644 kernel/tests/include/kernel/tests/simulated_memory.hpp delete mode 100644 kernel/tests/kapi/cio.cpp delete mode 100644 kernel/tests/kapi/cpu.cpp delete mode 100644 kernel/tests/kapi/interrupts.cpp delete mode 100644 kernel/tests/kapi/memory.cpp delete mode 100644 kernel/tests/src/log_buffer.cpp delete mode 100644 kernel/tests/src/main.cpp delete mode 100644 kernel/tests/src/simulated_memory.cpp delete mode 100644 kernel/tests/src/test_support.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 854fb33..d6b3a1b 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -87,6 +87,46 @@ if(CMAKE_CROSSCOMPILING) target_generate_bootable_iso("kernel") else() enable_coverage("kernel_objs") - add_subdirectory("tests") + + add_library("kernel_test_support" + "src/test_support/kapi/cpu.cpp" + "src/test_support/kapi/cio.cpp" + "src/test_support/kapi/interrupts.cpp" + "src/test_support/kapi/memory.cpp" + "src/test_support/log_buffer.cpp" + "src/test_support/simulated_memory.cpp" + ) + add_library("os::kernel_test_support" ALIAS "kernel_test_support") + + target_link_libraries("kernel_test_support" PUBLIC + "os::kernel" + "Catch2::Catch2" + ) + + add_executable("kernel_tests" + # KAPI Shim Tests + "kapi/cpu.tests.cpp" + "kapi/system.tests.cpp" + + # KSTD Shim Tests + "kstd/print.tests.cpp" + + # Test Executable Main + "src/main.tests.cpp" + ) + add_executable("os::kernel_tests" ALIAS "kernel_tests") + + target_link_libraries("kernel_tests" PRIVATE + "os::kernel_test_support" + ) + + set_target_properties("kernel_tests" PROPERTIES + C_CLANG_TIDY "" + CXX_CLANG_TIDY "" + EXCLUDE_FROM_ALL NO + ) + + enable_coverage("kernel_tests") + catch_discover_tests("os::kernel_tests") endif() diff --git a/kernel/include/kernel/tests/cpu.hpp b/kernel/include/kernel/tests/cpu.hpp new file mode 100644 index 0000000..81c0c6f --- /dev/null +++ b/kernel/include/kernel/tests/cpu.hpp @@ -0,0 +1,18 @@ +#ifndef TEACHOS_KERNEL_TESTS_CPU_HPP +#define TEACHOS_KERNEL_TESTS_CPU_HPP + +#include + +namespace kernel::tests::cpu +{ + + struct halt : std::runtime_error + { + halt() + : std::runtime_error{"CPU halt requested!"} + {} + }; + +} // namespace kernel::tests::cpu + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/tests/log_buffer.hpp b/kernel/include/kernel/tests/log_buffer.hpp new file mode 100644 index 0000000..5f2a1a7 --- /dev/null +++ b/kernel/include/kernel/tests/log_buffer.hpp @@ -0,0 +1,32 @@ +#ifndef KERNEL_TESTS_LOG_BUFFER_HPP +#define KERNEL_TESTS_LOG_BUFFER_HPP + +#include +#include + +namespace kernel::tests::log_buffer +{ + + //! Append a message to the testing log buffer. + //! + //! @param message The message to append. + auto append(std::string const & message) -> void; + + //! Clear the testing log buffer. + auto clear() -> void; + + //! Get the testing log buffer as a single string. + //! + //! @return The testing log buffer as a single string. + auto flat_messages() -> std::string; + + //! Get the testing log buffer. + //! + //! @note Messages may be split across multiple entries if they are longer than the internal kernel print buffer size. + //! + //! @return The testing log buffer. + auto messages() -> std::vector const &; + +} // namespace kernel::tests::log_buffer + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/tests/simulated_memory.hpp b/kernel/include/kernel/tests/simulated_memory.hpp new file mode 100644 index 0000000..156b1e1 --- /dev/null +++ b/kernel/include/kernel/tests/simulated_memory.hpp @@ -0,0 +1,19 @@ +#ifndef TEACHOS_KERNEL_TESTS_SIMULATED_MEMORY_HPP +#define TEACHOS_KERNEL_TESTS_SIMULATED_MEMORY_HPP + +#include + +#include + +namespace kernel::tests::simulated_memory +{ + + auto init(kstd::units::bytes size) -> void; + + auto pmm_metadata_base() -> std::byte *; + + auto ram_base() -> std::byte *; + +} // namespace kernel::tests::simulated_memory + +#endif \ No newline at end of file diff --git a/kernel/kapi/cpu.tests.cpp b/kernel/kapi/cpu.tests.cpp new file mode 100644 index 0000000..6fe026b --- /dev/null +++ b/kernel/kapi/cpu.tests.cpp @@ -0,0 +1,19 @@ +#include "kapi/cpu.hpp" + +#include "kernel/tests/cpu.hpp" + +#include + +SCENARIO("Kernel testing kapi::cpu shims", "[support]") +{ + GIVEN("the test support infrastructure is initialized") + { + WHEN("a CPU halt is requested") + { + THEN("the correct exception is thrown") + { + REQUIRE_THROWS_AS(kapi::cpu::halt(), kernel::tests::cpu::halt); + } + } + } +} \ No newline at end of file diff --git a/kernel/kapi/system.tests.cpp b/kernel/kapi/system.tests.cpp new file mode 100644 index 0000000..c130b54 --- /dev/null +++ b/kernel/kapi/system.tests.cpp @@ -0,0 +1,30 @@ +#include "kapi/system.hpp" + +#include "kernel/tests/cpu.hpp" +#include "kernel/tests/log_buffer.hpp" + +#include + +#include + +SCENARIO("Kernel testing kapi::system shims", "[support]") +{ + GIVEN("the test support infrastructure is initialized") + { + WHEN("a the system panics") + { + kernel::tests::log_buffer::clear(); + + THEN("the correct exception is thrown") + { + REQUIRE_THROWS_AS(kapi::system::panic("[kernel:tests] Test Panic"), kernel::tests::cpu::halt); + } + + THEN("the message is appended to the log buffer") + { + CHECK_THROWS(kapi::system::panic("[kernel:tests] Test Panic")); + REQUIRE(kernel::tests::log_buffer::flat_messages().contains("[kernel:tests] Test Panic")); + } + } + } +} \ No newline at end of file diff --git a/kernel/kstd/print.tests.cpp b/kernel/kstd/print.tests.cpp new file mode 100644 index 0000000..2ab829c --- /dev/null +++ b/kernel/kstd/print.tests.cpp @@ -0,0 +1,23 @@ +#include "kstd/print" + +#include "kernel/tests/log_buffer.hpp" + +#include + +SCENARIO("Kernel testing kstd shims", "[support]") +{ + GIVEN("the test support infrastructure is initialized") + { + WHEN("a regular print is issued") + { + kernel::tests::log_buffer::clear(); + + kstd::println("[kernel:tests] Test Print"); + + THEN("the message is appended to the log buffer") + { + REQUIRE(kernel::tests::log_buffer::flat_messages().contains("[kernel:tests] Test Print")); + } + } + } +} \ No newline at end of file diff --git a/kernel/src/main.tests.cpp b/kernel/src/main.tests.cpp new file mode 100644 index 0000000..b3ae142 --- /dev/null +++ b/kernel/src/main.tests.cpp @@ -0,0 +1,38 @@ +#include "kapi/interrupts.hpp" +#include "kapi/memory.hpp" +#include +#include + +#include + +auto main(int argc, char ** argv) -> int +{ + auto session = Catch::Session{}; + + if (auto result = session.applyCommandLine(argc, argv); result != 0) + { + return result; + } + + auto const & config = session.configData(); + auto skip_init = config.listTests || // + config.listTags || // + config.listReporters || // + config.listListeners || // + config.showHelp; + + if (!skip_init) + { + kapi::cio::init(); + kapi::cpu::init(); + kapi::interrupts::enable(); + + kapi::memory::init(); + // note: no kernel heap is created, since we are in the test environment. Nonetheless, we still initialize the + // memory subsystem, so that components that rely on it can be tested. No component must ever rely on the heap + // allocator directly, rather they have to go through the new and delete. However, some components may use the frame + // allocator and page mapper in order to perform their tasks. + } + + return session.run(); +} diff --git a/kernel/src/test_support/kapi/cio.cpp b/kernel/src/test_support/kapi/cio.cpp new file mode 100644 index 0000000..6359fa8 --- /dev/null +++ b/kernel/src/test_support/kapi/cio.cpp @@ -0,0 +1,38 @@ +#include + +#include "kernel/tests/log_buffer.hpp" + +#include +#include +#include + +namespace kapi::cio +{ + + namespace + { + + class test_output_device : public output_device + { + public: + test_output_device() = default; + + auto write(output_stream stream, std::string_view text) -> void override + { + auto & standard_stream = stream == output_stream::stdout ? std::cout : std::cerr; + standard_stream << text; + if (text != "\n") + { + kernel::tests::log_buffer::append(std::string{text}); + } + } + } device{}; + + } // namespace + + auto init() -> void + { + set_output_device(device); + } + +} // namespace kapi::cio \ No newline at end of file diff --git a/kernel/src/test_support/kapi/cpu.cpp b/kernel/src/test_support/kapi/cpu.cpp new file mode 100644 index 0000000..3ecaadc --- /dev/null +++ b/kernel/src/test_support/kapi/cpu.cpp @@ -0,0 +1,29 @@ +#include "kernel/tests/cpu.hpp" + +#include + +#include +#include + +namespace kapi::cpu +{ + + auto init() -> void + { + auto static initialized = std::atomic_flag{}; + if (initialized.test_and_set()) + { + throw std::logic_error("kapi::cpu::init() called more than once"); + } + + // TODO: make sure that simulated interrupt can run. + + return; + } + + auto halt() -> void + { + throw kernel::tests::cpu::halt{}; + } + +} // namespace kapi::cpu \ No newline at end of file diff --git a/kernel/src/test_support/kapi/interrupts.cpp b/kernel/src/test_support/kapi/interrupts.cpp new file mode 100644 index 0000000..0077266 --- /dev/null +++ b/kernel/src/test_support/kapi/interrupts.cpp @@ -0,0 +1,11 @@ +#include + +namespace kapi::interrupts +{ + + auto enable() -> void + { + // TODO: enable simulated interrupts. + } + +} // namespace kapi::interrupts \ No newline at end of file diff --git a/kernel/src/test_support/kapi/memory.cpp b/kernel/src/test_support/kapi/memory.cpp new file mode 100644 index 0000000..6de2f60 --- /dev/null +++ b/kernel/src/test_support/kapi/memory.cpp @@ -0,0 +1,86 @@ +#include "kapi/memory.hpp" + +#include + +#include "kernel/tests/simulated_memory.hpp" + +#include +#include + +#include +#include +#include +#include + +namespace kapi::memory +{ + + namespace + { + //! The size of the simulated RAM. + constexpr auto simulate_memory_size = kstd::units::MiB(32); + + struct test_boostrap_frame_allocator : frame_allocator + { + auto mark_used(frame) -> void override {} + + auto allocate_many(std::size_t count) noexcept -> std::optional> override + { + auto start = next_free_frame; + next_free_frame += count; + return std::pair{frame{start}, count}; + } + + auto release_many(std::pair) -> void override {} + + std::size_t next_free_frame{}; + } boostrap_allocator; + + struct test_page_mapper : page_mapper + { + auto map(page page, frame frame, flags flags) -> std::byte * override + { + kstd::println("mapping page {} onto frame {} with flags {}", page.number(), frame.number(), + static_cast(flags)); + + if ((page.start_address() & pmm_metadata_base.raw()) == pmm_metadata_base.raw()) + { + auto offset = page.start_address() & ~pmm_metadata_base.raw(); + return kernel::tests::simulated_memory::pmm_metadata_base() + offset; + } + + return nullptr; + } + + auto unmap(page page) -> void override + { + kstd::println("unmapping page {}", page.number()); + } + + auto try_unmap(page page) noexcept -> bool override + { + kstd::println("trying to unmap page {}", page.number()); + return false; + } + } test_mapper; + + auto handoff_to_kernel_pmm(frame_allocator & new_allocator) -> void + { + for (auto i = 0uz; i < boostrap_allocator.next_free_frame; ++i) + { + new_allocator.mark_used(frame{i}); + } + } + + } // namespace + + auto init() -> void + { + kernel::tests::simulated_memory::init(simulate_memory_size); + set_frame_allocator(boostrap_allocator); + set_page_mapper(test_mapper); + + init_pmm(simulate_memory_size / frame::size, handoff_to_kernel_pmm); + } + +} // namespace kapi::memory \ No newline at end of file diff --git a/kernel/src/test_support/log_buffer.cpp b/kernel/src/test_support/log_buffer.cpp new file mode 100644 index 0000000..9e30afb --- /dev/null +++ b/kernel/src/test_support/log_buffer.cpp @@ -0,0 +1,39 @@ +#include "kernel/tests/log_buffer.hpp" + +#include +#include +#include + +namespace kernel::tests::log_buffer +{ + + namespace + { + std::vector recorded_messages{}; + } + + auto append(std::string const & message) -> void + { + recorded_messages.push_back(message); + } + + auto clear() -> void + { + recorded_messages.clear(); + } + + auto flat_messages() -> std::string + { + return std::ranges::fold_left(recorded_messages, std::string{}, + [](std::string accumulator, std::string const & message) { + accumulator += message; + return accumulator; + }); + } + + auto messages() -> std::vector const & + { + return recorded_messages; + } + +} // namespace kernel::tests::log_buffer diff --git a/kernel/src/test_support/simulated_memory.cpp b/kernel/src/test_support/simulated_memory.cpp new file mode 100644 index 0000000..9a9b354 --- /dev/null +++ b/kernel/src/test_support/simulated_memory.cpp @@ -0,0 +1,33 @@ +#include "kernel/tests/simulated_memory.hpp" + +#include + +#include +#include + +namespace kernel::tests::simulated_memory +{ + + namespace + { + auto constinit ram_storage = std::vector{}; + auto constinit pmm_storage = std::vector{}; + } // namespace + + auto init(kstd::units::bytes size) -> void + { + ram_storage.resize(size / kstd::units::bytes{1}); + pmm_storage.resize(size / kstd::units::bytes{1}); + } + + auto pmm_metadata_base() -> std::byte * + { + return pmm_storage.data(); + } + + auto ram_base() -> std::byte * + { + return ram_storage.data(); + } + +} // namespace kernel::tests::simulated_memory \ No newline at end of file diff --git a/kernel/tests/CMakeLists.txt b/kernel/tests/CMakeLists.txt deleted file mode 100644 index 0855520..0000000 --- a/kernel/tests/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -#[============================================================================[ -# Kernel Test Support (Fakes, Stubs, Mocks, etc.) -#]============================================================================] - -add_library("kernel_test_support" - "kapi/cio.cpp" - "kapi/cpu.cpp" - "kapi/interrupts.cpp" - "kapi/memory.cpp" - - "src/log_buffer.cpp" - "src/main.cpp" - "src/simulated_memory.cpp" -) - -file(GLOB_RECURSE KERNEL_TEST_SUPPORT_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "include/**.hpp") - -target_sources("kernel_test_support" PUBLIC - FILE_SET HEADERS - BASE_DIRS "include" - FILES - ${KERNEL_TEST_SUPPORT_HEADERS} -) - -target_include_directories("kernel_test_support" PUBLIC - "include" -) - -target_link_libraries("kernel_test_support" PUBLIC - "os::kapi" - "os::kernel" - "Catch2::Catch2" -) - -add_library("os::kernel_test_support" ALIAS "kernel_test_support") - -#[============================================================================[ -# Kernel Tests -#]============================================================================] - -add_executable("kernel_tests" - "src/test_support.tests.cpp" -) - -target_include_directories("kernel_tests" PRIVATE - "include" -) - -target_link_libraries("kernel_tests" PRIVATE - "os::kernel_test_support" - "libs::kstd" -) - -set_target_properties("kernel_tests" PROPERTIES - C_CLANG_TIDY "" - CXX_CLANG_TIDY "" - EXCLUDE_FROM_ALL NO -) - -enable_coverage("kernel_tests") - -add_executable("os::kernel_tests" ALIAS "kernel_tests") - -catch_discover_tests("os::kernel_tests") \ No newline at end of file diff --git a/kernel/tests/include/kernel/tests/cpu.hpp b/kernel/tests/include/kernel/tests/cpu.hpp deleted file mode 100644 index 81c0c6f..0000000 --- a/kernel/tests/include/kernel/tests/cpu.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef TEACHOS_KERNEL_TESTS_CPU_HPP -#define TEACHOS_KERNEL_TESTS_CPU_HPP - -#include - -namespace kernel::tests::cpu -{ - - struct halt : std::runtime_error - { - halt() - : std::runtime_error{"CPU halt requested!"} - {} - }; - -} // namespace kernel::tests::cpu - -#endif \ No newline at end of file diff --git a/kernel/tests/include/kernel/tests/log_buffer.hpp b/kernel/tests/include/kernel/tests/log_buffer.hpp deleted file mode 100644 index 5f2a1a7..0000000 --- a/kernel/tests/include/kernel/tests/log_buffer.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef KERNEL_TESTS_LOG_BUFFER_HPP -#define KERNEL_TESTS_LOG_BUFFER_HPP - -#include -#include - -namespace kernel::tests::log_buffer -{ - - //! Append a message to the testing log buffer. - //! - //! @param message The message to append. - auto append(std::string const & message) -> void; - - //! Clear the testing log buffer. - auto clear() -> void; - - //! Get the testing log buffer as a single string. - //! - //! @return The testing log buffer as a single string. - auto flat_messages() -> std::string; - - //! Get the testing log buffer. - //! - //! @note Messages may be split across multiple entries if they are longer than the internal kernel print buffer size. - //! - //! @return The testing log buffer. - auto messages() -> std::vector const &; - -} // namespace kernel::tests::log_buffer - -#endif \ No newline at end of file diff --git a/kernel/tests/include/kernel/tests/simulated_memory.hpp b/kernel/tests/include/kernel/tests/simulated_memory.hpp deleted file mode 100644 index 156b1e1..0000000 --- a/kernel/tests/include/kernel/tests/simulated_memory.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef TEACHOS_KERNEL_TESTS_SIMULATED_MEMORY_HPP -#define TEACHOS_KERNEL_TESTS_SIMULATED_MEMORY_HPP - -#include - -#include - -namespace kernel::tests::simulated_memory -{ - - auto init(kstd::units::bytes size) -> void; - - auto pmm_metadata_base() -> std::byte *; - - auto ram_base() -> std::byte *; - -} // namespace kernel::tests::simulated_memory - -#endif \ No newline at end of file diff --git a/kernel/tests/kapi/cio.cpp b/kernel/tests/kapi/cio.cpp deleted file mode 100644 index 6359fa8..0000000 --- a/kernel/tests/kapi/cio.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include - -#include "kernel/tests/log_buffer.hpp" - -#include -#include -#include - -namespace kapi::cio -{ - - namespace - { - - class test_output_device : public output_device - { - public: - test_output_device() = default; - - auto write(output_stream stream, std::string_view text) -> void override - { - auto & standard_stream = stream == output_stream::stdout ? std::cout : std::cerr; - standard_stream << text; - if (text != "\n") - { - kernel::tests::log_buffer::append(std::string{text}); - } - } - } device{}; - - } // namespace - - auto init() -> void - { - set_output_device(device); - } - -} // namespace kapi::cio \ No newline at end of file diff --git a/kernel/tests/kapi/cpu.cpp b/kernel/tests/kapi/cpu.cpp deleted file mode 100644 index 3ecaadc..0000000 --- a/kernel/tests/kapi/cpu.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "kernel/tests/cpu.hpp" - -#include - -#include -#include - -namespace kapi::cpu -{ - - auto init() -> void - { - auto static initialized = std::atomic_flag{}; - if (initialized.test_and_set()) - { - throw std::logic_error("kapi::cpu::init() called more than once"); - } - - // TODO: make sure that simulated interrupt can run. - - return; - } - - auto halt() -> void - { - throw kernel::tests::cpu::halt{}; - } - -} // namespace kapi::cpu \ No newline at end of file diff --git a/kernel/tests/kapi/interrupts.cpp b/kernel/tests/kapi/interrupts.cpp deleted file mode 100644 index 0077266..0000000 --- a/kernel/tests/kapi/interrupts.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include - -namespace kapi::interrupts -{ - - auto enable() -> void - { - // TODO: enable simulated interrupts. - } - -} // namespace kapi::interrupts \ No newline at end of file diff --git a/kernel/tests/kapi/memory.cpp b/kernel/tests/kapi/memory.cpp deleted file mode 100644 index 6de2f60..0000000 --- a/kernel/tests/kapi/memory.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "kapi/memory.hpp" - -#include - -#include "kernel/tests/simulated_memory.hpp" - -#include -#include - -#include -#include -#include -#include - -namespace kapi::memory -{ - - namespace - { - //! The size of the simulated RAM. - constexpr auto simulate_memory_size = kstd::units::MiB(32); - - struct test_boostrap_frame_allocator : frame_allocator - { - auto mark_used(frame) -> void override {} - - auto allocate_many(std::size_t count) noexcept -> std::optional> override - { - auto start = next_free_frame; - next_free_frame += count; - return std::pair{frame{start}, count}; - } - - auto release_many(std::pair) -> void override {} - - std::size_t next_free_frame{}; - } boostrap_allocator; - - struct test_page_mapper : page_mapper - { - auto map(page page, frame frame, flags flags) -> std::byte * override - { - kstd::println("mapping page {} onto frame {} with flags {}", page.number(), frame.number(), - static_cast(flags)); - - if ((page.start_address() & pmm_metadata_base.raw()) == pmm_metadata_base.raw()) - { - auto offset = page.start_address() & ~pmm_metadata_base.raw(); - return kernel::tests::simulated_memory::pmm_metadata_base() + offset; - } - - return nullptr; - } - - auto unmap(page page) -> void override - { - kstd::println("unmapping page {}", page.number()); - } - - auto try_unmap(page page) noexcept -> bool override - { - kstd::println("trying to unmap page {}", page.number()); - return false; - } - } test_mapper; - - auto handoff_to_kernel_pmm(frame_allocator & new_allocator) -> void - { - for (auto i = 0uz; i < boostrap_allocator.next_free_frame; ++i) - { - new_allocator.mark_used(frame{i}); - } - } - - } // namespace - - auto init() -> void - { - kernel::tests::simulated_memory::init(simulate_memory_size); - set_frame_allocator(boostrap_allocator); - set_page_mapper(test_mapper); - - init_pmm(simulate_memory_size / frame::size, handoff_to_kernel_pmm); - } - -} // namespace kapi::memory \ No newline at end of file diff --git a/kernel/tests/src/log_buffer.cpp b/kernel/tests/src/log_buffer.cpp deleted file mode 100644 index 9e30afb..0000000 --- a/kernel/tests/src/log_buffer.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "kernel/tests/log_buffer.hpp" - -#include -#include -#include - -namespace kernel::tests::log_buffer -{ - - namespace - { - std::vector recorded_messages{}; - } - - auto append(std::string const & message) -> void - { - recorded_messages.push_back(message); - } - - auto clear() -> void - { - recorded_messages.clear(); - } - - auto flat_messages() -> std::string - { - return std::ranges::fold_left(recorded_messages, std::string{}, - [](std::string accumulator, std::string const & message) { - accumulator += message; - return accumulator; - }); - } - - auto messages() -> std::vector const & - { - return recorded_messages; - } - -} // namespace kernel::tests::log_buffer diff --git a/kernel/tests/src/main.cpp b/kernel/tests/src/main.cpp deleted file mode 100644 index b3ae142..0000000 --- a/kernel/tests/src/main.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "kapi/interrupts.hpp" -#include "kapi/memory.hpp" -#include -#include - -#include - -auto main(int argc, char ** argv) -> int -{ - auto session = Catch::Session{}; - - if (auto result = session.applyCommandLine(argc, argv); result != 0) - { - return result; - } - - auto const & config = session.configData(); - auto skip_init = config.listTests || // - config.listTags || // - config.listReporters || // - config.listListeners || // - config.showHelp; - - if (!skip_init) - { - kapi::cio::init(); - kapi::cpu::init(); - kapi::interrupts::enable(); - - kapi::memory::init(); - // note: no kernel heap is created, since we are in the test environment. Nonetheless, we still initialize the - // memory subsystem, so that components that rely on it can be tested. No component must ever rely on the heap - // allocator directly, rather they have to go through the new and delete. However, some components may use the frame - // allocator and page mapper in order to perform their tasks. - } - - return session.run(); -} diff --git a/kernel/tests/src/simulated_memory.cpp b/kernel/tests/src/simulated_memory.cpp deleted file mode 100644 index 9a9b354..0000000 --- a/kernel/tests/src/simulated_memory.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "kernel/tests/simulated_memory.hpp" - -#include - -#include -#include - -namespace kernel::tests::simulated_memory -{ - - namespace - { - auto constinit ram_storage = std::vector{}; - auto constinit pmm_storage = std::vector{}; - } // namespace - - auto init(kstd::units::bytes size) -> void - { - ram_storage.resize(size / kstd::units::bytes{1}); - pmm_storage.resize(size / kstd::units::bytes{1}); - } - - auto pmm_metadata_base() -> std::byte * - { - return pmm_storage.data(); - } - - auto ram_base() -> std::byte * - { - return ram_storage.data(); - } - -} // namespace kernel::tests::simulated_memory \ No newline at end of file diff --git a/kernel/tests/src/test_support.tests.cpp b/kernel/tests/src/test_support.tests.cpp deleted file mode 100644 index f835e65..0000000 --- a/kernel/tests/src/test_support.tests.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "kapi/cpu.hpp" -#include "kapi/system.hpp" - -#include "kernel/tests/cpu.hpp" -#include "kernel/tests/log_buffer.hpp" - -#include - -#include - -SCENARIO("Kernel test support infrastructure", "[support]") -{ - GIVEN("the test support infrastructure is initialized") - { - WHEN("a CPU halt is requested") - { - THEN("the correct exception is thrown") - { - REQUIRE_THROWS_AS(kapi::cpu::halt(), kernel::tests::cpu::halt); - } - } - - WHEN("a the system panics") - { - kernel::tests::log_buffer::clear(); - - THEN("the correct exception is thrown") - { - REQUIRE_THROWS_AS(kapi::system::panic("[kernel:tests] Test Panic"), kernel::tests::cpu::halt); - } - - THEN("the message is appended to the log buffer") - { - CHECK_THROWS(kapi::system::panic("[kernel:tests] Test Panic")); - REQUIRE(kernel::tests::log_buffer::flat_messages().contains("[kernel:tests] Test Panic")); - } - } - - WHEN("a regular print is issued") - { - kernel::tests::log_buffer::clear(); - - kstd::println("[kernel:tests] Test Print"); - - THEN("the message is appended to the log buffer") - { - REQUIRE(kernel::tests::log_buffer::flat_messages().contains("[kernel:tests] Test Print")); - } - } - } -} \ No newline at end of file -- cgit v1.2.3 From 6c1921d77a6d23bd5850db5b8db20e0f1bc67f40 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 12:23:00 +0200 Subject: kernel/tests: update coverage configuration --- kernel/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index d6b3a1b..9db2ab7 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -88,7 +88,7 @@ if(CMAKE_CROSSCOMPILING) else() enable_coverage("kernel_objs") - add_library("kernel_test_support" + add_library("kernel_test_support" OBJECT "src/test_support/kapi/cpu.cpp" "src/test_support/kapi/cio.cpp" "src/test_support/kapi/interrupts.cpp" @@ -117,13 +117,13 @@ else() add_executable("os::kernel_tests" ALIAS "kernel_tests") target_link_libraries("kernel_tests" PRIVATE + "os::kernel" "os::kernel_test_support" ) set_target_properties("kernel_tests" PROPERTIES C_CLANG_TIDY "" CXX_CLANG_TIDY "" - EXCLUDE_FROM_ALL NO ) enable_coverage("kernel_tests") -- cgit v1.2.3 From 790ffa870dee2c14cd45f669c0eb3e95c15fd1b6 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 13:31:20 +0200 Subject: kernel: add bitmap_allocator tests --- kernel/CMakeLists.txt | 3 + kernel/src/memory/bitmap_allocator.cpp | 20 +- kernel/src/memory/bitmap_allocator.tests.cpp | 289 +++++++++++++++++++++++++++ kernel/src/test_support/kapi/memory.cpp | 8 +- 4 files changed, 309 insertions(+), 11 deletions(-) create mode 100644 kernel/src/memory/bitmap_allocator.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 9db2ab7..926a682 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -111,6 +111,9 @@ else() # KSTD Shim Tests "kstd/print.tests.cpp" + # Memory Subsystem Tests + "src/memory/bitmap_allocator.tests.cpp" + # Test Executable Main "src/main.tests.cpp" ) diff --git a/kernel/src/memory/bitmap_allocator.cpp b/kernel/src/memory/bitmap_allocator.cpp index c010f77..caaf5a4 100644 --- a/kernel/src/memory/bitmap_allocator.cpp +++ b/kernel/src/memory/bitmap_allocator.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -17,7 +18,9 @@ namespace kernel::memory , m_frame_count{frame_count} , m_last_index{} { - std::ranges::fill(m_bitmap, ~0uz); + constexpr auto bits_per_word = 64uz; + auto to_fill = (frame_count + bits_per_word - 1) / bits_per_word; + std::ranges::fill(std::views::take(m_bitmap, to_fill), ~0uz); } auto bitmap_frame_allocator::allocate_many(std::size_t count) noexcept @@ -78,22 +81,25 @@ namespace kernel::memory auto bitmap_frame_allocator::test(std::size_t index) const noexcept -> bool { - auto entry_entry = index / 64; - auto entry_offset = index % 64; + constexpr auto bits_per_word = 64uz; + auto entry_entry = index / bits_per_word; + auto entry_offset = index % bits_per_word; return (m_bitmap[entry_entry] & (1uz << entry_offset)); } auto bitmap_frame_allocator::set(std::size_t index) noexcept -> void { - auto entry_entry = index / 64; - auto entry_offset = index % 64; + constexpr auto bits_per_word = 64uz; + auto entry_entry = index / bits_per_word; + auto entry_offset = index % bits_per_word; m_bitmap[entry_entry] |= (1uz << entry_offset); } auto bitmap_frame_allocator::clear(std::size_t index) noexcept -> void { - auto entry_entry = index / 64; - auto entry_offset = index % 64; + constexpr auto bits_per_word = 64uz; + auto entry_entry = index / bits_per_word; + auto entry_offset = index % bits_per_word; m_bitmap[entry_entry] &= ~(1uz << entry_offset); } diff --git a/kernel/src/memory/bitmap_allocator.tests.cpp b/kernel/src/memory/bitmap_allocator.tests.cpp new file mode 100644 index 0000000..56ec0a4 --- /dev/null +++ b/kernel/src/memory/bitmap_allocator.tests.cpp @@ -0,0 +1,289 @@ +#include "kernel/memory/bitmap_allocator.hpp" + +#include "kapi/memory.hpp" + +#include "catch2/matchers/catch_matchers.hpp" +#include "catch2/matchers/catch_matchers_range_equals.hpp" + +#include + +#include +#include +#include +#include +#include + +constexpr auto all_bits_set = std::numeric_limits::max(); +constexpr auto available_frames = 1024uz; + +SCENARIO("Bitmap allocator construction and initialization", "[memory][bitmap_allocator]") +{ + GIVEN("A storage region") + { + auto storage = std::vector(available_frames / 64, 0uz); + + WHEN("constructing the allocator with 0 frames") + { + auto allocator = kernel::memory::bitmap_frame_allocator{std::span(storage), 0}; + + THEN("the storage region is not modified") + { + REQUIRE_THAT(storage, Catch::Matchers::RangeEquals(std::vector(16, 0uz))); + } + } + + WHEN("constructing with 1 frame") + { + auto allocator = kernel::memory::bitmap_frame_allocator{std::span(storage), 1}; + + THEN("the first word of the storage region is set to all ones") + { + REQUIRE_THAT(std::views::take(storage, 1), Catch::Matchers::RangeEquals(std::vector(1, all_bits_set))); + } + + THEN("the rest of the storage region is not modified") + { + REQUIRE_THAT(std::views::drop(storage, 1), Catch::Matchers::RangeEquals(std::vector(15, 0uz))); + } + } + + WHEN("constructing with 64 frames") + { + auto allocator = kernel::memory::bitmap_frame_allocator{std::span(storage), 64}; + + THEN("the first word of the storage region is set to all ones") + { + REQUIRE_THAT(std::views::take(storage, 1), Catch::Matchers::RangeEquals(std::vector(1, all_bits_set))); + } + + THEN("the rest of the storage region is not modified") + { + REQUIRE_THAT(std::views::drop(storage, 1), Catch::Matchers::RangeEquals(std::vector(15, 0uz))); + } + } + + WHEN("constructing with all available frames") + { + auto allocator = kernel::memory::bitmap_frame_allocator{std::span(storage), available_frames}; + + THEN("the storage region is filled with all ones") + { + REQUIRE_THAT(storage, Catch::Matchers::RangeEquals(std::vector(16, all_bits_set))); + } + } + + WHEN("constructing with half the available frames") + { + auto allocator = kernel::memory::bitmap_frame_allocator{std::span(storage), available_frames / 2}; + + THEN("the first half of the storage region is filled with all ones") + { + REQUIRE_THAT(std::views::take(storage, (available_frames / 2) / 64), + Catch::Matchers::RangeEquals(std::vector((available_frames / 2) / 64, all_bits_set))); + } + + THEN("the second half of the storage region is filled with all zeros") + { + REQUIRE_THAT(std::views::drop(storage, (available_frames / 2) / 64), + Catch::Matchers::RangeEquals(std::vector((available_frames / 2) / 64, 0uz))); + } + } + } +} + +SCENARIO("Bitmap allocator frame allocation", "[memory][bitmap_allocator]") +{ + GIVEN("A storage region") + { + auto storage = std::vector(available_frames / 64, 0uz); + + AND_GIVEN("an allocator constructed with all available frames but no free ones") + { + auto allocator = kernel::memory::bitmap_frame_allocator{std::span(storage), available_frames}; + + WHEN("allocating 1 frame") + { + auto result = allocator.allocate_many(1); + + THEN("the result is empty") + { + REQUIRE_FALSE(result.has_value()); + } + } + } + + AND_GIVEN("an allocator constructed with all available frames but only one free one") + { + auto allocator = kernel::memory::bitmap_frame_allocator{std::span(storage), available_frames}; + allocator.release_many({kapi::memory::frame{0}, 1}); + + WHEN("allocating 1 frame") + { + auto result = allocator.allocate_many(1); + + THEN("the result is not empty") + { + REQUIRE(result.has_value()); + } + + THEN("the result contains 1 frame") + { + REQUIRE(result->second == 1); + } + } + + WHEN("allocating more frames than are free") + { + auto result = allocator.allocate_many(2); + + THEN("the result is empty") + { + REQUIRE_FALSE(result.has_value()); + } + + AND_WHEN("allocating a single frame") + { + auto result = allocator.allocate_many(1); + + THEN("the result is not empty") + { + REQUIRE(result.has_value()); + } + } + + WHEN("allocating 0 frames") + { + auto result = allocator.allocate_many(0); + + THEN("the result is empty") + { + REQUIRE_FALSE(result.has_value()); + } + } + } + } + + AND_GIVEN("an allocator with many single frame holes") + { + auto allocator = kernel::memory::bitmap_frame_allocator{std::span(storage), available_frames}; + for (auto i = 0uz; i < available_frames; i += 2) + { + allocator.release_many({kapi::memory::frame{i}, 1}); + } + + WHEN("allocating 1 frame") + { + auto result = allocator.allocate_many(1); + + THEN("the result is not empty") + { + REQUIRE(result.has_value()); + } + + THEN("the result contains 1 frame") + { + REQUIRE(result->second == 1); + } + } + + WHEN("allocating 2 frames") + { + auto result = allocator.allocate_many(2); + + THEN("the result is empty") + { + REQUIRE_FALSE(result.has_value()); + } + } + } + + AND_GIVEN("and allocator with all frames marked as free") + { + auto allocator = kernel::memory::bitmap_frame_allocator{std::span(storage), available_frames}; + allocator.release_many({kapi::memory::frame{0}, available_frames}); + + WHEN("allocating 1 frame") + { + auto result = allocator.allocate_many(1); + + THEN("the result is not empty") + { + REQUIRE(result.has_value()); + } + + THEN("the result contains 1 frame") + { + REQUIRE(result->second == 1); + } + } + + WHEN("allocating multiple frames") + { + auto result = allocator.allocate_many(20); + + THEN("the result is not empty") + { + REQUIRE(result.has_value()); + } + + THEN("the result contains 20 frames") + { + REQUIRE(result->second == 20); + } + } + + WHEN("marking all frames as used") + { + for (auto i = 0uz; i < available_frames; i++) + { + allocator.mark_used(kapi::memory::frame{i}); + } + + THEN("the allocator has no free frames") + { + REQUIRE_FALSE(allocator.allocate_many(1).has_value()); + } + } + } + + AND_GIVEN("an allocator with a contiguous block of free frames") + { + auto allocator = kernel::memory::bitmap_frame_allocator{std::span(storage), available_frames}; + allocator.release_many({kapi::memory::frame{0}, available_frames}); + for (auto i = 0uz; i < available_frames / 2; i++) + { + allocator.mark_used(kapi::memory::frame{i}); + } + + WHEN("allocating a single frame") + { + auto result = allocator.allocate_many(1); + + THEN("the result is not empty") + { + REQUIRE(result.has_value()); + } + + THEN("the result contains 1 frame") + { + REQUIRE(result->second == 1); + } + } + + WHEN("allocating multiple frames") + { + auto result = allocator.allocate_many(20); + + THEN("the result is not empty") + { + REQUIRE(result.has_value()); + } + + THEN("the result contains 20 frames") + { + REQUIRE(result->second == 20); + } + } + } + } +} \ No newline at end of file diff --git a/kernel/src/test_support/kapi/memory.cpp b/kernel/src/test_support/kapi/memory.cpp index 6de2f60..556962c 100644 --- a/kernel/src/test_support/kapi/memory.cpp +++ b/kernel/src/test_support/kapi/memory.cpp @@ -19,6 +19,7 @@ namespace kapi::memory { //! The size of the simulated RAM. constexpr auto simulate_memory_size = kstd::units::MiB(32); + constexpr auto number_of_simulated_frames = simulate_memory_size / frame::size; struct test_boostrap_frame_allocator : frame_allocator { @@ -66,10 +67,9 @@ namespace kapi::memory auto handoff_to_kernel_pmm(frame_allocator & new_allocator) -> void { - for (auto i = 0uz; i < boostrap_allocator.next_free_frame; ++i) - { - new_allocator.mark_used(frame{i}); - } + auto first_free_frame = boostrap_allocator.next_free_frame; + auto number_of_free_frames = number_of_simulated_frames - first_free_frame; + new_allocator.release_many({frame{first_free_frame}, number_of_free_frames}); } } // namespace -- 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 --- kernel/CMakeLists.txt | 3 + .../src/devices/storage/ram_disk/device.tests.cpp | 117 +++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 kernel/src/devices/storage/ram_disk/device.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 926a682..4fadf4c 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -114,6 +114,9 @@ else() # Memory Subsystem Tests "src/memory/bitmap_allocator.tests.cpp" + # Storage Subsystem Tests + "src/devices/storage/ram_disk/device.tests.cpp" + # Test Executable Main "src/main.tests.cpp" ) 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 eaec1833e978d2443ffdfc226fff60d0b5571cb6 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 16:27:51 +0200 Subject: kernel/tests: move initialization to a listener --- kernel/CMakeLists.txt | 6 +-- kernel/include/kernel/tests/simulated_memory.hpp | 2 + kernel/src/main.tests.cpp | 38 ------------------ kernel/src/test_support/kapi/cio.cpp | 5 +++ kernel/src/test_support/kapi/cpu.cpp | 18 +++++++-- kernel/src/test_support/kapi/memory.cpp | 14 +++++-- kernel/src/test_support/simulated_memory.cpp | 6 +++ kernel/src/test_support/state_reset_listener.cpp | 50 ++++++++++++++++++++++++ 8 files changed, 90 insertions(+), 49 deletions(-) delete mode 100644 kernel/src/main.tests.cpp create mode 100644 kernel/src/test_support/state_reset_listener.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 4fadf4c..ffd5156 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -95,12 +95,13 @@ else() "src/test_support/kapi/memory.cpp" "src/test_support/log_buffer.cpp" "src/test_support/simulated_memory.cpp" + "src/test_support/state_reset_listener.cpp" ) add_library("os::kernel_test_support" ALIAS "kernel_test_support") target_link_libraries("kernel_test_support" PUBLIC "os::kernel" - "Catch2::Catch2" + "Catch2::Catch2WithMain" ) add_executable("kernel_tests" @@ -116,9 +117,6 @@ else() # Storage Subsystem Tests "src/devices/storage/ram_disk/device.tests.cpp" - - # Test Executable Main - "src/main.tests.cpp" ) add_executable("os::kernel_tests" ALIAS "kernel_tests") diff --git a/kernel/include/kernel/tests/simulated_memory.hpp b/kernel/include/kernel/tests/simulated_memory.hpp index 156b1e1..fee4d7a 100644 --- a/kernel/include/kernel/tests/simulated_memory.hpp +++ b/kernel/include/kernel/tests/simulated_memory.hpp @@ -10,6 +10,8 @@ namespace kernel::tests::simulated_memory auto init(kstd::units::bytes size) -> void; + auto reset() -> void; + auto pmm_metadata_base() -> std::byte *; auto ram_base() -> std::byte *; diff --git a/kernel/src/main.tests.cpp b/kernel/src/main.tests.cpp deleted file mode 100644 index b3ae142..0000000 --- a/kernel/src/main.tests.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "kapi/interrupts.hpp" -#include "kapi/memory.hpp" -#include -#include - -#include - -auto main(int argc, char ** argv) -> int -{ - auto session = Catch::Session{}; - - if (auto result = session.applyCommandLine(argc, argv); result != 0) - { - return result; - } - - auto const & config = session.configData(); - auto skip_init = config.listTests || // - config.listTags || // - config.listReporters || // - config.listListeners || // - config.showHelp; - - if (!skip_init) - { - kapi::cio::init(); - kapi::cpu::init(); - kapi::interrupts::enable(); - - kapi::memory::init(); - // note: no kernel heap is created, since we are in the test environment. Nonetheless, we still initialize the - // memory subsystem, so that components that rely on it can be tested. No component must ever rely on the heap - // allocator directly, rather they have to go through the new and delete. However, some components may use the frame - // allocator and page mapper in order to perform their tasks. - } - - return session.run(); -} diff --git a/kernel/src/test_support/kapi/cio.cpp b/kernel/src/test_support/kapi/cio.cpp index 6359fa8..0dd4b8c 100644 --- a/kernel/src/test_support/kapi/cio.cpp +++ b/kernel/src/test_support/kapi/cio.cpp @@ -35,4 +35,9 @@ namespace kapi::cio set_output_device(device); } + auto reset() -> void + { + kernel::tests::log_buffer::clear(); + } + } // namespace kapi::cio \ No newline at end of file diff --git a/kernel/src/test_support/kapi/cpu.cpp b/kernel/src/test_support/kapi/cpu.cpp index 3ecaadc..9b2f0b9 100644 --- a/kernel/src/test_support/kapi/cpu.cpp +++ b/kernel/src/test_support/kapi/cpu.cpp @@ -8,17 +8,29 @@ namespace kapi::cpu { - auto init() -> void + namespace { auto static initialized = std::atomic_flag{}; + } + + auto reset() -> void + { + if (!initialized.test()) + { + throw std::logic_error{"kapi::cpu::reset() called before kapi::cpu::init()"}; + } + + initialized.clear(); + } + + auto init() -> void + { if (initialized.test_and_set()) { throw std::logic_error("kapi::cpu::init() called more than once"); } // TODO: make sure that simulated interrupt can run. - - return; } auto halt() -> void diff --git a/kernel/src/test_support/kapi/memory.cpp b/kernel/src/test_support/kapi/memory.cpp index 556962c..4f261ac 100644 --- a/kernel/src/test_support/kapi/memory.cpp +++ b/kernel/src/test_support/kapi/memory.cpp @@ -21,7 +21,7 @@ namespace kapi::memory constexpr auto simulate_memory_size = kstd::units::MiB(32); constexpr auto number_of_simulated_frames = simulate_memory_size / frame::size; - struct test_boostrap_frame_allocator : frame_allocator + struct test_bootstrap_frame_allocator : frame_allocator { auto mark_used(frame) -> void override {} @@ -35,7 +35,7 @@ namespace kapi::memory auto release_many(std::pair) -> void override {} std::size_t next_free_frame{}; - } boostrap_allocator; + } bootstrap_allocator; struct test_page_mapper : page_mapper { @@ -67,7 +67,7 @@ namespace kapi::memory auto handoff_to_kernel_pmm(frame_allocator & new_allocator) -> void { - auto first_free_frame = boostrap_allocator.next_free_frame; + auto first_free_frame = bootstrap_allocator.next_free_frame; auto number_of_free_frames = number_of_simulated_frames - first_free_frame; new_allocator.release_many({frame{first_free_frame}, number_of_free_frames}); } @@ -77,10 +77,16 @@ namespace kapi::memory auto init() -> void { kernel::tests::simulated_memory::init(simulate_memory_size); - set_frame_allocator(boostrap_allocator); + set_frame_allocator(bootstrap_allocator); set_page_mapper(test_mapper); init_pmm(simulate_memory_size / frame::size, handoff_to_kernel_pmm); } + auto reset() -> void + { + kernel::tests::simulated_memory::reset(); + bootstrap_allocator.next_free_frame = 0; + } + } // namespace kapi::memory \ No newline at end of file diff --git a/kernel/src/test_support/simulated_memory.cpp b/kernel/src/test_support/simulated_memory.cpp index 9a9b354..49e172f 100644 --- a/kernel/src/test_support/simulated_memory.cpp +++ b/kernel/src/test_support/simulated_memory.cpp @@ -20,6 +20,12 @@ namespace kernel::tests::simulated_memory pmm_storage.resize(size / kstd::units::bytes{1}); } + auto reset() -> void + { + ram_storage.clear(); + pmm_storage.clear(); + } + auto pmm_metadata_base() -> std::byte * { return pmm_storage.data(); diff --git a/kernel/src/test_support/state_reset_listener.cpp b/kernel/src/test_support/state_reset_listener.cpp new file mode 100644 index 0000000..e201a10 --- /dev/null +++ b/kernel/src/test_support/state_reset_listener.cpp @@ -0,0 +1,50 @@ +#include "kapi/cio.hpp" +#include "kapi/cpu.hpp" +#include "kapi/memory.hpp" + +#include +#include +#include +#include + +namespace kapi +{ + namespace cio + { + auto reset() -> void; + } + + namespace cpu + { + auto reset() -> void; + } + + namespace memory + { + auto reset() -> void; + } +} // namespace kapi + +struct state_reset_listener : Catch::EventListenerBase +{ + using EventListenerBase::EventListenerBase; + + void testCaseStarting(Catch::TestCaseInfo const &) override + { + kapi::cio::init(); + kapi::cpu::init(); + kapi::memory::init(); + } + + void testCaseEnded(Catch::TestCaseStats const &) override + { + kapi::memory::reset(); + kapi::cpu::reset(); + kapi::cio::reset(); + } +}; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +CATCH_REGISTER_LISTENER(state_reset_listener); +#pragma GCC diagnostic pop \ No newline at end of file -- cgit v1.2.3 From 1a22d810ff2772d6b4dba5b1eb27d21285668c6f Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 16:32:43 +0200 Subject: kernel/tests: improve memory cleanup --- kernel/src/test_support/kapi/memory.cpp | 35 +++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/src/test_support/kapi/memory.cpp b/kernel/src/test_support/kapi/memory.cpp index 4f261ac..652a3d3 100644 --- a/kernel/src/test_support/kapi/memory.cpp +++ b/kernel/src/test_support/kapi/memory.cpp @@ -35,7 +35,9 @@ namespace kapi::memory auto release_many(std::pair) -> void override {} std::size_t next_free_frame{}; - } bootstrap_allocator; + }; + + auto constinit bootstrap_allocator = std::optional{}; struct test_page_mapper : page_mapper { @@ -63,22 +65,31 @@ namespace kapi::memory kstd::println("trying to unmap page {}", page.number()); return false; } - } test_mapper; + }; + + auto constinit test_mapper = std::optional{}; auto handoff_to_kernel_pmm(frame_allocator & new_allocator) -> void { - auto first_free_frame = bootstrap_allocator.next_free_frame; + auto first_free_frame = bootstrap_allocator->next_free_frame; auto number_of_free_frames = number_of_simulated_frames - first_free_frame; new_allocator.release_many({frame{first_free_frame}, number_of_free_frames}); } + auto constinit previous_frame_allocator = std::optional{}; + auto constinit previous_page_mapper = std::optional{}; + } // namespace auto init() -> void { kernel::tests::simulated_memory::init(simulate_memory_size); - set_frame_allocator(bootstrap_allocator); - set_page_mapper(test_mapper); + + bootstrap_allocator.emplace(); + test_mapper.emplace(); + + previous_frame_allocator = set_frame_allocator(*bootstrap_allocator); + previous_page_mapper = set_page_mapper(*test_mapper); init_pmm(simulate_memory_size / frame::size, handoff_to_kernel_pmm); } @@ -86,7 +97,19 @@ namespace kapi::memory auto reset() -> void { kernel::tests::simulated_memory::reset(); - bootstrap_allocator.next_free_frame = 0; + + if (previous_frame_allocator && *previous_frame_allocator) + { + set_frame_allocator(**previous_frame_allocator); + } + + if (previous_page_mapper && *previous_page_mapper) + { + set_page_mapper(**previous_page_mapper); + } + + bootstrap_allocator.reset(); + test_mapper.reset(); } } // namespace kapi::memory \ No newline at end of file -- cgit v1.2.3 From b078f2bf4726b5c62584cebd84107ac1028bb083 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 17:26:13 +0200 Subject: kernel/tests: clean up fake memory implementation --- kernel/CMakeLists.txt | 1 + .../include/kernel/tests/bump_frame_allocator.hpp | 32 ++++++++ kernel/include/kernel/tests/page_mapper.hpp | 33 ++++++++ kernel/include/kernel/tests/simulated_memory.hpp | 18 +++-- kernel/src/test_support/kapi/memory.cpp | 92 +++++----------------- kernel/src/test_support/page_mapper.cpp | 57 ++++++++++++++ kernel/src/test_support/simulated_memory.cpp | 31 +++----- 7 files changed, 166 insertions(+), 98 deletions(-) create mode 100644 kernel/include/kernel/tests/bump_frame_allocator.hpp create mode 100644 kernel/include/kernel/tests/page_mapper.hpp create mode 100644 kernel/src/test_support/page_mapper.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index ffd5156..4264441 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -94,6 +94,7 @@ else() "src/test_support/kapi/interrupts.cpp" "src/test_support/kapi/memory.cpp" "src/test_support/log_buffer.cpp" + "src/test_support/page_mapper.cpp" "src/test_support/simulated_memory.cpp" "src/test_support/state_reset_listener.cpp" ) diff --git a/kernel/include/kernel/tests/bump_frame_allocator.hpp b/kernel/include/kernel/tests/bump_frame_allocator.hpp new file mode 100644 index 0000000..8344423 --- /dev/null +++ b/kernel/include/kernel/tests/bump_frame_allocator.hpp @@ -0,0 +1,32 @@ +#ifndef TEACHOS_KERNEL_TESTS_BUMP_FRAME_ALLOCATOR_HPP +#define TEACHOS_KERNEL_TESTS_BUMP_FRAME_ALLOCATOR_HPP + +#include "kapi/memory.hpp" + +#include +#include +#include + +namespace kernel::tests +{ + + struct bump_frame_allocator : kapi::memory::frame_allocator + { + auto mark_used(kapi::memory::frame) -> void override {} + + auto allocate_many(std::size_t count) noexcept + -> std::optional> override + { + auto start = next_free_frame; + next_free_frame += count; + return std::pair{kapi::memory::frame{start}, count}; + } + + auto release_many(std::pair) -> void override {} + + std::size_t next_free_frame{}; + }; + +} // namespace kernel::tests + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/tests/page_mapper.hpp b/kernel/include/kernel/tests/page_mapper.hpp new file mode 100644 index 0000000..9969976 --- /dev/null +++ b/kernel/include/kernel/tests/page_mapper.hpp @@ -0,0 +1,33 @@ +#ifndef TEACHOS_KERNEL_TESTS_PAGE_MAPPER_HPP +#define TEACHOS_KERNEL_TESTS_PAGE_MAPPER_HPP + +#include "kapi/memory.hpp" + +#include "kernel/tests/simulated_memory.hpp" + +#include + +#include +#include +#include + +namespace kernel::tests +{ + + struct page_mapper : kapi::memory::page_mapper + { + explicit page_mapper(kstd::units::bytes memory_size); + + auto map(kapi::memory::page page, kapi::memory::frame frame, flags) -> std::byte * override; + + auto unmap(kapi::memory::page page) -> void override; + + auto try_unmap(kapi::memory::page page) noexcept -> bool override; + + kernel::tests::simulated_memory memory; + std::unordered_map page_mappings; + }; + +} // namespace kernel::tests + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/tests/simulated_memory.hpp b/kernel/include/kernel/tests/simulated_memory.hpp index fee4d7a..446d558 100644 --- a/kernel/include/kernel/tests/simulated_memory.hpp +++ b/kernel/include/kernel/tests/simulated_memory.hpp @@ -4,18 +4,24 @@ #include #include +#include -namespace kernel::tests::simulated_memory +namespace kernel::tests { - auto init(kstd::units::bytes size) -> void; + struct simulated_memory + { + explicit simulated_memory(kstd::units::bytes size); - auto reset() -> void; + auto clear() -> void; - auto pmm_metadata_base() -> std::byte *; + auto ram_base() noexcept -> std::byte *; + [[nodiscard]] auto ram_base() const noexcept -> std::byte const *; - auto ram_base() -> std::byte *; + private: + std::vector m_memory; + }; -} // namespace kernel::tests::simulated_memory +} // namespace kernel::tests #endif \ No newline at end of file diff --git a/kernel/src/test_support/kapi/memory.cpp b/kernel/src/test_support/kapi/memory.cpp index 652a3d3..7b7a81e 100644 --- a/kernel/src/test_support/kapi/memory.cpp +++ b/kernel/src/test_support/kapi/memory.cpp @@ -2,15 +2,12 @@ #include -#include "kernel/tests/simulated_memory.hpp" +#include "kernel/tests/bump_frame_allocator.hpp" +#include "kernel/tests/page_mapper.hpp" -#include #include -#include -#include #include -#include namespace kapi::memory { @@ -18,97 +15,48 @@ namespace kapi::memory namespace { //! The size of the simulated RAM. - constexpr auto simulate_memory_size = kstd::units::MiB(32); - constexpr auto number_of_simulated_frames = simulate_memory_size / frame::size; + constexpr auto memory_size = kstd::units::MiB(32); + constexpr auto number_of_frames = memory_size / frame::size; - struct test_bootstrap_frame_allocator : frame_allocator - { - auto mark_used(frame) -> void override {} - - auto allocate_many(std::size_t count) noexcept -> std::optional> override - { - auto start = next_free_frame; - next_free_frame += count; - return std::pair{frame{start}, count}; - } - - auto release_many(std::pair) -> void override {} + auto constinit bump_allocator = std::optional{}; + auto constinit test_mapper = std::optional{}; - std::size_t next_free_frame{}; - }; - - auto constinit bootstrap_allocator = std::optional{}; - - struct test_page_mapper : page_mapper - { - auto map(page page, frame frame, flags flags) -> std::byte * override - { - kstd::println("mapping page {} onto frame {} with flags {}", page.number(), frame.number(), - static_cast(flags)); - - if ((page.start_address() & pmm_metadata_base.raw()) == pmm_metadata_base.raw()) - { - auto offset = page.start_address() & ~pmm_metadata_base.raw(); - return kernel::tests::simulated_memory::pmm_metadata_base() + offset; - } - - return nullptr; - } - - auto unmap(page page) -> void override - { - kstd::println("unmapping page {}", page.number()); - } - - auto try_unmap(page page) noexcept -> bool override - { - kstd::println("trying to unmap page {}", page.number()); - return false; - } - }; - - auto constinit test_mapper = std::optional{}; + auto constinit old_allocator = std::optional{}; + auto constinit old_mapper = std::optional{}; auto handoff_to_kernel_pmm(frame_allocator & new_allocator) -> void { - auto first_free_frame = bootstrap_allocator->next_free_frame; - auto number_of_free_frames = number_of_simulated_frames - first_free_frame; + auto first_free_frame = bump_allocator->next_free_frame; + auto number_of_free_frames = number_of_frames - first_free_frame; new_allocator.release_many({frame{first_free_frame}, number_of_free_frames}); } - auto constinit previous_frame_allocator = std::optional{}; - auto constinit previous_page_mapper = std::optional{}; - } // namespace auto init() -> void { - kernel::tests::simulated_memory::init(simulate_memory_size); + bump_allocator.emplace(); + test_mapper.emplace(memory_size); - bootstrap_allocator.emplace(); - test_mapper.emplace(); + old_allocator = set_frame_allocator(*bump_allocator); + old_mapper = set_page_mapper(*test_mapper); - previous_frame_allocator = set_frame_allocator(*bootstrap_allocator); - previous_page_mapper = set_page_mapper(*test_mapper); - - init_pmm(simulate_memory_size / frame::size, handoff_to_kernel_pmm); + init_pmm(memory_size / frame::size, handoff_to_kernel_pmm); } auto reset() -> void { - kernel::tests::simulated_memory::reset(); - - if (previous_frame_allocator && *previous_frame_allocator) + if (old_allocator && *old_allocator) { - set_frame_allocator(**previous_frame_allocator); + set_frame_allocator(**old_allocator); } - if (previous_page_mapper && *previous_page_mapper) + if (old_mapper && *old_mapper) { - set_page_mapper(**previous_page_mapper); + set_page_mapper(**old_mapper); } - bootstrap_allocator.reset(); + bump_allocator.reset(); test_mapper.reset(); } diff --git a/kernel/src/test_support/page_mapper.cpp b/kernel/src/test_support/page_mapper.cpp new file mode 100644 index 0000000..a026ec3 --- /dev/null +++ b/kernel/src/test_support/page_mapper.cpp @@ -0,0 +1,57 @@ +#include "kernel/tests/page_mapper.hpp" + +#include "kapi/memory.hpp" + +#include + +#include +#include +#include + +namespace kernel::tests +{ + + page_mapper::page_mapper(kstd::units::bytes memory_size) + : memory{memory_size} + {} + + auto page_mapper::map(kapi::memory::page page, kapi::memory::frame frame, flags) -> std::byte * + { + page_mappings.insert({page.number(), frame}); + + auto page_address = page.start_address(); + + if (page_address >= kapi::memory::mmio_base) + { + throw std::invalid_argument{"MMIO mapping not yet supported in testing!"}; + } + else if (page_address >= kapi::memory::higher_half_direct_map_base) + { + auto offset = frame.number() * kapi::memory::frame::size; + return memory.ram_base() + offset; + } + + return nullptr; + } + + auto page_mapper::unmap(kapi::memory::page page) -> void + { + if (!try_unmap(page)) + { + auto error = std::format("Page {} was never mapped!", page.number()); + throw std::invalid_argument{error}; + } + } + + auto page_mapper::try_unmap(kapi::memory::page page) noexcept -> bool + { + if (page_mappings.contains(page.number())) + { + page_mappings.erase(page.number()); + return true; + } + + return false; + } + +} // namespace kernel::tests \ No newline at end of file diff --git a/kernel/src/test_support/simulated_memory.cpp b/kernel/src/test_support/simulated_memory.cpp index 49e172f..d23350b 100644 --- a/kernel/src/test_support/simulated_memory.cpp +++ b/kernel/src/test_support/simulated_memory.cpp @@ -5,35 +5,26 @@ #include #include -namespace kernel::tests::simulated_memory +namespace kernel::tests { - namespace - { - auto constinit ram_storage = std::vector{}; - auto constinit pmm_storage = std::vector{}; - } // namespace - - auto init(kstd::units::bytes size) -> void - { - ram_storage.resize(size / kstd::units::bytes{1}); - pmm_storage.resize(size / kstd::units::bytes{1}); - } + simulated_memory::simulated_memory(kstd::units::bytes size) + : m_memory{size / kstd::units::bytes{1}} + {} - auto reset() -> void + auto simulated_memory::ram_base() noexcept -> std::byte * { - ram_storage.clear(); - pmm_storage.clear(); + return m_memory.data(); } - auto pmm_metadata_base() -> std::byte * + auto simulated_memory::ram_base() const noexcept -> std::byte const * { - return pmm_storage.data(); + return m_memory.data(); } - auto ram_base() -> std::byte * + auto simulated_memory::clear() -> void { - return ram_storage.data(); + m_memory.clear(); } -} // namespace kernel::tests::simulated_memory \ No newline at end of file +} // namespace kernel::tests \ No newline at end of file -- cgit v1.2.3 From 825d8bafef152a52cd76851764913fb12cdc685d Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 17:29:25 +0200 Subject: kernel/test: rename test include to test_support --- .../kernel/test_support/bump_frame_allocator.hpp | 32 +++++++++++++++++++++ kernel/include/kernel/test_support/cpu.hpp | 18 ++++++++++++ kernel/include/kernel/test_support/log_buffer.hpp | 32 +++++++++++++++++++++ kernel/include/kernel/test_support/page_mapper.hpp | 33 ++++++++++++++++++++++ .../kernel/test_support/simulated_memory.hpp | 27 ++++++++++++++++++ .../include/kernel/tests/bump_frame_allocator.hpp | 32 --------------------- kernel/include/kernel/tests/cpu.hpp | 18 ------------ kernel/include/kernel/tests/log_buffer.hpp | 32 --------------------- kernel/include/kernel/tests/page_mapper.hpp | 33 ---------------------- kernel/include/kernel/tests/simulated_memory.hpp | 27 ------------------ kernel/kapi/cpu.tests.cpp | 2 +- kernel/kapi/system.tests.cpp | 4 +-- kernel/kstd/print.tests.cpp | 2 +- kernel/src/test_support/kapi/cio.cpp | 2 +- kernel/src/test_support/kapi/cpu.cpp | 2 +- kernel/src/test_support/kapi/memory.cpp | 4 +-- kernel/src/test_support/log_buffer.cpp | 2 +- kernel/src/test_support/page_mapper.cpp | 2 +- kernel/src/test_support/simulated_memory.cpp | 2 +- 19 files changed, 153 insertions(+), 153 deletions(-) create mode 100644 kernel/include/kernel/test_support/bump_frame_allocator.hpp create mode 100644 kernel/include/kernel/test_support/cpu.hpp create mode 100644 kernel/include/kernel/test_support/log_buffer.hpp create mode 100644 kernel/include/kernel/test_support/page_mapper.hpp create mode 100644 kernel/include/kernel/test_support/simulated_memory.hpp delete mode 100644 kernel/include/kernel/tests/bump_frame_allocator.hpp delete mode 100644 kernel/include/kernel/tests/cpu.hpp delete mode 100644 kernel/include/kernel/tests/log_buffer.hpp delete mode 100644 kernel/include/kernel/tests/page_mapper.hpp delete mode 100644 kernel/include/kernel/tests/simulated_memory.hpp (limited to 'kernel') diff --git a/kernel/include/kernel/test_support/bump_frame_allocator.hpp b/kernel/include/kernel/test_support/bump_frame_allocator.hpp new file mode 100644 index 0000000..5203565 --- /dev/null +++ b/kernel/include/kernel/test_support/bump_frame_allocator.hpp @@ -0,0 +1,32 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_BUMP_FRAME_ALLOCATOR_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_BUMP_FRAME_ALLOCATOR_HPP + +#include "kapi/memory.hpp" + +#include +#include +#include + +namespace kernel::tests +{ + + struct bump_frame_allocator : kapi::memory::frame_allocator + { + auto mark_used(kapi::memory::frame) -> void override {} + + auto allocate_many(std::size_t count) noexcept + -> std::optional> override + { + auto start = next_free_frame; + next_free_frame += count; + return std::pair{kapi::memory::frame{start}, count}; + } + + auto release_many(std::pair) -> void override {} + + std::size_t next_free_frame{}; + }; + +} // namespace kernel::tests + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/cpu.hpp b/kernel/include/kernel/test_support/cpu.hpp new file mode 100644 index 0000000..5445473 --- /dev/null +++ b/kernel/include/kernel/test_support/cpu.hpp @@ -0,0 +1,18 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_CPU_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_CPU_HPP + +#include + +namespace kernel::tests::cpu +{ + + struct halt : std::runtime_error + { + halt() + : std::runtime_error{"CPU halt requested!"} + {} + }; + +} // namespace kernel::tests::cpu + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/log_buffer.hpp b/kernel/include/kernel/test_support/log_buffer.hpp new file mode 100644 index 0000000..581b32f --- /dev/null +++ b/kernel/include/kernel/test_support/log_buffer.hpp @@ -0,0 +1,32 @@ +#ifndef KERNEL_TEST_SUPPORT_LOG_BUFFER_HPP +#define KERNEL_TEST_SUPPORT_LOG_BUFFER_HPP + +#include +#include + +namespace kernel::tests::log_buffer +{ + + //! Append a message to the testing log buffer. + //! + //! @param message The message to append. + auto append(std::string const & message) -> void; + + //! Clear the testing log buffer. + auto clear() -> void; + + //! Get the testing log buffer as a single string. + //! + //! @return The testing log buffer as a single string. + auto flat_messages() -> std::string; + + //! Get the testing log buffer. + //! + //! @note Messages may be split across multiple entries if they are longer than the internal kernel print buffer size. + //! + //! @return The testing log buffer. + auto messages() -> std::vector const &; + +} // namespace kernel::tests::log_buffer + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/page_mapper.hpp b/kernel/include/kernel/test_support/page_mapper.hpp new file mode 100644 index 0000000..a40aa2e --- /dev/null +++ b/kernel/include/kernel/test_support/page_mapper.hpp @@ -0,0 +1,33 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_PAGE_MAPPER_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_PAGE_MAPPER_HPP + +#include "kapi/memory.hpp" + +#include "kernel/test_support/simulated_memory.hpp" + +#include + +#include +#include +#include + +namespace kernel::tests +{ + + struct page_mapper : kapi::memory::page_mapper + { + explicit page_mapper(kstd::units::bytes memory_size); + + auto map(kapi::memory::page page, kapi::memory::frame frame, flags) -> std::byte * override; + + auto unmap(kapi::memory::page page) -> void override; + + auto try_unmap(kapi::memory::page page) noexcept -> bool override; + + kernel::tests::simulated_memory memory; + std::unordered_map page_mappings; + }; + +} // namespace kernel::tests + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/simulated_memory.hpp b/kernel/include/kernel/test_support/simulated_memory.hpp new file mode 100644 index 0000000..fed9f43 --- /dev/null +++ b/kernel/include/kernel/test_support/simulated_memory.hpp @@ -0,0 +1,27 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_SIMULATED_MEMORY_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_SIMULATED_MEMORY_HPP + +#include + +#include +#include + +namespace kernel::tests +{ + + struct simulated_memory + { + explicit simulated_memory(kstd::units::bytes size); + + auto clear() -> void; + + auto ram_base() noexcept -> std::byte *; + [[nodiscard]] auto ram_base() const noexcept -> std::byte const *; + + private: + std::vector m_memory; + }; + +} // namespace kernel::tests + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/tests/bump_frame_allocator.hpp b/kernel/include/kernel/tests/bump_frame_allocator.hpp deleted file mode 100644 index 8344423..0000000 --- a/kernel/include/kernel/tests/bump_frame_allocator.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef TEACHOS_KERNEL_TESTS_BUMP_FRAME_ALLOCATOR_HPP -#define TEACHOS_KERNEL_TESTS_BUMP_FRAME_ALLOCATOR_HPP - -#include "kapi/memory.hpp" - -#include -#include -#include - -namespace kernel::tests -{ - - struct bump_frame_allocator : kapi::memory::frame_allocator - { - auto mark_used(kapi::memory::frame) -> void override {} - - auto allocate_many(std::size_t count) noexcept - -> std::optional> override - { - auto start = next_free_frame; - next_free_frame += count; - return std::pair{kapi::memory::frame{start}, count}; - } - - auto release_many(std::pair) -> void override {} - - std::size_t next_free_frame{}; - }; - -} // namespace kernel::tests - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/tests/cpu.hpp b/kernel/include/kernel/tests/cpu.hpp deleted file mode 100644 index 81c0c6f..0000000 --- a/kernel/include/kernel/tests/cpu.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef TEACHOS_KERNEL_TESTS_CPU_HPP -#define TEACHOS_KERNEL_TESTS_CPU_HPP - -#include - -namespace kernel::tests::cpu -{ - - struct halt : std::runtime_error - { - halt() - : std::runtime_error{"CPU halt requested!"} - {} - }; - -} // namespace kernel::tests::cpu - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/tests/log_buffer.hpp b/kernel/include/kernel/tests/log_buffer.hpp deleted file mode 100644 index 5f2a1a7..0000000 --- a/kernel/include/kernel/tests/log_buffer.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef KERNEL_TESTS_LOG_BUFFER_HPP -#define KERNEL_TESTS_LOG_BUFFER_HPP - -#include -#include - -namespace kernel::tests::log_buffer -{ - - //! Append a message to the testing log buffer. - //! - //! @param message The message to append. - auto append(std::string const & message) -> void; - - //! Clear the testing log buffer. - auto clear() -> void; - - //! Get the testing log buffer as a single string. - //! - //! @return The testing log buffer as a single string. - auto flat_messages() -> std::string; - - //! Get the testing log buffer. - //! - //! @note Messages may be split across multiple entries if they are longer than the internal kernel print buffer size. - //! - //! @return The testing log buffer. - auto messages() -> std::vector const &; - -} // namespace kernel::tests::log_buffer - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/tests/page_mapper.hpp b/kernel/include/kernel/tests/page_mapper.hpp deleted file mode 100644 index 9969976..0000000 --- a/kernel/include/kernel/tests/page_mapper.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef TEACHOS_KERNEL_TESTS_PAGE_MAPPER_HPP -#define TEACHOS_KERNEL_TESTS_PAGE_MAPPER_HPP - -#include "kapi/memory.hpp" - -#include "kernel/tests/simulated_memory.hpp" - -#include - -#include -#include -#include - -namespace kernel::tests -{ - - struct page_mapper : kapi::memory::page_mapper - { - explicit page_mapper(kstd::units::bytes memory_size); - - auto map(kapi::memory::page page, kapi::memory::frame frame, flags) -> std::byte * override; - - auto unmap(kapi::memory::page page) -> void override; - - auto try_unmap(kapi::memory::page page) noexcept -> bool override; - - kernel::tests::simulated_memory memory; - std::unordered_map page_mappings; - }; - -} // namespace kernel::tests - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/tests/simulated_memory.hpp b/kernel/include/kernel/tests/simulated_memory.hpp deleted file mode 100644 index 446d558..0000000 --- a/kernel/include/kernel/tests/simulated_memory.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef TEACHOS_KERNEL_TESTS_SIMULATED_MEMORY_HPP -#define TEACHOS_KERNEL_TESTS_SIMULATED_MEMORY_HPP - -#include - -#include -#include - -namespace kernel::tests -{ - - struct simulated_memory - { - explicit simulated_memory(kstd::units::bytes size); - - auto clear() -> void; - - auto ram_base() noexcept -> std::byte *; - [[nodiscard]] auto ram_base() const noexcept -> std::byte const *; - - private: - std::vector m_memory; - }; - -} // namespace kernel::tests - -#endif \ No newline at end of file diff --git a/kernel/kapi/cpu.tests.cpp b/kernel/kapi/cpu.tests.cpp index 6fe026b..85b20fd 100644 --- a/kernel/kapi/cpu.tests.cpp +++ b/kernel/kapi/cpu.tests.cpp @@ -1,6 +1,6 @@ #include "kapi/cpu.hpp" -#include "kernel/tests/cpu.hpp" +#include "kernel/test_support/cpu.hpp" #include diff --git a/kernel/kapi/system.tests.cpp b/kernel/kapi/system.tests.cpp index c130b54..ee31c51 100644 --- a/kernel/kapi/system.tests.cpp +++ b/kernel/kapi/system.tests.cpp @@ -1,7 +1,7 @@ #include "kapi/system.hpp" -#include "kernel/tests/cpu.hpp" -#include "kernel/tests/log_buffer.hpp" +#include "kernel/test_support/cpu.hpp" +#include "kernel/test_support/log_buffer.hpp" #include diff --git a/kernel/kstd/print.tests.cpp b/kernel/kstd/print.tests.cpp index 2ab829c..f8e600f 100644 --- a/kernel/kstd/print.tests.cpp +++ b/kernel/kstd/print.tests.cpp @@ -1,6 +1,6 @@ #include "kstd/print" -#include "kernel/tests/log_buffer.hpp" +#include "kernel/test_support/log_buffer.hpp" #include diff --git a/kernel/src/test_support/kapi/cio.cpp b/kernel/src/test_support/kapi/cio.cpp index 0dd4b8c..35452d4 100644 --- a/kernel/src/test_support/kapi/cio.cpp +++ b/kernel/src/test_support/kapi/cio.cpp @@ -1,6 +1,6 @@ #include -#include "kernel/tests/log_buffer.hpp" +#include "kernel/test_support/log_buffer.hpp" #include #include diff --git a/kernel/src/test_support/kapi/cpu.cpp b/kernel/src/test_support/kapi/cpu.cpp index 9b2f0b9..6592d15 100644 --- a/kernel/src/test_support/kapi/cpu.cpp +++ b/kernel/src/test_support/kapi/cpu.cpp @@ -1,4 +1,4 @@ -#include "kernel/tests/cpu.hpp" +#include "kernel/test_support/cpu.hpp" #include diff --git a/kernel/src/test_support/kapi/memory.cpp b/kernel/src/test_support/kapi/memory.cpp index 7b7a81e..3a2c2ba 100644 --- a/kernel/src/test_support/kapi/memory.cpp +++ b/kernel/src/test_support/kapi/memory.cpp @@ -2,8 +2,8 @@ #include -#include "kernel/tests/bump_frame_allocator.hpp" -#include "kernel/tests/page_mapper.hpp" +#include "kernel/test_support/bump_frame_allocator.hpp" +#include "kernel/test_support/page_mapper.hpp" #include diff --git a/kernel/src/test_support/log_buffer.cpp b/kernel/src/test_support/log_buffer.cpp index 9e30afb..36ed15e 100644 --- a/kernel/src/test_support/log_buffer.cpp +++ b/kernel/src/test_support/log_buffer.cpp @@ -1,4 +1,4 @@ -#include "kernel/tests/log_buffer.hpp" +#include "kernel/test_support/log_buffer.hpp" #include #include diff --git a/kernel/src/test_support/page_mapper.cpp b/kernel/src/test_support/page_mapper.cpp index a026ec3..5a1b747 100644 --- a/kernel/src/test_support/page_mapper.cpp +++ b/kernel/src/test_support/page_mapper.cpp @@ -1,4 +1,4 @@ -#include "kernel/tests/page_mapper.hpp" +#include "kernel/test_support/page_mapper.hpp" #include "kapi/memory.hpp" diff --git a/kernel/src/test_support/simulated_memory.cpp b/kernel/src/test_support/simulated_memory.cpp index d23350b..7264a35 100644 --- a/kernel/src/test_support/simulated_memory.cpp +++ b/kernel/src/test_support/simulated_memory.cpp @@ -1,4 +1,4 @@ -#include "kernel/tests/simulated_memory.hpp" +#include "kernel/test_support/simulated_memory.hpp" #include -- cgit v1.2.3 From dc64b1cba4677b40c9dda31ecd5109507837b817 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 20:59:55 +0200 Subject: kernel/tests: don't rely on vector for fake memory --- .../kernel/test_support/simulated_memory.hpp | 15 ++++- kernel/src/test_support/page_mapper.cpp | 20 +++++- kernel/src/test_support/simulated_memory.cpp | 77 ++++++++++++++++++++-- 3 files changed, 100 insertions(+), 12 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/test_support/simulated_memory.hpp b/kernel/include/kernel/test_support/simulated_memory.hpp index fed9f43..9a391d8 100644 --- a/kernel/include/kernel/test_support/simulated_memory.hpp +++ b/kernel/include/kernel/test_support/simulated_memory.hpp @@ -1,10 +1,11 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_SIMULATED_MEMORY_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_SIMULATED_MEMORY_HPP +#include "kapi/memory.hpp" + #include #include -#include namespace kernel::tests { @@ -13,13 +14,21 @@ namespace kernel::tests { explicit simulated_memory(kstd::units::bytes size); + ~simulated_memory(); + auto clear() -> void; - auto ram_base() noexcept -> std::byte *; + [[nodiscard]] auto ram_base() noexcept -> std::byte *; [[nodiscard]] auto ram_base() const noexcept -> std::byte const *; + [[nodiscard]] auto heap_base() const noexcept -> kapi::memory::linear_address; + [[nodiscard]] auto heap_size() const noexcept -> kstd::units::bytes; + [[nodiscard]] auto memory_descriptor() const noexcept -> int; private: - std::vector m_memory; + int m_memory_descriptor{}; + kstd::units::bytes m_size{0}; + std::byte * m_physical_base{nullptr}; + std::byte * m_virtual_base{nullptr}; }; } // namespace kernel::tests diff --git a/kernel/src/test_support/page_mapper.cpp b/kernel/src/test_support/page_mapper.cpp index 5a1b747..805998b 100644 --- a/kernel/src/test_support/page_mapper.cpp +++ b/kernel/src/test_support/page_mapper.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace kernel::tests { @@ -20,10 +21,25 @@ namespace kernel::tests page_mappings.insert({page.number(), frame}); auto page_address = page.start_address(); + auto sandbox_start = memory.heap_base(); + auto sandbox_end = sandbox_start + memory.heap_size(); - if (page_address >= kapi::memory::mmio_base) + if (page_address >= sandbox_start && page_address < sandbox_end) { - throw std::invalid_argument{"MMIO mapping not yet supported in testing!"}; + auto virtual_target = static_cast(page_address); + auto physical_offset = frame.number() * kapi::memory::frame::size; + auto mapped_ptr = mmap(virtual_target, kapi::memory::page::size.value, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_FIXED, memory.memory_descriptor(), physical_offset.value); + if (mapped_ptr == MAP_FAILED) + { + throw std::runtime_error("Failed to map page"); + } + + return static_cast(mapped_ptr); + } + else if (page_address >= kapi::memory::mmio_base) + { + throw std::runtime_error("MMIO mapping not yet supported in testing!"); } else if (page_address >= kapi::memory::higher_half_direct_map_base) { diff --git a/kernel/src/test_support/simulated_memory.cpp b/kernel/src/test_support/simulated_memory.cpp index 7264a35..fa3d36c 100644 --- a/kernel/src/test_support/simulated_memory.cpp +++ b/kernel/src/test_support/simulated_memory.cpp @@ -1,30 +1,93 @@ #include "kernel/test_support/simulated_memory.hpp" +#include "kapi/memory.hpp" + #include #include -#include +#include +#include +#include +#include +#include + +using namespace kstd::units_literals; namespace kernel::tests { + namespace + { + constexpr auto virtual_size = 1_GiB; + } simulated_memory::simulated_memory(kstd::units::bytes size) - : m_memory{size / kstd::units::bytes{1}} - {} + : m_memory_descriptor{memfd_create("teachos_simulated_memory", 0)} + , m_size{size} + { + if (m_memory_descriptor < 0) + { + throw std::runtime_error("Failed to create simulated memory"); + } + + if (ftruncate(m_memory_descriptor, static_cast(m_size.value)) < 0) + { + throw std::runtime_error("Failed to resize simulated memory"); + } + + auto mapped_pointer = mmap(nullptr, m_size.value, PROT_READ | PROT_WRITE, MAP_SHARED, m_memory_descriptor, 0); + if (mapped_pointer == MAP_FAILED) + { + throw std::runtime_error("Failed to map simulated memory"); + } + + m_physical_base = static_cast(mapped_pointer); + + auto virtual_pointer = mmap(nullptr, virtual_size.value, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (virtual_pointer == MAP_FAILED) + { + throw std::runtime_error("Failed to map simulated memory"); + } + + m_virtual_base = static_cast(virtual_pointer); + + clear(); + } + + simulated_memory::~simulated_memory() + { + munmap(m_physical_base, m_size.value); + munmap(m_virtual_base, virtual_size.value); + close(m_memory_descriptor); + } + + auto simulated_memory::clear() -> void + { + std::memset(m_physical_base, 0, m_size.value); + } auto simulated_memory::ram_base() noexcept -> std::byte * { - return m_memory.data(); + return m_physical_base; } auto simulated_memory::ram_base() const noexcept -> std::byte const * { - return m_memory.data(); + return m_physical_base; } - auto simulated_memory::clear() -> void + auto simulated_memory::heap_base() const noexcept -> kapi::memory::linear_address + { + return kapi::memory::linear_address{m_virtual_base}; + } + + auto simulated_memory::heap_size() const noexcept -> kstd::units::bytes + { + return virtual_size; + } + + auto simulated_memory::memory_descriptor() const noexcept -> int { - m_memory.clear(); + return m_memory_descriptor; } } // namespace kernel::tests \ No newline at end of file -- cgit v1.2.3 From f8456a8709b6894166865eb4ca067604f480eb7f Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 21:16:10 +0200 Subject: kernel/tests: add basic heap allocator tests --- kernel/CMakeLists.txt | 1 + kernel/include/kernel/test_support/memory.hpp | 11 ++++ kernel/src/memory/block_list_allocator.tests.cpp | 80 ++++++++++++++++++++++++ kernel/src/test_support/kapi/memory.cpp | 44 +++++++------ 4 files changed, 118 insertions(+), 18 deletions(-) create mode 100644 kernel/include/kernel/test_support/memory.hpp create mode 100644 kernel/src/memory/block_list_allocator.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 4264441..1b71a5f 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -115,6 +115,7 @@ else() # Memory Subsystem Tests "src/memory/bitmap_allocator.tests.cpp" + "src/memory/block_list_allocator.tests.cpp" # Storage Subsystem Tests "src/devices/storage/ram_disk/device.tests.cpp" diff --git a/kernel/include/kernel/test_support/memory.hpp b/kernel/include/kernel/test_support/memory.hpp new file mode 100644 index 0000000..c6b7449 --- /dev/null +++ b/kernel/include/kernel/test_support/memory.hpp @@ -0,0 +1,11 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_MEMORY_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_MEMORY_HPP + +#include "kapi/memory.hpp" + +namespace kernel::tests::memory +{ + auto heap_base() -> kapi::memory::linear_address; +} + +#endif \ No newline at end of file diff --git a/kernel/src/memory/block_list_allocator.tests.cpp b/kernel/src/memory/block_list_allocator.tests.cpp new file mode 100644 index 0000000..5f6f382 --- /dev/null +++ b/kernel/src/memory/block_list_allocator.tests.cpp @@ -0,0 +1,80 @@ +#include "kernel/memory/block_list_allocator.hpp" + +#include "kernel/test_support/memory.hpp" + +#include + +#include + +#include + +using namespace kstd::units_literals; + +SCENARIO("Block List Allocator Operations", "[memory][allocator]") +{ + GIVEN("A newly initialized block list allocator mapped via the test sandbox") + { + auto sandbox_base = kernel::tests::memory::heap_base(); + kernel::memory::block_list_allocator allocator{sandbox_base}; + + WHEN("a basic allocation request is made") + { + void * ptr = allocator.allocate(128_B, 8_B); + + THEN("a valid, non-null pointer is returned") + { + REQUIRE(ptr != nullptr); + } + + AND_THEN("the returned memory is writeable without causing segmentation faults") + { + auto byte_ptr = static_cast(ptr); + byte_ptr[0] = std::byte{0xDE}; + byte_ptr[127] = std::byte{0xAD}; + REQUIRE(byte_ptr[0] == std::byte{0xDE}); + REQUIRE(byte_ptr[127] == std::byte{0xAD}); + } + + allocator.deallocate(ptr); + } + + WHEN("multiple allocations are made sequentially") + { + void * ptr1 = allocator.allocate(64_B, 8_B); + void * ptr2 = allocator.allocate(64_B, 8_B); + void * ptr3 = allocator.allocate(1_KiB, 16_B); + + THEN("they return distinct, non-overlapping memory blocks") + { + REQUIRE(ptr1 != nullptr); + REQUIRE(ptr2 != nullptr); + REQUIRE(ptr3 != nullptr); + REQUIRE(ptr1 != ptr2); + REQUIRE(ptr2 != ptr3); + REQUIRE(ptr1 != ptr3); + } + + allocator.deallocate(ptr1); + allocator.deallocate(ptr2); + allocator.deallocate(ptr3); + } + + WHEN("a block is allocated and then completely freed") + { + void * original_ptr = allocator.allocate(512_B, 16_B); + allocator.deallocate(original_ptr); + + AND_WHEN("a new allocation of equal or smaller size is requested") + { + void * new_ptr = allocator.allocate(128_B, 16_B); + + THEN("the allocator actively reuses the coalesced space") + { + REQUIRE(new_ptr == original_ptr); + } + + allocator.deallocate(new_ptr); + } + } + } +} diff --git a/kernel/src/test_support/kapi/memory.cpp b/kernel/src/test_support/kapi/memory.cpp index 3a2c2ba..f244b7f 100644 --- a/kernel/src/test_support/kapi/memory.cpp +++ b/kernel/src/test_support/kapi/memory.cpp @@ -9,29 +9,29 @@ #include -namespace kapi::memory +namespace { + //! The size of the simulated RAM. + constexpr auto memory_size = kstd::units::MiB(32); + constexpr auto number_of_frames = memory_size / kapi::memory::frame::size; - namespace - { - //! The size of the simulated RAM. - constexpr auto memory_size = kstd::units::MiB(32); - constexpr auto number_of_frames = memory_size / frame::size; + auto constinit bump_allocator = std::optional{}; + auto constinit test_mapper = std::optional{}; - auto constinit bump_allocator = std::optional{}; - auto constinit test_mapper = std::optional{}; + auto constinit old_allocator = std::optional{}; + auto constinit old_mapper = std::optional{}; - auto constinit old_allocator = std::optional{}; - auto constinit old_mapper = std::optional{}; + auto handoff_to_kernel_pmm(kapi::memory::frame_allocator & new_allocator) -> void + { + auto first_free_frame = bump_allocator->next_free_frame; + auto number_of_free_frames = number_of_frames - first_free_frame; + new_allocator.release_many({kapi::memory::frame{first_free_frame}, number_of_free_frames}); + } - auto handoff_to_kernel_pmm(frame_allocator & new_allocator) -> void - { - auto first_free_frame = bump_allocator->next_free_frame; - auto number_of_free_frames = number_of_frames - first_free_frame; - new_allocator.release_many({frame{first_free_frame}, number_of_free_frames}); - } +} // namespace - } // namespace +namespace kapi::memory +{ auto init() -> void { @@ -60,4 +60,12 @@ namespace kapi::memory test_mapper.reset(); } -} // namespace kapi::memory \ No newline at end of file +} // namespace kapi::memory + +namespace kernel::tests::memory +{ + auto heap_base() -> kapi::memory::linear_address + { + return test_mapper->memory.heap_base(); + } +} // namespace kernel::tests::memory \ No newline at end of file -- cgit v1.2.3 From 3eb680cf5bcef626505cac82820996d8db4170d7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 1 Apr 2026 22:52:22 +0200 Subject: kernel/tests: prevent double mapping of pages --- kernel/src/memory/block_list_allocator.tests.cpp | 13 +++++++++++++ kernel/src/test_support/page_mapper.cpp | 7 ++++++- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/memory/block_list_allocator.tests.cpp b/kernel/src/memory/block_list_allocator.tests.cpp index 5f6f382..8ca426d 100644 --- a/kernel/src/memory/block_list_allocator.tests.cpp +++ b/kernel/src/memory/block_list_allocator.tests.cpp @@ -1,5 +1,7 @@ #include "kernel/memory/block_list_allocator.hpp" +#include "kapi/memory.hpp" + #include "kernel/test_support/memory.hpp" #include @@ -10,10 +12,21 @@ using namespace kstd::units_literals; +namespace kapi +{ + namespace memory + { + auto reset() -> void; + } +} // namespace kapi + SCENARIO("Block List Allocator Operations", "[memory][allocator]") { GIVEN("A newly initialized block list allocator mapped via the test sandbox") { + kapi::memory::reset(); + kapi::memory::init(); + auto sandbox_base = kernel::tests::memory::heap_base(); kernel::memory::block_list_allocator allocator{sandbox_base}; diff --git a/kernel/src/test_support/page_mapper.cpp b/kernel/src/test_support/page_mapper.cpp index 805998b..abdcae5 100644 --- a/kernel/src/test_support/page_mapper.cpp +++ b/kernel/src/test_support/page_mapper.cpp @@ -18,7 +18,12 @@ namespace kernel::tests auto page_mapper::map(kapi::memory::page page, kapi::memory::frame frame, flags) -> std::byte * { - page_mappings.insert({page.number(), frame}); + auto result = page_mappings.insert({page.number(), frame}); + if (!result.second) + { + auto error = std::format("Page {} was already mapped!", page.number()); + throw std::invalid_argument{error}; + } auto page_address = page.start_address(); auto sandbox_start = memory.heap_base(); -- cgit v1.2.3 From f7ff847498d629c05bb206b41a172f6735e2afe6 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 09:51:44 +0200 Subject: kernel/tests: clean up implementation structure --- kernel/CMakeLists.txt | 1 + kernel/include/kernel/test_support/cio.hpp | 29 ++++++++ kernel/include/kernel/test_support/cpu.hpp | 2 + kernel/include/kernel/test_support/log_buffer.hpp | 49 +++++++------- kernel/include/kernel/test_support/memory.hpp | 6 +- kernel/include/kernel/test_support/page_mapper.hpp | 2 +- .../kernel/test_support/simulated_memory.hpp | 23 ++++--- kernel/kapi/system.tests.cpp | 6 +- kernel/kstd/print.tests.cpp | 6 +- kernel/src/memory/block_list_allocator.tests.cpp | 12 +--- kernel/src/test_support/kapi/cio.cpp | 63 ++++++++++-------- kernel/src/test_support/kapi/cpu.cpp | 37 ++++++----- kernel/src/test_support/kapi/memory.cpp | 25 +++---- kernel/src/test_support/log_buffer.cpp | 32 ++++----- kernel/src/test_support/output_device.cpp | 28 ++++++++ kernel/src/test_support/page_mapper.cpp | 22 ++----- kernel/src/test_support/simulated_memory.cpp | 77 +++++++++++++--------- kernel/src/test_support/state_reset_listener.cpp | 28 ++------ 18 files changed, 261 insertions(+), 187 deletions(-) create mode 100644 kernel/include/kernel/test_support/cio.hpp create mode 100644 kernel/src/test_support/output_device.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 1b71a5f..f283588 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -94,6 +94,7 @@ else() "src/test_support/kapi/interrupts.cpp" "src/test_support/kapi/memory.cpp" "src/test_support/log_buffer.cpp" + "src/test_support/output_device.cpp" "src/test_support/page_mapper.cpp" "src/test_support/simulated_memory.cpp" "src/test_support/state_reset_listener.cpp" diff --git a/kernel/include/kernel/test_support/cio.hpp b/kernel/include/kernel/test_support/cio.hpp new file mode 100644 index 0000000..4b897b5 --- /dev/null +++ b/kernel/include/kernel/test_support/cio.hpp @@ -0,0 +1,29 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_CIO_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_CIO_HPP + +#include "kapi/cio.hpp" + +#include "kernel/test_support/log_buffer.hpp" + +#include + +namespace kernel::tests::cio +{ + struct output_device : kapi::cio::output_device + { + output_device() = default; + + auto write(kapi::cio::output_stream stream, std::string_view text) -> void override; + + [[nodiscard]] auto log_buffer() noexcept -> kernel::tests::log_buffer &; + + private: + kernel::tests::log_buffer m_log_buffer{}; + }; + + auto deinit() -> void; + + [[nodiscard]] auto log_buffer() -> kernel::tests::log_buffer &; +} // namespace kernel::tests::cio + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/cpu.hpp b/kernel/include/kernel/test_support/cpu.hpp index 5445473..037b1b2 100644 --- a/kernel/include/kernel/test_support/cpu.hpp +++ b/kernel/include/kernel/test_support/cpu.hpp @@ -13,6 +13,8 @@ namespace kernel::tests::cpu {} }; + auto deinit() -> void; + } // namespace kernel::tests::cpu #endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/log_buffer.hpp b/kernel/include/kernel/test_support/log_buffer.hpp index 581b32f..41d9a76 100644 --- a/kernel/include/kernel/test_support/log_buffer.hpp +++ b/kernel/include/kernel/test_support/log_buffer.hpp @@ -4,29 +4,34 @@ #include #include -namespace kernel::tests::log_buffer +namespace kernel::tests { - //! Append a message to the testing log buffer. - //! - //! @param message The message to append. - auto append(std::string const & message) -> void; - - //! Clear the testing log buffer. - auto clear() -> void; - - //! Get the testing log buffer as a single string. - //! - //! @return The testing log buffer as a single string. - auto flat_messages() -> std::string; - - //! Get the testing log buffer. - //! - //! @note Messages may be split across multiple entries if they are longer than the internal kernel print buffer size. - //! - //! @return The testing log buffer. - auto messages() -> std::vector const &; - -} // namespace kernel::tests::log_buffer + struct log_buffer + { + //! Append a message to this buffer. + //! @param message The message to append. + auto append(std::string const & message) -> void; + + //! Clear this buffer. + auto clear() -> void; + + //! Get all messages in this buffer as a single string. + //! + //! @return All messages in this buffer as a single string. + auto flat_messages() -> std::string; + + //! Get all messages in this buffer. + //! + //! @note Messages may be split across multiple entries if they are longer than the internal kernel print buffer + //! size. + //! + //! @return All messages in this buffer. + auto messages() -> std::vector const &; + + private: + std::vector m_messages{}; + }; +} // namespace kernel::tests #endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/memory.hpp b/kernel/include/kernel/test_support/memory.hpp index c6b7449..b475116 100644 --- a/kernel/include/kernel/test_support/memory.hpp +++ b/kernel/include/kernel/test_support/memory.hpp @@ -5,7 +5,9 @@ namespace kernel::tests::memory { - auto heap_base() -> kapi::memory::linear_address; -} + auto deinit() -> void; + + auto virtual_base() -> kapi::memory::linear_address; +} // namespace kernel::tests::memory #endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/page_mapper.hpp b/kernel/include/kernel/test_support/page_mapper.hpp index a40aa2e..1658455 100644 --- a/kernel/include/kernel/test_support/page_mapper.hpp +++ b/kernel/include/kernel/test_support/page_mapper.hpp @@ -16,7 +16,7 @@ namespace kernel::tests struct page_mapper : kapi::memory::page_mapper { - explicit page_mapper(kstd::units::bytes memory_size); + page_mapper(kstd::units::bytes physical_size, kstd::units::bytes virtual_size); auto map(kapi::memory::page page, kapi::memory::frame frame, flags) -> std::byte * override; diff --git a/kernel/include/kernel/test_support/simulated_memory.hpp b/kernel/include/kernel/test_support/simulated_memory.hpp index 9a391d8..1619f31 100644 --- a/kernel/include/kernel/test_support/simulated_memory.hpp +++ b/kernel/include/kernel/test_support/simulated_memory.hpp @@ -6,27 +6,34 @@ #include #include +#include namespace kernel::tests { struct simulated_memory { - explicit simulated_memory(kstd::units::bytes size); + simulated_memory(kstd::units::bytes physical_size, kstd::units::bytes virtual_size); ~simulated_memory(); auto clear() -> void; - [[nodiscard]] auto ram_base() noexcept -> std::byte *; - [[nodiscard]] auto ram_base() const noexcept -> std::byte const *; - [[nodiscard]] auto heap_base() const noexcept -> kapi::memory::linear_address; - [[nodiscard]] auto heap_size() const noexcept -> kstd::units::bytes; - [[nodiscard]] auto memory_descriptor() const noexcept -> int; + [[nodiscard]] auto physical_base() noexcept -> std::byte *; + [[nodiscard]] auto physical_base() const noexcept -> std::byte const *; + [[nodiscard]] auto physical_size() const noexcept -> kstd::units::bytes; + + [[nodiscard]] auto virtual_base() const noexcept -> kapi::memory::linear_address; + [[nodiscard]] auto virtual_size() const noexcept -> kstd::units::bytes; + + [[nodiscard]] auto descriptor() const noexcept -> int; + + [[nodiscard]] auto map(kstd::units::bytes size, std::byte * to, off_t offset) -> std::byte *; private: - int m_memory_descriptor{}; - kstd::units::bytes m_size{0}; + int m_descriptor{}; + kstd::units::bytes m_physical_size{0}; + kstd::units::bytes m_virtual_size{0}; std::byte * m_physical_base{nullptr}; std::byte * m_virtual_base{nullptr}; }; diff --git a/kernel/kapi/system.tests.cpp b/kernel/kapi/system.tests.cpp index ee31c51..687053e 100644 --- a/kernel/kapi/system.tests.cpp +++ b/kernel/kapi/system.tests.cpp @@ -1,7 +1,7 @@ #include "kapi/system.hpp" +#include "kernel/test_support/cio.hpp" #include "kernel/test_support/cpu.hpp" -#include "kernel/test_support/log_buffer.hpp" #include @@ -13,7 +13,7 @@ SCENARIO("Kernel testing kapi::system shims", "[support]") { WHEN("a the system panics") { - kernel::tests::log_buffer::clear(); + kernel::tests::cio::log_buffer().clear(); THEN("the correct exception is thrown") { @@ -23,7 +23,7 @@ SCENARIO("Kernel testing kapi::system shims", "[support]") THEN("the message is appended to the log buffer") { CHECK_THROWS(kapi::system::panic("[kernel:tests] Test Panic")); - REQUIRE(kernel::tests::log_buffer::flat_messages().contains("[kernel:tests] Test Panic")); + REQUIRE(kernel::tests::cio::log_buffer().flat_messages().contains("[kernel:tests] Test Panic")); } } } diff --git a/kernel/kstd/print.tests.cpp b/kernel/kstd/print.tests.cpp index f8e600f..8deeb17 100644 --- a/kernel/kstd/print.tests.cpp +++ b/kernel/kstd/print.tests.cpp @@ -1,6 +1,6 @@ #include "kstd/print" -#include "kernel/test_support/log_buffer.hpp" +#include "kernel/test_support/cio.hpp" #include @@ -10,13 +10,13 @@ SCENARIO("Kernel testing kstd shims", "[support]") { WHEN("a regular print is issued") { - kernel::tests::log_buffer::clear(); + kernel::tests::cio::log_buffer().clear(); kstd::println("[kernel:tests] Test Print"); THEN("the message is appended to the log buffer") { - REQUIRE(kernel::tests::log_buffer::flat_messages().contains("[kernel:tests] Test Print")); + REQUIRE(kernel::tests::cio::log_buffer().flat_messages().contains("[kernel:tests] Test Print")); } } } diff --git a/kernel/src/memory/block_list_allocator.tests.cpp b/kernel/src/memory/block_list_allocator.tests.cpp index 8ca426d..0571441 100644 --- a/kernel/src/memory/block_list_allocator.tests.cpp +++ b/kernel/src/memory/block_list_allocator.tests.cpp @@ -12,22 +12,14 @@ using namespace kstd::units_literals; -namespace kapi -{ - namespace memory - { - auto reset() -> void; - } -} // namespace kapi - SCENARIO("Block List Allocator Operations", "[memory][allocator]") { GIVEN("A newly initialized block list allocator mapped via the test sandbox") { - kapi::memory::reset(); + kernel::tests::memory::deinit(); kapi::memory::init(); - auto sandbox_base = kernel::tests::memory::heap_base(); + auto sandbox_base = kernel::tests::memory::virtual_base(); kernel::memory::block_list_allocator allocator{sandbox_base}; WHEN("a basic allocation request is made") diff --git a/kernel/src/test_support/kapi/cio.cpp b/kernel/src/test_support/kapi/cio.cpp index 35452d4..4a1cd1f 100644 --- a/kernel/src/test_support/kapi/cio.cpp +++ b/kernel/src/test_support/kapi/cio.cpp @@ -1,43 +1,54 @@ +#include "kernel/test_support/cio.hpp" + #include #include "kernel/test_support/log_buffer.hpp" -#include -#include -#include +#include +#include +#include + +namespace +{ + + auto constinit is_initialized = std::atomic_flag{}; + auto constinit device = std::optional{}; + +} // namespace namespace kapi::cio { - namespace + auto init() -> void { - - class test_output_device : public output_device + if (is_initialized.test_and_set()) { - public: - test_output_device() = default; - - auto write(output_stream stream, std::string_view text) -> void override - { - auto & standard_stream = stream == output_stream::stdout ? std::cout : std::cerr; - standard_stream << text; - if (text != "\n") - { - kernel::tests::log_buffer::append(std::string{text}); - } - } - } device{}; - - } // namespace + throw std::logic_error("kapi::cio::init() called more than once"); + } - auto init() -> void + device.emplace(); + set_output_device(*device); + } + +} // namespace kapi::cio + +namespace kernel::tests::cio +{ + + auto deinit() -> void { - set_output_device(device); + if (!is_initialized.test()) + { + throw std::logic_error("kapi::cio::deinit() called before kapi::cio::init()"); + } + + device.reset(); + is_initialized.clear(); } - auto reset() -> void + auto log_buffer() -> kernel::tests::log_buffer & { - kernel::tests::log_buffer::clear(); + return device->log_buffer(); } -} // namespace kapi::cio \ No newline at end of file +} // namespace kernel::tests::cio \ No newline at end of file diff --git a/kernel/src/test_support/kapi/cpu.cpp b/kernel/src/test_support/kapi/cpu.cpp index 6592d15..96dd10a 100644 --- a/kernel/src/test_support/kapi/cpu.cpp +++ b/kernel/src/test_support/kapi/cpu.cpp @@ -5,23 +5,13 @@ #include #include -namespace kapi::cpu +namespace { + auto static initialized = std::atomic_flag{}; +} - namespace - { - auto static initialized = std::atomic_flag{}; - } - - auto reset() -> void - { - if (!initialized.test()) - { - throw std::logic_error{"kapi::cpu::reset() called before kapi::cpu::init()"}; - } - - initialized.clear(); - } +namespace kapi::cpu +{ auto init() -> void { @@ -38,4 +28,19 @@ namespace kapi::cpu throw kernel::tests::cpu::halt{}; } -} // namespace kapi::cpu \ No newline at end of file +} // namespace kapi::cpu + +namespace kernel::tests::cpu +{ + + auto deinit() -> void + { + if (!initialized.test()) + { + throw std::logic_error{"kapi::cpu::reset() called before kapi::cpu::init()"}; + } + + initialized.clear(); + } + +} // namespace kernel::tests::cpu \ No newline at end of file diff --git a/kernel/src/test_support/kapi/memory.cpp b/kernel/src/test_support/kapi/memory.cpp index f244b7f..e926ba6 100644 --- a/kernel/src/test_support/kapi/memory.cpp +++ b/kernel/src/test_support/kapi/memory.cpp @@ -12,8 +12,10 @@ namespace { //! The size of the simulated RAM. - constexpr auto memory_size = kstd::units::MiB(32); - constexpr auto number_of_frames = memory_size / kapi::memory::frame::size; + constexpr auto physical_size = kstd::units::MiB(32); + constexpr auto virtual_size = kstd::units::GiB(1); + + constexpr auto number_of_frames = physical_size / kapi::memory::frame::size; auto constinit bump_allocator = std::optional{}; auto constinit test_mapper = std::optional{}; @@ -36,15 +38,19 @@ namespace kapi::memory auto init() -> void { bump_allocator.emplace(); - test_mapper.emplace(memory_size); + test_mapper.emplace(physical_size, virtual_size); old_allocator = set_frame_allocator(*bump_allocator); old_mapper = set_page_mapper(*test_mapper); - init_pmm(memory_size / frame::size, handoff_to_kernel_pmm); + init_pmm(physical_size / frame::size, handoff_to_kernel_pmm); } +} // namespace kapi::memory + +namespace kernel::tests::memory +{ - auto reset() -> void + auto deinit() -> void { if (old_allocator && *old_allocator) { @@ -60,12 +66,9 @@ namespace kapi::memory test_mapper.reset(); } -} // namespace kapi::memory - -namespace kernel::tests::memory -{ - auto heap_base() -> kapi::memory::linear_address + auto virtual_base() -> kapi::memory::linear_address { - return test_mapper->memory.heap_base(); + return test_mapper->memory.virtual_base(); } + } // namespace kernel::tests::memory \ No newline at end of file diff --git a/kernel/src/test_support/log_buffer.cpp b/kernel/src/test_support/log_buffer.cpp index 36ed15e..9cff596 100644 --- a/kernel/src/test_support/log_buffer.cpp +++ b/kernel/src/test_support/log_buffer.cpp @@ -4,36 +4,30 @@ #include #include -namespace kernel::tests::log_buffer +namespace kernel::tests { - namespace + auto log_buffer::append(std::string const & message) -> void { - std::vector recorded_messages{}; + m_messages.push_back(message); } - auto append(std::string const & message) -> void + auto log_buffer::clear() -> void { - recorded_messages.push_back(message); + m_messages.clear(); } - auto clear() -> void + auto log_buffer::flat_messages() -> std::string { - recorded_messages.clear(); + return std::ranges::fold_left(m_messages, std::string{}, [](std::string accumulator, std::string const & message) { + accumulator += message; + return accumulator; + }); } - auto flat_messages() -> std::string + auto log_buffer::messages() -> std::vector const & { - return std::ranges::fold_left(recorded_messages, std::string{}, - [](std::string accumulator, std::string const & message) { - accumulator += message; - return accumulator; - }); + return m_messages; } - auto messages() -> std::vector const & - { - return recorded_messages; - } - -} // namespace kernel::tests::log_buffer +} // namespace kernel::tests diff --git a/kernel/src/test_support/output_device.cpp b/kernel/src/test_support/output_device.cpp new file mode 100644 index 0000000..83dcbcc --- /dev/null +++ b/kernel/src/test_support/output_device.cpp @@ -0,0 +1,28 @@ +#include "kapi/cio.hpp" + +#include "kernel/test_support/cio.hpp" +#include "kernel/test_support/log_buffer.hpp" + +#include +#include +#include + +namespace kernel::tests::cio +{ + + auto output_device::write(kapi::cio::output_stream stream, std::string_view text) -> void + { + auto & standard_stream = stream == kapi::cio::output_stream::stdout ? std::cout : std::cerr; + standard_stream << text; + if (text != "\n") + { + m_log_buffer.append(std::string{text}); + } + } + + auto output_device::log_buffer() noexcept -> kernel::tests::log_buffer & + { + return m_log_buffer; + } + +} // namespace kernel::tests::cio \ No newline at end of file diff --git a/kernel/src/test_support/page_mapper.cpp b/kernel/src/test_support/page_mapper.cpp index abdcae5..9236deb 100644 --- a/kernel/src/test_support/page_mapper.cpp +++ b/kernel/src/test_support/page_mapper.cpp @@ -7,13 +7,12 @@ #include #include #include -#include namespace kernel::tests { - page_mapper::page_mapper(kstd::units::bytes memory_size) - : memory{memory_size} + page_mapper::page_mapper(kstd::units::bytes physical_size, kstd::units::bytes virtual_size) + : memory{physical_size, virtual_size} {} auto page_mapper::map(kapi::memory::page page, kapi::memory::frame frame, flags) -> std::byte * @@ -26,21 +25,14 @@ namespace kernel::tests } auto page_address = page.start_address(); - auto sandbox_start = memory.heap_base(); - auto sandbox_end = sandbox_start + memory.heap_size(); + auto virtual_base = memory.virtual_base(); + auto virtual_end = virtual_base + memory.virtual_size(); - if (page_address >= sandbox_start && page_address < sandbox_end) + if (page_address >= virtual_base && page_address < virtual_end) { auto virtual_target = static_cast(page_address); auto physical_offset = frame.number() * kapi::memory::frame::size; - auto mapped_ptr = mmap(virtual_target, kapi::memory::page::size.value, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_FIXED, memory.memory_descriptor(), physical_offset.value); - if (mapped_ptr == MAP_FAILED) - { - throw std::runtime_error("Failed to map page"); - } - - return static_cast(mapped_ptr); + return memory.map(kapi::memory::page::size, virtual_target, physical_offset.value); } else if (page_address >= kapi::memory::mmio_base) { @@ -49,7 +41,7 @@ namespace kernel::tests else if (page_address >= kapi::memory::higher_half_direct_map_base) { auto offset = frame.number() * kapi::memory::frame::size; - return memory.ram_base() + offset; + return memory.physical_base() + offset; } return nullptr; diff --git a/kernel/src/test_support/simulated_memory.cpp b/kernel/src/test_support/simulated_memory.cpp index fa3d36c..0648df2 100644 --- a/kernel/src/test_support/simulated_memory.cpp +++ b/kernel/src/test_support/simulated_memory.cpp @@ -4,50 +4,50 @@ #include +#include #include #include +#include #include #include #include #include -using namespace kstd::units_literals; - namespace kernel::tests { - namespace - { - constexpr auto virtual_size = 1_GiB; - } - simulated_memory::simulated_memory(kstd::units::bytes size) - : m_memory_descriptor{memfd_create("teachos_simulated_memory", 0)} - , m_size{size} + simulated_memory::simulated_memory(kstd::units::bytes physical_size, kstd::units::bytes virtual_size) + : m_descriptor{memfd_create("teachos_simulated_memory", 0)} + , m_physical_size{physical_size} + , m_virtual_size{virtual_size} { - if (m_memory_descriptor < 0) + if (m_descriptor < 0) { - throw std::runtime_error("Failed to create simulated memory"); + auto error = std::format("Failed to allocate backing memory: {}", strerror(errno)); + throw std::runtime_error(error); } - if (ftruncate(m_memory_descriptor, static_cast(m_size.value)) < 0) + if (ftruncate(m_descriptor, static_cast(m_physical_size.value)) < 0) { - throw std::runtime_error("Failed to resize simulated memory"); + auto error = std::format("Failed to reserve backing memory: {}", strerror(errno)); + throw std::runtime_error(error); } - auto mapped_pointer = mmap(nullptr, m_size.value, PROT_READ | PROT_WRITE, MAP_SHARED, m_memory_descriptor, 0); - if (mapped_pointer == MAP_FAILED) + auto physical_storage = mmap(nullptr, m_physical_size.value, PROT_READ | PROT_WRITE, MAP_SHARED, m_descriptor, 0); + if (physical_storage == MAP_FAILED) { - throw std::runtime_error("Failed to map simulated memory"); + auto error = std::format("Failed to map backing memory: {}", strerror(errno)); + throw std::runtime_error(error); } - m_physical_base = static_cast(mapped_pointer); - auto virtual_pointer = mmap(nullptr, virtual_size.value, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (virtual_pointer == MAP_FAILED) { - throw std::runtime_error("Failed to map simulated memory"); + auto error = std::format("Failed to reserve virtual memory: {}", strerror(errno)); + throw std::runtime_error(error); } + m_physical_base = static_cast(physical_storage); m_virtual_base = static_cast(virtual_pointer); clear(); @@ -55,39 +55,56 @@ namespace kernel::tests simulated_memory::~simulated_memory() { - munmap(m_physical_base, m_size.value); - munmap(m_virtual_base, virtual_size.value); - close(m_memory_descriptor); + munmap(m_virtual_base, m_virtual_size.value); + munmap(m_physical_base, m_physical_size.value); + close(m_descriptor); } auto simulated_memory::clear() -> void { - std::memset(m_physical_base, 0, m_size.value); + std::memset(m_physical_base, 0, m_physical_size.value); } - auto simulated_memory::ram_base() noexcept -> std::byte * + auto simulated_memory::physical_base() noexcept -> std::byte * { return m_physical_base; } - auto simulated_memory::ram_base() const noexcept -> std::byte const * + auto simulated_memory::physical_base() const noexcept -> std::byte const * { return m_physical_base; } - auto simulated_memory::heap_base() const noexcept -> kapi::memory::linear_address + auto simulated_memory::physical_size() const noexcept -> kstd::units::bytes + { + return m_physical_size; + } + + auto simulated_memory::virtual_base() const noexcept -> kapi::memory::linear_address { return kapi::memory::linear_address{m_virtual_base}; } - auto simulated_memory::heap_size() const noexcept -> kstd::units::bytes + auto simulated_memory::virtual_size() const noexcept -> kstd::units::bytes { - return virtual_size; + return m_virtual_size; } - auto simulated_memory::memory_descriptor() const noexcept -> int + auto simulated_memory::descriptor() const noexcept -> int { - return m_memory_descriptor; + return m_descriptor; + } + + auto simulated_memory::map(kstd::units::bytes size, std::byte * to, off_t offset) -> std::byte * + { + auto mapped_ptr = mmap(to, size.value, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, m_descriptor, offset); + if (mapped_ptr == MAP_FAILED) + { + auto error = std::format("Failed to map page: {}", strerror(errno)); + throw std::runtime_error(error); + } + + return static_cast(mapped_ptr); } } // namespace kernel::tests \ No newline at end of file diff --git a/kernel/src/test_support/state_reset_listener.cpp b/kernel/src/test_support/state_reset_listener.cpp index e201a10..8c95cc8 100644 --- a/kernel/src/test_support/state_reset_listener.cpp +++ b/kernel/src/test_support/state_reset_listener.cpp @@ -2,29 +2,15 @@ #include "kapi/cpu.hpp" #include "kapi/memory.hpp" +#include "kernel/test_support/cio.hpp" +#include "kernel/test_support/cpu.hpp" +#include "kernel/test_support/memory.hpp" + #include #include #include #include -namespace kapi -{ - namespace cio - { - auto reset() -> void; - } - - namespace cpu - { - auto reset() -> void; - } - - namespace memory - { - auto reset() -> void; - } -} // namespace kapi - struct state_reset_listener : Catch::EventListenerBase { using EventListenerBase::EventListenerBase; @@ -38,9 +24,9 @@ struct state_reset_listener : Catch::EventListenerBase void testCaseEnded(Catch::TestCaseStats const &) override { - kapi::memory::reset(); - kapi::cpu::reset(); - kapi::cio::reset(); + kernel::tests::memory::deinit(); + kernel::tests::cpu::deinit(); + kernel::tests::cio::deinit(); } }; -- cgit v1.2.3 From 39d2696ee75db377c7e31fda1e29e4a7d3cfb378 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 10:15:18 +0200 Subject: kernel/tests: improve documentation --- .../kernel/test_support/bump_frame_allocator.hpp | 24 ++++++++++++++++++- kernel/include/kernel/test_support/cio.hpp | 14 +++++++++-- kernel/include/kernel/test_support/cpu.hpp | 3 +++ kernel/include/kernel/test_support/memory.hpp | 9 ++++++++ kernel/include/kernel/test_support/page_mapper.hpp | 16 +++++++++++++ .../kernel/test_support/simulated_memory.hpp | 27 ++++++++++++++++++++-- kernel/src/test_support/simulated_memory.cpp | 5 ---- 7 files changed, 88 insertions(+), 10 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/test_support/bump_frame_allocator.hpp b/kernel/include/kernel/test_support/bump_frame_allocator.hpp index 5203565..6380294 100644 --- a/kernel/include/kernel/test_support/bump_frame_allocator.hpp +++ b/kernel/include/kernel/test_support/bump_frame_allocator.hpp @@ -10,10 +10,28 @@ namespace kernel::tests { + //! A simple bump-based frame allocator used for initial test bootstrap. + //! + //! We emulate the expected behavior of a platform, in that there is a handover to the kernel PMM that needs to happen + //! during boot. The expectation of the PMM initializer is that there is an active (if simple) frame allocator it can + //! use to reserve space for it's own metadata. + //! + //! @see kapi::memory::init_pmm struct bump_frame_allocator : kapi::memory::frame_allocator { - auto mark_used(kapi::memory::frame) -> void override {} + //! @copydoc kapi::memory::frame_allocator::mark_used + //! + //! @note Due to the simple nature of this allocator, all frames up to the given frame will be marked as used as + //! well. + auto mark_used(kapi::memory::frame frame) -> void override + { + if (frame.number() >= next_free_frame) + { + next_free_frame = frame.number() + 1; + } + } + //! @copydoc kapi::memory::frame_allocator::allocate_many auto allocate_many(std::size_t count) noexcept -> std::optional> override { @@ -22,8 +40,12 @@ namespace kernel::tests return std::pair{kapi::memory::frame{start}, count}; } + //! @copydoc kapi::memory::frame_allocator::release_many + //! + //! @note Due to the simple nature of this allocator, frames are never actually released. auto release_many(std::pair) -> void override {} + //! The next free frame to be allocated. std::size_t next_free_frame{}; }; diff --git a/kernel/include/kernel/test_support/cio.hpp b/kernel/include/kernel/test_support/cio.hpp index 4b897b5..f7bac2d 100644 --- a/kernel/include/kernel/test_support/cio.hpp +++ b/kernel/include/kernel/test_support/cio.hpp @@ -9,20 +9,30 @@ namespace kernel::tests::cio { + + //! A simple output device that writes to one of the standard output streams and a log buffer. struct output_device : kapi::cio::output_device { - output_device() = default; - + //! @copydoc kapi::cio::output_device::write auto write(kapi::cio::output_stream stream, std::string_view text) -> void override; + //! Get the log buffer associated with this device. + //! + //! @return The associated log buffer. [[nodiscard]] auto log_buffer() noexcept -> kernel::tests::log_buffer &; private: + //! The log buffer of this device. kernel::tests::log_buffer m_log_buffer{}; }; + //! Deinitialize the CIO subsystem. auto deinit() -> void; + //! Get the log buffer of the currently active output device. + //! + //! @throws std::runtime_error if no output device has been registered. + //! @return The currently active device's log buffer. [[nodiscard]] auto log_buffer() -> kernel::tests::log_buffer &; } // namespace kernel::tests::cio diff --git a/kernel/include/kernel/test_support/cpu.hpp b/kernel/include/kernel/test_support/cpu.hpp index 037b1b2..c99d1a7 100644 --- a/kernel/include/kernel/test_support/cpu.hpp +++ b/kernel/include/kernel/test_support/cpu.hpp @@ -6,13 +6,16 @@ namespace kernel::tests::cpu { + //! Exception thrown when the CPU is halted. struct halt : std::runtime_error { + //! Construct a new halt exception. halt() : std::runtime_error{"CPU halt requested!"} {} }; + //! Deinitialize the CPU subsystem. auto deinit() -> void; } // namespace kernel::tests::cpu diff --git a/kernel/include/kernel/test_support/memory.hpp b/kernel/include/kernel/test_support/memory.hpp index b475116..6034a1e 100644 --- a/kernel/include/kernel/test_support/memory.hpp +++ b/kernel/include/kernel/test_support/memory.hpp @@ -5,9 +5,18 @@ namespace kernel::tests::memory { + + //! Deinitialize the memory subsystem. auto deinit() -> void; + //! Get the virtual base address of the simulated system. + //! + //! Since we do not have direct access to an actual MMU, we simulate the virtual address space by mapping the + //! physical address space starting at some process local virtual address. + //! + //! @return The virtual base address of the simulated system. auto virtual_base() -> kapi::memory::linear_address; + } // namespace kernel::tests::memory #endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/page_mapper.hpp b/kernel/include/kernel/test_support/page_mapper.hpp index 1658455..7ae9a4f 100644 --- a/kernel/include/kernel/test_support/page_mapper.hpp +++ b/kernel/include/kernel/test_support/page_mapper.hpp @@ -16,15 +16,31 @@ namespace kernel::tests struct page_mapper : kapi::memory::page_mapper { + //! Construct a new page mapper. + //! + //! @param physical_size The size of the physical memory. + //! @param virtual_size The size of the virtual address space. page_mapper(kstd::units::bytes physical_size, kstd::units::bytes virtual_size); + //! @copydoc kapi::memory::page_mapper::map + //! + //! @throws std::invalid_argument if the page has already been mapped. + //! @throws std::runtime_error if the page cannot be mapped. + //! @throws std::runtime_error if the underlying simulated memory cannot map the page. auto map(kapi::memory::page page, kapi::memory::frame frame, flags) -> std::byte * override; + //! @copydoc kapi::memory::page_mapper::unmap + //! + //! @throws std::invalid_argument if the page has not been mapped. auto unmap(kapi::memory::page page) -> void override; + //! @copydoc kapi::memory::page_mapper::try_unmap auto try_unmap(kapi::memory::page page) noexcept -> bool override; + //! The simulated memory. kernel::tests::simulated_memory memory; + + //! The simplified page table entries. std::unordered_map page_mappings; }; diff --git a/kernel/include/kernel/test_support/simulated_memory.hpp b/kernel/include/kernel/test_support/simulated_memory.hpp index 1619f31..fa78aed 100644 --- a/kernel/include/kernel/test_support/simulated_memory.hpp +++ b/kernel/include/kernel/test_support/simulated_memory.hpp @@ -11,23 +11,46 @@ namespace kernel::tests { + //! A simulated memory device that can be used in tests. + //! + //! The general idea is to provide a means to simulate the physical and virtual address spaces of the system. This + //! implementation provides for a single physical and a single virtual address space. + //! + //! @note This is not a full-featured MMU. It is a simple simulation that can be used for testing only. struct simulated_memory { + //! Construct a new simulated memory device. + //! @param physical_size The size of the physical memory. + //! @param virtual_size The size of the virtual address space. simulated_memory(kstd::units::bytes physical_size, kstd::units::bytes virtual_size); + //! Destroy this device ~simulated_memory(); + //! Clear the contents of the physical memory of this device. auto clear() -> void; + //! Get the base address of the physical memory of this device. [[nodiscard]] auto physical_base() noexcept -> std::byte *; + + //! Get the base address of the physical memory of this device. [[nodiscard]] auto physical_base() const noexcept -> std::byte const *; + + //! Get the size of the physical memory of this device. [[nodiscard]] auto physical_size() const noexcept -> kstd::units::bytes; + //! Get the base address of the virtual address space of this device. [[nodiscard]] auto virtual_base() const noexcept -> kapi::memory::linear_address; - [[nodiscard]] auto virtual_size() const noexcept -> kstd::units::bytes; - [[nodiscard]] auto descriptor() const noexcept -> int; + //! Get the size of the virtual address space of this device. + [[nodiscard]] auto virtual_size() const noexcept -> kstd::units::bytes; + //! Map a region of physical memory to a region of virtual memory. + //! + //! @param size The size of the region to map. + //! @param to The base address of the virtual region. + //! @param offset The offset into the physical memory to map. + //! @return A pointer to the first byte of the mapped region. [[nodiscard]] auto map(kstd::units::bytes size, std::byte * to, off_t offset) -> std::byte *; private: diff --git a/kernel/src/test_support/simulated_memory.cpp b/kernel/src/test_support/simulated_memory.cpp index 0648df2..03dac1d 100644 --- a/kernel/src/test_support/simulated_memory.cpp +++ b/kernel/src/test_support/simulated_memory.cpp @@ -90,11 +90,6 @@ namespace kernel::tests return m_virtual_size; } - auto simulated_memory::descriptor() const noexcept -> int - { - return m_descriptor; - } - auto simulated_memory::map(kstd::units::bytes size, std::byte * to, off_t offset) -> std::byte * { auto mapped_ptr = mmap(to, size.value, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, m_descriptor, offset); -- 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/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 From bd585306e31889ee4fce60abb79bc3b3a58e2b84 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 13:11:15 +0200 Subject: kapi: add basic ACPI support --- kernel/include/kernel/memory/block_list_allocator.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/memory/block_list_allocator.hpp b/kernel/include/kernel/memory/block_list_allocator.hpp index f319097..de89f3b 100644 --- a/kernel/include/kernel/memory/block_list_allocator.hpp +++ b/kernel/include/kernel/memory/block_list_allocator.hpp @@ -43,10 +43,10 @@ namespace kernel::memory private: struct block_header final { - kstd::units::bytes usable_size; - bool free; - block_header * next; - block_header * prev; + kstd::units::bytes usable_size{}; + bool free{}; + block_header * next{}; + block_header * prev{}; }; //! The size of the metadata required for each allocated block. @@ -87,4 +87,4 @@ namespace kernel::memory } // namespace kernel::memory -#endif \ No newline at end of file +#endif -- cgit v1.2.3 From 6e54333bcc08ddd8dbcb6aa9c3404001c309ec74 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 13:27:22 +0200 Subject: kapi: move independent implementation to kernel --- kernel/CMakeLists.txt | 1 + kernel/kapi/acpi.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 kernel/kapi/acpi.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 9868eb9..ab77467 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,5 +1,6 @@ add_library("kernel_objs" OBJECT # Platform-independent KAPI implementation + "kapi/acpi.cpp" "kapi/boot_modules.cpp" "kapi/cio.cpp" "kapi/cpu.cpp" diff --git a/kernel/kapi/acpi.cpp b/kernel/kapi/acpi.cpp new file mode 100644 index 0000000..aa0066d --- /dev/null +++ b/kernel/kapi/acpi.cpp @@ -0,0 +1,68 @@ +#include "kapi/acpi.hpp" + +#include "kapi/memory.hpp" + +#include + +#include +#include +#include +#include +#include +#include + +namespace kapi::acpi +{ + + namespace + { + constexpr auto validate_checksum(std::span data) -> bool + { + auto sum = std::ranges::fold_left( + data, std::uint8_t{}, [](std::uint8_t acc, auto byte) { return static_cast(byte) + acc; }); + return sum == 0; + } + } // namespace + + auto root_system_description_pointer::oem_id() const noexcept -> std::string_view + { + return {m_oem_id.data(), m_oem_id.size()}; + } + + auto root_system_description_pointer::revision() const noexcept -> std::uint8_t + { + return m_revision; + } + + auto root_system_description_pointer::signature() const noexcept -> std::string_view + { + return {m_signature.data(), m_signature.size()}; + } + + auto root_system_description_pointer::table_address() const noexcept -> memory::physical_address + { + auto raw = std::bit_cast(m_rsdt_address); + return memory::physical_address{static_cast(raw)}; + } + + auto root_system_description_pointer::validate() const noexcept -> bool + { + return validate_checksum({reinterpret_cast(this), sizeof(root_system_description_pointer)}); + } + + auto extended_system_description_pointer::length() const noexcept -> kstd::units::bytes + { + return kstd::units::bytes{m_length}; + } + + auto extended_system_description_pointer::table_address() const noexcept -> memory::physical_address + { + return memory::physical_address{std::bit_cast(m_xsdt_address)}; + } + + auto extended_system_description_pointer::validate() const noexcept -> bool + { + return validate_checksum({reinterpret_cast(this), m_length}); + } + +}; // namespace kapi::acpi -- cgit v1.2.3 From 3dcd14a0570fef3bcc68d7df42fe3ff4cd496f93 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 14:47:37 +0200 Subject: kapi: hook ACPI initialization up to boot process --- kernel/CMakeLists.txt | 1 + kernel/include/kernel/acpi/manager.hpp | 26 ++++++++++++++++ kernel/kapi/acpi.cpp | 32 ++++++++++++++++---- kernel/src/acpi/manager.cpp | 54 ++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 kernel/include/kernel/acpi/manager.hpp create mode 100644 kernel/src/acpi/manager.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index ab77467..fc01723 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -14,6 +14,7 @@ add_library("kernel_objs" OBJECT "kstd/print.cpp" # Kernel Implementation + "src/acpi/manager.cpp" "src/memory/bitmap_allocator.cpp" "src/memory/block_list_allocator.cpp" "src/memory.cpp" diff --git a/kernel/include/kernel/acpi/manager.hpp b/kernel/include/kernel/acpi/manager.hpp new file mode 100644 index 0000000..fc76685 --- /dev/null +++ b/kernel/include/kernel/acpi/manager.hpp @@ -0,0 +1,26 @@ +#ifndef TEACHOS_KERNEL_ACPI_MANAGER_HPP +#define TEACHOS_KERNEL_ACPI_MANAGER_HPP + +#include "kapi/acpi.hpp" + +#include + +namespace kernel::acpi +{ + + struct manager + { + explicit manager(kapi::acpi::root_system_description_pointer const & sdp); + + auto load_tables() -> bool; + + private: + kapi::acpi::root_system_description_pointer const * m_sdp{}; + kapi::acpi::system_description_table_header const * m_rsdt{}; + kstd::vector m_tables{}; + bool m_extended{}; + }; + +} // namespace kernel::acpi + +#endif diff --git a/kernel/kapi/acpi.cpp b/kernel/kapi/acpi.cpp index aa0066d..787bcff 100644 --- a/kernel/kapi/acpi.cpp +++ b/kernel/kapi/acpi.cpp @@ -1,13 +1,18 @@ #include "kapi/acpi.hpp" #include "kapi/memory.hpp" +#include "kapi/system.hpp" + +#include "kernel/acpi/manager.hpp" #include #include +#include #include #include #include +#include #include #include @@ -16,12 +21,7 @@ namespace kapi::acpi namespace { - constexpr auto validate_checksum(std::span data) -> bool - { - auto sum = std::ranges::fold_left( - data, std::uint8_t{}, [](std::uint8_t acc, auto byte) { return static_cast(byte) + acc; }); - return sum == 0; - } + auto constinit manager = std::optional{}; } // namespace auto root_system_description_pointer::oem_id() const noexcept -> std::string_view @@ -65,4 +65,24 @@ namespace kapi::acpi return validate_checksum({reinterpret_cast(this), m_length}); } + auto init(root_system_description_pointer const & sdp) -> bool + { + auto static constinit initialized = std::atomic_flag{}; + if (initialized.test_and_set()) + { + system::panic("[OS::ACPI] The ACPI manager has already been initialized!"); + } + + manager.emplace(sdp); + return manager->load_tables(); + } + + auto validate_checksum(std::span data) -> bool + { + auto sum = std::ranges::fold_left(data, std::uint8_t{}, [](auto acc, auto byte) { + return static_cast(acc + static_cast(byte)); + }); + return sum == 0; + } + }; // namespace kapi::acpi diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp new file mode 100644 index 0000000..6a17920 --- /dev/null +++ b/kernel/src/acpi/manager.cpp @@ -0,0 +1,54 @@ +#include "kernel/acpi/manager.hpp" + +#include "kapi/acpi.hpp" +#include "kapi/memory.hpp" +#include "kapi/system.hpp" + +#include + +namespace kernel::acpi +{ + + manager::manager(kapi::acpi::root_system_description_pointer const & sdp) + : m_sdp{&sdp} + { + if (m_sdp->signature() != "RSD PTR ") + { + kapi::system::panic("[OS:ACPI] Invalid RSDP signature!"); + } + + if (m_sdp->revision() >= 2) + { + auto const xsdp = static_cast(m_sdp); + if (!xsdp->validate()) + { + kapi::system::panic("[OS:ACPI] Invalid XSDP signature!"); + } + auto physical_extended_table_address = xsdp->table_address(); + auto linear_extended_table_address = kapi::memory::hhdm_to_linear(physical_extended_table_address); + m_rsdt = static_cast(linear_extended_table_address); + m_extended = true; + } + else + { + if (!m_sdp->validate()) + { + kapi::system::panic("[OS:ACPI] Invalid RSDP checksum!"); + } + auto physical_root_table_address = m_sdp->table_address(); + auto linear_root_table_address = kapi::memory::hhdm_to_linear(physical_root_table_address); + m_rsdt = static_cast(linear_root_table_address); + } + } + + auto manager::load_tables() -> bool + { + if (!kapi::acpi::validate_checksum({reinterpret_cast(m_rsdt), m_rsdt->length})) + { + kapi::system::panic("[OS:ACPI] Invalid RSDT checksum!"); + } + + return false; + } + +} // namespace kernel::acpi -- cgit v1.2.3 From 4d938cd31a35cd4322fe914edd568faa5391c9c2 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 15:10:04 +0200 Subject: kernel/acpi: implement basic table discovery --- kernel/include/kernel/acpi/manager.hpp | 5 +++- kernel/kapi/acpi.cpp | 45 ++++++++++++++++++++++++++++++++++ kernel/src/acpi/manager.cpp | 42 +++++++++++++++++++++++++++++-- 3 files changed, 89 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/acpi/manager.hpp b/kernel/include/kernel/acpi/manager.hpp index fc76685..437d4c8 100644 --- a/kernel/include/kernel/acpi/manager.hpp +++ b/kernel/include/kernel/acpi/manager.hpp @@ -3,8 +3,11 @@ #include "kapi/acpi.hpp" +#include #include +#include + namespace kernel::acpi { @@ -17,7 +20,7 @@ namespace kernel::acpi private: kapi::acpi::root_system_description_pointer const * m_sdp{}; kapi::acpi::system_description_table_header const * m_rsdt{}; - kstd::vector m_tables{}; + kstd::flat_map m_tables{}; bool m_extended{}; }; diff --git a/kernel/kapi/acpi.cpp b/kernel/kapi/acpi.cpp index 787bcff..998d7a0 100644 --- a/kernel/kapi/acpi.cpp +++ b/kernel/kapi/acpi.cpp @@ -65,6 +65,51 @@ namespace kapi::acpi return validate_checksum({reinterpret_cast(this), m_length}); } + [[nodiscard]] auto system_description_table_header::checksum() const noexcept -> std::uint8_t + { + return m_checksum; + } + + [[nodiscard]] auto system_description_table_header::creator_revision() const noexcept -> std::uint32_t + { + return m_creator_revision; + } + + [[nodiscard]] auto system_description_table_header::creator_id() const noexcept -> std::uint32_t + { + return m_creator_id; + } + + [[nodiscard]] auto system_description_table_header::length() const noexcept -> kstd::units::bytes + { + return kstd::units::bytes{m_length}; + } + + [[nodiscard]] auto system_description_table_header::oem_id() const noexcept -> std::string_view + { + return {m_oem_id.data(), m_oem_id.size()}; + } + + [[nodiscard]] auto system_description_table_header::oem_revision() const noexcept -> std::uint32_t + { + return m_oem_revision; + } + + [[nodiscard]] auto system_description_table_header::oem_table_id() const noexcept -> std::string_view + { + return {m_oem_table_id.data(), m_oem_table_id.size()}; + } + + [[nodiscard]] auto system_description_table_header::revision() const noexcept -> std::uint8_t + { + return m_revision; + } + + [[nodiscard]] auto system_description_table_header::signature() const noexcept -> std::string_view + { + return {m_signature.data(), m_signature.size()}; + } + auto init(root_system_description_pointer const & sdp) -> bool { auto static constinit initialized = std::atomic_flag{}; diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 6a17920..180d458 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -4,7 +4,10 @@ #include "kapi/memory.hpp" #include "kapi/system.hpp" +#include + #include +#include namespace kernel::acpi { @@ -43,12 +46,47 @@ namespace kernel::acpi auto manager::load_tables() -> bool { - if (!kapi::acpi::validate_checksum({reinterpret_cast(m_rsdt), m_rsdt->length})) + if (!kapi::acpi::validate_checksum({reinterpret_cast(m_rsdt), m_rsdt->length().value})) { kapi::system::panic("[OS:ACPI] Invalid RSDT checksum!"); } - return false; + auto entry_size = m_extended ? sizeof(std::uint64_t) : sizeof(std::uint32_t); + auto entry_count = (m_rsdt->length().value - sizeof(kapi::acpi::system_description_table_header)) / entry_size; + auto entries_base = + reinterpret_cast(m_rsdt) + sizeof(kapi::acpi::system_description_table_header); + + for (std::size_t i = 0; i < entry_count; ++i) + { + auto physical_table_address = kapi::memory::physical_address{}; + + if (m_extended) + { + auto entry = reinterpret_cast(entries_base + (i * entry_size)); + physical_table_address = kapi::memory::physical_address{*entry}; + } + else + { + auto entry = reinterpret_cast(entries_base + (i * entry_size)); + physical_table_address = kapi::memory::physical_address{*entry}; + } + + auto linear_table_address = kapi::memory::hhdm_to_linear(physical_table_address); + auto table = static_cast(linear_table_address); + + if (!kapi::acpi::validate_checksum({reinterpret_cast(table), table->length().value})) + { + kstd::println(kstd::print_sink::stderr, "[OS:ACPI] Invalid table checksum!"); + } + else + { + kstd::println("[OS:ACPI] Found table: {}@{:#x}/{:#x} OEM: {} Rev: {}", table->signature(), linear_table_address, + physical_table_address, table->oem_id(), table->creator_revision()); + m_tables.emplace(table->signature(), table); + } + } + + return !m_tables.empty(); } } // namespace kernel::acpi -- 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/CMakeLists.txt | 1 + kernel/include/kernel/acpi/manager.hpp | 3 ++ kernel/include/kernel/devices/cpu.hpp | 33 ++++++++++++ kernel/kapi/acpi.cpp | 43 ++++++++++++++- kernel/kapi/devices.cpp | 10 ++++ kernel/src/acpi/manager.cpp | 15 +++++- kernel/src/devices/cpu.cpp | 97 ++++++++++++++++++++++++++++++++++ kernel/src/main.cpp | 10 ++++ 8 files changed, 209 insertions(+), 3 deletions(-) create mode 100644 kernel/include/kernel/devices/cpu.hpp create mode 100644 kernel/src/devices/cpu.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index fc01723..92e2bda 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -20,6 +20,7 @@ add_library("kernel_objs" OBJECT "src/memory.cpp" "src/devices/block_device.cpp" "src/devices/block_device_utils.cpp" + "src/devices/cpu.cpp" "src/devices/root_bus.cpp" "src/devices/storage/controller.cpp" "src/devices/storage/management.cpp" diff --git a/kernel/include/kernel/acpi/manager.hpp b/kernel/include/kernel/acpi/manager.hpp index 437d4c8..fae59a6 100644 --- a/kernel/include/kernel/acpi/manager.hpp +++ b/kernel/include/kernel/acpi/manager.hpp @@ -4,6 +4,7 @@ #include "kapi/acpi.hpp" #include +#include #include #include @@ -17,6 +18,8 @@ namespace kernel::acpi auto load_tables() -> bool; + auto get_table(std::string_view signature) -> kstd::observer_ptr; + private: kapi::acpi::root_system_description_pointer const * m_sdp{}; kapi::acpi::system_description_table_header const * m_rsdt{}; diff --git a/kernel/include/kernel/devices/cpu.hpp b/kernel/include/kernel/devices/cpu.hpp new file mode 100644 index 0000000..b056665 --- /dev/null +++ b/kernel/include/kernel/devices/cpu.hpp @@ -0,0 +1,33 @@ +#ifndef TEACHOS_KERNEL_DEVICES_CPU_HPP +#define TEACHOS_KERNEL_DEVICES_CPU_HPP + +#include "kapi/devices.hpp" + +#include +#include + +namespace kernel::devices +{ + + struct cpu final : kapi::devices::bus + { + struct core final : kapi::devices::bus + { + explicit core(std::size_t major_number, std::size_t minor_number, std::uint64_t hardware_id, bool is_bsp); + + [[nodiscard]] auto hardware_id() const -> std::uint64_t; + [[nodiscard]] auto is_bsp() const -> bool; + + private: + std::uint64_t m_hardware_id; + bool m_is_bsp; + }; + + explicit cpu(std::size_t major_number); + + auto probe() -> bool final; + }; + +} // namespace kernel::devices + +#endif \ No newline at end of file diff --git a/kernel/kapi/acpi.cpp b/kernel/kapi/acpi.cpp index 998d7a0..1283d7e 100644 --- a/kernel/kapi/acpi.cpp +++ b/kernel/kapi/acpi.cpp @@ -5,6 +5,7 @@ #include "kernel/acpi/manager.hpp" +#include #include #include @@ -110,12 +111,47 @@ namespace kapi::acpi return {m_signature.data(), m_signature.size()}; } + [[nodiscard]] auto madt_header::local_interrupt_controller_address() const noexcept -> memory::physical_address + { + return memory::physical_address{static_cast(m_local_interrupt_controller_address)}; + } + + [[nodiscard]] auto madt_header::flags() const noexcept -> std::uint32_t + { + return m_flags; + } + + [[nodiscard]] auto madt_subtable_header::type() const noexcept -> std::uint8_t + { + return m_type; + } + + [[nodiscard]] auto madt_subtable_header::length() const noexcept -> std::size_t + { + return m_length; + } + + [[nodiscard]] auto madt_local_apic::apic_id() const noexcept -> std::uint8_t + { + return m_apic_id; + } + + [[nodiscard]] auto madt_local_apic::flags() const noexcept -> std::uint32_t + { + return m_flags; + } + + [[nodiscard]] auto madt_local_apic::processor_id() const noexcept -> std::uint32_t + { + return m_processor_id; + } + auto init(root_system_description_pointer const & sdp) -> bool { auto static constinit initialized = std::atomic_flag{}; if (initialized.test_and_set()) { - system::panic("[OS::ACPI] The ACPI manager has already been initialized!"); + system::panic("[OS:ACPI] The ACPI manager has already been initialized!"); } manager.emplace(sdp); @@ -130,4 +166,9 @@ namespace kapi::acpi return sum == 0; } + auto get_table(std::string_view signature) -> kstd::observer_ptr + { + return manager->get_table(signature); + } + }; // namespace kapi::acpi diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp index 031f2c9..b2911b0 100644 --- a/kernel/kapi/devices.cpp +++ b/kernel/kapi/devices.cpp @@ -1,7 +1,9 @@ #include "kapi/devices.hpp" +#include "kapi/acpi.hpp" #include "kapi/system.hpp" +#include "kernel/devices/cpu.hpp" #include "kernel/devices/root_bus.hpp" #include @@ -35,6 +37,14 @@ namespace kapi::devices auto & bus = root_bus.emplace(); register_device(bus); bus.init(); + + auto madt = kapi::acpi::get_table("APIC"); + if (madt) + { + auto cpu_major = allocate_major_number(); + auto cpu = kstd::make_unique(cpu_major); + bus.add_child(std::move(cpu)); + } } auto get_root_bus() -> bus & diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 180d458..300b85e 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -4,10 +4,12 @@ #include "kapi/memory.hpp" #include "kapi/system.hpp" +#include #include #include #include +#include namespace kernel::acpi { @@ -80,8 +82,7 @@ namespace kernel::acpi } else { - kstd::println("[OS:ACPI] Found table: {}@{:#x}/{:#x} OEM: {} Rev: {}", table->signature(), linear_table_address, - physical_table_address, table->oem_id(), table->creator_revision()); + kstd::println("[OS:ACPI] Found '{}' ACPI table", table->signature()); m_tables.emplace(table->signature(), table); } } @@ -89,4 +90,14 @@ namespace kernel::acpi return !m_tables.empty(); } + auto manager::get_table(std::string_view signature) + -> kstd::observer_ptr + { + if (m_tables.contains(signature)) + { + return kstd::make_observer(m_tables.at(signature)); + } + return nullptr; + } + } // namespace kernel::acpi 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 diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 2eaa2d8..e704955 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,3 +1,4 @@ +#include "kapi/acpi.hpp" #include "kapi/boot_modules.hpp" #include "kapi/cio.hpp" #include "kapi/cpu.hpp" @@ -179,6 +180,15 @@ auto main() -> int kstd::println("[OS] Memory subsystem initialized."); kapi::system::memory_initialized(); + auto acpi_root_pointer = kapi::acpi::get_root_pointer(); + if (acpi_root_pointer && acpi_root_pointer->validate()) + { + if (kapi::acpi::init(*acpi_root_pointer)) + { + kstd::println("[OS] ACPI subsystem initialized."); + } + } + kapi::devices::init(); kstd::println("[OS] System root bus initialized."); -- cgit v1.2.3 From 8d08b3b905d211e989848e1abf3a8ff2535836c8 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 18:13:21 +0200 Subject: kapi: extract more code to the kernel --- kernel/CMakeLists.txt | 2 ++ kernel/kapi/devices/bus.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++ kernel/kapi/devices/device.cpp | 35 +++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 kernel/kapi/devices/bus.cpp create mode 100644 kernel/kapi/devices/device.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 92e2bda..6e081bd 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -5,6 +5,8 @@ add_library("kernel_objs" OBJECT "kapi/cio.cpp" "kapi/cpu.cpp" "kapi/devices.cpp" + "kapi/devices/bus.cpp" + "kapi/devices/device.cpp" "kapi/interrupts.cpp" "kapi/memory.cpp" "kapi/system.cpp" diff --git a/kernel/kapi/devices/bus.cpp b/kernel/kapi/devices/bus.cpp new file mode 100644 index 0000000..68874c4 --- /dev/null +++ b/kernel/kapi/devices/bus.cpp @@ -0,0 +1,65 @@ +#include "kapi/devices/bus.hpp" + +#include "kapi/devices.hpp" +#include "kapi/system.hpp" + +#include +#include +#include +#include + +#include +#include +#include + +namespace kapi::devices +{ + bus::bus(std::size_t major, std::size_t minor, kstd::string const & name) + : device(major, minor, name) + {} + + auto bus::init() -> bool + { + if (m_initialized.test_and_set()) + { + return true; + } + + if (!probe()) + { + return false; + } + + return std::ranges::fold_left(m_devices, true, [&](bool acc, auto & child) -> bool { + kstd::println("[OS:DEV] Initializing child device {}@{}", child->name(), name()); + return child->init() && acc; + }); + } + + auto bus::add_child(kstd::unique_ptr child) -> void + { + auto observer = m_observers.emplace_back(child.get()); + m_devices.push_back(std::move(child)); + kapi::devices::register_device(*observer); + + if (m_initialized.test()) + { + kstd::println("[OS:DEV] Initializing child device {}@{}", observer->name(), name()); + if (!observer->init()) + { + kapi::system::panic("[OS:DEV] Failed to initialize child device"); + } + } + } + + [[nodiscard]] auto bus::children() const -> kstd::vector> const & + { + return m_observers; + } + + auto bus::probe() -> bool + { + return true; + } + +} // namespace kapi::devices \ No newline at end of file diff --git a/kernel/kapi/devices/device.cpp b/kernel/kapi/devices/device.cpp new file mode 100644 index 0000000..9f7a404 --- /dev/null +++ b/kernel/kapi/devices/device.cpp @@ -0,0 +1,35 @@ +#include "kapi/devices/device.hpp" + +#include + +#include + +namespace kapi::devices +{ + device::device(size_t major, size_t minor, kstd::string const & name) + : m_major(major) + , m_minor(minor) + , m_name(name) + {} + + [[nodiscard]] auto device::major() const -> size_t + { + return m_major; + } + + [[nodiscard]] auto device::minor() const -> size_t + { + return m_minor; + } + + [[nodiscard]] auto device::name() const -> kstd::string const & + { + return m_name; + } + + [[nodiscard]] auto device::is_block_device() const -> bool + { + return false; + } + +} // namespace kapi::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/CMakeLists.txt | 1 + kernel/kapi/devices.cpp | 11 +++------ kernel/kapi/platform.cpp | 32 +++++++++++++++++++++++++ kernel/src/devices/cpu.cpp | 58 +++------------------------------------------- 4 files changed, 39 insertions(+), 63 deletions(-) create mode 100644 kernel/kapi/platform.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 6e081bd..22513ea 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -9,6 +9,7 @@ add_library("kernel_objs" OBJECT "kapi/devices/device.cpp" "kapi/interrupts.cpp" "kapi/memory.cpp" + "kapi/platform.cpp" "kapi/system.cpp" # KSTD OS Implementation diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp index b2911b0..dad1fe4 100644 --- a/kernel/kapi/devices.cpp +++ b/kernel/kapi/devices.cpp @@ -1,6 +1,5 @@ #include "kapi/devices.hpp" -#include "kapi/acpi.hpp" #include "kapi/system.hpp" #include "kernel/devices/cpu.hpp" @@ -38,13 +37,9 @@ namespace kapi::devices register_device(bus); bus.init(); - auto madt = kapi::acpi::get_table("APIC"); - if (madt) - { - auto cpu_major = allocate_major_number(); - auto cpu = kstd::make_unique(cpu_major); - bus.add_child(std::move(cpu)); - } + auto cpu_major = allocate_major_number(); + auto cpu = kstd::make_unique(cpu_major); + bus.add_child(std::move(cpu)); } auto get_root_bus() -> bus & diff --git a/kernel/kapi/platform.cpp b/kernel/kapi/platform.cpp new file mode 100644 index 0000000..deb72de --- /dev/null +++ b/kernel/kapi/platform.cpp @@ -0,0 +1,32 @@ +#include "kapi/platform.hpp" + +#include "kapi/devices.hpp" + +#include "kernel/devices/cpu.hpp" + +#include + +#include +#include + +namespace kapi::platform +{ + + auto cpu_detected(kapi::devices::bus & bus, std::uint64_t hardware_id, bool is_bsp) -> bool + { + auto static const core_major = kapi::devices::allocate_major_number(); + auto static const interrupt_controller_major = kapi::devices::allocate_major_number(); + auto static core_index = 0uz; + + auto core = kstd::make_unique(core_major, core_index, hardware_id, is_bsp); + auto lapic = kapi::platform::create_core_interrupt_controller(interrupt_controller_major, core_index, hardware_id); + + core->add_child(std::move(lapic)); + bus.add_child(std::move(core)); + + ++core_index; + + return true; + } + +} // namespace kapi::platform \ No newline at end of file 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 d5c2e101d62f6b4b69c45c127e7a729d246da566 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 19:04:16 +0200 Subject: kapi/platform: invert discovery dependencies --- kernel/kapi/platform.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/platform.cpp b/kernel/kapi/platform.cpp index deb72de..7638cf9 100644 --- a/kernel/kapi/platform.cpp +++ b/kernel/kapi/platform.cpp @@ -6,26 +6,21 @@ #include +#include #include #include namespace kapi::platform { - auto cpu_detected(kapi::devices::bus & bus, std::uint64_t hardware_id, bool is_bsp) -> bool + auto cpu_detected(kapi::devices::bus & bus, std::size_t major, std::size_t minor, std::uint64_t hardware_id, + bool is_bsp, kstd::unique_ptr core_interrupt_controller) -> bool { - auto static const core_major = kapi::devices::allocate_major_number(); - auto static const interrupt_controller_major = kapi::devices::allocate_major_number(); - auto static core_index = 0uz; + auto core = kstd::make_unique(major, minor, hardware_id, is_bsp); - auto core = kstd::make_unique(core_major, core_index, hardware_id, is_bsp); - auto lapic = kapi::platform::create_core_interrupt_controller(interrupt_controller_major, core_index, hardware_id); - - core->add_child(std::move(lapic)); + core->add_child(std::move(core_interrupt_controller)); bus.add_child(std::move(core)); - ++core_index; - return true; } -- cgit v1.2.3 From 8ad4fad2440c20aa19e26ade8cdb881cab7734e2 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 6 Apr 2026 19:09:34 +0200 Subject: kernel/tests: fix link issue --- kernel/CMakeLists.txt | 1 + kernel/src/test_support/kapi/platform.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 kernel/src/test_support/kapi/platform.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 22513ea..ef73586 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -101,6 +101,7 @@ else() "src/test_support/kapi/cio.cpp" "src/test_support/kapi/interrupts.cpp" "src/test_support/kapi/memory.cpp" + "src/test_support/kapi/platform.cpp" "src/test_support/log_buffer.cpp" "src/test_support/output_device.cpp" "src/test_support/page_mapper.cpp" diff --git a/kernel/src/test_support/kapi/platform.cpp b/kernel/src/test_support/kapi/platform.cpp new file mode 100644 index 0000000..497c992 --- /dev/null +++ b/kernel/src/test_support/kapi/platform.cpp @@ -0,0 +1,14 @@ +#include "kapi/platform.hpp" + +#include "kapi/devices.hpp" + +namespace kapi::platform +{ + + auto discover_cpu_topology(devices::bus &) -> bool + { + // TODO: implement more meaningful simulated CPU topology discovery + return true; + } + +} // namespace kapi::platform \ No newline at end of file -- cgit v1.2.3 From 878852c94c4d56f303366cec177b3edef9b3b9c5 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 8 Apr 2026 13:54:52 +0200 Subject: kapi: add basic support for MMIO mapping --- kernel/CMakeLists.txt | 41 ++++----- kernel/include/kernel/memory/mmio_allocator.hpp | 41 +++++++++ kernel/kapi/memory.cpp | 25 ++++++ kernel/src/memory/mmio_allocator.cpp | 107 ++++++++++++++++++++++++ 4 files changed, 194 insertions(+), 20 deletions(-) create mode 100644 kernel/include/kernel/memory/mmio_allocator.hpp create mode 100644 kernel/src/memory/mmio_allocator.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index ef73586..67db0a8 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -20,6 +20,7 @@ add_library("kernel_objs" OBJECT "src/acpi/manager.cpp" "src/memory/bitmap_allocator.cpp" "src/memory/block_list_allocator.cpp" + "src/memory/mmio_allocator.cpp" "src/memory.cpp" "src/devices/block_device.cpp" "src/devices/block_device_utils.cpp" @@ -66,37 +67,37 @@ target_sources("kernel_objs" PUBLIC add_library("os::kernel" ALIAS "kernel_objs") if(CMAKE_CROSSCOMPILING) - add_executable("kernel" + add_executable("kernel" "src/main.cpp" "src/memory/operators.cpp" ) - target_link_libraries("kernel" PRIVATE + target_link_libraries("kernel" PRIVATE "os::arch" "os::kernel" ) - target_link_options("kernel" PRIVATE + target_link_options("kernel" PRIVATE "-T${KERNEL_LINKER_SCRIPT}" "-no-pie" "-nostdlib" ) - set_property(TARGET "kernel" + set_property(TARGET "kernel" APPEND PROPERTY LINK_DEPENDS "${KERNEL_LINKER_SCRIPT}" ) - target_disassemble("kernel") - target_extract_debug_symbols("kernel") - target_strip("kernel") + target_disassemble("kernel") + target_extract_debug_symbols("kernel") + target_strip("kernel") - target_generate_bootable_iso("kernel") + target_generate_bootable_iso("kernel") else() - enable_coverage("kernel_objs") + enable_coverage("kernel_objs") - add_library("kernel_test_support" OBJECT + add_library("kernel_test_support" OBJECT "src/test_support/kapi/cpu.cpp" "src/test_support/kapi/cio.cpp" "src/test_support/kapi/interrupts.cpp" @@ -108,21 +109,21 @@ else() "src/test_support/simulated_memory.cpp" "src/test_support/state_reset_listener.cpp" ) - add_library("os::kernel_test_support" ALIAS "kernel_test_support") + add_library("os::kernel_test_support" ALIAS "kernel_test_support") - target_link_libraries("kernel_test_support" PUBLIC + target_link_libraries("kernel_test_support" PUBLIC "os::kernel" "Catch2::Catch2WithMain" ) - add_executable("kernel_tests" + add_executable("kernel_tests" # KAPI Shim Tests "kapi/cpu.tests.cpp" "kapi/system.tests.cpp" - + # KSTD Shim Tests "kstd/print.tests.cpp" - + # Memory Subsystem Tests "src/memory/bitmap_allocator.tests.cpp" "src/memory/block_list_allocator.tests.cpp" @@ -130,19 +131,19 @@ else() # Storage Subsystem Tests "src/devices/storage/ram_disk/device.tests.cpp" ) - add_executable("os::kernel_tests" ALIAS "kernel_tests") + add_executable("os::kernel_tests" ALIAS "kernel_tests") - target_link_libraries("kernel_tests" PRIVATE + target_link_libraries("kernel_tests" PRIVATE "os::kernel" "os::kernel_test_support" ) - set_target_properties("kernel_tests" PROPERTIES + set_target_properties("kernel_tests" PROPERTIES C_CLANG_TIDY "" CXX_CLANG_TIDY "" ) - enable_coverage("kernel_tests") - catch_discover_tests("os::kernel_tests") + enable_coverage("kernel_tests") + catch_discover_tests("os::kernel_tests") endif() diff --git a/kernel/include/kernel/memory/mmio_allocator.hpp b/kernel/include/kernel/memory/mmio_allocator.hpp new file mode 100644 index 0000000..4ec6bec --- /dev/null +++ b/kernel/include/kernel/memory/mmio_allocator.hpp @@ -0,0 +1,41 @@ +#ifndef TEACHOS_KERNEL_MEMORY_MMIO_ALLOCATOR_HPP +#define TEACHOS_KERNEL_MEMORY_MMIO_ALLOCATOR_HPP + +#include "kapi/memory.hpp" + +#include +#include + +#include + +namespace kernel::memory +{ + + struct mmio_allocator + { + mmio_allocator(kapi::memory::linear_address base, std::size_t pages); + + [[nodiscard]] auto allocate(std::size_t page_count) -> kapi::memory::linear_address; + auto release(kapi::memory::linear_address base) -> void; + + private: + struct node + { + kapi::memory::linear_address base{}; + std::size_t page_count{}; + node * next{}; + node * previous{}; + bool is_free{}; + }; + + auto make_node(kapi::memory::linear_address base, std::size_t page_count, node * next, node * previous, + bool is_free) -> node *; + auto destroy_node(node *) -> void; + + [[no_unique_address]] kstd::allocator m_allocator{}; + node * m_head{}; + }; + +} // namespace kernel::memory + +#endif diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp index 06a3165..b224c50 100644 --- a/kernel/kapi/memory.cpp +++ b/kernel/kapi/memory.cpp @@ -3,6 +3,7 @@ #include "kapi/system.hpp" #include "kernel/memory/bitmap_allocator.hpp" +#include "kernel/memory/mmio_allocator.hpp" #include #include @@ -63,6 +64,7 @@ namespace kapi::memory constinit bad_frame_allocator bad_frame_allocator::instance{}; constinit bad_page_mapper bad_page_mapper::instance{}; auto constinit allocator = std::optional{}; + auto constinit mmio_allocator = std::optional{}; } // namespace constinit auto static active_frame_allocator = static_cast(&bad_frame_allocator::instance); @@ -147,4 +149,27 @@ namespace kapi::memory kstd::println("[OS:MEM] Physical memory manager initialized."); } + auto init_mmio(linear_address base, std::size_t page_count) -> void + { + mmio_allocator.emplace(base, page_count); + } + + auto allocate_mmio_region(std::size_t page_count) -> linear_address + { + auto region = mmio_allocator->allocate(page_count); + return region; + } + + auto map_mmio_region(linear_address base, physical_address hw_base, page_mapper::flags flags) -> std::byte * + { + auto start_page = page::containing(base); + auto start_frame = frame::containing(hw_base); + return map(start_page, start_frame, flags | page_mapper::flags::uncached); + } + + auto release_mmio_region(linear_address base) -> void + { + mmio_allocator->release(base); + } + } // namespace kapi::memory diff --git a/kernel/src/memory/mmio_allocator.cpp b/kernel/src/memory/mmio_allocator.cpp new file mode 100644 index 0000000..f77f14f --- /dev/null +++ b/kernel/src/memory/mmio_allocator.cpp @@ -0,0 +1,107 @@ +#include "kernel/memory/mmio_allocator.hpp" + +#include "kapi/memory.hpp" +#include "kapi/system.hpp" + +#include + +#include +#include +#include + +namespace kernel::memory +{ + + mmio_allocator::mmio_allocator(kapi::memory::linear_address base, std::size_t pages) + : m_head{make_node(base, pages, nullptr, nullptr, true)} + {} + + auto mmio_allocator::allocate(std::size_t count) -> kapi::memory::linear_address + { + if (count == 0 || !m_head) + { + return {}; + } + + auto current = m_head; + while (current) + { + if (current->page_count > count) + { + auto new_base = current->base + (count * kapi::memory::page::size); + auto split_node = make_node(new_base, current->page_count - count, std::move(current->next), current, true); + + if (current->next) + { + current->next->previous = split_node; + } + current->next = split_node; + current->page_count = count; + } + + current->is_free = false; + return current->base; + } + + kapi::system::panic("[OS:MEM] MMIO alloctor out of memory!"); + return {}; + } + + auto mmio_allocator::release(kapi::memory::linear_address base) -> void + { + auto current = m_head; + + while (current) + { + if (current->base == base && !current->is_free) + { + current->is_free = true; + + if (current->next && current->next->is_free) + { + auto removed = current->next; + current->page_count += removed->page_count; + current->next = removed->next; + if (current->next) + { + current->next->previous = current; + } + destroy_node(removed); + } + + if (current->previous && current->previous->is_free) + { + auto removed = current; + removed->previous->page_count += removed->page_count; + removed->previous->next = removed->next; + if (removed->next) + { + removed->next->previous = removed->previous; + } + destroy_node(removed); + } + return; + } + current = current->next; + } + } + + auto mmio_allocator::make_node(kapi::memory::linear_address base, std::size_t page_count, node * next, + node * previous, bool is_free) -> node * + { + using traits = std::allocator_traits>; + + auto new_node = traits::allocate(m_allocator, 1); + traits::construct(m_allocator, new_node, base, page_count, next, previous, is_free); + return new_node; + } + + auto mmio_allocator::destroy_node(node * instance) -> void + { + using traits = std::allocator_traits>; + + traits::destroy(m_allocator, instance); + traits::deallocate(m_allocator, instance, 1); + } + +} // namespace kernel::memory -- cgit v1.2.3 From 1c52a859d105f6b0f8afb16565b10435fa728882 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 8 Apr 2026 14:15:56 +0200 Subject: kapi: fix mmio initialization --- kernel/src/main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index e704955..4b61948 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -19,11 +19,14 @@ #include #include #include +#include #include #include #include +using namespace kstd::units_literals; + auto test_device_names() -> void { auto storage_mgmt = kernel::devices::storage::management::get(); @@ -177,8 +180,9 @@ auto main() -> int kapi::memory::init(); kernel::memory::init_heap(kapi::memory::heap_base); - kstd::println("[OS] Memory subsystem initialized."); kapi::system::memory_initialized(); + kapi::memory::init_mmio(kapi::memory::mmio_base, 1_GiB / kapi::memory::page::size); + kstd::println("[OS] Memory subsystem initialized."); auto acpi_root_pointer = kapi::acpi::get_root_pointer(); if (acpi_root_pointer && acpi_root_pointer->validate()) -- cgit v1.2.3 From 77b408b4e18fabb29f4cab5e899e7c8db1bc1204 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 8 Apr 2026 14:16:13 +0200 Subject: kernel: fix mmio allocator --- kernel/src/memory/mmio_allocator.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/src/memory/mmio_allocator.cpp b/kernel/src/memory/mmio_allocator.cpp index f77f14f..ddbdfc2 100644 --- a/kernel/src/memory/mmio_allocator.cpp +++ b/kernel/src/memory/mmio_allocator.cpp @@ -26,21 +26,25 @@ namespace kernel::memory auto current = m_head; while (current) { - if (current->page_count > count) + if (current->is_free && current->page_count >= count) { - auto new_base = current->base + (count * kapi::memory::page::size); - auto split_node = make_node(new_base, current->page_count - count, std::move(current->next), current, true); - - if (current->next) + if (current->page_count > count) { - current->next->previous = split_node; + auto new_base = current->base + (count * kapi::memory::page::size); + auto split_node = make_node(new_base, current->page_count - count, std::move(current->next), current, true); + + if (current->next) + { + current->next->previous = split_node; + } + current->next = split_node; + current->page_count = count; } - current->next = split_node; - current->page_count = count; - } - current->is_free = false; - return current->base; + current->is_free = false; + return current->base; + } + current = current->next; } kapi::system::panic("[OS:MEM] MMIO alloctor out of memory!"); -- cgit v1.2.3 From 0e92017837490d3ce806cf511977ada06d11a2a7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 8 Apr 2026 15:50:48 +0200 Subject: kapi/bus: fix eager initialization --- kernel/kapi/devices/bus.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/devices/bus.cpp b/kernel/kapi/devices/bus.cpp index 68874c4..66b84d2 100644 --- a/kernel/kapi/devices/bus.cpp +++ b/kernel/kapi/devices/bus.cpp @@ -20,20 +20,26 @@ namespace kapi::devices auto bus::init() -> bool { - if (m_initialized.test_and_set()) + if (m_init_was_called.test_and_set()) { + kstd::println(kstd::print_sink::stderr, "[OS:DEV] Bus {}:{}:{} already initialized", name(), major(), minor()); return true; } if (!probe()) { + kstd::println(kstd::print_sink::stderr, "[OS:DEV] Bus {}:{}:{} probe failed", name(), major(), minor()); return false; } - return std::ranges::fold_left(m_devices, true, [&](bool acc, auto & child) -> bool { + auto child_status = std::ranges::fold_left(m_devices, true, [&](bool acc, auto & child) -> bool { kstd::println("[OS:DEV] Initializing child device {}@{}", child->name(), name()); return child->init() && acc; }); + + m_initialized.test_and_set(); + + return child_status; } auto bus::add_child(kstd::unique_ptr child) -> void -- cgit v1.2.3 From aa208226f992523865328d4612ae4a7679f57a04 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 8 Apr 2026 17:17:11 +0200 Subject: kapi: return region pair for MMIO allocation --- kernel/kapi/memory.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp index b224c50..31cd1f4 100644 --- a/kernel/kapi/memory.cpp +++ b/kernel/kapi/memory.cpp @@ -154,22 +154,33 @@ namespace kapi::memory mmio_allocator.emplace(base, page_count); } - auto allocate_mmio_region(std::size_t page_count) -> linear_address + auto allocate_mmio_region(std::size_t page_count) -> mmio_region { auto region = mmio_allocator->allocate(page_count); - return region; + return {region, page_count}; } - auto map_mmio_region(linear_address base, physical_address hw_base, page_mapper::flags flags) -> std::byte * + auto map_mmio_region(mmio_region region, physical_address hw_base, page_mapper::flags flags) -> std::byte * { - auto start_page = page::containing(base); + auto start_page = page::containing(region.first); auto start_frame = frame::containing(hw_base); - return map(start_page, start_frame, flags | page_mapper::flags::uncached); + + flags |= page_mapper::flags::uncached; + + auto start = map(start_page, start_frame, flags); + + std::ranges::for_each(std::views::iota(1uz, region.second), [&](auto index) { + auto page = page::containing(region.first + index * page::size); + auto frame = frame::containing(hw_base + index * page::size); + map(page, frame, flags); + }); + + return start; } - auto release_mmio_region(linear_address base) -> void + auto release_mmio_region(mmio_region region) -> void { - mmio_allocator->release(base); + mmio_allocator->release(region.first); } } // namespace kapi::memory -- cgit v1.2.3 From f6bea6a5f1939f3261392633f6caca186befd555 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 9 Apr 2026 15:54:04 +0200 Subject: kapi: restructure ACPI implementation --- kernel/CMakeLists.txt | 3 + kernel/kapi/acpi.cpp | 124 --------------------- .../kapi/acpi/multiple_apic_description_table.cpp | 70 ++++++++++++ kernel/kapi/acpi/pointers.cpp | 55 +++++++++ .../kapi/acpi/system_description_table_header.cpp | 51 +++++++++ 5 files changed, 179 insertions(+), 124 deletions(-) create mode 100644 kernel/kapi/acpi/multiple_apic_description_table.cpp create mode 100644 kernel/kapi/acpi/pointers.cpp create mode 100644 kernel/kapi/acpi/system_description_table_header.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 67db0a8..8af6fe7 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,6 +1,9 @@ add_library("kernel_objs" OBJECT # Platform-independent KAPI implementation "kapi/acpi.cpp" + "kapi/acpi/multiple_apic_description_table.cpp" + "kapi/acpi/pointers.cpp" + "kapi/acpi/system_description_table_header.cpp" "kapi/boot_modules.cpp" "kapi/cio.cpp" "kapi/cpu.cpp" diff --git a/kernel/kapi/acpi.cpp b/kernel/kapi/acpi.cpp index 1283d7e..e7c4921 100644 --- a/kernel/kapi/acpi.cpp +++ b/kernel/kapi/acpi.cpp @@ -1,16 +1,13 @@ #include "kapi/acpi.hpp" -#include "kapi/memory.hpp" #include "kapi/system.hpp" #include "kernel/acpi/manager.hpp" #include -#include #include #include -#include #include #include #include @@ -25,127 +22,6 @@ namespace kapi::acpi auto constinit manager = std::optional{}; } // namespace - auto root_system_description_pointer::oem_id() const noexcept -> std::string_view - { - return {m_oem_id.data(), m_oem_id.size()}; - } - - auto root_system_description_pointer::revision() const noexcept -> std::uint8_t - { - return m_revision; - } - - auto root_system_description_pointer::signature() const noexcept -> std::string_view - { - return {m_signature.data(), m_signature.size()}; - } - - auto root_system_description_pointer::table_address() const noexcept -> memory::physical_address - { - auto raw = std::bit_cast(m_rsdt_address); - return memory::physical_address{static_cast(raw)}; - } - - auto root_system_description_pointer::validate() const noexcept -> bool - { - return validate_checksum({reinterpret_cast(this), sizeof(root_system_description_pointer)}); - } - - auto extended_system_description_pointer::length() const noexcept -> kstd::units::bytes - { - return kstd::units::bytes{m_length}; - } - - auto extended_system_description_pointer::table_address() const noexcept -> memory::physical_address - { - return memory::physical_address{std::bit_cast(m_xsdt_address)}; - } - - auto extended_system_description_pointer::validate() const noexcept -> bool - { - return validate_checksum({reinterpret_cast(this), m_length}); - } - - [[nodiscard]] auto system_description_table_header::checksum() const noexcept -> std::uint8_t - { - return m_checksum; - } - - [[nodiscard]] auto system_description_table_header::creator_revision() const noexcept -> std::uint32_t - { - return m_creator_revision; - } - - [[nodiscard]] auto system_description_table_header::creator_id() const noexcept -> std::uint32_t - { - return m_creator_id; - } - - [[nodiscard]] auto system_description_table_header::length() const noexcept -> kstd::units::bytes - { - return kstd::units::bytes{m_length}; - } - - [[nodiscard]] auto system_description_table_header::oem_id() const noexcept -> std::string_view - { - return {m_oem_id.data(), m_oem_id.size()}; - } - - [[nodiscard]] auto system_description_table_header::oem_revision() const noexcept -> std::uint32_t - { - return m_oem_revision; - } - - [[nodiscard]] auto system_description_table_header::oem_table_id() const noexcept -> std::string_view - { - return {m_oem_table_id.data(), m_oem_table_id.size()}; - } - - [[nodiscard]] auto system_description_table_header::revision() const noexcept -> std::uint8_t - { - return m_revision; - } - - [[nodiscard]] auto system_description_table_header::signature() const noexcept -> std::string_view - { - return {m_signature.data(), m_signature.size()}; - } - - [[nodiscard]] auto madt_header::local_interrupt_controller_address() const noexcept -> memory::physical_address - { - return memory::physical_address{static_cast(m_local_interrupt_controller_address)}; - } - - [[nodiscard]] auto madt_header::flags() const noexcept -> std::uint32_t - { - return m_flags; - } - - [[nodiscard]] auto madt_subtable_header::type() const noexcept -> std::uint8_t - { - return m_type; - } - - [[nodiscard]] auto madt_subtable_header::length() const noexcept -> std::size_t - { - return m_length; - } - - [[nodiscard]] auto madt_local_apic::apic_id() const noexcept -> std::uint8_t - { - return m_apic_id; - } - - [[nodiscard]] auto madt_local_apic::flags() const noexcept -> std::uint32_t - { - return m_flags; - } - - [[nodiscard]] auto madt_local_apic::processor_id() const noexcept -> std::uint32_t - { - return m_processor_id; - } - auto init(root_system_description_pointer const & sdp) -> bool { auto static constinit initialized = std::atomic_flag{}; diff --git a/kernel/kapi/acpi/multiple_apic_description_table.cpp b/kernel/kapi/acpi/multiple_apic_description_table.cpp new file mode 100644 index 0000000..c0360a3 --- /dev/null +++ b/kernel/kapi/acpi/multiple_apic_description_table.cpp @@ -0,0 +1,70 @@ +#include "kapi/acpi.hpp" +#include "kapi/memory.hpp" + +#include +#include + +namespace kapi::acpi +{ + + auto multiple_apic_description_table::local_interrupt_controller_address() const noexcept -> memory::physical_address + { + return memory::physical_address{static_cast(m_local_interrupt_controller_address)}; + } + + auto multiple_apic_description_table::flags() const noexcept -> std::uint32_t + { + return m_flags; + } + + auto multiple_apic_description_table_entry::type() const noexcept -> types + { + return static_cast(m_type); + } + + auto multiple_apic_description_table_entry::length() const noexcept -> std::size_t + { + return m_length; + } + + auto processor_local_apic::apic_id() const noexcept -> std::uint8_t + { + return m_apic_id; + } + + auto processor_local_apic::active_flags() const noexcept -> flags + { + return static_cast(m_flags); + } + + auto processor_local_apic::processor_id() const noexcept -> std::uint32_t + { + return m_processor_id; + } + + auto multiple_apic_description_table::begin() const noexcept -> iterator + { + auto base = reinterpret_cast(this); + base += sizeof(multiple_apic_description_table); + auto limit = reinterpret_cast(this); + limit += length().value; + return iterator{reinterpret_cast(base), + reinterpret_cast(limit)}; + } + + auto multiple_apic_description_table::cbegin() const noexcept -> iterator + { + return begin(); + } + + auto multiple_apic_description_table::end() const noexcept -> iterator + { + return {}; + } + + auto multiple_apic_description_table::cend() const noexcept -> iterator + { + return end(); + } + +} // namespace kapi::acpi diff --git a/kernel/kapi/acpi/pointers.cpp b/kernel/kapi/acpi/pointers.cpp new file mode 100644 index 0000000..63831e9 --- /dev/null +++ b/kernel/kapi/acpi/pointers.cpp @@ -0,0 +1,55 @@ +#include "kapi/acpi.hpp" +#include "kapi/memory.hpp" + +#include + +#include +#include +#include +#include + +namespace kapi::acpi +{ + + auto root_system_description_pointer::oem_id() const noexcept -> std::string_view + { + return {m_oem_id.data(), m_oem_id.size()}; + } + + auto root_system_description_pointer::revision() const noexcept -> std::uint8_t + { + return m_revision; + } + + auto root_system_description_pointer::signature() const noexcept -> std::string_view + { + return {m_signature.data(), m_signature.size()}; + } + + auto root_system_description_pointer::table_address() const noexcept -> memory::physical_address + { + auto raw = std::bit_cast(m_rsdt_address); + return memory::physical_address{static_cast(raw)}; + } + + auto root_system_description_pointer::validate() const noexcept -> bool + { + return validate_checksum({reinterpret_cast(this), sizeof(root_system_description_pointer)}); + } + + auto extended_system_description_pointer::length() const noexcept -> kstd::units::bytes + { + return kstd::units::bytes{m_length}; + } + + auto extended_system_description_pointer::table_address() const noexcept -> memory::physical_address + { + return memory::physical_address{std::bit_cast(m_xsdt_address)}; + } + + auto extended_system_description_pointer::validate() const noexcept -> bool + { + return validate_checksum({reinterpret_cast(this), m_length}); + } + +} // namespace kapi::acpi diff --git a/kernel/kapi/acpi/system_description_table_header.cpp b/kernel/kapi/acpi/system_description_table_header.cpp new file mode 100644 index 0000000..f688b4d --- /dev/null +++ b/kernel/kapi/acpi/system_description_table_header.cpp @@ -0,0 +1,51 @@ +#include "kapi/acpi.hpp" + +#include + +#include +#include + +namespace kapi::acpi +{ + + [[nodiscard]] auto system_description_table_header::creator_revision() const noexcept -> std::uint32_t + { + return m_creator_revision; + } + + [[nodiscard]] auto system_description_table_header::creator_id() const noexcept -> std::uint32_t + { + return m_creator_id; + } + + [[nodiscard]] auto system_description_table_header::length() const noexcept -> kstd::units::bytes + { + return kstd::units::bytes{m_length}; + } + + [[nodiscard]] auto system_description_table_header::oem_id() const noexcept -> std::string_view + { + return {m_oem_id.data(), m_oem_id.size()}; + } + + [[nodiscard]] auto system_description_table_header::oem_revision() const noexcept -> std::uint32_t + { + return m_oem_revision; + } + + [[nodiscard]] auto system_description_table_header::oem_table_id() const noexcept -> std::string_view + { + return {m_oem_table_id.data(), m_oem_table_id.size()}; + } + + [[nodiscard]] auto system_description_table_header::revision() const noexcept -> std::uint8_t + { + return m_revision; + } + + [[nodiscard]] auto system_description_table_header::signature() const noexcept -> std::string_view + { + return {m_signature.data(), m_signature.size()}; + } + +} // namespace kapi::acpi -- 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/CMakeLists.txt | 1 - kernel/kapi/cpu.cpp | 19 +++++++++++++++++++ kernel/kapi/platform.cpp | 27 --------------------------- kernel/src/devices/cpu.cpp | 4 ++-- 4 files changed, 21 insertions(+), 30 deletions(-) delete mode 100644 kernel/kapi/platform.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 8af6fe7..61bc6f1 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -12,7 +12,6 @@ add_library("kernel_objs" OBJECT "kapi/devices/device.cpp" "kapi/interrupts.cpp" "kapi/memory.cpp" - "kapi/platform.cpp" "kapi/system.cpp" # KSTD OS Implementation diff --git a/kernel/kapi/cpu.cpp b/kernel/kapi/cpu.cpp index 13de584..d632628 100644 --- a/kernel/kapi/cpu.cpp +++ b/kernel/kapi/cpu.cpp @@ -1,9 +1,17 @@ #include "kapi/cpu.hpp" +#include "kapi/devices.hpp" #include "kapi/system.hpp" +#include "kernel/devices/cpu.hpp" + +#include #include +#include +#include +#include + namespace kapi::cpu { @@ -32,4 +40,15 @@ namespace kapi::cpu } } + auto core_detected(kapi::devices::bus & bus, std::size_t major, std::size_t minor, std::uint64_t hardware_id, + bool is_bsp, kstd::unique_ptr core_interrupt_controller) -> bool + { + auto core = kstd::make_unique(major, minor, hardware_id, is_bsp); + + core->add_child(std::move(core_interrupt_controller)); + bus.add_child(std::move(core)); + + return true; + } + } // namespace kapi::cpu \ No newline at end of file diff --git a/kernel/kapi/platform.cpp b/kernel/kapi/platform.cpp deleted file mode 100644 index 7638cf9..0000000 --- a/kernel/kapi/platform.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "kapi/platform.hpp" - -#include "kapi/devices.hpp" - -#include "kernel/devices/cpu.hpp" - -#include - -#include -#include -#include - -namespace kapi::platform -{ - - auto cpu_detected(kapi::devices::bus & bus, std::size_t major, std::size_t minor, std::uint64_t hardware_id, - bool is_bsp, kstd::unique_ptr core_interrupt_controller) -> bool - { - auto core = kstd::make_unique(major, minor, hardware_id, is_bsp); - - core->add_child(std::move(core_interrupt_controller)); - bus.add_child(std::move(core)); - - return true; - } - -} // namespace kapi::platform \ No newline at end of file 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 ed663488a66383e136534a5c43c66ef5868cb2d3 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 10 Apr 2026 09:53:25 +0200 Subject: fixup! kapi: move platform functions to CPU --- kernel/CMakeLists.txt | 1 - kernel/src/test_support/kapi/cpu.cpp | 7 +++++++ kernel/src/test_support/kapi/platform.cpp | 14 -------------- 3 files changed, 7 insertions(+), 15 deletions(-) delete mode 100644 kernel/src/test_support/kapi/platform.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 61bc6f1..ca8fae7 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -104,7 +104,6 @@ else() "src/test_support/kapi/cio.cpp" "src/test_support/kapi/interrupts.cpp" "src/test_support/kapi/memory.cpp" - "src/test_support/kapi/platform.cpp" "src/test_support/log_buffer.cpp" "src/test_support/output_device.cpp" "src/test_support/page_mapper.cpp" diff --git a/kernel/src/test_support/kapi/cpu.cpp b/kernel/src/test_support/kapi/cpu.cpp index 96dd10a..a89bec8 100644 --- a/kernel/src/test_support/kapi/cpu.cpp +++ b/kernel/src/test_support/kapi/cpu.cpp @@ -1,5 +1,6 @@ #include "kernel/test_support/cpu.hpp" +#include "kapi/devices.hpp" #include #include @@ -28,6 +29,12 @@ namespace kapi::cpu throw kernel::tests::cpu::halt{}; } + auto discover_topology(devices::bus &) -> bool + { + // TODO: implement more meaningful simulated CPU topology discovery + return true; + } + } // namespace kapi::cpu namespace kernel::tests::cpu diff --git a/kernel/src/test_support/kapi/platform.cpp b/kernel/src/test_support/kapi/platform.cpp deleted file mode 100644 index 497c992..0000000 --- a/kernel/src/test_support/kapi/platform.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "kapi/platform.hpp" - -#include "kapi/devices.hpp" - -namespace kapi::platform -{ - - auto discover_cpu_topology(devices::bus &) -> bool - { - // TODO: implement more meaningful simulated CPU topology discovery - return true; - } - -} // namespace kapi::platform \ No newline at end of file -- 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/CMakeLists.txt | 2 +- kernel/include/kernel/devices/cpu.hpp | 33 ------------------------- kernel/kapi/cpu.cpp | 19 --------------- kernel/kapi/devices.cpp | 7 ++---- kernel/kapi/devices/cpu.cpp | 31 ++++++++++++++++++++++++ kernel/src/devices/cpu.cpp | 45 ----------------------------------- kernel/src/test_support/kapi/cpu.cpp | 3 +-- 7 files changed, 35 insertions(+), 105 deletions(-) delete mode 100644 kernel/include/kernel/devices/cpu.hpp create mode 100644 kernel/kapi/devices/cpu.cpp delete mode 100644 kernel/src/devices/cpu.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index ca8fae7..b9e01eb 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -9,6 +9,7 @@ add_library("kernel_objs" OBJECT "kapi/cpu.cpp" "kapi/devices.cpp" "kapi/devices/bus.cpp" + "kapi/devices/cpu.cpp" "kapi/devices/device.cpp" "kapi/interrupts.cpp" "kapi/memory.cpp" @@ -26,7 +27,6 @@ add_library("kernel_objs" OBJECT "src/memory.cpp" "src/devices/block_device.cpp" "src/devices/block_device_utils.cpp" - "src/devices/cpu.cpp" "src/devices/root_bus.cpp" "src/devices/storage/controller.cpp" "src/devices/storage/management.cpp" diff --git a/kernel/include/kernel/devices/cpu.hpp b/kernel/include/kernel/devices/cpu.hpp deleted file mode 100644 index b056665..0000000 --- a/kernel/include/kernel/devices/cpu.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef TEACHOS_KERNEL_DEVICES_CPU_HPP -#define TEACHOS_KERNEL_DEVICES_CPU_HPP - -#include "kapi/devices.hpp" - -#include -#include - -namespace kernel::devices -{ - - struct cpu final : kapi::devices::bus - { - struct core final : kapi::devices::bus - { - explicit core(std::size_t major_number, std::size_t minor_number, std::uint64_t hardware_id, bool is_bsp); - - [[nodiscard]] auto hardware_id() const -> std::uint64_t; - [[nodiscard]] auto is_bsp() const -> bool; - - private: - std::uint64_t m_hardware_id; - bool m_is_bsp; - }; - - explicit cpu(std::size_t major_number); - - auto probe() -> bool final; - }; - -} // namespace kernel::devices - -#endif \ No newline at end of file diff --git a/kernel/kapi/cpu.cpp b/kernel/kapi/cpu.cpp index d632628..13de584 100644 --- a/kernel/kapi/cpu.cpp +++ b/kernel/kapi/cpu.cpp @@ -1,17 +1,9 @@ #include "kapi/cpu.hpp" -#include "kapi/devices.hpp" #include "kapi/system.hpp" -#include "kernel/devices/cpu.hpp" - -#include #include -#include -#include -#include - namespace kapi::cpu { @@ -40,15 +32,4 @@ namespace kapi::cpu } } - auto core_detected(kapi::devices::bus & bus, std::size_t major, std::size_t minor, std::uint64_t hardware_id, - bool is_bsp, kstd::unique_ptr core_interrupt_controller) -> bool - { - auto core = kstd::make_unique(major, minor, hardware_id, is_bsp); - - core->add_child(std::move(core_interrupt_controller)); - bus.add_child(std::move(core)); - - return true; - } - } // namespace kapi::cpu \ No newline at end of file diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp index dad1fe4..b8aa44b 100644 --- a/kernel/kapi/devices.cpp +++ b/kernel/kapi/devices.cpp @@ -1,8 +1,8 @@ #include "kapi/devices.hpp" +#include "kapi/cpu.hpp" #include "kapi/system.hpp" -#include "kernel/devices/cpu.hpp" #include "kernel/devices/root_bus.hpp" #include @@ -17,7 +17,6 @@ namespace kapi::devices { - namespace { auto constinit next_major_number = std::atomic_size_t{1}; @@ -37,9 +36,7 @@ namespace kapi::devices register_device(bus); bus.init(); - auto cpu_major = allocate_major_number(); - auto cpu = kstd::make_unique(cpu_major); - bus.add_child(std::move(cpu)); + kapi::cpu::discover_topology(); } auto get_root_bus() -> bus & diff --git a/kernel/kapi/devices/cpu.cpp b/kernel/kapi/devices/cpu.cpp new file mode 100644 index 0000000..9de5f94 --- /dev/null +++ b/kernel/kapi/devices/cpu.cpp @@ -0,0 +1,31 @@ +#include "kapi/devices/cpu.hpp" + +#include "kapi/devices.hpp" + +#include +#include + +namespace kapi::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, std::size_t minor) + : kapi::devices::bus{major, minor, "cpu"} + {} + +} // namespace kapi::devices \ No newline at end of file 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 diff --git a/kernel/src/test_support/kapi/cpu.cpp b/kernel/src/test_support/kapi/cpu.cpp index a89bec8..671097e 100644 --- a/kernel/src/test_support/kapi/cpu.cpp +++ b/kernel/src/test_support/kapi/cpu.cpp @@ -1,6 +1,5 @@ #include "kernel/test_support/cpu.hpp" -#include "kapi/devices.hpp" #include #include @@ -29,7 +28,7 @@ namespace kapi::cpu throw kernel::tests::cpu::halt{}; } - auto discover_topology(devices::bus &) -> bool + auto discover_topology() -> bool { // TODO: implement more meaningful simulated CPU topology discovery return true; -- cgit v1.2.3 From 5a6b6ab376e67b173ef36f831445ccba7e86e038 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 10 Apr 2026 10:38:51 +0200 Subject: kapi/devices: add parent back-pointer to device --- kernel/kapi/devices/bus.cpp | 1 + kernel/kapi/devices/device.cpp | 8 ++++++++ 2 files changed, 9 insertions(+) (limited to 'kernel') diff --git a/kernel/kapi/devices/bus.cpp b/kernel/kapi/devices/bus.cpp index 66b84d2..5f0dfcd 100644 --- a/kernel/kapi/devices/bus.cpp +++ b/kernel/kapi/devices/bus.cpp @@ -45,6 +45,7 @@ namespace kapi::devices auto bus::add_child(kstd::unique_ptr child) -> void { auto observer = m_observers.emplace_back(child.get()); + child->set_parent(kstd::make_observer(this)); m_devices.push_back(std::move(child)); kapi::devices::register_device(*observer); diff --git a/kernel/kapi/devices/device.cpp b/kernel/kapi/devices/device.cpp index 9f7a404..41d96dc 100644 --- a/kernel/kapi/devices/device.cpp +++ b/kernel/kapi/devices/device.cpp @@ -1,5 +1,8 @@ #include "kapi/devices/device.hpp" +#include "kapi/devices/bus.hpp" + +#include #include #include @@ -32,4 +35,9 @@ namespace kapi::devices return false; } + auto device::set_parent(kstd::observer_ptr parent) -> void + { + m_parent = parent; + } + } // namespace kapi::devices \ No newline at end of file -- cgit v1.2.3 From c3f7b747f02a79b34ed914c54ce74be973b17af1 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 10 Apr 2026 17:39:14 +0200 Subject: kapi: extract ACPI functionality to libs --- kernel/CMakeLists.txt | 3 - kernel/include/kernel/acpi/manager.hpp | 14 ++--- kernel/kapi/acpi.cpp | 18 ++---- .../kapi/acpi/multiple_apic_description_table.cpp | 70 ---------------------- kernel/kapi/acpi/pointers.cpp | 55 ----------------- .../kapi/acpi/system_description_table_header.cpp | 51 ---------------- kernel/src/acpi/manager.cpp | 29 +++++---- 7 files changed, 25 insertions(+), 215 deletions(-) delete mode 100644 kernel/kapi/acpi/multiple_apic_description_table.cpp delete mode 100644 kernel/kapi/acpi/pointers.cpp delete mode 100644 kernel/kapi/acpi/system_description_table_header.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index b9e01eb..74233cb 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,9 +1,6 @@ add_library("kernel_objs" OBJECT # Platform-independent KAPI implementation "kapi/acpi.cpp" - "kapi/acpi/multiple_apic_description_table.cpp" - "kapi/acpi/pointers.cpp" - "kapi/acpi/system_description_table_header.cpp" "kapi/boot_modules.cpp" "kapi/cio.cpp" "kapi/cpu.cpp" diff --git a/kernel/include/kernel/acpi/manager.hpp b/kernel/include/kernel/acpi/manager.hpp index fae59a6..420b44a 100644 --- a/kernel/include/kernel/acpi/manager.hpp +++ b/kernel/include/kernel/acpi/manager.hpp @@ -1,12 +1,12 @@ #ifndef TEACHOS_KERNEL_ACPI_MANAGER_HPP #define TEACHOS_KERNEL_ACPI_MANAGER_HPP -#include "kapi/acpi.hpp" - #include #include #include +#include + #include namespace kernel::acpi @@ -14,16 +14,16 @@ namespace kernel::acpi struct manager { - explicit manager(kapi::acpi::root_system_description_pointer const & sdp); + explicit manager(::acpi::rsdp const & sdp); auto load_tables() -> bool; - auto get_table(std::string_view signature) -> kstd::observer_ptr; + auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const>; private: - kapi::acpi::root_system_description_pointer const * m_sdp{}; - kapi::acpi::system_description_table_header const * m_rsdt{}; - kstd::flat_map m_tables{}; + ::acpi::rsdp const * m_sdp{}; + ::acpi::sdt const * m_rsdt{}; + kstd::flat_map m_tables{}; bool m_extended{}; }; diff --git a/kernel/kapi/acpi.cpp b/kernel/kapi/acpi.cpp index e7c4921..df2bf05 100644 --- a/kernel/kapi/acpi.cpp +++ b/kernel/kapi/acpi.cpp @@ -6,12 +6,10 @@ #include -#include +#include + #include -#include -#include #include -#include #include namespace kapi::acpi @@ -22,7 +20,7 @@ namespace kapi::acpi auto constinit manager = std::optional{}; } // namespace - auto init(root_system_description_pointer const & sdp) -> bool + auto init(::acpi::rsdp const & sdp) -> bool { auto static constinit initialized = std::atomic_flag{}; if (initialized.test_and_set()) @@ -34,15 +32,7 @@ namespace kapi::acpi return manager->load_tables(); } - auto validate_checksum(std::span data) -> bool - { - auto sum = std::ranges::fold_left(data, std::uint8_t{}, [](auto acc, auto byte) { - return static_cast(acc + static_cast(byte)); - }); - return sum == 0; - } - - auto get_table(std::string_view signature) -> kstd::observer_ptr + auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const> { return manager->get_table(signature); } diff --git a/kernel/kapi/acpi/multiple_apic_description_table.cpp b/kernel/kapi/acpi/multiple_apic_description_table.cpp deleted file mode 100644 index c0360a3..0000000 --- a/kernel/kapi/acpi/multiple_apic_description_table.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "kapi/acpi.hpp" -#include "kapi/memory.hpp" - -#include -#include - -namespace kapi::acpi -{ - - auto multiple_apic_description_table::local_interrupt_controller_address() const noexcept -> memory::physical_address - { - return memory::physical_address{static_cast(m_local_interrupt_controller_address)}; - } - - auto multiple_apic_description_table::flags() const noexcept -> std::uint32_t - { - return m_flags; - } - - auto multiple_apic_description_table_entry::type() const noexcept -> types - { - return static_cast(m_type); - } - - auto multiple_apic_description_table_entry::length() const noexcept -> std::size_t - { - return m_length; - } - - auto processor_local_apic::apic_id() const noexcept -> std::uint8_t - { - return m_apic_id; - } - - auto processor_local_apic::active_flags() const noexcept -> flags - { - return static_cast(m_flags); - } - - auto processor_local_apic::processor_id() const noexcept -> std::uint32_t - { - return m_processor_id; - } - - auto multiple_apic_description_table::begin() const noexcept -> iterator - { - auto base = reinterpret_cast(this); - base += sizeof(multiple_apic_description_table); - auto limit = reinterpret_cast(this); - limit += length().value; - return iterator{reinterpret_cast(base), - reinterpret_cast(limit)}; - } - - auto multiple_apic_description_table::cbegin() const noexcept -> iterator - { - return begin(); - } - - auto multiple_apic_description_table::end() const noexcept -> iterator - { - return {}; - } - - auto multiple_apic_description_table::cend() const noexcept -> iterator - { - return end(); - } - -} // namespace kapi::acpi diff --git a/kernel/kapi/acpi/pointers.cpp b/kernel/kapi/acpi/pointers.cpp deleted file mode 100644 index 63831e9..0000000 --- a/kernel/kapi/acpi/pointers.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "kapi/acpi.hpp" -#include "kapi/memory.hpp" - -#include - -#include -#include -#include -#include - -namespace kapi::acpi -{ - - auto root_system_description_pointer::oem_id() const noexcept -> std::string_view - { - return {m_oem_id.data(), m_oem_id.size()}; - } - - auto root_system_description_pointer::revision() const noexcept -> std::uint8_t - { - return m_revision; - } - - auto root_system_description_pointer::signature() const noexcept -> std::string_view - { - return {m_signature.data(), m_signature.size()}; - } - - auto root_system_description_pointer::table_address() const noexcept -> memory::physical_address - { - auto raw = std::bit_cast(m_rsdt_address); - return memory::physical_address{static_cast(raw)}; - } - - auto root_system_description_pointer::validate() const noexcept -> bool - { - return validate_checksum({reinterpret_cast(this), sizeof(root_system_description_pointer)}); - } - - auto extended_system_description_pointer::length() const noexcept -> kstd::units::bytes - { - return kstd::units::bytes{m_length}; - } - - auto extended_system_description_pointer::table_address() const noexcept -> memory::physical_address - { - return memory::physical_address{std::bit_cast(m_xsdt_address)}; - } - - auto extended_system_description_pointer::validate() const noexcept -> bool - { - return validate_checksum({reinterpret_cast(this), m_length}); - } - -} // namespace kapi::acpi diff --git a/kernel/kapi/acpi/system_description_table_header.cpp b/kernel/kapi/acpi/system_description_table_header.cpp deleted file mode 100644 index f688b4d..0000000 --- a/kernel/kapi/acpi/system_description_table_header.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "kapi/acpi.hpp" - -#include - -#include -#include - -namespace kapi::acpi -{ - - [[nodiscard]] auto system_description_table_header::creator_revision() const noexcept -> std::uint32_t - { - return m_creator_revision; - } - - [[nodiscard]] auto system_description_table_header::creator_id() const noexcept -> std::uint32_t - { - return m_creator_id; - } - - [[nodiscard]] auto system_description_table_header::length() const noexcept -> kstd::units::bytes - { - return kstd::units::bytes{m_length}; - } - - [[nodiscard]] auto system_description_table_header::oem_id() const noexcept -> std::string_view - { - return {m_oem_id.data(), m_oem_id.size()}; - } - - [[nodiscard]] auto system_description_table_header::oem_revision() const noexcept -> std::uint32_t - { - return m_oem_revision; - } - - [[nodiscard]] auto system_description_table_header::oem_table_id() const noexcept -> std::string_view - { - return {m_oem_table_id.data(), m_oem_table_id.size()}; - } - - [[nodiscard]] auto system_description_table_header::revision() const noexcept -> std::uint8_t - { - return m_revision; - } - - [[nodiscard]] auto system_description_table_header::signature() const noexcept -> std::string_view - { - return {m_signature.data(), m_signature.size()}; - } - -} // namespace kapi::acpi diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 300b85e..501ce92 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -1,12 +1,13 @@ #include "kernel/acpi/manager.hpp" -#include "kapi/acpi.hpp" #include "kapi/memory.hpp" #include "kapi/system.hpp" #include #include +#include + #include #include #include @@ -14,7 +15,7 @@ namespace kernel::acpi { - manager::manager(kapi::acpi::root_system_description_pointer const & sdp) + manager::manager(::acpi::rsdp const & sdp) : m_sdp{&sdp} { if (m_sdp->signature() != "RSD PTR ") @@ -24,14 +25,14 @@ namespace kernel::acpi if (m_sdp->revision() >= 2) { - auto const xsdp = static_cast(m_sdp); + auto const xsdp = static_cast<::acpi::xsdp const *>(m_sdp); if (!xsdp->validate()) { kapi::system::panic("[OS:ACPI] Invalid XSDP signature!"); } - auto physical_extended_table_address = xsdp->table_address(); + auto physical_extended_table_address = kapi::memory::physical_address{xsdp->table_address()}; auto linear_extended_table_address = kapi::memory::hhdm_to_linear(physical_extended_table_address); - m_rsdt = static_cast(linear_extended_table_address); + m_rsdt = static_cast<::acpi::sdt const *>(linear_extended_table_address); m_extended = true; } else @@ -40,23 +41,22 @@ namespace kernel::acpi { kapi::system::panic("[OS:ACPI] Invalid RSDP checksum!"); } - auto physical_root_table_address = m_sdp->table_address(); + auto physical_root_table_address = kapi::memory::physical_address{m_sdp->table_address()}; auto linear_root_table_address = kapi::memory::hhdm_to_linear(physical_root_table_address); - m_rsdt = static_cast(linear_root_table_address); + m_rsdt = static_cast<::acpi::sdt const *>(linear_root_table_address); } } auto manager::load_tables() -> bool { - if (!kapi::acpi::validate_checksum({reinterpret_cast(m_rsdt), m_rsdt->length().value})) + if (!::acpi::validate_checksum({reinterpret_cast(m_rsdt), m_rsdt->length().value})) { kapi::system::panic("[OS:ACPI] Invalid RSDT checksum!"); } auto entry_size = m_extended ? sizeof(std::uint64_t) : sizeof(std::uint32_t); - auto entry_count = (m_rsdt->length().value - sizeof(kapi::acpi::system_description_table_header)) / entry_size; - auto entries_base = - reinterpret_cast(m_rsdt) + sizeof(kapi::acpi::system_description_table_header); + auto entry_count = (m_rsdt->length().value - sizeof(::acpi::sdt)) / entry_size; + auto entries_base = reinterpret_cast(m_rsdt) + sizeof(::acpi::sdt); for (std::size_t i = 0; i < entry_count; ++i) { @@ -74,9 +74,9 @@ namespace kernel::acpi } auto linear_table_address = kapi::memory::hhdm_to_linear(physical_table_address); - auto table = static_cast(linear_table_address); + auto table = static_cast<::acpi::sdt const *>(linear_table_address); - if (!kapi::acpi::validate_checksum({reinterpret_cast(table), table->length().value})) + if (!::acpi::validate_checksum({reinterpret_cast(table), table->length().value})) { kstd::println(kstd::print_sink::stderr, "[OS:ACPI] Invalid table checksum!"); } @@ -90,8 +90,7 @@ namespace kernel::acpi return !m_tables.empty(); } - auto manager::get_table(std::string_view signature) - -> kstd::observer_ptr + auto manager::get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const> { if (m_tables.contains(signature)) { -- cgit v1.2.3 From 21fd1281cf19572e202d583689b99c33ec68da50 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 10 Apr 2026 17:49:40 +0200 Subject: kernel: let arch initialize the ACPI manager --- kernel/kapi/devices.cpp | 3 --- kernel/src/main.cpp | 10 ---------- 2 files changed, 13 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp index b8aa44b..2250319 100644 --- a/kernel/kapi/devices.cpp +++ b/kernel/kapi/devices.cpp @@ -1,6 +1,5 @@ #include "kapi/devices.hpp" -#include "kapi/cpu.hpp" #include "kapi/system.hpp" #include "kernel/devices/root_bus.hpp" @@ -35,8 +34,6 @@ namespace kapi::devices auto & bus = root_bus.emplace(); register_device(bus); bus.init(); - - kapi::cpu::discover_topology(); } auto get_root_bus() -> bus & diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 4b61948..b920674 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,4 +1,3 @@ -#include "kapi/acpi.hpp" #include "kapi/boot_modules.hpp" #include "kapi/cio.hpp" #include "kapi/cpu.hpp" @@ -184,15 +183,6 @@ auto main() -> int kapi::memory::init_mmio(kapi::memory::mmio_base, 1_GiB / kapi::memory::page::size); kstd::println("[OS] Memory subsystem initialized."); - auto acpi_root_pointer = kapi::acpi::get_root_pointer(); - if (acpi_root_pointer && acpi_root_pointer->validate()) - { - if (kapi::acpi::init(*acpi_root_pointer)) - { - kstd::println("[OS] ACPI subsystem initialized."); - } - } - kapi::devices::init(); kstd::println("[OS] System root bus initialized."); -- cgit v1.2.3 From 72b40ecf33fb0ef2d4232b80560642296c79399c Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 2 Apr 2026 09:49:17 +0200 Subject: automatically detect the mounted file system type by trial-and-error --- kernel/include/kernel/filesystem/filesystem.hpp | 3 ++- kernel/src/filesystem/filesystem.cpp | 29 +++++++++++++++++++++---- kernel/src/filesystem/vfs.cpp | 5 +---- kernel/src/main.cpp | 4 ++-- 4 files changed, 30 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index 1d86178..05f96dc 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -2,6 +2,7 @@ #define TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP #include "kapi/devices/device.hpp" + #include "kernel/filesystem/inode.hpp" #include @@ -15,7 +16,7 @@ namespace kernel::filesystem { virtual ~filesystem() = default; - virtual auto mount(kstd::shared_ptr const & device) -> int; + auto static mount(kstd::shared_ptr const & device) -> kstd::shared_ptr; virtual auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr = 0; [[nodiscard]] auto root_inode() const -> kstd::shared_ptr const &; diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index 0ac9cf8..e0c760f 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -1,20 +1,41 @@ #include "kernel/filesystem/filesystem.hpp" #include "kapi/devices/device.hpp" +#include "kapi/system.hpp" + +#include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/filesystem/inode.hpp" #include +#include + namespace kernel::filesystem { - auto filesystem::mount(kstd::shared_ptr const & device) -> int + namespace + { + constexpr auto static filesystem_factories = std::array{ + []() { return kstd::make_shared(); }, + }; + } // namespace + + auto filesystem::mount(kstd::shared_ptr const & device) -> kstd::shared_ptr { if (!device) { - return -1; // TODO BA-FS26 panic or errorcode? + kapi::system::panic("[FILESYSTEM] cannot mount filesystem: device is null."); } - m_device = device; - return 0; + + for (auto & factory : filesystem_factories) + { + auto fs = factory(); + if (fs->mount(device) == 0) + { + return fs; + } + } + + kapi::system::panic("[FILESYSTEM] cannot mount filesystem: no suitable filesystem found on device."); } auto filesystem::root_inode() const -> kstd::shared_ptr const & diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 06214d2..66aa91e 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -5,7 +5,6 @@ #include "kernel/devices/storage/management.hpp" #include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/devfs/filesystem.hpp" -#include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/mount.hpp" #include "kernel/filesystem/open_file_description.hpp" @@ -46,9 +45,7 @@ namespace kernel::filesystem auto storage_mgmt = devices::storage::management::get(); if (auto boot_device = storage_mgmt.determine_boot_device()) { - // TODO BA-FS26 detect fs type from boot device and load corresponding fs, for now just assume ext2 - auto boot_root_fs = kstd::make_shared(); - boot_root_fs->mount(boot_device); + auto boot_root_fs = kernel::filesystem::filesystem::mount(boot_device); do_mount_internal("/", root_fs_root_dentry, boot_root_fs); } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index b920674..382f12d 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -130,9 +130,9 @@ auto test_file_lookup() -> void kstd::os::panic("test code failed"); } - auto new_filesystem = kstd::make_shared(); auto device = storage_mgmt.device_by_major_minor(1, 16); - new_filesystem->mount(device); + auto new_filesystem = kernel::filesystem::filesystem::mount(device); + if (vfs.do_mount("/a/b", new_filesystem) != 0) { kstd::os::panic("test code failed"); -- cgit v1.2.3 From 93bca4c2a7c1852fc89df6965c835a7dbbdd6512 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 2 Apr 2026 09:50:14 +0200 Subject: read ext2 superblock and check the magic number --- .../include/kernel/filesystem/ext2/filesystem.hpp | 11 +++- kernel/src/filesystem/ext2/filesystem.cpp | 66 ++++++++++++---------- 2 files changed, 47 insertions(+), 30 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index 078da31..176d83c 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -2,20 +2,29 @@ #define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP #include "kapi/devices/device.hpp" + +#include "kernel/filesystem/ext2/superblock.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" #include +#include #include namespace kernel::filesystem::ext2 { struct filesystem : kernel::filesystem::filesystem { - auto mount(kstd::shared_ptr const & device) -> int override; + auto mount(kstd::shared_ptr const & device) -> int; auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; + + private: + auto get_block_size() -> size_t; + auto get_inode_size() -> size_t; + + superblock m_superblock; }; } // namespace kernel::filesystem::ext2 diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index eb9edc4..a3425b5 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -1,10 +1,10 @@ #include "kernel/filesystem/ext2/filesystem.hpp" -#include "kernel/devices/block_device_utils.hpp" #include "kapi/devices/device.hpp" + +#include "kernel/devices/block_device_utils.hpp" #include "kernel/filesystem/ext2/inode.hpp" #include "kernel/filesystem/ext2/superblock.hpp" -#include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" #include @@ -17,37 +17,35 @@ namespace kernel::filesystem::ext2 { namespace { - // constexpr size_t SUPERBLOCK_OFFSET = 1024; - // constexpr uint16_t EXT2_MAGIC = 0xEF53; - - // // Mode bits - // constexpr uint16_t S_IFMT = 0xF000; - // constexpr uint16_t S_IFREG = 0x8000; - // constexpr uint16_t S_IFDIR = 0x4000; - - // auto S_ISREG(uint16_t mode) -> bool - // { - // return (mode & S_IFMT) == S_IFREG; - // } - // auto S_ISDIR(uint16_t mode) -> bool - // { - // return (mode & S_IFMT) == S_IFDIR; - // } - - // auto get_block_size(superblock const & superblock) -> size_t - // { - // return 1024U << superblock.log_block_size; - // } - - // auto get_inode_size(superblock const & superblock) -> size_t - // { - // return superblock.rev_level == 0 ? 128 : superblock.inode_size; - // } + constexpr size_t SUPERBLOCK_OFFSET = 1024; + constexpr uint16_t EXT2_MAGIC = 0xEF53; + + // Mode bits + constexpr uint16_t S_IFMT = 0xF000; + constexpr uint16_t S_IFREG = 0x8000; + constexpr uint16_t S_IFDIR = 0x4000; + + auto S_ISREG(uint16_t mode) -> bool + { + return (mode & S_IFMT) == S_IFREG; + } + auto S_ISDIR(uint16_t mode) -> bool + { + return (mode & S_IFMT) == S_IFDIR; + } } // namespace auto filesystem::mount(kstd::shared_ptr const & device) -> int { - kernel::filesystem::filesystem::mount(device); // TODO BA-FS26 error handling? + m_device = device; + + kernel::devices::block_device_utils::read(m_device, &m_superblock, SUPERBLOCK_OFFSET, sizeof(m_superblock)); + + if (m_superblock.magic != EXT2_MAGIC) + { + return -1; + } + // TODO BA-FS26 load proper root inode from ext2 metadata // m_root_inode = inode{inode_kind::directory}; @@ -69,4 +67,14 @@ namespace kernel::filesystem::ext2 return kstd::make_shared(); } + + auto filesystem::get_block_size() -> size_t + { + return 1024U << m_superblock.log_block_size; + } + + auto filesystem::get_inode_size() -> size_t + { + return m_superblock.rev_level == 0 ? 128 : m_superblock.inode_size; + } } // namespace kernel::filesystem::ext2 -- cgit v1.2.3 From 1dcf253fdf8169a3b2b71bfac68f2f25951af1a8 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 2 Apr 2026 10:04:04 +0200 Subject: fix build, refactoring --- .../include/kernel/filesystem/devfs/filesystem.hpp | 1 + .../include/kernel/filesystem/ext2/filesystem.hpp | 2 +- kernel/include/kernel/filesystem/filesystem.hpp | 4 +++- .../kernel/filesystem/rootfs/filesystem.hpp | 1 + kernel/src/filesystem/ext2/filesystem.cpp | 27 +++++++++++----------- kernel/src/filesystem/filesystem.cpp | 9 +++++++- kernel/src/filesystem/rootfs/filesystem.cpp | 1 + kernel/src/filesystem/vfs.cpp | 2 +- kernel/src/main.cpp | 4 ++-- 9 files changed, 32 insertions(+), 19 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/devfs/filesystem.hpp b/kernel/include/kernel/filesystem/devfs/filesystem.hpp index 29ae388..3edeabb 100644 --- a/kernel/include/kernel/filesystem/devfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/devfs/filesystem.hpp @@ -2,6 +2,7 @@ #define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_FILESYSTEM_HPP #include "kapi/devices/device.hpp" + #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index 176d83c..f6cd17f 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -16,7 +16,7 @@ namespace kernel::filesystem::ext2 { struct filesystem : kernel::filesystem::filesystem { - auto mount(kstd::shared_ptr const & device) -> int; + auto mount(kstd::shared_ptr const & device) -> int override; auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index 05f96dc..1c45377 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -16,7 +16,9 @@ namespace kernel::filesystem { virtual ~filesystem() = default; - auto static mount(kstd::shared_ptr const & device) -> kstd::shared_ptr; + auto static probe_and_mount(kstd::shared_ptr const & device) -> kstd::shared_ptr; + + virtual auto mount(kstd::shared_ptr const & device) -> int; virtual auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr = 0; [[nodiscard]] auto root_inode() const -> kstd::shared_ptr const &; diff --git a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp index 5632d86..7931d87 100644 --- a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp @@ -2,6 +2,7 @@ #define TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_FILESYSTEM_HPP #include "kapi/devices/device.hpp" + #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index a3425b5..0ebb243 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -5,6 +5,7 @@ #include "kernel/devices/block_device_utils.hpp" #include "kernel/filesystem/ext2/inode.hpp" #include "kernel/filesystem/ext2/superblock.hpp" +#include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" #include @@ -21,23 +22,23 @@ namespace kernel::filesystem::ext2 constexpr uint16_t EXT2_MAGIC = 0xEF53; // Mode bits - constexpr uint16_t S_IFMT = 0xF000; - constexpr uint16_t S_IFREG = 0x8000; - constexpr uint16_t S_IFDIR = 0x4000; - - auto S_ISREG(uint16_t mode) -> bool - { - return (mode & S_IFMT) == S_IFREG; - } - auto S_ISDIR(uint16_t mode) -> bool - { - return (mode & S_IFMT) == S_IFDIR; - } + // constexpr uint16_t S_IFMT = 0xF000; + // constexpr uint16_t S_IFREG = 0x8000; + // constexpr uint16_t S_IFDIR = 0x4000; + + // auto S_ISREG(uint16_t mode) -> bool + // { + // return (mode & S_IFMT) == S_IFREG; + // } + // auto S_ISDIR(uint16_t mode) -> bool + // { + // return (mode & S_IFMT) == S_IFDIR; + // } } // namespace auto filesystem::mount(kstd::shared_ptr const & device) -> int { - m_device = device; + kernel::filesystem::filesystem::mount(device); kernel::devices::block_device_utils::read(m_device, &m_superblock, SUPERBLOCK_OFFSET, sizeof(m_superblock)); diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index e0c760f..a06eb80 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -19,7 +19,8 @@ namespace kernel::filesystem }; } // namespace - auto filesystem::mount(kstd::shared_ptr const & device) -> kstd::shared_ptr + auto filesystem::probe_and_mount(kstd::shared_ptr const & device) + -> kstd::shared_ptr { if (!device) { @@ -38,6 +39,12 @@ namespace kernel::filesystem kapi::system::panic("[FILESYSTEM] cannot mount filesystem: no suitable filesystem found on device."); } + auto filesystem::mount(kstd::shared_ptr const & device) -> int + { + m_device = device; + return 0; + } + auto filesystem::root_inode() const -> kstd::shared_ptr const & { return m_root_inode; diff --git a/kernel/src/filesystem/rootfs/filesystem.cpp b/kernel/src/filesystem/rootfs/filesystem.cpp index 37bf588..a7c746e 100644 --- a/kernel/src/filesystem/rootfs/filesystem.cpp +++ b/kernel/src/filesystem/rootfs/filesystem.cpp @@ -1,6 +1,7 @@ #include "kernel/filesystem/rootfs/filesystem.hpp" #include "kapi/devices/device.hpp" + #include "kernel/filesystem/inode.hpp" #include "kernel/filesystem/rootfs/inode.hpp" diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 66aa91e..d611fc9 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -45,7 +45,7 @@ namespace kernel::filesystem auto storage_mgmt = devices::storage::management::get(); if (auto boot_device = storage_mgmt.determine_boot_device()) { - auto boot_root_fs = kernel::filesystem::filesystem::mount(boot_device); + auto boot_root_fs = kernel::filesystem::filesystem::probe_and_mount(boot_device); do_mount_internal("/", root_fs_root_dentry, boot_root_fs); } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 382f12d..8df6767 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -8,8 +8,8 @@ #include "kernel/devices/storage/management.hpp" #include "kernel/filesystem/device_inode.hpp" -#include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/filesystem/file_descriptor_table.hpp" +#include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/open_file_description.hpp" #include "kernel/filesystem/vfs.hpp" #include "kernel/memory.hpp" @@ -131,7 +131,7 @@ auto test_file_lookup() -> void } auto device = storage_mgmt.device_by_major_minor(1, 16); - auto new_filesystem = kernel::filesystem::filesystem::mount(device); + auto new_filesystem = kernel::filesystem::filesystem::probe_and_mount(device); if (vfs.do_mount("/a/b", new_filesystem) != 0) { -- cgit v1.2.3 From 16b854e991bb791694268d09eb696c719cdff42f Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 2 Apr 2026 11:09:13 +0200 Subject: read block_group_descriptors --- kernel/include/kernel/filesystem/ext2/filesystem.hpp | 3 +++ kernel/src/filesystem/ext2/filesystem.cpp | 13 +++++++++++++ 2 files changed, 16 insertions(+) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index f6cd17f..59b9cba 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -3,11 +3,13 @@ #include "kapi/devices/device.hpp" +#include "kernel/filesystem/ext2/block_group_descriptor.hpp" #include "kernel/filesystem/ext2/superblock.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" #include +#include #include #include @@ -25,6 +27,7 @@ namespace kernel::filesystem::ext2 auto get_inode_size() -> size_t; superblock m_superblock; + kstd::vector m_block_group_descriptors; }; } // namespace kernel::filesystem::ext2 diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 0ebb243..96c1589 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -3,12 +3,14 @@ #include "kapi/devices/device.hpp" #include "kernel/devices/block_device_utils.hpp" +#include "kernel/filesystem/ext2/block_group_descriptor.hpp" #include "kernel/filesystem/ext2/inode.hpp" #include "kernel/filesystem/ext2/superblock.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" #include +#include #include #include @@ -47,6 +49,17 @@ namespace kernel::filesystem::ext2 return -1; } + auto const block_size = get_block_size(); + auto const blocks_per_group = m_superblock.blocks_per_group; + auto const num_block_groups = (m_superblock.blocks_count + blocks_per_group - 1) / blocks_per_group; + + m_block_group_descriptors = kstd::vector(num_block_groups); + + auto const block_group_descriptor_table_offset = block_size == 1024 ? 2 * block_size : block_size; + kernel::devices::block_device_utils::read(m_device, m_block_group_descriptors.data(), + block_group_descriptor_table_offset, + num_block_groups * sizeof(block_group_descriptor)); + // TODO BA-FS26 load proper root inode from ext2 metadata // m_root_inode = inode{inode_kind::directory}; -- cgit v1.2.3 From 91db623189133cb14693ae60ee54ac293cec3b54 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 2 Apr 2026 11:33:14 +0200 Subject: remove todos --- kernel/include/kernel/filesystem/ext2/superblock.hpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/superblock.hpp b/kernel/include/kernel/filesystem/ext2/superblock.hpp index 8600b4c..e7e15f2 100644 --- a/kernel/include/kernel/filesystem/ext2/superblock.hpp +++ b/kernel/include/kernel/filesystem/ext2/superblock.hpp @@ -41,11 +41,8 @@ namespace kernel::filesystem::ext2 uint32_t feature_compat; uint32_t feature_incompat; uint32_t feature_ro_compat; - // uint8_t uuid[16]; // TODO BA-FS26 really correct? std::array uuid; - // uint8_t volume_name[16]; // TODO BA-FS26 really correct? std::array volume_name; - // uint8_t last_mounted[64]; // TODO BA-FS26 really correct? std::array last_mounted; uint32_t algorithm_usage_bitmap; @@ -55,14 +52,12 @@ namespace kernel::filesystem::ext2 uint16_t padding1; // Journaling Support - // uint8_t journal_uuid[16]; // TODO BA-FS26 really correct? std::array journal_uuid; uint32_t journal_inum; uint32_t journal_dev; uint32_t last_orphan; // Directory Indexing Support - // uint32_t hash_seed[4]; // TODO BA-FS26 really correct? std::array hash_seed; uint8_t def_hash_version; std::array padding2; -- cgit v1.2.3 From baf63039d5430c0b3b1e6235b561c12f60e97f49 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 2 Apr 2026 15:03:06 +0200 Subject: implement read_inode --- .../filesystem/ext2/block_group_descriptor.hpp | 2 +- .../include/kernel/filesystem/ext2/filesystem.hpp | 4 +++ kernel/include/kernel/filesystem/ext2/inode.hpp | 19 +++++++----- .../filesystem/ext2/linked_directory_entry.hpp | 2 +- .../include/kernel/filesystem/ext2/superblock.hpp | 2 +- kernel/src/filesystem/ext2/filesystem.cpp | 35 +++++++++++++++++----- 6 files changed, 45 insertions(+), 19 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp b/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp index a23c045..2ff91d9 100644 --- a/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp +++ b/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp @@ -6,7 +6,7 @@ namespace kernel::filesystem::ext2 { - struct block_group_descriptor + struct [[gnu::packed]] block_group_descriptor { uint32_t block_bitmap; uint32_t inode_bitmap; diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index 59b9cba..ccee172 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -4,6 +4,7 @@ #include "kapi/devices/device.hpp" #include "kernel/filesystem/ext2/block_group_descriptor.hpp" +#include "kernel/filesystem/ext2/inode.hpp" #include "kernel/filesystem/ext2/superblock.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" @@ -12,6 +13,7 @@ #include #include +#include #include namespace kernel::filesystem::ext2 @@ -23,6 +25,8 @@ namespace kernel::filesystem::ext2 -> kstd::shared_ptr override; private: + auto read_inode(uint32_t inode_number) -> kstd::shared_ptr; + auto get_block_size() -> size_t; auto get_inode_size() -> size_t; diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp index 2c27c17..4284e6f 100644 --- a/kernel/include/kernel/filesystem/ext2/inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/inode.hpp @@ -11,13 +11,8 @@ namespace kernel::filesystem::ext2 { - struct inode : kernel::filesystem::inode + struct [[gnu::packed]] inode_data { - inode(); - - auto read(void * buffer, size_t offset, size_t size) const -> size_t override; - auto write(void const * buffer, size_t offset, size_t size) -> size_t override; - uint16_t mode; uint16_t uid; uint32_t size; @@ -30,15 +25,23 @@ namespace kernel::filesystem::ext2 uint32_t blocks; uint32_t flags; uint32_t osd1; - // uint32_t block[15]; // TODO BA-FS26 really correct? std::array block; // NOLINT(readability-magic-numbers) uint32_t generation; uint32_t file_acl; uint32_t dir_acl; uint32_t faddr; - // uint8_t osd2[12]; // TODO BA-FS26 really correct? std::array osd2; // NOLINT(readability-magic-numbers) }; + + struct inode : kernel::filesystem::inode + { + inode(); + + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + + inode_data m_data{}; + }; } // namespace kernel::filesystem::ext2 #endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp b/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp index 8dd42a1..f44255a 100644 --- a/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp +++ b/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp @@ -6,7 +6,7 @@ namespace kernel::filesystem::ext2 { - struct linked_directory_entry + struct [[gnu::packed]] linked_directory_entry { uint32_t inode; uint16_t rec_len; diff --git a/kernel/include/kernel/filesystem/ext2/superblock.hpp b/kernel/include/kernel/filesystem/ext2/superblock.hpp index e7e15f2..8e57ae7 100644 --- a/kernel/include/kernel/filesystem/ext2/superblock.hpp +++ b/kernel/include/kernel/filesystem/ext2/superblock.hpp @@ -6,7 +6,7 @@ namespace kernel::filesystem::ext2 { - struct superblock + struct [[gnu::packed]] superblock { uint32_t inodes_count; uint32_t blocks_count; diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 96c1589..d650e97 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -21,7 +21,9 @@ namespace kernel::filesystem::ext2 namespace { constexpr size_t SUPERBLOCK_OFFSET = 1024; - constexpr uint16_t EXT2_MAGIC = 0xEF53; + constexpr uint16_t MAGIC_NUMBER = 0xEF53; + + constexpr uint32_t ROOT_INODE_NUMBER = 2; // Mode bits // constexpr uint16_t S_IFMT = 0xF000; @@ -44,7 +46,7 @@ namespace kernel::filesystem::ext2 kernel::devices::block_device_utils::read(m_device, &m_superblock, SUPERBLOCK_OFFSET, sizeof(m_superblock)); - if (m_superblock.magic != EXT2_MAGIC) + if (m_superblock.magic != MAGIC_NUMBER) { return -1; } @@ -60,12 +62,7 @@ namespace kernel::filesystem::ext2 block_group_descriptor_table_offset, num_block_groups * sizeof(block_group_descriptor)); - // TODO BA-FS26 load proper root inode from ext2 metadata - // m_root_inode = inode{inode_kind::directory}; - - // TODO BA-FS26 implement - m_root_inode = kstd::make_shared(); - // devices::block_device_utils::read(device, nullptr, 0, 0); // TODO BA-FS26 just for testing + m_root_inode = read_inode(ROOT_INODE_NUMBER); return 0; } @@ -82,6 +79,28 @@ namespace kernel::filesystem::ext2 return kstd::make_shared(); } + auto filesystem::read_inode(uint32_t inode_number) -> kstd::shared_ptr + { + auto const block_size = get_block_size(); + auto const inodes_per_group = m_superblock.inodes_per_group; + auto const block_group_index = (inode_number - 1) / inodes_per_group; + auto const inode_index_within_group = (inode_number - 1) % inodes_per_group; + + if (block_group_index >= m_block_group_descriptors.size()) + { + return nullptr; + } + + auto const & block_group_descriptor = m_block_group_descriptors.at(block_group_index); + auto const inode_table_start_block = block_group_descriptor.inode_table; + auto const inode_table_offset = static_cast(inode_table_start_block) * block_size; + auto const inode_offset = inode_table_offset + inode_index_within_group * get_inode_size(); + + auto new_inode = kstd::make_shared(); + kernel::devices::block_device_utils::read(m_device, &new_inode->m_data, inode_offset, sizeof(inode_data)); + return new_inode; + } + auto filesystem::get_block_size() -> size_t { return 1024U << m_superblock.log_block_size; -- cgit v1.2.3 From 794de4a7f8dbea164d857ae9e4525536f338518d Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 2 Apr 2026 16:06:40 +0200 Subject: temporary implementation of inode kind --- kernel/include/kernel/filesystem/inode.hpp | 3 ++- kernel/src/filesystem/ext2/filesystem.cpp | 41 +++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 13 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp index d97b5ab..59207df 100644 --- a/kernel/include/kernel/filesystem/inode.hpp +++ b/kernel/include/kernel/filesystem/inode.hpp @@ -25,7 +25,8 @@ namespace kernel::filesystem [[nodiscard]] auto is_regular() const -> bool; [[nodiscard]] auto is_device() const -> bool; - private: + // TODO BA-FS26 improve inode_kind really needed? + public: inode_kind m_kind{inode_kind::regular}; }; } // namespace kernel::filesystem diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index d650e97..31dc6f2 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -26,18 +26,18 @@ namespace kernel::filesystem::ext2 constexpr uint32_t ROOT_INODE_NUMBER = 2; // Mode bits - // constexpr uint16_t S_IFMT = 0xF000; - // constexpr uint16_t S_IFREG = 0x8000; - // constexpr uint16_t S_IFDIR = 0x4000; - - // auto S_ISREG(uint16_t mode) -> bool - // { - // return (mode & S_IFMT) == S_IFREG; - // } - // auto S_ISDIR(uint16_t mode) -> bool - // { - // return (mode & S_IFMT) == S_IFDIR; - // } + constexpr uint16_t S_IFMT = 0xF000; + constexpr uint16_t S_IFREG = 0x8000; + constexpr uint16_t S_IFDIR = 0x4000; + + auto S_ISREG(uint16_t mode) -> bool + { + return (mode & S_IFMT) == S_IFREG; + } + auto S_ISDIR(uint16_t mode) -> bool + { + return (mode & S_IFMT) == S_IFDIR; + } } // namespace auto filesystem::mount(kstd::shared_ptr const & device) -> int @@ -63,6 +63,7 @@ namespace kernel::filesystem::ext2 num_block_groups * sizeof(block_group_descriptor)); m_root_inode = read_inode(ROOT_INODE_NUMBER); + // TODO BA-FS26 check if root inode is valid and is a directory ?? return 0; } @@ -98,6 +99,22 @@ namespace kernel::filesystem::ext2 auto new_inode = kstd::make_shared(); kernel::devices::block_device_utils::read(m_device, &new_inode->m_data, inode_offset, sizeof(inode_data)); + + // TODO BA-FS26 improve inode_kind really needed? or just map it to the mode bits? + if (S_ISREG(new_inode->m_data.mode)) + { + new_inode->m_kind = inode::inode_kind::regular; + } + else if (S_ISDIR(new_inode->m_data.mode)) + { + new_inode->m_kind = inode::inode_kind::directory; + } + else + { + // TODO BA-FS26 really correct?? + return nullptr; + } + return new_inode; } -- cgit v1.2.3 From 82c8a4c16e3af3d62d7211e741b051da900de79c Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 3 Apr 2026 10:16:36 +0200 Subject: first lookup draft --- kernel/src/filesystem/ext2/filesystem.cpp | 48 ++++++++++++++++++++++++++++++- kernel/src/main.cpp | 2 ++ 2 files changed, 49 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 31dc6f2..82fcba9 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -5,11 +5,13 @@ #include "kernel/devices/block_device_utils.hpp" #include "kernel/filesystem/ext2/block_group_descriptor.hpp" #include "kernel/filesystem/ext2/inode.hpp" +#include "kernel/filesystem/ext2/linked_directory_entry.hpp" #include "kernel/filesystem/ext2/superblock.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" #include +#include #include #include @@ -24,6 +26,7 @@ namespace kernel::filesystem::ext2 constexpr uint16_t MAGIC_NUMBER = 0xEF53; constexpr uint32_t ROOT_INODE_NUMBER = 2; + constexpr size_t DIRECT_BLOCK_COUNT = 12; // Mode bits constexpr uint16_t S_IFMT = 0xF000; @@ -67,9 +70,52 @@ namespace kernel::filesystem::ext2 return 0; } - auto filesystem::lookup(kstd::shared_ptr const & /*parent*/, std::string_view name) + auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr { + if (!parent || !parent->is_directory()) + { + return nullptr; + } + + auto * ext2_parent = static_cast(parent.get()); + if (!ext2_parent) + { + return nullptr; + } + + auto const block_size = get_block_size(); + auto const & inode_data = ext2_parent->m_data; + kstd::vector buffer(block_size); + + for (size_t i = 0; i < DIRECT_BLOCK_COUNT && inode_data.block[i] != 0; ++i) + { + kernel::devices::block_device_utils::read(m_device, buffer.data(), inode_data.block[i] * block_size, block_size); + + size_t offset = 0; + while (offset < block_size) + { + auto * entry = reinterpret_cast(buffer.data() + offset); + if (entry->inode == 0) + break; + + // Stop if the directory entry is malformed to avoid overruns/loops. + // if (entry->rec_len < sizeof(linked_directory_entry) || offset + entry->rec_len > block_size) + // { + // break; + // } + + std::string_view entry_name(reinterpret_cast(entry->name.data()), entry->name_len); + if (entry_name == name) + { + return read_inode(entry->inode); + } + + offset += entry->rec_len; + } + } + + return nullptr; // TODO BA-FS26 implement ext2 directory traversal and inode loading if (name == "dev") { diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 8df6767..258c28b 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -117,6 +117,8 @@ auto test_file_lookup() -> void auto vfs = kernel::filesystem::vfs::get(); auto storage_mgmt = kernel::devices::storage::management::get(); + auto ofd_hello = vfs.open("/hello.txt"); + auto ofd1 = vfs.open("/a/b/c"); auto ofd2 = vfs.open("/dev/ram0"); auto ofd3 = vfs.open("/a/d/e"); -- cgit v1.2.3 From 15ea1551e54c36ebac26f21dc156636e326298c6 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 3 Apr 2026 14:29:32 +0200 Subject: fix linked_directory_entry struct --- kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp b/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp index f44255a..76eb6f5 100644 --- a/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp +++ b/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp @@ -12,8 +12,7 @@ namespace kernel::filesystem::ext2 uint16_t rec_len; uint8_t name_len; uint8_t file_type; - uint8_t pad; - std::array name; // NOLINT(readability-magic-numbers) + std::array name; // NOLINT(readability-magic-numbers) }; } // namespace kernel::filesystem::ext2 -- cgit v1.2.3 From 7e6137b2725d5cf2b16f55678dcfb99091f03fe9 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 3 Apr 2026 14:30:20 +0200 Subject: implement map_inode_block_index_to_global_block_number and lookup --- .../include/kernel/filesystem/ext2/filesystem.hpp | 2 + kernel/src/filesystem/ext2/filesystem.cpp | 120 ++++++++++++++++----- 2 files changed, 98 insertions(+), 24 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index ccee172..dea059f 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -26,9 +26,11 @@ namespace kernel::filesystem::ext2 private: auto read_inode(uint32_t inode_number) -> kstd::shared_ptr; + auto map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) -> uint32_t; auto get_block_size() -> size_t; auto get_inode_size() -> size_t; + auto get_inode_block_count(inode_data const & data) -> uint32_t; superblock m_superblock; kstd::vector m_block_group_descriptors; diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 82fcba9..a84414f 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -11,6 +11,7 @@ #include "kernel/filesystem/inode.hpp" #include +#include #include #include @@ -26,7 +27,11 @@ namespace kernel::filesystem::ext2 constexpr uint16_t MAGIC_NUMBER = 0xEF53; constexpr uint32_t ROOT_INODE_NUMBER = 2; + constexpr size_t DIRECT_BLOCK_COUNT = 12; + constexpr size_t INDIRECT_BLOCK_INDEX = DIRECT_BLOCK_COUNT; + constexpr size_t DOUBLY_INDIRECT_BLOCK_INDEX = INDIRECT_BLOCK_INDEX + 1; + constexpr size_t TRIPLY_INDIRECT_BLOCK_INDEX = DOUBLY_INDIRECT_BLOCK_INDEX + 1; // Mode bits constexpr uint16_t S_IFMT = 0xF000; @@ -37,6 +42,7 @@ namespace kernel::filesystem::ext2 { return (mode & S_IFMT) == S_IFREG; } + auto S_ISDIR(uint16_t mode) -> bool { return (mode & S_IFMT) == S_IFDIR; @@ -88,42 +94,29 @@ namespace kernel::filesystem::ext2 auto const & inode_data = ext2_parent->m_data; kstd::vector buffer(block_size); - for (size_t i = 0; i < DIRECT_BLOCK_COUNT && inode_data.block[i] != 0; ++i) + for (uint32_t i = 0; i < get_inode_block_count(inode_data); ++i) { - kernel::devices::block_device_utils::read(m_device, buffer.data(), inode_data.block[i] * block_size, block_size); - - size_t offset = 0; - while (offset < block_size) - { - auto * entry = reinterpret_cast(buffer.data() + offset); - if (entry->inode == 0) - break; + auto const global_block_number = map_inode_block_index_to_global_block_number(i, inode_data); + auto const block_offset = global_block_number * block_size; + kernel::devices::block_device_utils::read(m_device, buffer.data(), block_offset, block_size); - // Stop if the directory entry is malformed to avoid overruns/loops. - // if (entry->rec_len < sizeof(linked_directory_entry) || offset + entry->rec_len > block_size) - // { - // break; - // } + auto const * entry = reinterpret_cast(buffer.data()); + auto bytes_read = 0uz; - std::string_view entry_name(reinterpret_cast(entry->name.data()), entry->name_len); + while (bytes_read < block_size && entry->inode != 0) + { + auto const entry_name = std::string_view{entry->name.data(), entry->name_len}; if (entry_name == name) { return read_inode(entry->inode); } - offset += entry->rec_len; + bytes_read += entry->rec_len; + entry = reinterpret_cast(buffer.data() + bytes_read); } } return nullptr; - // TODO BA-FS26 implement ext2 directory traversal and inode loading - if (name == "dev") - { - // TODO BA-FS26 just for testing - return nullptr; - } - - return kstd::make_shared(); } auto filesystem::read_inode(uint32_t inode_number) -> kstd::shared_ptr @@ -164,6 +157,80 @@ namespace kernel::filesystem::ext2 return new_inode; } + auto filesystem::map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) -> uint32_t + { + if (inode_block_index < DIRECT_BLOCK_COUNT) + { + return data.block.at(inode_block_index); + } + inode_block_index -= DIRECT_BLOCK_COUNT; + + auto const block_size = get_block_size(); + auto const numbers_per_block = block_size / sizeof(uint32_t); + uint32_t block_number_buffer = 0; + + auto const number_of_singly_indirect_blocks = numbers_per_block; + if (inode_block_index < number_of_singly_indirect_blocks) + { + auto const indirect_block_start_offset = data.block.at(INDIRECT_BLOCK_INDEX) * block_size; + auto const direct_block_number_index = inode_block_index; + auto const direct_block_number_offset = + indirect_block_start_offset + direct_block_number_index * sizeof(uint32_t); + kernel::devices::block_device_utils::read(m_device, &block_number_buffer, direct_block_number_offset, + sizeof(uint32_t)); + return block_number_buffer; + } + inode_block_index -= number_of_singly_indirect_blocks; + + auto const number_of_doubly_indirect_blocks = numbers_per_block * numbers_per_block; + if (inode_block_index < number_of_doubly_indirect_blocks) + { + auto const doubly_indirect_block_start_offset = data.block.at(DOUBLY_INDIRECT_BLOCK_INDEX) * block_size; + auto const indirect_block_number_index = inode_block_index / numbers_per_block; + auto const indirect_block_number_offset = + doubly_indirect_block_start_offset + indirect_block_number_index * sizeof(uint32_t); + kernel::devices::block_device_utils::read(m_device, &block_number_buffer, indirect_block_number_offset, + sizeof(uint32_t)); + + auto const indirect_block_start_offset = block_number_buffer * block_size; + auto const direct_block_number_index = inode_block_index % numbers_per_block; + auto const direct_block_number_offset = + indirect_block_start_offset + direct_block_number_index * sizeof(uint32_t); + kernel::devices::block_device_utils::read(m_device, &block_number_buffer, direct_block_number_offset, + sizeof(uint32_t)); + return block_number_buffer; + } + inode_block_index -= number_of_doubly_indirect_blocks; + + auto const number_of_triply_indirect_blocks = numbers_per_block * numbers_per_block * numbers_per_block; + if (inode_block_index < number_of_triply_indirect_blocks) + { + auto const triply_indirect_block_start_offset = data.block.at(TRIPLY_INDIRECT_BLOCK_INDEX) * block_size; + auto const doubly_indirect_block_number_index = inode_block_index / (numbers_per_block * numbers_per_block); + auto const doubly_indirect_block_number_offset = + triply_indirect_block_start_offset + doubly_indirect_block_number_index * sizeof(uint32_t); + kernel::devices::block_device_utils::read(m_device, &block_number_buffer, doubly_indirect_block_number_offset, + sizeof(uint32_t)); + + auto const doubly_indirect_block_start_offset = block_number_buffer * block_size; + auto const indirect_block_number_index = (inode_block_index / numbers_per_block) % numbers_per_block; + auto const indirect_block_number_offset = + doubly_indirect_block_start_offset + indirect_block_number_index * sizeof(uint32_t); + kernel::devices::block_device_utils::read(m_device, &block_number_buffer, indirect_block_number_offset, + sizeof(uint32_t)); + + auto const indirect_block_start_offset = block_number_buffer * block_size; + auto const direct_block_number_index = inode_block_index % numbers_per_block; + auto const direct_block_number_offset = + indirect_block_start_offset + direct_block_number_index * sizeof(uint32_t); + kernel::devices::block_device_utils::read(m_device, &block_number_buffer, direct_block_number_offset, + sizeof(uint32_t)); + return block_number_buffer; + } + + return 0; // TODO BA-FS26 really correct?? + } + auto filesystem::get_block_size() -> size_t { return 1024U << m_superblock.log_block_size; @@ -173,4 +240,9 @@ namespace kernel::filesystem::ext2 { return m_superblock.rev_level == 0 ? 128 : m_superblock.inode_size; } + + auto filesystem::get_inode_block_count(inode_data const & data) -> uint32_t + { + return data.blocks / (2 << m_superblock.log_block_size); + } } // namespace kernel::filesystem::ext2 -- cgit v1.2.3 From fe8706422605e466427ae2727ddb98ce5cd984f6 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 3 Apr 2026 15:38:16 +0200 Subject: refactoring map_inode_block_index_to_global_block_number --- .../include/kernel/filesystem/ext2/filesystem.hpp | 1 + kernel/src/filesystem/ext2/filesystem.cpp | 101 ++++++++++----------- 2 files changed, 49 insertions(+), 53 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index dea059f..9761903 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -27,6 +27,7 @@ namespace kernel::filesystem::ext2 private: auto read_inode(uint32_t inode_number) -> kstd::shared_ptr; auto map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) -> uint32_t; + auto read_block_number_at_index(uint32_t block_number, uint32_t index) -> uint32_t; auto get_block_size() -> size_t; auto get_inode_size() -> size_t; diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index a84414f..56c0b88 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -29,8 +29,8 @@ namespace kernel::filesystem::ext2 constexpr uint32_t ROOT_INODE_NUMBER = 2; constexpr size_t DIRECT_BLOCK_COUNT = 12; - constexpr size_t INDIRECT_BLOCK_INDEX = DIRECT_BLOCK_COUNT; - constexpr size_t DOUBLY_INDIRECT_BLOCK_INDEX = INDIRECT_BLOCK_INDEX + 1; + constexpr size_t SINGLY_INDIRECT_BLOCK_INDEX = DIRECT_BLOCK_COUNT; + constexpr size_t DOUBLY_INDIRECT_BLOCK_INDEX = SINGLY_INDIRECT_BLOCK_INDEX + 1; constexpr size_t TRIPLY_INDIRECT_BLOCK_INDEX = DOUBLY_INDIRECT_BLOCK_INDEX + 1; // Mode bits @@ -167,70 +167,65 @@ namespace kernel::filesystem::ext2 auto const block_size = get_block_size(); auto const numbers_per_block = block_size / sizeof(uint32_t); - uint32_t block_number_buffer = 0; - auto const number_of_singly_indirect_blocks = numbers_per_block; - if (inode_block_index < number_of_singly_indirect_blocks) + auto const block_numbers_per_singly_indirect_block = numbers_per_block; + auto const block_numbers_per_doubly_indirect_block = numbers_per_block * block_numbers_per_singly_indirect_block; + auto const block_numbers_per_triply_indirect_block = numbers_per_block * block_numbers_per_doubly_indirect_block; + + if (inode_block_index < block_numbers_per_singly_indirect_block) { - auto const indirect_block_start_offset = data.block.at(INDIRECT_BLOCK_INDEX) * block_size; - auto const direct_block_number_index = inode_block_index; - auto const direct_block_number_offset = - indirect_block_start_offset + direct_block_number_index * sizeof(uint32_t); - kernel::devices::block_device_utils::read(m_device, &block_number_buffer, direct_block_number_offset, - sizeof(uint32_t)); - return block_number_buffer; + auto const singly_indirect_block_number = data.block.at(SINGLY_INDIRECT_BLOCK_INDEX); + return read_block_number_at_index(singly_indirect_block_number, inode_block_index); } - inode_block_index -= number_of_singly_indirect_blocks; + inode_block_index -= block_numbers_per_singly_indirect_block; - auto const number_of_doubly_indirect_blocks = numbers_per_block * numbers_per_block; - if (inode_block_index < number_of_doubly_indirect_blocks) + if (inode_block_index < block_numbers_per_doubly_indirect_block) { - auto const doubly_indirect_block_start_offset = data.block.at(DOUBLY_INDIRECT_BLOCK_INDEX) * block_size; - auto const indirect_block_number_index = inode_block_index / numbers_per_block; - auto const indirect_block_number_offset = - doubly_indirect_block_start_offset + indirect_block_number_index * sizeof(uint32_t); - kernel::devices::block_device_utils::read(m_device, &block_number_buffer, indirect_block_number_offset, - sizeof(uint32_t)); - - auto const indirect_block_start_offset = block_number_buffer * block_size; - auto const direct_block_number_index = inode_block_index % numbers_per_block; - auto const direct_block_number_offset = - indirect_block_start_offset + direct_block_number_index * sizeof(uint32_t); - kernel::devices::block_device_utils::read(m_device, &block_number_buffer, direct_block_number_offset, - sizeof(uint32_t)); - return block_number_buffer; + auto const doubly_indirect_block_number = data.block.at(DOUBLY_INDIRECT_BLOCK_INDEX); + auto const singly_indirect_block_index_in_doubly_indirect_block = + inode_block_index / block_numbers_per_singly_indirect_block; + auto const singly_indirect_block_number = read_block_number_at_index( + doubly_indirect_block_number, singly_indirect_block_index_in_doubly_indirect_block); + + auto const block_index_in_singly_indirect_block = inode_block_index % block_numbers_per_singly_indirect_block; + return read_block_number_at_index(singly_indirect_block_number, block_index_in_singly_indirect_block); } - inode_block_index -= number_of_doubly_indirect_blocks; + inode_block_index -= block_numbers_per_doubly_indirect_block; - auto const number_of_triply_indirect_blocks = numbers_per_block * numbers_per_block * numbers_per_block; - if (inode_block_index < number_of_triply_indirect_blocks) + if (inode_block_index < block_numbers_per_triply_indirect_block) { - auto const triply_indirect_block_start_offset = data.block.at(TRIPLY_INDIRECT_BLOCK_INDEX) * block_size; - auto const doubly_indirect_block_number_index = inode_block_index / (numbers_per_block * numbers_per_block); - auto const doubly_indirect_block_number_offset = - triply_indirect_block_start_offset + doubly_indirect_block_number_index * sizeof(uint32_t); - kernel::devices::block_device_utils::read(m_device, &block_number_buffer, doubly_indirect_block_number_offset, - sizeof(uint32_t)); - - auto const doubly_indirect_block_start_offset = block_number_buffer * block_size; - auto const indirect_block_number_index = (inode_block_index / numbers_per_block) % numbers_per_block; - auto const indirect_block_number_offset = - doubly_indirect_block_start_offset + indirect_block_number_index * sizeof(uint32_t); - kernel::devices::block_device_utils::read(m_device, &block_number_buffer, indirect_block_number_offset, - sizeof(uint32_t)); - - auto const indirect_block_start_offset = block_number_buffer * block_size; - auto const direct_block_number_index = inode_block_index % numbers_per_block; - auto const direct_block_number_offset = - indirect_block_start_offset + direct_block_number_index * sizeof(uint32_t); - kernel::devices::block_device_utils::read(m_device, &block_number_buffer, direct_block_number_offset, - sizeof(uint32_t)); - return block_number_buffer; + auto const triply_indirect_block_number = data.block.at(TRIPLY_INDIRECT_BLOCK_INDEX); + auto const doubly_indirect_block_index_in_triply_indirect_block = + inode_block_index / block_numbers_per_doubly_indirect_block; + auto const doubly_indirect_block_number = read_block_number_at_index( + triply_indirect_block_number, doubly_indirect_block_index_in_triply_indirect_block); + + auto const remaining_block_numbers = inode_block_index % block_numbers_per_doubly_indirect_block; + + auto const singly_indirect_block_index_in_doubly_indirect_block = + remaining_block_numbers / block_numbers_per_singly_indirect_block; + auto const singly_indirect_block_number = read_block_number_at_index( + doubly_indirect_block_number, singly_indirect_block_index_in_doubly_indirect_block); + + auto const block_index_in_singly_indirect_block = + remaining_block_numbers % block_numbers_per_singly_indirect_block; + return read_block_number_at_index(singly_indirect_block_number, block_index_in_singly_indirect_block); } return 0; // TODO BA-FS26 really correct?? } + auto filesystem::read_block_number_at_index(uint32_t block_number, uint32_t index) -> uint32_t + { + uint32_t block_number_buffer = 0; + + auto const block_start_offset = block_number * get_block_size(); + auto const number_start_address = block_start_offset + index * sizeof(uint32_t); + kernel::devices::block_device_utils::read(m_device, &block_number_buffer, number_start_address, sizeof(uint32_t)); + + return block_number_buffer; + } + auto filesystem::get_block_size() -> size_t { return 1024U << m_superblock.log_block_size; -- cgit v1.2.3 From 725116d22e850c502e6cb8d42b100da1080dfec0 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 6 Apr 2026 10:35:45 +0200 Subject: Add file system pointer to ext2 inode --- kernel/include/kernel/filesystem/ext2/inode.hpp | 5 ++++- kernel/src/filesystem/ext2/filesystem.cpp | 2 +- kernel/src/filesystem/ext2/inode.cpp | 12 ++++++++++-- 3 files changed, 15 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp index 4284e6f..9318008 100644 --- a/kernel/include/kernel/filesystem/ext2/inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/inode.hpp @@ -11,6 +11,8 @@ namespace kernel::filesystem::ext2 { + struct filesystem; + struct [[gnu::packed]] inode_data { uint16_t mode; @@ -35,12 +37,13 @@ namespace kernel::filesystem::ext2 struct inode : kernel::filesystem::inode { - inode(); + explicit inode(filesystem * fs); auto read(void * buffer, size_t offset, size_t size) const -> size_t override; auto write(void const * buffer, size_t offset, size_t size) -> size_t override; inode_data m_data{}; + filesystem * m_filesystem; }; } // namespace kernel::filesystem::ext2 diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 56c0b88..514bb59 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -136,7 +136,7 @@ namespace kernel::filesystem::ext2 auto const inode_table_offset = static_cast(inode_table_start_block) * block_size; auto const inode_offset = inode_table_offset + inode_index_within_group * get_inode_size(); - auto new_inode = kstd::make_shared(); + auto new_inode = kstd::make_shared(this); kernel::devices::block_device_utils::read(m_device, &new_inode->m_data, inode_offset, sizeof(inode_data)); // TODO BA-FS26 improve inode_kind really needed? or just map it to the mode bits? diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index b75969a..4d36e66 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -1,14 +1,22 @@ #include "kernel/filesystem/ext2/inode.hpp" +#include "kapi/system.hpp" + #include "kernel/filesystem/inode.hpp" #include namespace kernel::filesystem::ext2 { - inode::inode() + inode::inode(filesystem * fs) : kernel::filesystem::inode(inode_kind::regular) - {} + , m_filesystem(fs) + { + if (!m_filesystem) + { + kapi::system::panic("[EXT2] ext2::inode constructed with filesystem null pointer"); + } + } auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t { -- cgit v1.2.3 From 4a2d4fb3ab38a64c4b10832f5a6318b7240829cc Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 6 Apr 2026 11:40:12 +0200 Subject: Implement read data in ext2 inode --- .../include/kernel/filesystem/ext2/filesystem.hpp | 5 ++-- kernel/include/kernel/filesystem/filesystem.hpp | 1 + kernel/src/filesystem/ext2/inode.cpp | 33 ++++++++++++++++++++-- kernel/src/filesystem/filesystem.cpp | 5 ++++ 4 files changed, 39 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index 9761903..762f590 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -24,12 +24,13 @@ namespace kernel::filesystem::ext2 auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; + auto get_block_size() -> size_t; + auto map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) -> uint32_t; + private: auto read_inode(uint32_t inode_number) -> kstd::shared_ptr; - auto map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) -> uint32_t; auto read_block_number_at_index(uint32_t block_number, uint32_t index) -> uint32_t; - auto get_block_size() -> size_t; auto get_inode_size() -> size_t; auto get_inode_block_count(inode_data const & data) -> uint32_t; diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index 1c45377..0f9de9f 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -22,6 +22,7 @@ namespace kernel::filesystem virtual auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr = 0; [[nodiscard]] auto root_inode() const -> kstd::shared_ptr const &; + [[nodiscard]] auto device() const -> kstd::shared_ptr const &; protected: kstd::shared_ptr m_root_inode{}; diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index 4d36e66..7f4cf69 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -2,9 +2,13 @@ #include "kapi/system.hpp" +#include "kernel/devices/block_device_utils.hpp" +#include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/filesystem/inode.hpp" +#include #include +#include namespace kernel::filesystem::ext2 { @@ -18,10 +22,33 @@ namespace kernel::filesystem::ext2 } } - auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t + auto inode::read(void * buffer, size_t offset, size_t size) const -> size_t { - // TODO BA-FS26 implement - return 0; + auto block_index = offset / m_filesystem->get_block_size(); + auto in_block_offset = offset % m_filesystem->get_block_size(); + + auto bytes_read = 0uz; + + while (bytes_read < size) + { + auto const block_number = m_filesystem->map_inode_block_index_to_global_block_number(block_index, m_data); + if (block_number == 0) // TODO BA-FS26 really correct? + { + break; + } + + auto const block_start_offset = block_number * m_filesystem->get_block_size(); + auto const read_offset = block_start_offset + in_block_offset; + auto const bytes_to_read = std::min(size - bytes_read, m_filesystem->get_block_size() - in_block_offset); + + bytes_read += kernel::devices::block_device_utils::read( + m_filesystem->device(), static_cast(buffer) + bytes_read, read_offset, bytes_to_read); + + block_index++; + in_block_offset = 0; // After the first block, we always start at the beginning of the block + } + + return bytes_read; } auto inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index a06eb80..26c57b6 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -49,4 +49,9 @@ namespace kernel::filesystem { return m_root_inode; } + + auto filesystem::device() const -> kstd::shared_ptr const & + { + return m_device; + } } // namespace kernel::filesystem \ No newline at end of file -- cgit v1.2.3 From bf90441a49d9fa2ab3a1c315679f97289cb33dbe Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 6 Apr 2026 11:41:23 +0200 Subject: Add test for reading file --- kernel/src/main.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 258c28b..186d32e 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -23,6 +23,7 @@ #include #include +#include using namespace kstd::units_literals; @@ -119,6 +120,14 @@ auto test_file_lookup() -> void auto ofd_hello = vfs.open("/hello.txt"); + kstd::vector buffer(64); + auto number_of_read_bytes = ofd_hello->read(buffer.data(), buffer.size()); + kstd::println("read bytes: {}", number_of_read_bytes); + kstd::println("buffer: {::#04x}", buffer); + + std::string_view hello_str{reinterpret_cast(buffer.data()), number_of_read_bytes}; + kstd::println("hello_str: {}", hello_str); + auto ofd1 = vfs.open("/a/b/c"); auto ofd2 = vfs.open("/dev/ram0"); auto ofd3 = vfs.open("/a/d/e"); -- cgit v1.2.3 From 2240b9a36e4a9f6f8291c9271e6aac8f5536dbd7 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 7 Apr 2026 22:13:49 +0200 Subject: refactoring --- kernel/include/kernel/filesystem/ext2/filesystem.hpp | 2 +- kernel/src/filesystem/device_inode.cpp | 4 +--- kernel/src/filesystem/ext2/filesystem.cpp | 2 -- kernel/src/filesystem/vfs.cpp | 1 + kernel/src/main.cpp | 2 -- 5 files changed, 3 insertions(+), 8 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index 762f590..abab0a6 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -34,7 +34,7 @@ namespace kernel::filesystem::ext2 auto get_inode_size() -> size_t; auto get_inode_block_count(inode_data const & data) -> uint32_t; - superblock m_superblock; + superblock m_superblock; // TODO BA-FS26 initialize kstd::vector m_block_group_descriptors; }; } // namespace kernel::filesystem::ext2 diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp index af8cecc..397a0fd 100644 --- a/kernel/src/filesystem/device_inode.cpp +++ b/kernel/src/filesystem/device_inode.cpp @@ -1,14 +1,12 @@ #include "kernel/filesystem/device_inode.hpp" +#include "kapi/devices/device.hpp" #include "kapi/system.hpp" #include "kernel/devices/block_device_utils.hpp" -#include "kapi/devices/device.hpp" #include "kernel/filesystem/inode.hpp" -#include #include -#include #include diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 514bb59..d7c989c 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -11,8 +11,6 @@ #include "kernel/filesystem/inode.hpp" #include -#include -#include #include #include diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index d611fc9..f9a051a 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -74,6 +74,7 @@ namespace kernel::filesystem return nullptr; } + // TODO BA-FS26 implement unmount auto vfs::do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> int { if (!filesystem) diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 186d32e..a2c531f 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -88,8 +88,6 @@ auto test_file_description_manually() -> void auto test_device_with_vfs() -> void { - // TODO BA-FS26 - auto vfs = kernel::filesystem::vfs::get(); auto ofd = vfs.open("/dev/ram0"); if (!ofd) -- cgit v1.2.3 From dd330e7a05905713acfa87ec109956bfe78f78c4 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 09:31:32 +0200 Subject: add descriptions, some refactoring --- .../include/kernel/devices/block_device_utils.hpp | 29 +++++++++++++- kernel/include/kernel/filesystem/dentry.hpp | 46 ++++++++++++++++++++++ .../include/kernel/filesystem/devfs/filesystem.hpp | 18 +++++++++ kernel/include/kernel/filesystem/devfs/inode.hpp | 22 +++++++++++ kernel/include/kernel/filesystem/device_inode.hpp | 31 +++++++++++++++ .../filesystem/ext2/block_group_descriptor.hpp | 3 ++ .../include/kernel/filesystem/ext2/filesystem.hpp | 29 +++++++++++++- kernel/include/kernel/filesystem/ext2/inode.hpp | 27 +++++++++++++ .../filesystem/ext2/linked_directory_entry.hpp | 3 ++ .../include/kernel/filesystem/ext2/superblock.hpp | 3 ++ .../kernel/filesystem/file_descriptor_table.hpp | 34 ++++++++++++++++ kernel/include/kernel/filesystem/filesystem.hpp | 37 +++++++++++++++++ kernel/include/kernel/filesystem/inode.hpp | 44 +++++++++++++++++++++ kernel/include/kernel/filesystem/mount.hpp | 28 ++++++++++++- kernel/include/kernel/filesystem/mount_table.hpp | 16 +++++++- .../kernel/filesystem/open_file_description.hpp | 28 +++++++++++++ .../kernel/filesystem/rootfs/filesystem.hpp | 18 +++++++++ kernel/include/kernel/filesystem/rootfs/inode.hpp | 34 ++++++++++++++++ kernel/include/kernel/filesystem/vfs.hpp | 31 +++++++++++++++ kernel/src/filesystem/ext2/filesystem.cpp | 12 +++++- kernel/src/filesystem/ext2/inode.cpp | 2 +- kernel/src/filesystem/filesystem.cpp | 3 +- kernel/src/filesystem/mount.cpp | 2 +- kernel/src/filesystem/mount_table.cpp | 2 +- kernel/src/filesystem/vfs.cpp | 19 +++++---- 25 files changed, 500 insertions(+), 21 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/devices/block_device_utils.hpp b/kernel/include/kernel/devices/block_device_utils.hpp index 5e862ba..7b1daec 100644 --- a/kernel/include/kernel/devices/block_device_utils.hpp +++ b/kernel/include/kernel/devices/block_device_utils.hpp @@ -9,7 +9,34 @@ namespace kernel::devices::block_device_utils { - auto read(kstd::shared_ptr const & device, void * buffer, size_t offset, size_t size) -> size_t; + /** + @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 Reads data from a @p device into a @p buffer, starting at a specific @p offset and for a given @p size. + @warning Panics if @p buffer or @p device is null. + @param device The block device to read from. + @param buffer The buffer to read data into. + @param offset The offset on the block device to start reading from. + @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 const & device, void * buffer, size_t offset, size_t size) + -> size_t; + + /** + @brief Writes data from a @p buffer to a @p device, starting at a specific @p offset and for a given @p size. + @warning Panics if @p buffer or @p device is null. + @param device The block device to write to. + @param buffer The buffer to write data from. + @param offset The offset on the block device to start writing to. + @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 const & device, void const * buffer, size_t offset, size_t size) -> size_t; } // namespace kernel::devices::block_device_utils diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index fc85a7d..72d758f 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -12,23 +12,69 @@ namespace kernel::filesystem { + /** + @brief Represents a directory entry (dentry) in the filesystem. A dentry is a node in the directory tree that + represents a file or directory. It contains a reference to its parent dentry, a reference to the associated real + filesystem inode, and a list of child dentries. + */ struct dentry { + /** + @brief Flags for the dentry. + */ enum class dentry_flags : uint32_t { dcache_mounted = 1 << 15 }; + /** + @brief Create a dentry with the given @p parent, associated @p node, and optional @p name. The dentry is initialized + with the provided parent and inode, and the name is stored for lookup purposes. + */ dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & node, std::string_view name = {}); + /** + @brief Get the associated inode. + @return A reference to the associated inode. + */ [[nodiscard]] auto get_inode() const -> kstd::shared_ptr const &; + + /** + @brief Get the parent dentry. + @return A reference to the parent dentry. + */ [[nodiscard]] auto get_parent() const -> kstd::shared_ptr const &; + /** + @brief Add a @p child dentry. + @param child The child dentry to add. + */ auto add_child(kstd::shared_ptr const & child) -> void; + + /** + @brief Find a child dentry by @p name. + @param name The name of the child dentry to find. + @return A pointer to the found child dentry, or a null pointer if not found. + */ [[nodiscard]] auto find_child(std::string_view name) const -> kstd::shared_ptr; + /** + @brief Set a @p flag for the dentry. + @param flag The flag to set. + */ auto set_flag(dentry_flags flag) -> void; + + /** + @brief Unset a @p flag for the dentry. + @param flag The flag to unset. + */ auto unset_flag(dentry_flags flag) -> void; + + /** + @brief Check if the dentry has a specific @p flag. + @param flag The flag to check. + @return True if the dentry has the flag, false otherwise. + */ [[nodiscard]] auto has_flag(dentry_flags flag) const -> bool; private: diff --git a/kernel/include/kernel/filesystem/devfs/filesystem.hpp b/kernel/include/kernel/filesystem/devfs/filesystem.hpp index 3edeabb..60c39cf 100644 --- a/kernel/include/kernel/filesystem/devfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/devfs/filesystem.hpp @@ -13,9 +13,27 @@ namespace kernel::filesystem::devfs { + /** + @brief A filesystem for managing device nodes in the virtual filesystem. This filesystem provides a way to represent + devices as files in the /dev directory, allowing user-space applications to interact with devices using standard file + operations. The devfs filesystem dynamically creates inodes for devices registered in the system, enabling seamless + access to device functionality through the filesystem interface. + */ struct filesystem : kernel::filesystem::filesystem { + /** + @brief Initializes the devfs instance and builds the device inode table. + @param device Backing device passed by the generic filesystem interface (not required by devfs). + @return 0 on success, -1 on failure. + */ auto mount(kstd::shared_ptr const & device) -> int override; + + /** + @brief Looks up an inode by @p name within a @p parent directory. + @param parent The parent directory inode. + @param name The name of the inode to look up. + @return A pointer to the found inode, or a null pointer if not found. + */ auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; diff --git a/kernel/include/kernel/filesystem/devfs/inode.hpp b/kernel/include/kernel/filesystem/devfs/inode.hpp index 9c11edf..c117bd2 100644 --- a/kernel/include/kernel/filesystem/devfs/inode.hpp +++ b/kernel/include/kernel/filesystem/devfs/inode.hpp @@ -7,11 +7,33 @@ namespace kernel::filesystem::devfs { + /** + @brief Inode implementation for the devfs filesystem. + This inode represents root device node in the /dev directory. + */ struct inode : kernel::filesystem::inode { + /** + @brief Create a devfs inode. The inode is initialized with the appropriate kind (directory). + */ inode(); + /** + @brief Reads from the devfs directory inode. + @param buffer Destination buffer. + @param offset Read offset in bytes. + @param size Number of bytes requested. + @return Number of bytes read (always 0 because this inode does not expose file data). + */ auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + + /** + @brief Writes to the devfs directory inode. + @param buffer Source buffer. + @param offset Write offset in bytes. + @param size Number of bytes requested. + @return Number of bytes written (always 0 because writes are not supported for this inode). + */ auto write(void const * buffer, size_t offset, size_t size) -> size_t override; }; } // namespace kernel::filesystem::devfs diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index 18a98f5..c33be2a 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -2,6 +2,7 @@ #define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP #include "kapi/devices/device.hpp" + #include "kernel/filesystem/inode.hpp" #include @@ -10,13 +11,43 @@ namespace kernel::filesystem { + /** + @brief Inode implementation for device inodes in the filesystem. This inode represents a device file that provides + access to a device registered in the system. The device inode allows reading from and writing to the associated + device. + */ struct device_inode : inode { + /** + @brief Create a device inode with the given @p device. + @param device The device to associate with the inode. + */ explicit device_inode(kstd::shared_ptr const & device); + /** + @brief Read data from the device inode (and in the background from the associated device) into a @p buffer, starting + at @p offset and reading @p size bytes. + @param buffer The buffer to read data into. + @param offset The offset to read from. + @param size The number of bytes to read. + @return The number of bytes read. + */ auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + + /** + @brief Write data to the device inode (and in the background from the associated device) from a @p buffer, starting + at @p offset and writing @p size bytes. + @param buffer The buffer containing data to write. + @param offset The offset to write to. + @param size The number of bytes to write. + @return The number of bytes written. + */ auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + /** + @brief Get the associated device. + @return A reference to the associated device. + */ [[nodiscard]] auto device() const -> kstd::shared_ptr const &; private: diff --git a/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp b/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp index 2ff91d9..7fbba3f 100644 --- a/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp +++ b/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp @@ -6,6 +6,9 @@ namespace kernel::filesystem::ext2 { + /** + @brief Represents a block group descriptor in the ext2 filesystem. + */ struct [[gnu::packed]] block_group_descriptor { uint32_t block_bitmap; diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index abab0a6..32374dc 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -18,13 +18,40 @@ namespace kernel::filesystem::ext2 { + /** + @brief A filesystem implementation for the ext2 filesystem format. This class provides methods for mounting an ext2 + filesystem, and looking up inodes. + */ struct filesystem : kernel::filesystem::filesystem { + /** + @brief Initializes the ext2 filesystem with the given @p device. + @param device The device to mount. + @return 0 on success, negative error code on failure. + */ auto mount(kstd::shared_ptr const & device) -> int override; + + /** + @brief Looks up an inode by @p name within a @p parent directory. + @param parent The parent directory inode. + @param name The name of the inode to look up. + @return A pointer to the found inode, or a null pointer if not found. + */ auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; + /** + @brief Gets the size of a block in the filesystem. + @return The size of a block in bytes. + */ auto get_block_size() -> size_t; + + /** + @brief Maps an inode block index to a global block number. + @param inode_block_index The index of the block within the inode. + @param data The inode data. + @return The global block number. + */ auto map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) -> uint32_t; private: @@ -34,7 +61,7 @@ namespace kernel::filesystem::ext2 auto get_inode_size() -> size_t; auto get_inode_block_count(inode_data const & data) -> uint32_t; - superblock m_superblock; // TODO BA-FS26 initialize + superblock m_superblock{}; kstd::vector m_block_group_descriptors; }; } // namespace kernel::filesystem::ext2 diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp index 9318008..a1645cd 100644 --- a/kernel/include/kernel/filesystem/ext2/inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/inode.hpp @@ -13,6 +13,9 @@ namespace kernel::filesystem::ext2 { struct filesystem; + /** + @brief Represents the data associated with an ext2 inode. + */ struct [[gnu::packed]] inode_data { uint16_t mode; @@ -37,12 +40,36 @@ namespace kernel::filesystem::ext2 struct inode : kernel::filesystem::inode { + /** + @brief Create an ext2 inode associated with the given filesystem. + */ explicit inode(filesystem * fs); + /** + @brief Reads from the ext2 inode into a @p buffer, starting at the specified @p offset and for a given @p size. + @param buffer Destination buffer. + @param offset Read offset in bytes. + @param size Number of bytes requested. + @return Number of bytes read. + */ auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + + /** + @brief Writes to the ext2 inode into a @p buffer, starting at the specified @p offset and for a given @p size. + @warning This method is not implemented yet and will panic if called. + @param buffer Source buffer. + @param offset Write offset in bytes. + @param size Number of bytes requested. + @return Number of bytes written. + */ auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + /** + @brief The raw inode data as read from the disk. + */ inode_data m_data{}; + + private: filesystem * m_filesystem; }; } // namespace kernel::filesystem::ext2 diff --git a/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp b/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp index 76eb6f5..4097cbb 100644 --- a/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp +++ b/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp @@ -6,6 +6,9 @@ namespace kernel::filesystem::ext2 { + /** + @brief Represents a linked directory entry in the ext2 filesystem. + */ struct [[gnu::packed]] linked_directory_entry { uint32_t inode; diff --git a/kernel/include/kernel/filesystem/ext2/superblock.hpp b/kernel/include/kernel/filesystem/ext2/superblock.hpp index 8e57ae7..41ad935 100644 --- a/kernel/include/kernel/filesystem/ext2/superblock.hpp +++ b/kernel/include/kernel/filesystem/ext2/superblock.hpp @@ -6,6 +6,9 @@ namespace kernel::filesystem::ext2 { + /** + @brief Represents the superblock in the ext2 filesystem. + */ struct [[gnu::packed]] superblock { uint32_t inodes_count; diff --git a/kernel/include/kernel/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/filesystem/file_descriptor_table.hpp index 91e2960..5d52c19 100644 --- a/kernel/include/kernel/filesystem/file_descriptor_table.hpp +++ b/kernel/include/kernel/filesystem/file_descriptor_table.hpp @@ -8,15 +8,49 @@ namespace kernel::filesystem { + /** + @brief A table for managing file descriptors in the filesystem. This class provides methods for adding, retrieving, + and removing open file descriptions. + */ struct file_descriptor_table { + /** + @brief Initialize the global file descriptor table. This method creates the singleton instance of the file + descriptor table. + @warning Panics if called more than once. + */ auto static init() -> void; + + /** + @brief Get the global file descriptor table instance. + @return A reference to the global file descriptor table. + @warning Panics if the file descriptor table has not been initialized. + */ auto static get() -> file_descriptor_table &; + /** + @brief Destructor for the file descriptor table. + */ ~file_descriptor_table() = default; + /** + @brief Add a file to the descriptor table. + @param f The file description to add. + @return The file descriptor index assigned to the file, or -1 on failure. + */ auto add_file(kstd::shared_ptr const & f) -> int; + + /** + @brief Get a file from the descriptor table. + @param fd The file descriptor index to retrieve. + @return A pointer to the requested file description, or a null pointer if not found. + */ [[nodiscard]] auto get_file(int fd) const -> kstd::shared_ptr; + + /** + @brief Remove a file from the descriptor table. + @param fd The file descriptor index to remove. + */ auto remove_file(int fd) -> void; private: diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index 0f9de9f..f855380 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -12,16 +12,53 @@ namespace kernel::filesystem { + /** + @brief A base class for implementing filesystems in the kernel. This class provides a common interface for managing + files and directories within the virtual filesystem. + */ struct filesystem { + /** + @brief Virtual destructor for the filesystem. + */ virtual ~filesystem() = default; + /** + @brief Probes the given @p device to determine if it contains a recognizable filesystem, and if so, mounts it and + returns a pointer to the mounted filesystem instance. This method iterates through known filesystem types and + attempts to initialize it with the device until the mount was successful or all types have been tried. + @param device The device to probe and mount. + @return A pointer to the mounted filesystem instance if successful, or a null pointer if no recognizable filesystem + is found on the device. + @warning Panics if @p device is null. + */ auto static probe_and_mount(kstd::shared_ptr const & device) -> kstd::shared_ptr; + /** + @brief Initializes the filesystem with the given @p device. + @param device The device to mount. + @return 0 on success, or a negative error code on failure. + */ virtual auto mount(kstd::shared_ptr const & device) -> int; + + /** + @brief Looks up a child inode within the given @p parent inode with the specified @p name. This method must be + implemented by concrete filesystem subclasses to provide the logic for traversing the filesystem structure and + finding the requested inode. + @param parent The parent inode. + @param name The name of the child inode to look up. + @return A pointer to the requested child inode, or a null pointer if not found. + */ virtual auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr = 0; + /** + @brief Returns a reference to the root inode of the filesystem. + */ [[nodiscard]] auto root_inode() const -> kstd::shared_ptr const &; + + /** + @brief Returns a reference to the device associated with the filesystem. + */ [[nodiscard]] auto device() const -> kstd::shared_ptr const &; protected: diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp index 59207df..7237184 100644 --- a/kernel/include/kernel/filesystem/inode.hpp +++ b/kernel/include/kernel/filesystem/inode.hpp @@ -5,8 +5,14 @@ namespace kernel::filesystem { + /** + @brief Represents an inode in the filesystem. + */ struct inode { + /** + @brief Represents the kind of an inode. + */ enum class inode_kind { regular, @@ -14,15 +20,53 @@ namespace kernel::filesystem device }; + /** + @brief Create an inode with the given @p kind. + @param kind The kind of the inode. + */ explicit inode(inode_kind kind); + /** + @brief Virtual destructor for the inode. + */ virtual ~inode() = default; + /** + @brief Reads from the inode into a @p buffer, starting at the specified @p offset and for a given @p size. This + method must be implemented by concrete inode subclasses. + @param buffer Destination buffer. + @param offset Read offset in bytes. + @param size Number of bytes requested. + @return Number of bytes read. + */ virtual auto read(void * buffer, size_t offset, size_t size) const -> size_t = 0; + + /** + @brief Writes to the inode into a @p buffer, starting at the specified @p offset and for a given @p size. This + method must be implemented by concrete inode subclasses. + @param buffer Source buffer. + @param offset Write offset in bytes. + @param size Number of bytes to write. + @return Number of bytes written. + */ virtual auto write(void const * buffer, size_t offset, size_t size) -> size_t = 0; + /** + @brief Returns whether the inode is a directory. + @return true if the inode is a directory, false otherwise. + */ [[nodiscard]] auto is_directory() const -> bool; + + /** + @brief Returns whether the inode is a regular file. + @return true if the inode is a regular file, false otherwise. + */ [[nodiscard]] auto is_regular() const -> bool; + + /** + @brief Returns whether the inode is a device. + @return true if the inode is a device, false otherwise. + */ [[nodiscard]] auto is_device() const -> bool; // TODO BA-FS26 improve inode_kind really needed? diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index a054750..3e3c69f 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -11,15 +11,41 @@ namespace kernel::filesystem { + /** + @brief Represents a mounted filesystem in the kernel. + */ struct mount { + /** + @brief Creates a mount for the given @p filesystem at the specified @p mount_path. The @p mount_dentry represents + the dentry where the filesystem is mounted, and the @p root_dentry represents the root dentry of the mounted + filesystem. + @param mount_dentry The dentry where the filesystem is mounted. + @param root_dentry The root dentry of the mounted filesystem. + @param fs The filesystem instance being mounted. + @param mount_path The path at which the filesystem is mounted. + */ mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & root_dentry, kstd::shared_ptr const & fs, std::string_view mount_path); - [[nodiscard]] auto get_mount_dentry() const -> kstd::shared_ptr; + /** + @brief Get the dentry where the filesystem is mounted. + */ + [[nodiscard]] auto get_mount_dentry() const -> kstd::shared_ptr const &; + + /** + @brief Get the root dentry of the mounted filesystem. + */ [[nodiscard]] auto root_dentry() const -> kstd::shared_ptr const &; + /** + @brief Get the filesystem instance being mounted. + */ [[nodiscard]] auto get_filesystem() const -> kstd::shared_ptr const &; + + /** + @brief Get the path at which the filesystem is mounted. + */ [[nodiscard]] auto get_mount_path() const -> std::string_view; private: diff --git a/kernel/include/kernel/filesystem/mount_table.hpp b/kernel/include/kernel/filesystem/mount_table.hpp index 6dc2218..a8ef59e 100644 --- a/kernel/include/kernel/filesystem/mount_table.hpp +++ b/kernel/include/kernel/filesystem/mount_table.hpp @@ -10,11 +10,23 @@ namespace kernel::filesystem { + /** + @brief A table for managing mounted filesystems in the kernel. + */ struct mount_table { - public: - void add_mount(kstd::shared_ptr); + /** + @brief Adds a mount to the table. + @param mount The mount to add. + */ + void add_mount(kstd::shared_ptr const & mount); + /** + @brief Finds the mount with the longest prefix matching the given @p path. This method is used to determine which + mounted filesystem should handle a given path lookup. + @param path The path to match against the mount paths in the table. + @return A pointer to the mount with the longest matching prefix, or a null pointer if no mount matches the path. + */ [[nodiscard]] auto find_longest_prefix_mount(std::string_view path) const -> kstd::shared_ptr; private: diff --git a/kernel/include/kernel/filesystem/open_file_description.hpp b/kernel/include/kernel/filesystem/open_file_description.hpp index 45719cf..ed878a7 100644 --- a/kernel/include/kernel/filesystem/open_file_description.hpp +++ b/kernel/include/kernel/filesystem/open_file_description.hpp @@ -9,13 +9,41 @@ namespace kernel::filesystem { + /** + @brief Represents an open file description in the filesystem. This class encapsulates the state of an open file, + including a reference to the associated inode and the current file offset. + */ struct open_file_description { + /** + @brief Constructs an open file description for the given @p inode. + @param inode The inode to associate with the open file description. + */ explicit open_file_description(kstd::shared_ptr const & inode); + /** + @brief Destructor for the open file description. + */ ~open_file_description() = default; + /** + @brief Reads data from the open file description into a @p buffer, starting at the current file offset and for a + given + @p size. The file offset is advanced by the number of bytes read. + @param buffer The buffer to read data into. + @param size The number of bytes to read. + @return The number of bytes read. + */ auto read(void * buffer, size_t size) -> size_t; + + /** + @brief Writes data to the open file description from a @p buffer, starting at the current file offset and for a + given + @p size. The file offset is advanced by the number of bytes written. + @param buffer The buffer to write data from. + @param size The number of bytes to write. + @return The number of bytes written. + */ auto write(void const * buffer, size_t size) -> size_t; private: diff --git a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp index 7931d87..b7e7c6f 100644 --- a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp @@ -14,9 +14,27 @@ namespace kernel::filesystem::rootfs { + /** + @brief A filesystem for the root filesystem. This filesystem provides access to the root directory and its contents, + which are typically populated by the init process during system startup. The rootfs filesystem serves as the top-level + directory in the filesystem hierarchy. It is responsible for providing a stable and consistent interface to the root + directory. + */ struct filesystem : kernel::filesystem::filesystem { + /** + @brief Initializes the rootfs filesystem with the given @p device. + @param device The device to mount (not required by rootfs). + @return 0 on success, negative error code on failure. + */ auto mount(kstd::shared_ptr const & device) -> int override; + + /** + @brief Looks up an inode by @p name within a @p parent directory. + @param parent The parent directory inode. + @param name The name of the inode to look up. + @return A pointer to the found inode, or a null pointer if not found. + */ auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; }; diff --git a/kernel/include/kernel/filesystem/rootfs/inode.hpp b/kernel/include/kernel/filesystem/rootfs/inode.hpp index 24d3e6b..469e47a 100644 --- a/kernel/include/kernel/filesystem/rootfs/inode.hpp +++ b/kernel/include/kernel/filesystem/rootfs/inode.hpp @@ -13,14 +13,48 @@ namespace kernel::filesystem::rootfs { + /** + @brief Represents an inode in the rootfs filesystem. This inode represents a directory in the root filesystem and + maintains a list of child inodes corresponding to files and subdirectories within the root directory. The rootfs inode + provides methods for reading and writing data (which are no-ops for the root directory), as well as adding and looking + up child inodes by name. + */ struct inode : kernel::filesystem::inode { + /** + @brief Create a rootfs inode. The inode is initialized with the appropriate kind (directory). + */ inode(); + /** + @brief Reads from the rootfs directory inode. + @param buffer Destination buffer. + @param offset Read offset in bytes. + @param size Number of bytes requested. + @return Number of bytes read (always 0 because this inode does not expose file data). + */ auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + + /** + @brief Writes to the rootfs directory inode. + @param buffer Source buffer. + @param offset Write offset in bytes. + @param size Number of bytes requested. + @return Number of bytes written (always 0 because writes are not supported for this inode). + */ auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + /** + @brief Adds a child inode to the rootfs directory inode with the specified @p name. + @param name The name of the child inode. + */ auto add_child(std::string_view name) -> void; + + /** + @brief Looks up a child inode by @p name. + @param name The name of the child inode to look up. + @return A pointer to the found child inode, or a null pointer if not found. + */ auto lookup_child(std::string_view name) -> kstd::shared_ptr; private: diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 5823a83..2d05765 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -12,14 +12,45 @@ namespace kernel::filesystem { + /** + @brief The virtual filesystem (VFS) is responsible for managing mounted filesystems and providing a unified interface + for file operations across different filesystem types. The VFS maintains a mount table to keep track of mounted + filesystems and their associated mount points. It provides methods for opening files by path, which involvesresolving + the path to the appropriate mounted filesystem and delegating the file operation to that filesystem's implementation. + */ struct vfs { + /** + @brief Initialize the virtual filesystem. + @warning Panics if the VFS has already been initialized. + */ auto static init() -> void; + + /** + @brief Get the singleton instance of the virtual filesystem. + @return A reference to the VFS instance. + @warning Panics if the VFS has not been initialized yet. + */ auto static get() -> vfs &; + /** + @brief Destructor for the VFS. + */ ~vfs() = default; + /** + @brief Open a file by its @p path. This method resolves the path and creates an open file description. + @param path The path to the file to open. + @return A shared pointer to the open file description or a null pointer if the file could not be opened. + */ auto open(std::string_view path) -> kstd::shared_ptr; + + /** + @brief Mount a @p filesystem at a specific @p path. + @param path The path where the filesystem should be mounted. + @param filesystem The filesystem to mount. + @return 0 on success, or a negative error code on failure. + */ auto do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> int; private: diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index d7c989c..7ee1072 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -36,6 +36,10 @@ namespace kernel::filesystem::ext2 constexpr uint16_t S_IFREG = 0x8000; constexpr uint16_t S_IFDIR = 0x4000; + // Error codes + constexpr int INVALID_MAGIC_NUMBER = -1; + constexpr int INVALID_ROOT_INODE = -2; + auto S_ISREG(uint16_t mode) -> bool { return (mode & S_IFMT) == S_IFREG; @@ -55,7 +59,7 @@ namespace kernel::filesystem::ext2 if (m_superblock.magic != MAGIC_NUMBER) { - return -1; + return INVALID_MAGIC_NUMBER; } auto const block_size = get_block_size(); @@ -70,7 +74,11 @@ namespace kernel::filesystem::ext2 num_block_groups * sizeof(block_group_descriptor)); m_root_inode = read_inode(ROOT_INODE_NUMBER); - // TODO BA-FS26 check if root inode is valid and is a directory ?? + + if (!m_root_inode || !m_root_inode->is_directory()) + { + return INVALID_ROOT_INODE; + } return 0; } diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index 7f4cf69..a29bb3b 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -53,7 +53,7 @@ namespace kernel::filesystem::ext2 auto inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t { - // TODO BA-FS26 implement + kapi::system::panic("[EXT2] inode::write is not implemented yet"); return 0; } } // namespace kernel::filesystem::ext2 \ No newline at end of file diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index 26c57b6..b08b520 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -36,11 +36,12 @@ namespace kernel::filesystem } } - kapi::system::panic("[FILESYSTEM] cannot mount filesystem: no suitable filesystem found on device."); + return nullptr; } auto filesystem::mount(kstd::shared_ptr const & device) -> int { + // TODO BA-FS26 maybe check if device is null and panic here already? m_device = device; return 0; } diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index f9e709c..a6d2f7e 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -25,7 +25,7 @@ namespace kernel::filesystem } } - auto mount::get_mount_dentry() const -> kstd::shared_ptr + auto mount::get_mount_dentry() const -> kstd::shared_ptr const & { return m_mount_dentry; } diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 737434e..195f48a 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -9,7 +9,7 @@ namespace kernel::filesystem { - void mount_table::add_mount(kstd::shared_ptr mount) + void mount_table::add_mount(kstd::shared_ptr const & mount) { m_mounts.push_back(mount); } diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index f9a051a..2578036 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -21,6 +21,11 @@ namespace kernel::filesystem namespace { constinit auto static active_vfs = std::optional{}; + + // Error codes + constexpr int INVALID_PATH = -1; + constexpr int MOUNT_POINT_NOT_FOUND = -2; + constexpr int FILESYSTEM_NULL = -3; } // namespace auto vfs::init() -> void @@ -79,18 +84,12 @@ namespace kernel::filesystem { if (!filesystem) { - return -1; // TODO BA-FS26 panic or errorcode? - } - - if (path.empty() || path.front() != '/') - { - return -1; // TODO BA-FS26 panic or errorcode? + return FILESYSTEM_NULL; } - // TODO BA-FS26 better path validation - if ((path.size() > 1 && path.back() == '/')) + if (path.empty() || path.front() != '/' || (path.size() > 1 && path.back() == '/')) { - return -1; // TODO BA-FS26 panic or errorcode? + return INVALID_PATH; } if (auto mount_point_dentry = resolve_path(path)) @@ -99,7 +98,7 @@ namespace kernel::filesystem return 0; } - return -1; + return MOUNT_POINT_NOT_FOUND; } auto vfs::do_mount_internal(std::string_view path, kstd::shared_ptr const & mount_point_dentry, -- cgit v1.2.3 From 9c0fb15aa67a4dda6beed3cbdfc4cc510674313f Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 14:13:19 +0200 Subject: add test with multiple correct formatted ext2 file systems increase QEMU memory --- kernel/src/main.cpp | 69 ++++++++++++++++++++++------------------------------- 1 file changed, 29 insertions(+), 40 deletions(-) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index a2c531f..1893b84 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -111,51 +111,40 @@ auto test_device_with_vfs() -> void auto test_file_lookup() -> void { - // TODO BA-FS26 implement a more complete test with multiple files and directories and mounts etc. - auto vfs = kernel::filesystem::vfs::get(); - auto storage_mgmt = kernel::devices::storage::management::get(); - - auto ofd_hello = vfs.open("/hello.txt"); - - kstd::vector buffer(64); - auto number_of_read_bytes = ofd_hello->read(buffer.data(), buffer.size()); - kstd::println("read bytes: {}", number_of_read_bytes); - kstd::println("buffer: {::#04x}", buffer); - - std::string_view hello_str{reinterpret_cast(buffer.data()), number_of_read_bytes}; - kstd::println("hello_str: {}", hello_str); - - auto ofd1 = vfs.open("/a/b/c"); - auto ofd2 = vfs.open("/dev/ram0"); - auto ofd3 = vfs.open("/a/d/e"); - if (!ofd1 || !ofd2 || !ofd3) - { - kstd::os::panic("test code failed"); - } - - if (auto ofd4 = vfs.open("/dev/xxx")) - { - kstd::os::panic("test code failed"); - } + auto read_and_write_file = [&vfs](std::string_view path) { + kstd::println("[TEST] Reading and writing file at path: {}", path); + auto ofd = vfs.open(path); + if (!ofd) + { + kstd::os::panic("test code failed"); + } + + kstd::vector buffer{32}; + auto number_of_read_bytes = ofd->read(buffer.data(), buffer.size()); + kstd::println("read bytes: {}", number_of_read_bytes); + kstd::println("buffer: {::#04x}", buffer); + + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), number_of_read_bytes}; + kstd::println("buffer_as_str: {}", buffer_as_str); + }; + + read_and_write_file("/info.txt"); + read_and_write_file("/enclosures/info.txt"); + read_and_write_file("/enclosures/aquarium/tank_1/fish_4.txt"); + read_and_write_file("/enclosures/elephant_house/elephant_1.txt"); + read_and_write_file( + "/enclosures/aquarium/tank_2/" + "this_is_a_very_very_long_fish_filename_that_keeps_going_and_going_until_it_almost_breaks_linux_filesystem_" + "limits_for_testing_purposes_and_we_add_more_characters_to_make_it_even_longer_30.txt"); + auto storage_mgmt = kernel::devices::storage::management::get(); auto device = storage_mgmt.device_by_major_minor(1, 16); auto new_filesystem = kernel::filesystem::filesystem::probe_and_mount(device); - if (vfs.do_mount("/a/b", new_filesystem) != 0) - { - kstd::os::panic("test code failed"); - } - auto ofd5 = vfs.open("/a/b/c"); - if (!ofd5) - { - kstd::os::panic("test code failed"); - } - - if (auto ofd6 = vfs.open("x/y/z")) - { - kstd::os::panic("test code failed"); - } + vfs.do_mount("/enclosures/aquarium", new_filesystem); + read_and_write_file("/enclosures/aquarium/closed.txt"); + read_and_write_file("/enclosures/aquarium/information/info_2.txt"); } auto run_test_code() -> void -- cgit v1.2.3 From 2793770dc6eba30b73b4a4993618d2cbe184790e Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 15:21:10 +0200 Subject: implement unmount, improve error codes --- .../include/kernel/filesystem/devfs/filesystem.hpp | 4 +- .../include/kernel/filesystem/ext2/filesystem.hpp | 4 +- kernel/include/kernel/filesystem/filesystem.hpp | 12 +++- kernel/include/kernel/filesystem/mount.hpp | 10 +++- kernel/include/kernel/filesystem/mount_table.hpp | 21 ++++++- .../kernel/filesystem/rootfs/filesystem.hpp | 4 +- kernel/include/kernel/filesystem/vfs.hpp | 23 +++++++- kernel/src/filesystem/devfs/filesystem.cpp | 5 +- kernel/src/filesystem/ext2/filesystem.cpp | 12 ++-- kernel/src/filesystem/filesystem.cpp | 6 +- kernel/src/filesystem/mount.cpp | 9 ++- kernel/src/filesystem/mount_table.cpp | 69 +++++++++++++++++++++- kernel/src/filesystem/rootfs/filesystem.cpp | 4 +- kernel/src/filesystem/vfs.cpp | 45 +++++++++----- kernel/src/main.cpp | 3 + 15 files changed, 187 insertions(+), 44 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/devfs/filesystem.hpp b/kernel/include/kernel/filesystem/devfs/filesystem.hpp index 60c39cf..137eca3 100644 --- a/kernel/include/kernel/filesystem/devfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/devfs/filesystem.hpp @@ -24,9 +24,9 @@ namespace kernel::filesystem::devfs /** @brief Initializes the devfs instance and builds the device inode table. @param device Backing device passed by the generic filesystem interface (not required by devfs). - @return 0 on success, -1 on failure. + @return The result of the mount operation. */ - auto mount(kstd::shared_ptr const & device) -> int override; + auto mount(kstd::shared_ptr const & device) -> operation_result override; /** @brief Looks up an inode by @p name within a @p parent directory. diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index 32374dc..65324c8 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -27,9 +27,9 @@ namespace kernel::filesystem::ext2 /** @brief Initializes the ext2 filesystem with the given @p device. @param device The device to mount. - @return 0 on success, negative error code on failure. + @return The result of the mount operation. */ - auto mount(kstd::shared_ptr const & device) -> int override; + auto mount(kstd::shared_ptr const & device) -> operation_result override; /** @brief Looks up an inode by @p name within a @p parent directory. diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index f855380..ef6929a 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -18,6 +18,14 @@ namespace kernel::filesystem */ struct filesystem { + enum class operation_result : int + { + success = 0, + invalid_magic_number = -1, + invalid_root_inode = -2, + unmount_failed = -3 + }; + /** @brief Virtual destructor for the filesystem. */ @@ -37,9 +45,9 @@ namespace kernel::filesystem /** @brief Initializes the filesystem with the given @p device. @param device The device to mount. - @return 0 on success, or a negative error code on failure. + @return The result of the mount operation. */ - virtual auto mount(kstd::shared_ptr const & device) -> int; + virtual auto mount(kstd::shared_ptr const & device) -> operation_result; /** @brief Looks up a child inode within the given @p parent inode with the specified @p name. This method must be diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index 3e3c69f..0ac6b2f 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -24,9 +24,11 @@ namespace kernel::filesystem @param root_dentry The root dentry of the mounted filesystem. @param fs The filesystem instance being mounted. @param mount_path The path at which the filesystem is mounted. + @param parent_mount The parent mount that this mount is attached beneath. */ mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & root_dentry, - kstd::shared_ptr const & fs, std::string_view mount_path); + kstd::shared_ptr const & fs, std::string_view mount_path, + kstd::shared_ptr const & parent_mount); /** @brief Get the dentry where the filesystem is mounted. @@ -48,11 +50,17 @@ namespace kernel::filesystem */ [[nodiscard]] auto get_mount_path() const -> std::string_view; + /** + @brief Get the parent mount that this mount was attached beneath. + */ + [[nodiscard]] auto get_parent_mount() const -> kstd::shared_ptr const &; + private: kstd::string m_mount_path; kstd::shared_ptr m_mount_dentry; kstd::shared_ptr m_root_dentry; kstd::shared_ptr m_filesystem{}; + kstd::shared_ptr m_parent_mount{}; }; } // namespace kernel::filesystem diff --git a/kernel/include/kernel/filesystem/mount_table.hpp b/kernel/include/kernel/filesystem/mount_table.hpp index a8ef59e..a5cdde6 100644 --- a/kernel/include/kernel/filesystem/mount_table.hpp +++ b/kernel/include/kernel/filesystem/mount_table.hpp @@ -15,11 +15,28 @@ namespace kernel::filesystem */ struct mount_table { + /** + @brief Results for mount table operations. + */ + enum class operation_result : int + { + removed = 0, + has_child_mounts = -1, + mount_not_found = -2 + }; + /** @brief Adds a mount to the table. @param mount The mount to add. */ - void add_mount(kstd::shared_ptr const & mount); + auto add_mount(kstd::shared_ptr const & mount) -> void; + + /** + @brief Removes the topmost mount at the given @p path. + @param path The mount path to remove. + @return The result of the removal operation. + */ + [[nodiscard]] auto remove_mount(std::string_view path) -> operation_result; /** @brief Finds the mount with the longest prefix matching the given @p path. This method is used to determine which @@ -30,6 +47,8 @@ namespace kernel::filesystem [[nodiscard]] auto find_longest_prefix_mount(std::string_view path) const -> kstd::shared_ptr; private: + [[nodiscard]] auto has_child_mounts(kstd::shared_ptr const & parent_mount) const -> bool; + kstd::vector> m_mounts; }; } // namespace kernel::filesystem diff --git a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp index b7e7c6f..0155c41 100644 --- a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp @@ -25,9 +25,9 @@ namespace kernel::filesystem::rootfs /** @brief Initializes the rootfs filesystem with the given @p device. @param device The device to mount (not required by rootfs). - @return 0 on success, negative error code on failure. + @return The result of the mount operation. */ - auto mount(kstd::shared_ptr const & device) -> int override; + auto mount(kstd::shared_ptr const & device) -> operation_result override; /** @brief Looks up an inode by @p name within a @p parent directory. diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 2d05765..4dd2a83 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -20,6 +20,18 @@ namespace kernel::filesystem */ struct vfs { + /** + @brief Results for VFS operations. + */ + enum class operation_result : int + { + success = 0, + invalid_path = -1, + mount_point_not_found = -2, + filesystem_null = -3, + unmount_failed = -4 + }; + /** @brief Initialize the virtual filesystem. @warning Panics if the VFS has already been initialized. @@ -49,9 +61,16 @@ namespace kernel::filesystem @brief Mount a @p filesystem at a specific @p path. @param path The path where the filesystem should be mounted. @param filesystem The filesystem to mount. - @return 0 on success, or a negative error code on failure. + @return The result of the mount operation. + */ + auto do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> operation_result; + + /** + @brief Unmount the filesystem mounted at the specified @p path. + @param path The path where the filesystem is mounted. + @return The result of the unmount operation. */ - auto do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> int; + auto unmount(std::string_view path) -> operation_result; private: vfs() = default; diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp index 9043ac5..03b4218 100644 --- a/kernel/src/filesystem/devfs/filesystem.cpp +++ b/kernel/src/filesystem/devfs/filesystem.cpp @@ -1,6 +1,7 @@ #include "kernel/filesystem/devfs/filesystem.hpp" #include "kapi/devices/device.hpp" + #include "kernel/devices/storage/management.hpp" #include "kernel/filesystem/devfs/inode.hpp" #include "kernel/filesystem/device_inode.hpp" @@ -13,12 +14,12 @@ namespace kernel::filesystem::devfs { - auto filesystem::mount(kstd::shared_ptr const &) -> int + auto filesystem::mount(kstd::shared_ptr const &) -> operation_result { m_root_inode = kstd::make_shared(); build_device_inode_table(); - return 0; + return operation_result::success; } auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 7ee1072..6d5960e 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -36,10 +36,6 @@ namespace kernel::filesystem::ext2 constexpr uint16_t S_IFREG = 0x8000; constexpr uint16_t S_IFDIR = 0x4000; - // Error codes - constexpr int INVALID_MAGIC_NUMBER = -1; - constexpr int INVALID_ROOT_INODE = -2; - auto S_ISREG(uint16_t mode) -> bool { return (mode & S_IFMT) == S_IFREG; @@ -51,7 +47,7 @@ namespace kernel::filesystem::ext2 } } // namespace - auto filesystem::mount(kstd::shared_ptr const & device) -> int + auto filesystem::mount(kstd::shared_ptr const & device) -> operation_result { kernel::filesystem::filesystem::mount(device); @@ -59,7 +55,7 @@ namespace kernel::filesystem::ext2 if (m_superblock.magic != MAGIC_NUMBER) { - return INVALID_MAGIC_NUMBER; + return operation_result::invalid_magic_number; } auto const block_size = get_block_size(); @@ -77,9 +73,9 @@ namespace kernel::filesystem::ext2 if (!m_root_inode || !m_root_inode->is_directory()) { - return INVALID_ROOT_INODE; + return operation_result::invalid_root_inode; } - return 0; + return operation_result::success; } auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index b08b520..da2838d 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -30,7 +30,7 @@ namespace kernel::filesystem for (auto & factory : filesystem_factories) { auto fs = factory(); - if (fs->mount(device) == 0) + if (fs->mount(device) == operation_result::success) { return fs; } @@ -39,11 +39,11 @@ namespace kernel::filesystem return nullptr; } - auto filesystem::mount(kstd::shared_ptr const & device) -> int + auto filesystem::mount(kstd::shared_ptr const & device) -> operation_result { // TODO BA-FS26 maybe check if device is null and panic here already? m_device = device; - return 0; + return operation_result::success; } auto filesystem::root_inode() const -> kstd::shared_ptr const & diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index a6d2f7e..d165385 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -13,11 +13,13 @@ namespace kernel::filesystem { mount::mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & root_dentry, - kstd::shared_ptr const & fs, std::string_view mount_path) + kstd::shared_ptr const & fs, std::string_view mount_path, + kstd::shared_ptr const & parent_mount) : m_mount_path(mount_path) , m_mount_dentry(mount_dentry) , m_root_dentry(root_dentry) , m_filesystem(fs) + , m_parent_mount(parent_mount) { if (!m_filesystem) { @@ -44,4 +46,9 @@ namespace kernel::filesystem { return m_mount_path.view(); } + + auto mount::get_parent_mount() const -> kstd::shared_ptr const & + { + return m_parent_mount; + } } // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 195f48a..3b1dee3 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -1,17 +1,83 @@ #include "kernel/filesystem/mount_table.hpp" +#include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/mount.hpp" #include +#include +#include #include +#include #include namespace kernel::filesystem { + namespace + { + auto is_descendant_of(kstd::shared_ptr const & candidate, kstd::shared_ptr const & ancestor) -> bool + { + for (auto current = candidate; current; current = current->get_parent_mount()) + { + if (current == ancestor) + { + return true; + } + } + + return false; + } + + auto is_strict_prefix(std::string_view prefix, std::string_view path) -> bool + { + return prefix != "/" && path.starts_with(prefix) && path.size() > prefix.size() && path[prefix.size()] == '/'; + } + + auto is_visible_mount(kstd::shared_ptr const & candidate, + kstd::vector> const & mounts) -> bool + { + return std::ranges::none_of(mounts, [&](auto const & other) { + return other != candidate && is_strict_prefix(other->get_mount_path(), candidate->get_mount_path()) && + !is_descendant_of(candidate, other); + }); + } + } // namespace + + auto mount_table::has_child_mounts(kstd::shared_ptr const & parent_mount) const -> bool + { + return std::ranges::any_of( + m_mounts, [&parent_mount](auto const & mount) { return mount->get_parent_mount() == parent_mount; }); + } + void mount_table::add_mount(kstd::shared_ptr const & mount) { m_mounts.push_back(mount); + if (auto mount_dentry = mount->get_mount_dentry()) + { + mount_dentry->set_flag(dentry::dentry_flags::dcache_mounted); + } + } + + auto mount_table::remove_mount(std::string_view path) -> operation_result + { + auto mount_it = std::ranges::find_if(std::ranges::reverse_view(m_mounts), [&](auto const & mount) { + return mount->get_mount_path() == path && is_visible_mount(mount, m_mounts); + }); + + if (mount_it == std::ranges::reverse_view(m_mounts).end()) + { + return operation_result::mount_not_found; + } + + auto const & mount = *mount_it; + if (has_child_mounts(mount)) + { + return operation_result::has_child_mounts; + } + + mount->get_mount_dentry()->unset_flag(dentry::dentry_flags::dcache_mounted); + m_mounts.erase(std::ranges::find(m_mounts, mount)); + return operation_result::removed; } auto mount_table::find_longest_prefix_mount(std::string_view path) const -> kstd::shared_ptr @@ -25,8 +91,9 @@ namespace kernel::filesystem // /a/b/c should match /a/b but not /a/bb or /a/b/c/d, / should match everything bool is_prefix = path.starts_with(mp) && (mp == "/" || path.size() == mp.size() || path[mp.size()] == '/'); + bool visible = is_visible_mount(mount, m_mounts); - if (is_prefix && mp.size() >= best_len) + if (is_prefix && visible && mp.size() >= best_len) { mount_with_longest_prefix = mount; best_len = mp.size(); diff --git a/kernel/src/filesystem/rootfs/filesystem.cpp b/kernel/src/filesystem/rootfs/filesystem.cpp index a7c746e..dffef99 100644 --- a/kernel/src/filesystem/rootfs/filesystem.cpp +++ b/kernel/src/filesystem/rootfs/filesystem.cpp @@ -11,13 +11,13 @@ namespace kernel::filesystem::rootfs { - auto filesystem::mount(kstd::shared_ptr const &) -> int + auto filesystem::mount(kstd::shared_ptr const &) -> operation_result { auto rfs_inode = kstd::make_shared(); rfs_inode->add_child("dev"); m_root_inode = rfs_inode; - return 0; + return operation_result::success; } auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 2578036..45ae053 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -7,6 +7,7 @@ #include "kernel/filesystem/devfs/filesystem.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/mount.hpp" +#include "kernel/filesystem/mount_table.hpp" #include "kernel/filesystem/open_file_description.hpp" #include "kernel/filesystem/rootfs/filesystem.hpp" @@ -21,11 +22,6 @@ namespace kernel::filesystem namespace { constinit auto static active_vfs = std::optional{}; - - // Error codes - constexpr int INVALID_PATH = -1; - constexpr int MOUNT_POINT_NOT_FOUND = -2; - constexpr int FILESYSTEM_NULL = -3; } // namespace auto vfs::init() -> void @@ -45,7 +41,7 @@ namespace kernel::filesystem root_fs->mount(nullptr); auto root_fs_root_dentry = kstd::make_shared(nullptr, root_fs->root_inode()); - m_mount_table.add_mount(kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, "")); + m_mount_table.add_mount(kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, "", nullptr)); auto storage_mgmt = devices::storage::management::get(); if (auto boot_device = storage_mgmt.determine_boot_device()) @@ -79,36 +75,55 @@ namespace kernel::filesystem return nullptr; } - // TODO BA-FS26 implement unmount - auto vfs::do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> int + auto vfs::do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> operation_result { if (!filesystem) { - return FILESYSTEM_NULL; + return operation_result::filesystem_null; } if (path.empty() || path.front() != '/' || (path.size() > 1 && path.back() == '/')) { - return INVALID_PATH; + return operation_result::invalid_path; } if (auto mount_point_dentry = resolve_path(path)) { do_mount_internal(path, mount_point_dentry, filesystem); - return 0; + return operation_result::success; + } + + return operation_result::mount_point_not_found; + } + + auto vfs::unmount(std::string_view path) -> operation_result + { + if (path.empty() || path.front() != '/' || (path.size() > 1 && path.back() == '/')) + { + return operation_result::invalid_path; + } + + auto remove_result = m_mount_table.remove_mount(path); + if (remove_result == mount_table::operation_result::removed) + { + return operation_result::success; + } + + if (remove_result == mount_table::operation_result::has_child_mounts) + { + return operation_result::unmount_failed; } - return MOUNT_POINT_NOT_FOUND; + return operation_result::mount_point_not_found; } auto vfs::do_mount_internal(std::string_view path, kstd::shared_ptr const & mount_point_dentry, kstd::shared_ptr const & fs) -> void { - // TODO BA-FS26 check if mount point is already mounted and handle it (unmount old fs, fail, etc.) + auto parent_mount = m_mount_table.find_longest_prefix_mount(path); auto new_fs_root = kstd::make_shared(mount_point_dentry, fs->root_inode()); - auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, path); + auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, path, parent_mount); m_mount_table.add_mount(new_mount); - mount_point_dentry->set_flag(dentry::dentry_flags::dcache_mounted); } auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 1893b84..1d73e20 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -145,6 +145,9 @@ auto test_file_lookup() -> void vfs.do_mount("/enclosures/aquarium", new_filesystem); read_and_write_file("/enclosures/aquarium/closed.txt"); read_and_write_file("/enclosures/aquarium/information/info_2.txt"); + + vfs.unmount("/enclosures/aquarium"); + read_and_write_file("/enclosures/aquarium/tank_1/fish_4.txt"); } auto run_test_code() -> void -- cgit v1.2.3 From 5865dac062f3291b8081eca39c2835015d2c43c6 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 15:48:32 +0200 Subject: extend tests with another filesystem --- kernel/src/main.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 1d73e20..79ed703 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -139,15 +139,37 @@ auto test_file_lookup() -> void "limits_for_testing_purposes_and_we_add_more_characters_to_make_it_even_longer_30.txt"); auto storage_mgmt = kernel::devices::storage::management::get(); - auto device = storage_mgmt.device_by_major_minor(1, 16); - auto new_filesystem = kernel::filesystem::filesystem::probe_and_mount(device); + auto device_1 = storage_mgmt.device_by_major_minor(1, 16); + auto fs_1 = kernel::filesystem::filesystem::probe_and_mount(device_1); - vfs.do_mount("/enclosures/aquarium", new_filesystem); + vfs.do_mount("/enclosures/aquarium", fs_1); read_and_write_file("/enclosures/aquarium/closed.txt"); read_and_write_file("/enclosures/aquarium/information/info_2.txt"); vfs.unmount("/enclosures/aquarium"); read_and_write_file("/enclosures/aquarium/tank_1/fish_4.txt"); + + auto device_2 = storage_mgmt.device_by_major_minor(1, 32); + auto fs_2 = kernel::filesystem::filesystem::probe_and_mount(device_2); + + vfs.do_mount("/enclosures/elephant_house", fs_2); + read_and_write_file("/enclosures/elephant_house/monkey_house/infrastructure/info.txt"); + + vfs.do_mount("/enclosures/elephant_house/monkey_house", fs_1); + read_and_write_file("/enclosures/elephant_house/monkey_house/information/info_2.txt"); + + auto result = vfs.unmount("/enclosures/elephant_house"); + if (result == kernel::filesystem::vfs::operation_result::unmount_failed) + { + kstd::println("[TEST] Unmount failed as expected due to active child mount."); + } + + vfs.unmount("/enclosures/elephant_house/monkey_house"); + result = vfs.unmount("/enclosures/elephant_house"); + if (result == kernel::filesystem::vfs::operation_result::success) + { + kstd::println("[TEST] Unmount succeeded after unmounting child mount."); + } } auto run_test_code() -> void -- cgit v1.2.3 From e2c08ddb3d79f946399ca5d3bc07b4e6c4de9328 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 16:21:33 +0200 Subject: add dentry tests --- kernel/CMakeLists.txt | 3 + kernel/include/kernel/filesystem/dentry.hpp | 15 ++- kernel/src/filesystem/dentry.cpp | 9 +- kernel/src/filesystem/dentry.tests.cpp | 136 ++++++++++++++++++++++++++++ 4 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 kernel/src/filesystem/dentry.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 74233cb..85c7661 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -126,6 +126,9 @@ else() "src/memory/bitmap_allocator.tests.cpp" "src/memory/block_list_allocator.tests.cpp" + # Filesystem Subsystem Tests + "src/filesystem/dentry.tests.cpp" + # Storage Subsystem Tests "src/devices/storage/ram_disk/device.tests.cpp" ) diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index 72d758f..58a918f 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -28,10 +28,13 @@ namespace kernel::filesystem }; /** - @brief Create a dentry with the given @p parent, associated @p node, and optional @p name. The dentry is initialized - with the provided parent and inode, and the name is stored for lookup purposes. + @brief Create a dentry with the given @p parent, associated @p inode, and optional @p name. The dentry is + initialized with the provided parent and inode, and the name is stored for lookup purposes. + @param parent The parent dentry. + @param inode The associated inode for this dentry. + @param name The name of the dentry (optional). */ - dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & node, std::string_view name = {}); + dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & inode, std::string_view name = {}); /** @brief Get the associated inode. @@ -45,6 +48,12 @@ namespace kernel::filesystem */ [[nodiscard]] auto get_parent() const -> kstd::shared_ptr const &; + /** + @brief Get the name of the dentry. + @return The name of the dentry. + */ + [[nodiscard]] auto get_name() const -> std::string_view; + /** @brief Add a @p child dentry. @param child The child dentry to add. diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index 2f99e91..6591011 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -12,10 +12,10 @@ namespace kernel::filesystem { - dentry::dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & node, std::string_view name) + dentry::dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & inode, std::string_view name) : m_name(name) , m_parent(parent) - , m_inode(node) + , m_inode(inode) { if (!m_inode) { @@ -33,6 +33,11 @@ namespace kernel::filesystem return m_parent; } + auto dentry::get_name() const -> std::string_view + { + return m_name.view(); + } + auto dentry::add_child(kstd::shared_ptr const & child) -> void { m_children.push_back(child); diff --git a/kernel/src/filesystem/dentry.tests.cpp b/kernel/src/filesystem/dentry.tests.cpp new file mode 100644 index 0000000..f82024a --- /dev/null +++ b/kernel/src/filesystem/dentry.tests.cpp @@ -0,0 +1,136 @@ +#include "kernel/filesystem/dentry.hpp" + +#include "kernel/filesystem/devfs/inode.hpp" +#include "kernel/test_support/cio.hpp" +#include "kernel/test_support/cpu.hpp" + +#include +#include + +#include + +SCENARIO("Dentry construction", "[filesystem][dentry]") +{ + GIVEN("A parent dentry and inode") + { + auto inode = kstd::make_shared(); + auto parent_dentry = kstd::make_shared(nullptr, inode); + + WHEN("constructing a dentry") + { + auto child_dentry = kernel::filesystem::dentry{parent_dentry, inode, "child"}; + + THEN("the dentry has the correct parent, inode, and name") + { + REQUIRE(child_dentry.get_parent() == parent_dentry); + REQUIRE(child_dentry.get_inode() == inode); + REQUIRE(child_dentry.get_name() == "child"); + } + + THEN("no flag is set") + { + REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + } + } + + WHEN("constructing a dentry with an empty name") + { + auto child_dentry = kernel::filesystem::dentry{parent_dentry, inode}; + + THEN("the dentry has the correct parent and inode, and an empty name") + { + REQUIRE(child_dentry.get_parent() == parent_dentry); + REQUIRE(child_dentry.get_inode() == inode); + REQUIRE(child_dentry.get_name().empty()); + } + + THEN("no flag is set") + { + REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + } + } + + WHEN("constructing a dentry with a null parent") + { + auto child_dentry = kernel::filesystem::dentry{nullptr, inode, "child"}; + + THEN("the dentry has a null parent, the correct inode, and the correct name") + { + REQUIRE(child_dentry.get_parent() == nullptr); + REQUIRE(child_dentry.get_inode() == inode); + REQUIRE(child_dentry.get_name() == "child"); + } + + THEN("no flag is set") + { + REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + } + } + + WHEN("constructing a dentry with a null inode") + { + THEN("the system panics") + { + REQUIRE_THROWS_AS((kernel::filesystem::dentry{parent_dentry, nullptr, "child"}), kernel::tests::cpu::halt); + } + } + } +} + +SCENARIO("Dentry child logic", "[filesystem][dentry]") +{ + GIVEN("A parent dentry and inode") + { + auto inode = kstd::make_shared(); + auto parent_dentry = kstd::make_shared(nullptr, inode); + + WHEN("adding child dentries") + { + auto child1 = kstd::make_shared(parent_dentry, inode, "child1"); + auto child2 = kstd::make_shared(parent_dentry, inode, "child2"); + parent_dentry->add_child(child1); + parent_dentry->add_child(child2); + + THEN("the children can be found by name") + { + REQUIRE(parent_dentry->find_child("child1") == child1); + REQUIRE(parent_dentry->find_child("child2") == child2); + } + + THEN("finding a non-existent child returns null") + { + REQUIRE(parent_dentry->find_child("nonexistent") == nullptr); + } + } + } +} + +SCENARIO("Dentry Flag logic", "[filesystem][dentry]") +{ + GIVEN("A dentry") + { + auto inode = kstd::make_shared(); + auto dentry = kernel::filesystem::dentry{nullptr, inode, "test"}; + + WHEN("setting a flag") + { + dentry.set_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted); + + THEN("the flag is set") + { + REQUIRE(dentry.has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + } + } + + WHEN("unsetting a flag") + { + dentry.set_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted); + dentry.unset_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted); + + THEN("the flag is unset") + { + REQUIRE_FALSE(dentry.has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + } + } + } +} -- cgit v1.2.3 From bf90905a5ded3995af5677685bc31228d485e64b Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 18:52:11 +0200 Subject: add test block_device --- kernel/CMakeLists.txt | 1 + .../kernel/test_support/devices/block_device.hpp | 31 ++++++++++++ kernel/src/test_support/devices/block_device.cpp | 58 ++++++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 kernel/include/kernel/test_support/devices/block_device.hpp create mode 100644 kernel/src/test_support/devices/block_device.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 85c7661..12683a1 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -101,6 +101,7 @@ else() "src/test_support/kapi/cio.cpp" "src/test_support/kapi/interrupts.cpp" "src/test_support/kapi/memory.cpp" + "src/test_support/devices/block_device.cpp" "src/test_support/log_buffer.cpp" "src/test_support/output_device.cpp" "src/test_support/page_mapper.cpp" diff --git a/kernel/include/kernel/test_support/devices/block_device.hpp b/kernel/include/kernel/test_support/devices/block_device.hpp new file mode 100644 index 0000000..2327fc4 --- /dev/null +++ b/kernel/include/kernel/test_support/devices/block_device.hpp @@ -0,0 +1,31 @@ +#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 +#include + +#include +#include + +namespace kernel::tests::devices +{ + + struct block_device : kernel::devices::block_device + { + block_device(size_t major, size_t minor, kstd::string const & name, size_t block_size); + + auto init() -> bool override; + + auto read_block(size_t block_index, void * buffer) const -> void override; + auto write_block(size_t block_index, void const * buffer) -> void override; + + [[nodiscard]] auto size() const -> size_t override; + + kstd::vector data{}; + }; + +} // namespace kernel::tests::devices + +#endif \ No newline at end of file diff --git a/kernel/src/test_support/devices/block_device.cpp b/kernel/src/test_support/devices/block_device.cpp new file mode 100644 index 0000000..bce415f --- /dev/null +++ b/kernel/src/test_support/devices/block_device.cpp @@ -0,0 +1,58 @@ +#include "kernel/test_support/devices/block_device.hpp" + +#include "kernel/devices/block_device.hpp" + +#include +#include + +#include +#include +#include +#include +#include + +namespace kernel::tests::devices +{ + block_device::block_device(size_t major, size_t minor, kstd::string const & name, size_t block_size) + : kernel::devices::block_device(major, minor, name, block_size) + {} + + auto block_device::init() -> bool + { + return true; + } + + auto block_device::read_block(size_t block_index, void * buffer) const -> void + { + auto const offset = block_index * block_size(); + if (offset >= data.size()) + { + kstd::libc::memset(buffer, 0, block_size()); + return; + } + + auto const bytes_to_read = std::min(block_size(), data.size() - offset); + kstd::libc::memcpy(buffer, data.data() + offset, bytes_to_read); + if (bytes_to_read < block_size()) + { + kstd::libc::memset(static_cast(buffer) + bytes_to_read, 0, block_size() - bytes_to_read); + } + } + + auto block_device::write_block(size_t block_index, void const * buffer) -> void + { + auto const offset = block_index * block_size(); + auto const write_end = offset + block_size(); + if (write_end > data.size()) + { + data.resize(write_end, 0); + } + + kstd::libc::memcpy(data.data() + offset, static_cast(buffer), block_size()); + } + + auto block_device::size() const -> size_t + { + return data.size(); + } +} // namespace kernel::tests::devices \ No newline at end of file -- cgit v1.2.3 From 63c6299262411fc06afca4f224e00e1b2d25eb25 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 19:01:16 +0200 Subject: clean up includes --- kernel/src/filesystem/dentry.tests.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/dentry.tests.cpp b/kernel/src/filesystem/dentry.tests.cpp index f82024a..94aa48d 100644 --- a/kernel/src/filesystem/dentry.tests.cpp +++ b/kernel/src/filesystem/dentry.tests.cpp @@ -1,7 +1,6 @@ #include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/devfs/inode.hpp" -#include "kernel/test_support/cio.hpp" #include "kernel/test_support/cpu.hpp" #include -- 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/CMakeLists.txt | 1 + kernel/src/devices/block_device_utils.cpp | 2 +- kernel/src/devices/block_device_utils.tests.cpp | 189 ++++++++++++++++++++++++ 3 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 kernel/src/devices/block_device_utils.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 12683a1..be21fc3 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -131,6 +131,7 @@ else() "src/filesystem/dentry.tests.cpp" # Storage Subsystem Tests + "src/devices/block_device_utils.tests.cpp" "src/devices/storage/ram_disk/device.tests.cpp" ) add_executable("os::kernel_tests" ALIAS "kernel_tests") 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/CMakeLists.txt | 1 + .../kernel/test_support/devices/block_device.hpp | 2 +- kernel/src/devices/block_device.cpp | 3 +- kernel/src/devices/block_device.tests.cpp | 46 ++++++++++++++++++++++ kernel/src/devices/block_device_utils.tests.cpp | 4 +- kernel/src/test_support/devices/block_device.cpp | 7 +++- 6 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 kernel/src/devices/block_device.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index be21fc3..a360f17 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -132,6 +132,7 @@ else() # Storage Subsystem Tests "src/devices/block_device_utils.tests.cpp" + "src/devices/block_device.tests.cpp" "src/devices/storage/ram_disk/device.tests.cpp" ) add_executable("os::kernel_tests" ALIAS "kernel_tests") diff --git a/kernel/include/kernel/test_support/devices/block_device.hpp b/kernel/include/kernel/test_support/devices/block_device.hpp index 2327fc4..110872f 100644 --- a/kernel/include/kernel/test_support/devices/block_device.hpp +++ b/kernel/include/kernel/test_support/devices/block_device.hpp @@ -14,7 +14,7 @@ namespace kernel::tests::devices struct block_device : kernel::devices::block_device { - block_device(size_t major, size_t minor, kstd::string const & name, size_t block_size); + block_device(size_t major, size_t minor, kstd::string const & name, size_t block_size, size_t initial_size = 0); auto init() -> bool override; 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") { diff --git a/kernel/src/test_support/devices/block_device.cpp b/kernel/src/test_support/devices/block_device.cpp index bce415f..d1d4101 100644 --- a/kernel/src/test_support/devices/block_device.cpp +++ b/kernel/src/test_support/devices/block_device.cpp @@ -13,9 +13,12 @@ namespace kernel::tests::devices { - block_device::block_device(size_t major, size_t minor, kstd::string const & name, size_t block_size) + block_device::block_device(size_t major, size_t minor, kstd::string const & name, size_t block_size, + size_t initial_size) : kernel::devices::block_device(major, minor, name, block_size) - {} + { + data.resize(initial_size, 0); + } auto block_device::init() -> bool { -- cgit v1.2.3 From 6d72142158970119ee0d36d9149c0e0572dedf5f Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 19:43:15 +0200 Subject: add non block device for tests --- kernel/CMakeLists.txt | 1 + .../test_support/devices/character_device.hpp | 23 ++++++++++++++++++++++ .../src/test_support/devices/character_device.cpp | 20 +++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 kernel/include/kernel/test_support/devices/character_device.hpp create mode 100644 kernel/src/test_support/devices/character_device.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index a360f17..df20704 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -102,6 +102,7 @@ else() "src/test_support/kapi/interrupts.cpp" "src/test_support/kapi/memory.cpp" "src/test_support/devices/block_device.cpp" + "src/test_support/devices/character_device.cpp" "src/test_support/log_buffer.cpp" "src/test_support/output_device.cpp" "src/test_support/page_mapper.cpp" diff --git a/kernel/include/kernel/test_support/devices/character_device.hpp b/kernel/include/kernel/test_support/devices/character_device.hpp new file mode 100644 index 0000000..a106cfb --- /dev/null +++ b/kernel/include/kernel/test_support/devices/character_device.hpp @@ -0,0 +1,23 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_DEVICES_CHARACTER_DEVICE_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_DEVICES_CHARACTER_DEVICE_HPP + +#include "kapi/devices/device.hpp" + +#include +#include + +#include + +namespace kernel::tests::devices +{ + // TODO fix inheritance when character devices are implemented + struct character_device : kapi::devices::device + { + character_device(size_t major, size_t minor, kstd::string const & name); + + auto init() -> bool override; + }; + +} // namespace kernel::tests::devices + +#endif \ No newline at end of file diff --git a/kernel/src/test_support/devices/character_device.cpp b/kernel/src/test_support/devices/character_device.cpp new file mode 100644 index 0000000..9e9227d --- /dev/null +++ b/kernel/src/test_support/devices/character_device.cpp @@ -0,0 +1,20 @@ + +#include "kernel/test_support/devices/character_device.hpp" + +#include "kapi/devices.hpp" + +#include + +#include + +namespace kernel::tests::devices +{ + character_device::character_device(size_t major, size_t minor, kstd::string const & name) + : kapi::devices::device(major, minor, name) + {} + + auto character_device::init() -> bool + { + return true; + } +} // namespace kernel::tests::devices \ No newline at end of file -- 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/CMakeLists.txt | 1 + kernel/src/devices/block_device_utils.cpp | 5 +- kernel/src/devices/block_device_utils.tests.cpp | 32 ++++++- kernel/src/filesystem/device_inode.tests.cpp | 108 ++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 kernel/src/filesystem/device_inode.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index df20704..53ed107 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -130,6 +130,7 @@ else() # Filesystem Subsystem Tests "src/filesystem/dentry.tests.cpp" + "src/filesystem/device_inode.tests.cpp" # Storage Subsystem Tests "src/devices/block_device_utils.tests.cpp" 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); + } + } + } +} diff --git a/kernel/src/filesystem/device_inode.tests.cpp b/kernel/src/filesystem/device_inode.tests.cpp new file mode 100644 index 0000000..4e31812 --- /dev/null +++ b/kernel/src/filesystem/device_inode.tests.cpp @@ -0,0 +1,108 @@ +#include "kernel/filesystem/device_inode.hpp" + +#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 +#include + +SCENARIO("Device inode construction", "[filesystem][device_inode]") +{ + GIVEN("a block device") + { + auto device = kstd::make_shared(0, 0, "test_block_device", 512, 3 * 512); + + WHEN("constructing a device inode with the block device") + { + auto inode = kernel::filesystem::device_inode{device}; + + THEN("the device inode has the correct device") + { + REQUIRE(inode.device() == device); + } + + THEN("the device inode has the correct kind") + { + REQUIRE(inode.is_device()); + REQUIRE_FALSE(inode.is_directory()); + REQUIRE_FALSE(inode.is_regular()); + } + } + + WHEN("constructing a device inode with a null device") + { + THEN("the constructor panics") + { + REQUIRE_THROWS_AS((kernel::filesystem::device_inode{nullptr}), kernel::tests::cpu::halt); + } + } + } +} + +SCENARIO("Device inode read/write", "[filesystem][device_inode]") +{ + GIVEN("a block device and a device inode for that device") + { + auto device = kstd::make_shared(0, 0, "test_block_device", 512, 3 * 512); + auto inode = kernel::filesystem::device_inode{device}; + + WHEN("writing to the device inode") + { + kstd::vector write_buffer(1024); + for (size_t i = 0; i < write_buffer.size(); ++i) + { + write_buffer[i] = static_cast(i % 256); + } + + auto bytes_written = inode.write(write_buffer.data(), 256, write_buffer.size()); + + THEN("the correct number of bytes is written") + { + REQUIRE(bytes_written == 1024); + } + + THEN("the data written matches the data read back from the device inode") + { + kstd::vector read_buffer(1024); + auto bytes_read = inode.read(read_buffer.data(), 256, read_buffer.size()); + + REQUIRE(bytes_read == write_buffer.size()); + REQUIRE(read_buffer == write_buffer); + } + } + } +} + +SCENARIO("Device inode read/write with a non-block device", "[filesystem][device_inode]") +{ + GIVEN("a non-block device and a device inode for that device") + { + auto device = kstd::make_shared(0, 0, "test_character_device"); + auto inode = kernel::filesystem::device_inode{device}; + + WHEN("reading from the device inode") + { + kstd::vector read_buffer(512); + THEN("the system panics") + { + REQUIRE_THROWS_AS(inode.read(read_buffer.data(), 0, read_buffer.size()), kernel::tests::cpu::halt); + } + } + + WHEN("writing to the device inode") + { + kstd::vector write_buffer(512); + THEN("the system panics") + { + REQUIRE_THROWS_AS(inode.write(write_buffer.data(), 0, write_buffer.size()), kernel::tests::cpu::halt); + } + } + } +} -- cgit v1.2.3 From 153d061ddfcc6cb9bff1f691a3fe5415f94a3615 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 20:41:49 +0200 Subject: remove todos --- kernel/include/kernel/filesystem/inode.hpp | 1 - kernel/src/filesystem/filesystem.cpp | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp index 7237184..072f198 100644 --- a/kernel/include/kernel/filesystem/inode.hpp +++ b/kernel/include/kernel/filesystem/inode.hpp @@ -69,7 +69,6 @@ namespace kernel::filesystem */ [[nodiscard]] auto is_device() const -> bool; - // TODO BA-FS26 improve inode_kind really needed? public: inode_kind m_kind{inode_kind::regular}; }; diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index da2838d..d8b04eb 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -41,7 +41,11 @@ namespace kernel::filesystem auto filesystem::mount(kstd::shared_ptr const & device) -> operation_result { - // TODO BA-FS26 maybe check if device is null and panic here already? + if (!device) + { + kapi::system::panic("[FILESYSTEM] cannot mount filesystem: device is null."); + } + m_device = device; return operation_result::success; } -- cgit v1.2.3 From 597251886a0934315468f5ba4dc595910cbf734c Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 20:42:12 +0200 Subject: use separate test inode --- kernel/CMakeLists.txt | 1 + .../kernel/test_support/filesystem/inode.hpp | 19 +++++++++++++++++++ kernel/src/filesystem/dentry.tests.cpp | 8 ++++---- kernel/src/test_support/filesystem/inode.cpp | 22 ++++++++++++++++++++++ 4 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 kernel/include/kernel/test_support/filesystem/inode.hpp create mode 100644 kernel/src/test_support/filesystem/inode.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 53ed107..0025e4c 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -103,6 +103,7 @@ else() "src/test_support/kapi/memory.cpp" "src/test_support/devices/block_device.cpp" "src/test_support/devices/character_device.cpp" + "src/test_support/filesystem/inode.cpp" "src/test_support/log_buffer.cpp" "src/test_support/output_device.cpp" "src/test_support/page_mapper.cpp" diff --git a/kernel/include/kernel/test_support/filesystem/inode.hpp b/kernel/include/kernel/test_support/filesystem/inode.hpp new file mode 100644 index 0000000..6568f24 --- /dev/null +++ b/kernel/include/kernel/test_support/filesystem/inode.hpp @@ -0,0 +1,19 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_INODE_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_INODE_HPP + +#include "kernel/filesystem/inode.hpp" + +#include + +namespace kernel::tests::filesystem +{ + struct inode : kernel::filesystem::inode + { + inode(); + + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + }; +} // namespace kernel::tests::filesystem + +#endif diff --git a/kernel/src/filesystem/dentry.tests.cpp b/kernel/src/filesystem/dentry.tests.cpp index 94aa48d..a6620d3 100644 --- a/kernel/src/filesystem/dentry.tests.cpp +++ b/kernel/src/filesystem/dentry.tests.cpp @@ -1,7 +1,7 @@ #include "kernel/filesystem/dentry.hpp" -#include "kernel/filesystem/devfs/inode.hpp" #include "kernel/test_support/cpu.hpp" +#include "kernel/test_support/filesystem/inode.hpp" #include #include @@ -12,7 +12,7 @@ SCENARIO("Dentry construction", "[filesystem][dentry]") { GIVEN("A parent dentry and inode") { - auto inode = kstd::make_shared(); + auto inode = kstd::make_shared(); auto parent_dentry = kstd::make_shared(nullptr, inode); WHEN("constructing a dentry") @@ -80,7 +80,7 @@ SCENARIO("Dentry child logic", "[filesystem][dentry]") { GIVEN("A parent dentry and inode") { - auto inode = kstd::make_shared(); + auto inode = kstd::make_shared(); auto parent_dentry = kstd::make_shared(nullptr, inode); WHEN("adding child dentries") @@ -108,7 +108,7 @@ SCENARIO("Dentry Flag logic", "[filesystem][dentry]") { GIVEN("A dentry") { - auto inode = kstd::make_shared(); + auto inode = kstd::make_shared(); auto dentry = kernel::filesystem::dentry{nullptr, inode, "test"}; WHEN("setting a flag") diff --git a/kernel/src/test_support/filesystem/inode.cpp b/kernel/src/test_support/filesystem/inode.cpp new file mode 100644 index 0000000..6352d5a --- /dev/null +++ b/kernel/src/test_support/filesystem/inode.cpp @@ -0,0 +1,22 @@ +#include "kernel/test_support/filesystem/inode.hpp" + +#include "kernel/filesystem/inode.hpp" + +#include + +namespace kernel::tests::filesystem +{ + inode::inode() + : kernel::filesystem::inode(inode_kind::regular) + {} + + auto inode::read(void *, size_t, size_t) const -> size_t + { + return 0; + } + + auto inode::write(void const *, size_t, size_t) -> size_t + { + return 0; + } +} // namespace kernel::tests::filesystem \ No newline at end of file -- cgit v1.2.3 From 2500898ec94d5071fddb32432ed8041b8e9de26c Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 20:55:49 +0200 Subject: add test_support filesystem --- kernel/CMakeLists.txt | 1 + .../kernel/test_support/filesystem/filesystem.hpp | 22 ++++++++++++++++++++++ kernel/src/test_support/filesystem/filesystem.cpp | 17 +++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 kernel/include/kernel/test_support/filesystem/filesystem.hpp create mode 100644 kernel/src/test_support/filesystem/filesystem.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 0025e4c..502efcc 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -104,6 +104,7 @@ else() "src/test_support/devices/block_device.cpp" "src/test_support/devices/character_device.cpp" "src/test_support/filesystem/inode.cpp" + "src/test_support/filesystem/filesystem.cpp" "src/test_support/log_buffer.cpp" "src/test_support/output_device.cpp" "src/test_support/page_mapper.cpp" diff --git a/kernel/include/kernel/test_support/filesystem/filesystem.hpp b/kernel/include/kernel/test_support/filesystem/filesystem.hpp new file mode 100644 index 0000000..13aade4 --- /dev/null +++ b/kernel/include/kernel/test_support/filesystem/filesystem.hpp @@ -0,0 +1,22 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_FILESYSTEM_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_FILESYSTEM_HPP + +#include "kernel/filesystem/filesystem.hpp" +#include "kernel/filesystem/inode.hpp" + +#include + +#include + +namespace kernel::tests::filesystem +{ + struct filesystem : kernel::filesystem::filesystem + { + filesystem() = default; + + auto lookup(kstd::shared_ptr const & parent, std::string_view name) + -> kstd::shared_ptr override; + }; +} // namespace kernel::tests::filesystem + +#endif diff --git a/kernel/src/test_support/filesystem/filesystem.cpp b/kernel/src/test_support/filesystem/filesystem.cpp new file mode 100644 index 0000000..225d096 --- /dev/null +++ b/kernel/src/test_support/filesystem/filesystem.cpp @@ -0,0 +1,17 @@ +#include "kernel/test_support/filesystem/filesystem.hpp" + +#include "kernel/filesystem/inode.hpp" +#include "kernel/test_support/filesystem/inode.hpp" + +#include + +#include + +namespace kernel::tests::filesystem +{ + auto filesystem::lookup(kstd::shared_ptr const &, std::string_view) + -> kstd::shared_ptr + { + return kstd::make_shared(); + } +} // namespace kernel::tests::filesystem \ No newline at end of file -- cgit v1.2.3 From b36f4ed031bf8da10ccf2b97c9a61d71e672621e Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 20:56:06 +0200 Subject: add mount tests --- kernel/CMakeLists.txt | 1 + kernel/src/filesystem/mount.tests.cpp | 49 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 kernel/src/filesystem/mount.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 502efcc..c00ec14 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -133,6 +133,7 @@ else() # Filesystem Subsystem Tests "src/filesystem/dentry.tests.cpp" "src/filesystem/device_inode.tests.cpp" + "src/filesystem/mount.tests.cpp" # Storage Subsystem Tests "src/devices/block_device_utils.tests.cpp" diff --git a/kernel/src/filesystem/mount.tests.cpp b/kernel/src/filesystem/mount.tests.cpp new file mode 100644 index 0000000..4c4393a --- /dev/null +++ b/kernel/src/filesystem/mount.tests.cpp @@ -0,0 +1,49 @@ +#include "kernel/filesystem/mount.hpp" + +#include "kernel/filesystem/dentry.hpp" +#include "kernel/test_support/cpu.hpp" +#include "kernel/test_support/filesystem/filesystem.hpp" +#include "kernel/test_support/filesystem/inode.hpp" + +#include +#include +#include + +#include + +SCENARIO("Mount construction", "[filesystem][mount]") +{ + GIVEN("a filesystem and a root dentry") + { + auto fs = kstd::make_shared(); + auto root_inode = kstd::make_shared(); + auto root_dentry = kstd::make_shared(nullptr, root_inode, "/"); + + WHEN("constructing a mount with the filesystem and root dentry") + { + auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, "/", nullptr}; + + THEN("the mount has the correct filesystem, root dentry, mount dentry, and mount path") + { + REQUIRE(mount.get_filesystem() == fs); + REQUIRE(mount.root_dentry() == root_dentry); + REQUIRE(mount.get_mount_dentry() == root_dentry); + REQUIRE(mount.get_mount_path() == "/"); + } + + THEN("the mount has no parent mount") + { + REQUIRE(mount.get_parent_mount() == nullptr); + } + } + + WHEN("constructing a mount with a null filesystem") + { + THEN("the constructor panics") + { + REQUIRE_THROWS_AS((kernel::filesystem::mount{root_dentry, root_dentry, nullptr, "/", nullptr}), + kernel::tests::cpu::halt); + } + } + } +} -- cgit v1.2.3 From f4e210b1e6169df99db621ca624555027047bc50 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 21:08:08 +0200 Subject: add mount_table tests --- kernel/CMakeLists.txt | 1 + kernel/src/filesystem/mount_table.tests.cpp | 164 ++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 kernel/src/filesystem/mount_table.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index c00ec14..d7f2cc4 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -133,6 +133,7 @@ else() # Filesystem Subsystem Tests "src/filesystem/dentry.tests.cpp" "src/filesystem/device_inode.tests.cpp" + "src/filesystem/mount_table.tests.cpp" "src/filesystem/mount.tests.cpp" # Storage Subsystem Tests diff --git a/kernel/src/filesystem/mount_table.tests.cpp b/kernel/src/filesystem/mount_table.tests.cpp new file mode 100644 index 0000000..9f390c6 --- /dev/null +++ b/kernel/src/filesystem/mount_table.tests.cpp @@ -0,0 +1,164 @@ +#include "kernel/filesystem/mount_table.hpp" + +#include "kernel/filesystem/dentry.hpp" +#include "kernel/filesystem/mount.hpp" +#include "kernel/test_support/cpu.hpp" +#include "kernel/test_support/filesystem/filesystem.hpp" +#include "kernel/test_support/filesystem/inode.hpp" + +#include +#include +#include + +#include + +#include + +SCENARIO("Mount table construction", "[filesystem][mount_table]") +{ + GIVEN("an empty mount table") + { + kernel::filesystem::mount_table table; + + THEN("finding any mount returns null") + { + REQUIRE(table.find_longest_prefix_mount("/") == nullptr); + REQUIRE(table.find_longest_prefix_mount("/any/path") == nullptr); + } + + THEN("removing any mount returns mount_not_found") + { + REQUIRE(table.remove_mount("/") == kernel::filesystem::mount_table::operation_result::mount_not_found); + REQUIRE(table.remove_mount("/any/path") == kernel::filesystem::mount_table::operation_result::mount_not_found); + } + } +} + +SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem][mount_table]") +{ + GIVEN("a mount table and some mounts") + { + kernel::filesystem::mount_table table; + + auto fs1 = kstd::make_shared(); + auto root_inode1 = kstd::make_shared(); + auto root_dentry1 = kstd::make_shared(nullptr, root_inode1, "/"); + auto mount1 = kstd::make_shared(root_dentry1, root_dentry1, fs1, "/", nullptr); + + auto fs2 = kstd::make_shared(); + auto root_inode2 = kstd::make_shared(); + auto root_dentry2 = kstd::make_shared(nullptr, root_inode2, "/"); + auto mount2 = kstd::make_shared(root_dentry1, root_dentry2, fs2, "/mnt", nullptr); + + table.add_mount(mount1); + table.add_mount(mount2); + + THEN("dentry flags are set correctly for mounted dentries") + { + REQUIRE(root_dentry1->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + REQUIRE(root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + } + + THEN("finding mounts by path returns the correct mount") + { + REQUIRE(table.find_longest_prefix_mount("/") == mount1); + REQUIRE(table.find_longest_prefix_mount("/file") == mount1); + REQUIRE(table.find_longest_prefix_mount("/mnt") == mount2); + REQUIRE(table.find_longest_prefix_mount("/mnt/file") == mount2); + REQUIRE(table.find_longest_prefix_mount("/other") == mount1); + } + + THEN("removing a mount that has no child mounts succeeds") + { + REQUIRE(table.remove_mount("/mnt") == kernel::filesystem::mount_table::operation_result::removed); + REQUIRE(!root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + REQUIRE(table.find_longest_prefix_mount("/mnt") == nullptr); + } + + THEN("removing a mount that does not exist returns mount_not_found") + { + REQUIRE(table.remove_mount("/nonexistent") == kernel::filesystem::mount_table::operation_result::mount_not_found); + } + } + + GIVEN("multiple mounts with the same path") + { + kernel::filesystem::mount_table table; + + auto fs1 = kstd::make_shared(); + auto root_inode1 = kstd::make_shared(); + auto root_dentry1 = kstd::make_shared(nullptr, root_inode1, "/"); + auto mount1 = kstd::make_shared(root_dentry1, root_dentry1, fs1, "/", nullptr); + + auto fs2 = kstd::make_shared(); + auto root_inode2 = kstd::make_shared(); + auto root_dentry2 = kstd::make_shared(nullptr, root_inode2, "/"); + auto mount2 = kstd::make_shared(root_dentry1, root_dentry2, fs2, "/", mount1); + + table.add_mount(mount1); + table.add_mount(mount2); + + THEN("finding mounts by path returns the correct mount based on longest prefix") + { + REQUIRE(table.find_longest_prefix_mount("/") == mount2); + REQUIRE(table.find_longest_prefix_mount("/file") == mount2); + REQUIRE(table.find_longest_prefix_mount("/mnt") == mount2); + REQUIRE(table.find_longest_prefix_mount("/mnt/file") == mount2); + REQUIRE(table.find_longest_prefix_mount("/other") == mount2); + } + + THEN("removing the topmost mount with the same path succeeds") + { + REQUIRE(table.remove_mount("/") == kernel::filesystem::mount_table::operation_result::removed); + REQUIRE(!root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + REQUIRE(table.find_longest_prefix_mount("/") == mount1); + } + } + + GIVEN("a mount with child mounts") + { + kernel::filesystem::mount_table table; + + auto fs1 = kstd::make_shared(); + auto root_inode1 = kstd::make_shared(); + auto root_dentry1 = kstd::make_shared(nullptr, root_inode1, "/"); + auto mount1 = kstd::make_shared(root_dentry1, root_dentry1, fs1, "/", nullptr); + + auto fs2 = kstd::make_shared(); + auto root_inode2 = kstd::make_shared(); + auto root_dentry2 = kstd::make_shared(nullptr, root_inode2, "/"); + auto mount2 = kstd::make_shared(root_dentry1, root_dentry2, fs2, "/mnt", mount1); + + auto fs3 = kstd::make_shared(); + auto root_inode3 = kstd::make_shared(); + auto root_dentry3 = kstd::make_shared(nullptr, root_inode3, "/"); + auto mount3 = kstd::make_shared(root_dentry2, root_dentry3, fs3, "/mnt/submnt", mount2); + + table.add_mount(mount1); + table.add_mount(mount2); + table.add_mount(mount3); + + THEN("finding mounts by path returns the correct mount based on longest prefix") + { + REQUIRE(table.find_longest_prefix_mount("/") == mount1); + REQUIRE(table.find_longest_prefix_mount("/file") == mount1); + REQUIRE(table.find_longest_prefix_mount("/mnt") == mount2); + REQUIRE(table.find_longest_prefix_mount("/mnt/file") == mount2); + REQUIRE(table.find_longest_prefix_mount("/mnt/submnt") == mount3); + REQUIRE(table.find_longest_prefix_mount("/other") == mount1); + } + + THEN("removing a mount with child mounts returns has_child_mounts") + { + REQUIRE(table.remove_mount("/") == kernel::filesystem::mount_table::operation_result::has_child_mounts); + REQUIRE(table.remove_mount("/mnt") == kernel::filesystem::mount_table::operation_result::has_child_mounts); + } + + THEN("removing a leaf mount succeeds") + { + REQUIRE(table.remove_mount("/mnt/submnt") == kernel::filesystem::mount_table::operation_result::removed); + REQUIRE(!root_dentry3->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + REQUIRE(table.find_longest_prefix_mount("/mnt/submnt") == nullptr); + } + } +} -- cgit v1.2.3 From 7a7c0106257665358e68bbbc99b41acc0c87c0ba Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 21:16:14 +0200 Subject: fix mount table tests --- kernel/src/filesystem/mount_table.tests.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/mount_table.tests.cpp b/kernel/src/filesystem/mount_table.tests.cpp index 9f390c6..439fe97 100644 --- a/kernel/src/filesystem/mount_table.tests.cpp +++ b/kernel/src/filesystem/mount_table.tests.cpp @@ -2,7 +2,6 @@ #include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/mount.hpp" -#include "kernel/test_support/cpu.hpp" #include "kernel/test_support/filesystem/filesystem.hpp" #include "kernel/test_support/filesystem/inode.hpp" @@ -56,7 +55,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("dentry flags are set correctly for mounted dentries") { REQUIRE(root_dentry1->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); - REQUIRE(root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + REQUIRE(!root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); } THEN("finding mounts by path returns the correct mount") @@ -72,7 +71,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] { REQUIRE(table.remove_mount("/mnt") == kernel::filesystem::mount_table::operation_result::removed); REQUIRE(!root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); - REQUIRE(table.find_longest_prefix_mount("/mnt") == nullptr); + REQUIRE(table.find_longest_prefix_mount("/mnt") == mount1); } THEN("removing a mount that does not exist returns mount_not_found") @@ -158,7 +157,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] { REQUIRE(table.remove_mount("/mnt/submnt") == kernel::filesystem::mount_table::operation_result::removed); REQUIRE(!root_dentry3->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); - REQUIRE(table.find_longest_prefix_mount("/mnt/submnt") == nullptr); + REQUIRE(table.find_longest_prefix_mount("/mnt/submnt") == mount2); } } } -- cgit v1.2.3 From af048d3e550bc2a7a6526f4c9714871e32bf7cf4 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 21:38:50 +0200 Subject: add open_file_description tests --- kernel/CMakeLists.txt | 1 + .../kernel/filesystem/open_file_description.hpp | 6 +++ kernel/src/filesystem/open_file_description.cpp | 6 +++ .../src/filesystem/open_file_description.tests.cpp | 60 ++++++++++++++++++++++ kernel/src/test_support/filesystem/inode.cpp | 8 +-- 5 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 kernel/src/filesystem/open_file_description.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index d7f2cc4..f578632 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -135,6 +135,7 @@ else() "src/filesystem/device_inode.tests.cpp" "src/filesystem/mount_table.tests.cpp" "src/filesystem/mount.tests.cpp" + "src/filesystem/open_file_description.tests.cpp" # Storage Subsystem Tests "src/devices/block_device_utils.tests.cpp" diff --git a/kernel/include/kernel/filesystem/open_file_description.hpp b/kernel/include/kernel/filesystem/open_file_description.hpp index ed878a7..738afd4 100644 --- a/kernel/include/kernel/filesystem/open_file_description.hpp +++ b/kernel/include/kernel/filesystem/open_file_description.hpp @@ -46,6 +46,12 @@ namespace kernel::filesystem */ auto write(void const * buffer, size_t size) -> size_t; + /** + @brief Returns the current file offset for this open file description. + @return The current file offset in bytes. + */ + [[nodiscard]] auto offset() const -> size_t; + private: kstd::shared_ptr m_inode; size_t m_offset; diff --git a/kernel/src/filesystem/open_file_description.cpp b/kernel/src/filesystem/open_file_description.cpp index 8c04225..f049a34 100644 --- a/kernel/src/filesystem/open_file_description.cpp +++ b/kernel/src/filesystem/open_file_description.cpp @@ -32,4 +32,10 @@ namespace kernel::filesystem m_offset += written_bytes; return written_bytes; } + + auto open_file_description::offset() const -> size_t + { + return m_offset; + } + } // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/open_file_description.tests.cpp b/kernel/src/filesystem/open_file_description.tests.cpp new file mode 100644 index 0000000..f045094 --- /dev/null +++ b/kernel/src/filesystem/open_file_description.tests.cpp @@ -0,0 +1,60 @@ +#include "kernel/filesystem/open_file_description.hpp" + +#include "kernel/test_support/filesystem/inode.hpp" + +#include +#include +#include + +#include + +SCENARIO("Open file description construction", "[filesystem][open_file_description]") +{ + GIVEN("an inode and an open file description for that inode") + { + auto inode = kstd::make_shared(); + auto file_description = kernel::filesystem::open_file_description{inode}; + + THEN("the initial offset is zero") + { + REQUIRE(file_description.offset() == 0); + } + } +} + +SCENARIO("Open file description read/write offset management", "[filesystem][open_file_description]") +{ + GIVEN("an inode that tracks read/write calls and an open file description for that inode") + { + auto inode = kstd::make_shared(); + auto file_description = kernel::filesystem::open_file_description{inode}; + + THEN("the offset is updated correctly after reads") + { + REQUIRE(file_description.read(nullptr, 100) == 100); + REQUIRE(file_description.offset() == 100); + REQUIRE(file_description.read(nullptr, 50) == 50); + REQUIRE(file_description.offset() == 150); + } + + THEN("the offset is updated correctly after writes") + { + REQUIRE(file_description.write(nullptr, 200) == 200); + REQUIRE(file_description.offset() == 200); + REQUIRE(file_description.write(nullptr, 25) == 25); + REQUIRE(file_description.offset() == 225); + } + + THEN("reads and writes both update the same offset") + { + REQUIRE(file_description.read(nullptr, 10) == 10); + REQUIRE(file_description.offset() == 10); + REQUIRE(file_description.write(nullptr, 20) == 20); + REQUIRE(file_description.offset() == 30); + REQUIRE(file_description.read(nullptr, 5) == 5); + REQUIRE(file_description.offset() == 35); + REQUIRE(file_description.write(nullptr, 15) == 15); + REQUIRE(file_description.offset() == 50); + } + } +} diff --git a/kernel/src/test_support/filesystem/inode.cpp b/kernel/src/test_support/filesystem/inode.cpp index 6352d5a..5df7bcd 100644 --- a/kernel/src/test_support/filesystem/inode.cpp +++ b/kernel/src/test_support/filesystem/inode.cpp @@ -10,13 +10,13 @@ namespace kernel::tests::filesystem : kernel::filesystem::inode(inode_kind::regular) {} - auto inode::read(void *, size_t, size_t) const -> size_t + auto inode::read(void *, size_t, size_t size) const -> size_t { - return 0; + return size; } - auto inode::write(void const *, size_t, size_t) -> size_t + auto inode::write(void const *, size_t, size_t size) -> size_t { - return 0; + return size; } } // namespace kernel::tests::filesystem \ No newline at end of file -- cgit v1.2.3 From 530a478b3e755ef4585b27422a33bd0de1556ce2 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 22:12:51 +0200 Subject: add file_descriptor_table tests --- kernel/CMakeLists.txt | 1 + .../kernel/filesystem/file_descriptor_table.hpp | 6 + kernel/src/filesystem/file_descriptor_table.cpp | 5 + .../src/filesystem/file_descriptor_table.tests.cpp | 155 +++++++++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 kernel/src/filesystem/file_descriptor_table.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index f578632..b664def 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -133,6 +133,7 @@ else() # Filesystem Subsystem Tests "src/filesystem/dentry.tests.cpp" "src/filesystem/device_inode.tests.cpp" + "src/filesystem/file_descriptor_table.tests.cpp" "src/filesystem/mount_table.tests.cpp" "src/filesystem/mount.tests.cpp" "src/filesystem/open_file_description.tests.cpp" diff --git a/kernel/include/kernel/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/filesystem/file_descriptor_table.hpp index 5d52c19..cc31511 100644 --- a/kernel/include/kernel/filesystem/file_descriptor_table.hpp +++ b/kernel/include/kernel/filesystem/file_descriptor_table.hpp @@ -28,6 +28,12 @@ namespace kernel::filesystem */ auto static get() -> file_descriptor_table &; + /** + @brief Reset the file descriptor table to an empty state. This method is intended for testing purposes to allow + resetting the state of the file descriptor table between test cases. + */ + auto static reset() -> void; + /** @brief Destructor for the file descriptor table. */ diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp index 287aea2..a31e2e6 100644 --- a/kernel/src/filesystem/file_descriptor_table.cpp +++ b/kernel/src/filesystem/file_descriptor_table.cpp @@ -37,6 +37,11 @@ namespace kernel::filesystem return *global_file_descriptor_table; } + auto file_descriptor_table::reset() -> void + { + global_file_descriptor_table.reset(); + } + auto file_descriptor_table::add_file(kstd::shared_ptr const & file_description) -> int { if (!file_description) diff --git a/kernel/src/filesystem/file_descriptor_table.tests.cpp b/kernel/src/filesystem/file_descriptor_table.tests.cpp new file mode 100644 index 0000000..c431d01 --- /dev/null +++ b/kernel/src/filesystem/file_descriptor_table.tests.cpp @@ -0,0 +1,155 @@ +#include "kernel/filesystem/file_descriptor_table.hpp" + +#include "kernel/filesystem/open_file_description.hpp" +#include "kernel/test_support/cpu.hpp" +#include "kernel/test_support/filesystem/inode.hpp" + +#include +#include +#include + +#include + +struct file_descriptor_table_RAII +{ + file_descriptor_table_RAII() + { + kernel::filesystem::file_descriptor_table::init(); + } + ~file_descriptor_table_RAII() + { + kernel::filesystem::file_descriptor_table::reset(); + } +}; + +struct file_descriptor_table_reset_only +{ + ~file_descriptor_table_reset_only() + { + kernel::filesystem::file_descriptor_table::reset(); + } +}; + +SCENARIO_METHOD(file_descriptor_table_reset_only, "File descriptor table initialization", + "[filesystem][file_descriptor_table]") +{ + THEN("accessing the file descriptor table before initialization panics") + { + REQUIRE_THROWS_AS(kernel::filesystem::file_descriptor_table::get(), kernel::tests::cpu::halt); + } + + THEN("the file descriptor table can be initialized and accessed") + { + kernel::filesystem::file_descriptor_table::init(); + REQUIRE_NOTHROW(kernel::filesystem::file_descriptor_table::get()); + } + + THEN("initializing the file descriptor table more than once panics") + { + kernel::filesystem::file_descriptor_table::init(); + REQUIRE_THROWS_AS(kernel::filesystem::file_descriptor_table::init(), kernel::tests::cpu::halt); + } +} + +SCENARIO_METHOD(file_descriptor_table_RAII, "File descriptor table add/get file", "[filesystem][file_descriptor_table]") +{ + GIVEN("a file descriptor table and an open file description") + { + auto & table = kernel::filesystem::file_descriptor_table::get(); + auto inode = kstd::make_shared(); + auto file_description_1 = kstd::make_shared(inode); + auto file_description_2 = kstd::make_shared(inode); + + WHEN("adding the open file description to the file descriptor table") + { + auto fd_1 = table.add_file(file_description_1); + auto fd_2 = table.add_file(file_description_2); + auto fd_3 = table.add_file(file_description_2); + + THEN("a valid file descriptor is returned") + { + REQUIRE(fd_1 == 0); + REQUIRE(fd_2 == 1); + REQUIRE(fd_3 == 1); + } + + THEN("the file description can be retrieved using the returned file descriptor") + { + auto retrieved_description = table.get_file(fd_1); + REQUIRE(retrieved_description == file_description_1); + } + } + } + + GIVEN("a invalid open file description") + { + auto & table = kernel::filesystem::file_descriptor_table::get(); + + THEN("adding a null file description returns an error code") + { + auto fd = table.add_file(nullptr); + REQUIRE(fd == -1); + } + + THEN("retrieving a file description with a negative file descriptor returns a null pointer") + { + auto retrieved_description = table.get_file(-1); + REQUIRE(retrieved_description == nullptr); + } + + THEN("retrieving a file description with an out-of-bounds file descriptor returns a null pointer") + { + auto retrieved_description = table.get_file(1000); + REQUIRE(retrieved_description == nullptr); + } + } +} + +SCENARIO_METHOD(file_descriptor_table_RAII, "File descriptor table remove file", "[filesystem][file_descriptor_table]") +{ + GIVEN("a file descriptor table with an open file description") + { + auto & table = kernel::filesystem::file_descriptor_table::get(); + auto inode = kstd::make_shared(); + auto file_description = kstd::make_shared(inode); + auto fd = table.add_file(file_description); + + WHEN("removing the file description using the file descriptor") + { + table.remove_file(fd); + + THEN("the file description can no longer be retrieved using the file descriptor") + { + auto retrieved_description = table.get_file(fd); + REQUIRE(retrieved_description == nullptr); + } + } + + WHEN("removing a file description the other file descriptor keep the same index") + { + auto fd2 = table.add_file(file_description); + table.remove_file(fd); + + THEN("the second file description can still be retrieved using its file descriptor") + { + auto retrieved_description = table.get_file(fd2); + REQUIRE(retrieved_description == file_description); + } + } + } + + GIVEN("an invalid file descriptor") + { + auto & table = kernel::filesystem::file_descriptor_table::get(); + + THEN("removing a file with a negative file descriptor does nothing") + { + REQUIRE_NOTHROW(table.remove_file(-1)); + } + + THEN("removing a file with an out-of-bounds file descriptor does nothing") + { + REQUIRE_NOTHROW(table.remove_file(1000)); + } + } +} \ No newline at end of file -- cgit v1.2.3 From 643cbff68aa0a5e029b9ce46eb69846c8b01dca7 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 22:17:15 +0200 Subject: fix test --- kernel/src/filesystem/file_descriptor_table.tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/file_descriptor_table.tests.cpp b/kernel/src/filesystem/file_descriptor_table.tests.cpp index c431d01..d8c05ca 100644 --- a/kernel/src/filesystem/file_descriptor_table.tests.cpp +++ b/kernel/src/filesystem/file_descriptor_table.tests.cpp @@ -70,7 +70,7 @@ SCENARIO_METHOD(file_descriptor_table_RAII, "File descriptor table add/get file" { REQUIRE(fd_1 == 0); REQUIRE(fd_2 == 1); - REQUIRE(fd_3 == 1); + REQUIRE(fd_3 == 2); } THEN("the file description can be retrieved using the returned file descriptor") -- cgit v1.2.3 From 60118b1df5196c4e416ddd6ad2a40be062f68251 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 22:57:55 +0200 Subject: add devfs and rootfs inode tests --- kernel/CMakeLists.txt | 2 + kernel/src/filesystem/devfs/inode.tests.cpp | 54 ++++++++++++++++++ kernel/src/filesystem/rootfs/inode.tests.cpp | 83 ++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 kernel/src/filesystem/devfs/inode.tests.cpp create mode 100644 kernel/src/filesystem/rootfs/inode.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index b664def..e3a357b 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -131,6 +131,8 @@ else() "src/memory/block_list_allocator.tests.cpp" # Filesystem Subsystem Tests + "src/filesystem/devfs/inode.tests.cpp" + "src/filesystem/rootfs/inode.tests.cpp" "src/filesystem/dentry.tests.cpp" "src/filesystem/device_inode.tests.cpp" "src/filesystem/file_descriptor_table.tests.cpp" diff --git a/kernel/src/filesystem/devfs/inode.tests.cpp b/kernel/src/filesystem/devfs/inode.tests.cpp new file mode 100644 index 0000000..50e34a7 --- /dev/null +++ b/kernel/src/filesystem/devfs/inode.tests.cpp @@ -0,0 +1,54 @@ +#include "kernel/filesystem/devfs/inode.hpp" + +#include +#include +#include + +#include + +#include + +SCENARIO("Devfs inode creation", "[filesystem][devfs][inode]") +{ + GIVEN("a devfs inode") + { + auto inode = kernel::filesystem::devfs::inode{}; + + THEN("the inode has the correct kind") + { + REQUIRE(inode.is_directory()); + REQUIRE_FALSE(inode.is_device()); + REQUIRE_FALSE(inode.is_regular()); + } + } +} + +SCENARIO("Devfs inode read/write", "[filesystem][devfs][inode]") +{ + GIVEN("a devfs inode") + { + auto inode = kernel::filesystem::devfs::inode{}; + + WHEN("attempting to read from the devfs inode") + { + kstd::vector buffer(512); + auto bytes_read = inode.read(buffer.data(), 0, buffer.size()); + + THEN("no bytes are read") + { + REQUIRE(bytes_read == 0); + } + } + + WHEN("attempting to write to the devfs inode") + { + kstd::vector buffer(512); + auto bytes_written = inode.write(buffer.data(), 0, buffer.size()); + + THEN("no bytes are written") + { + REQUIRE(bytes_written == 0); + } + } + } +} diff --git a/kernel/src/filesystem/rootfs/inode.tests.cpp b/kernel/src/filesystem/rootfs/inode.tests.cpp new file mode 100644 index 0000000..a0c5938 --- /dev/null +++ b/kernel/src/filesystem/rootfs/inode.tests.cpp @@ -0,0 +1,83 @@ +#include "kernel/filesystem/rootfs/inode.hpp" + +#include +#include +#include + +#include + +SCENARIO("Rootfs inode creation", "[filesystem][rootfs][inode]") +{ + GIVEN("a rootfs inode") + { + auto inode = kernel::filesystem::rootfs::inode{}; + + THEN("the inode has the correct kind") + { + REQUIRE(inode.is_directory()); + REQUIRE_FALSE(inode.is_device()); + REQUIRE_FALSE(inode.is_regular()); + } + + THEN("the inode has no children") + { + REQUIRE(inode.lookup_child("child") == nullptr); + } + } +} + +SCENARIO("Rootfs inode child management", "[filesystem][rootfs][inode]") +{ + GIVEN("a rootfs inode") + { + auto inode = kernel::filesystem::rootfs::inode{}; + + WHEN("adding a child inode") + { + inode.add_child("child"); + inode.add_child("another child"); + + THEN("the child can be looked up by name") + { + auto child_inode = inode.lookup_child("child"); + REQUIRE(child_inode != nullptr); + REQUIRE(child_inode->is_directory()); + } + + THEN("looking up a non-existent child returns null") + { + REQUIRE(inode.lookup_child("nonexistent") == nullptr); + } + } + } +} + +SCENARIO("Rootfs inode read/write", "[filesystem][rootfs][inode]") +{ + GIVEN("a rootfs inode") + { + auto inode = kernel::filesystem::rootfs::inode{}; + + WHEN("reading from the inode") + { + kstd::vector buffer(10); + auto bytes_read = inode.read(buffer.data(), 0, buffer.size()); + + THEN("no bytes are read") + { + REQUIRE(bytes_read == 0); + } + } + + WHEN("writing to the inode") + { + kstd::vector buffer(10, 'x'); + auto bytes_written = inode.write(buffer.data(), 0, buffer.size()); + + THEN("no bytes are written") + { + REQUIRE(bytes_written == 0); + } + } + } +} -- cgit v1.2.3 From 9ce8ed3dd3aa5f6e21b53d02bac4f62eb8b3f337 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 8 Apr 2026 23:04:40 +0200 Subject: add rootfs filesystem tests --- kernel/CMakeLists.txt | 1 + kernel/src/filesystem/rootfs/filesystem.tests.cpp | 45 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 kernel/src/filesystem/rootfs/filesystem.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index e3a357b..1cbb9e4 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -132,6 +132,7 @@ else() # Filesystem Subsystem Tests "src/filesystem/devfs/inode.tests.cpp" + "src/filesystem/rootfs/filesystem.tests.cpp" "src/filesystem/rootfs/inode.tests.cpp" "src/filesystem/dentry.tests.cpp" "src/filesystem/device_inode.tests.cpp" diff --git a/kernel/src/filesystem/rootfs/filesystem.tests.cpp b/kernel/src/filesystem/rootfs/filesystem.tests.cpp new file mode 100644 index 0000000..b013f78 --- /dev/null +++ b/kernel/src/filesystem/rootfs/filesystem.tests.cpp @@ -0,0 +1,45 @@ +#include "kernel/filesystem/rootfs/filesystem.hpp" + +#include "kernel/filesystem/filesystem.hpp" + +#include +#include +#include + +#include + +SCENARIO("Rootfs filesystem mount and lookup", "[filesystem][rootfs][filesystem]") +{ + GIVEN("a mounted rootfs filesystem") + { + auto fs = kernel::filesystem::rootfs::filesystem{}; + auto result = fs.mount(nullptr); + + THEN("the filesystem can be mounted successfully") + { + REQUIRE(result == kernel::filesystem::filesystem::operation_result::success); + REQUIRE(fs.root_inode() != nullptr); + } + + THEN("looking up the 'dev' directory returns a valid inode") + { + auto dev_inode = fs.lookup(fs.root_inode(), "dev"); + REQUIRE(dev_inode != nullptr); + REQUIRE(dev_inode->is_directory()); + } + + THEN("looking up a non-existent directory returns null") + { + auto non_existent_inode_1 = fs.lookup(fs.root_inode(), ""); + REQUIRE(non_existent_inode_1 == nullptr); + auto non_existent_inode_2 = fs.lookup(fs.root_inode(), "nonexistent"); + REQUIRE(non_existent_inode_2 == nullptr); + } + + THEN("looking up with a null parent inode returns null") + { + auto result = fs.lookup(nullptr, "dev"); + REQUIRE(result == nullptr); + } + } +} -- 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/filesystem/file_descriptor_table.hpp | 6 --- .../include/kernel/test_support/boot_modules.hpp | 10 +++++ .../test_support/devices/storage/management.hpp | 10 +++++ .../filesystem/file_descriptor_table.hpp | 10 +++++ .../include/kernel/test_support/filesystem/vfs.hpp | 10 +++++ kernel/kapi/boot_modules.cpp | 19 ++++++--- kernel/src/devices/storage/management.cpp | 28 ++++++++----- kernel/src/filesystem/file_descriptor_table.cpp | 25 ++++++------ .../src/filesystem/file_descriptor_table.tests.cpp | 46 +--------------------- kernel/src/filesystem/vfs.cpp | 24 +++++++---- kernel/src/test_support/state_reset_listener.cpp | 12 ++++++ 11 files changed, 116 insertions(+), 84 deletions(-) create mode 100644 kernel/include/kernel/test_support/boot_modules.hpp create mode 100644 kernel/include/kernel/test_support/devices/storage/management.hpp create mode 100644 kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp create mode 100644 kernel/include/kernel/test_support/filesystem/vfs.hpp (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/filesystem/file_descriptor_table.hpp index cc31511..5d52c19 100644 --- a/kernel/include/kernel/filesystem/file_descriptor_table.hpp +++ b/kernel/include/kernel/filesystem/file_descriptor_table.hpp @@ -28,12 +28,6 @@ namespace kernel::filesystem */ auto static get() -> file_descriptor_table &; - /** - @brief Reset the file descriptor table to an empty state. This method is intended for testing purposes to allow - resetting the state of the file descriptor table between test cases. - */ - auto static reset() -> void; - /** @brief Destructor for the file descriptor table. */ diff --git a/kernel/include/kernel/test_support/boot_modules.hpp b/kernel/include/kernel/test_support/boot_modules.hpp new file mode 100644 index 0000000..2343a10 --- /dev/null +++ b/kernel/include/kernel/test_support/boot_modules.hpp @@ -0,0 +1,10 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_BOOT_MODULES_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_BOOT_MODULES_HPP + +namespace kernel::tests::boot_modules +{ + //! Deinitialize the boot module registry. + auto deinit() -> void; +} // namespace kernel::tests::boot_modules + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/devices/storage/management.hpp b/kernel/include/kernel/test_support/devices/storage/management.hpp new file mode 100644 index 0000000..7c0d304 --- /dev/null +++ b/kernel/include/kernel/test_support/devices/storage/management.hpp @@ -0,0 +1,10 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_DEVICES_STORAGE_MANAGEMENT_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_DEVICES_STORAGE_MANAGEMENT_HPP + +namespace kernel::tests::devices::storage +{ + //! Deinitialize the storage management singleton. + auto deinit() -> void; +} // namespace kernel::tests::devices::storage + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp new file mode 100644 index 0000000..bbc0f4a --- /dev/null +++ b/kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp @@ -0,0 +1,10 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP + +namespace kernel::tests::filesystem::file_descriptor_table +{ + //! Deinitialize the file descriptor table singleton. + auto deinit() -> void; +} // namespace kernel::tests::filesystem::file_descriptor_table + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/filesystem/vfs.hpp b/kernel/include/kernel/test_support/filesystem/vfs.hpp new file mode 100644 index 0000000..739e353 --- /dev/null +++ b/kernel/include/kernel/test_support/filesystem/vfs.hpp @@ -0,0 +1,10 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_VFS_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_VFS_HPP + +namespace kernel::tests::filesystem::vfs +{ + //! Deinitialize the VFS singleton. + auto deinit() -> void; +} // namespace kernel::tests::filesystem::vfs + +#endif \ No newline at end of file diff --git a/kernel/kapi/boot_modules.cpp b/kernel/kapi/boot_modules.cpp index 5a0ef7f..0549368 100644 --- a/kernel/kapi/boot_modules.cpp +++ b/kernel/kapi/boot_modules.cpp @@ -4,14 +4,13 @@ #include -namespace kapi::boot_modules +namespace { + constinit auto static registry = std::optional{}; +} // namespace - namespace - { - constinit auto static registry = std::optional{}; - } // namespace - +namespace kapi::boot_modules +{ auto set_boot_module_registry(boot_module_registry & new_registry) -> void { if (registry) @@ -32,3 +31,11 @@ namespace kapi::boot_modules return *registry; } } // namespace kapi::boot_modules + +namespace kernel::tests::boot_modules +{ + auto deinit() -> void + { + registry.reset(); + } +} // namespace kernel::tests::boot_modules 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 diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp index a31e2e6..1c062a1 100644 --- a/kernel/src/filesystem/file_descriptor_table.cpp +++ b/kernel/src/filesystem/file_descriptor_table.cpp @@ -10,13 +10,13 @@ #include #include -namespace kernel::filesystem +namespace { - namespace - { - constinit auto static global_file_descriptor_table = std::optional{}; - } // namespace + constinit auto static global_file_descriptor_table = std::optional{}; +} // namespace +namespace kernel::filesystem +{ auto file_descriptor_table::init() -> void { if (global_file_descriptor_table) @@ -37,11 +37,6 @@ namespace kernel::filesystem return *global_file_descriptor_table; } - auto file_descriptor_table::reset() -> void - { - global_file_descriptor_table.reset(); - } - auto file_descriptor_table::add_file(kstd::shared_ptr const & file_description) -> int { if (!file_description) @@ -92,4 +87,12 @@ namespace kernel::filesystem m_open_files.at(index) = nullptr; } -} // namespace kernel::filesystem \ No newline at end of file +} // namespace kernel::filesystem + +namespace kernel::tests::filesystem::file_descriptor_table +{ + auto deinit() -> void + { + global_file_descriptor_table.reset(); + } +} // namespace kernel::tests::filesystem::file_descriptor_table diff --git a/kernel/src/filesystem/file_descriptor_table.tests.cpp b/kernel/src/filesystem/file_descriptor_table.tests.cpp index d8c05ca..5aeadb2 100644 --- a/kernel/src/filesystem/file_descriptor_table.tests.cpp +++ b/kernel/src/filesystem/file_descriptor_table.tests.cpp @@ -1,7 +1,6 @@ #include "kernel/filesystem/file_descriptor_table.hpp" #include "kernel/filesystem/open_file_description.hpp" -#include "kernel/test_support/cpu.hpp" #include "kernel/test_support/filesystem/inode.hpp" #include @@ -10,48 +9,7 @@ #include -struct file_descriptor_table_RAII -{ - file_descriptor_table_RAII() - { - kernel::filesystem::file_descriptor_table::init(); - } - ~file_descriptor_table_RAII() - { - kernel::filesystem::file_descriptor_table::reset(); - } -}; - -struct file_descriptor_table_reset_only -{ - ~file_descriptor_table_reset_only() - { - kernel::filesystem::file_descriptor_table::reset(); - } -}; - -SCENARIO_METHOD(file_descriptor_table_reset_only, "File descriptor table initialization", - "[filesystem][file_descriptor_table]") -{ - THEN("accessing the file descriptor table before initialization panics") - { - REQUIRE_THROWS_AS(kernel::filesystem::file_descriptor_table::get(), kernel::tests::cpu::halt); - } - - THEN("the file descriptor table can be initialized and accessed") - { - kernel::filesystem::file_descriptor_table::init(); - REQUIRE_NOTHROW(kernel::filesystem::file_descriptor_table::get()); - } - - THEN("initializing the file descriptor table more than once panics") - { - kernel::filesystem::file_descriptor_table::init(); - REQUIRE_THROWS_AS(kernel::filesystem::file_descriptor_table::init(), kernel::tests::cpu::halt); - } -} - -SCENARIO_METHOD(file_descriptor_table_RAII, "File descriptor table add/get file", "[filesystem][file_descriptor_table]") +SCENARIO("File descriptor table add/get file", "[filesystem][file_descriptor_table]") { GIVEN("a file descriptor table and an open file description") { @@ -105,7 +63,7 @@ SCENARIO_METHOD(file_descriptor_table_RAII, "File descriptor table add/get file" } } -SCENARIO_METHOD(file_descriptor_table_RAII, "File descriptor table remove file", "[filesystem][file_descriptor_table]") +SCENARIO("File descriptor table remove file", "[filesystem][file_descriptor_table]") { GIVEN("a file descriptor table with an open file description") { diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 45ae053..67d1af2 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -17,13 +17,13 @@ #include #include -namespace kernel::filesystem +namespace { - namespace - { - constinit auto static active_vfs = std::optional{}; - } // namespace + constinit auto static active_vfs = std::optional{}; +} // namespace +namespace kernel::filesystem +{ auto vfs::init() -> void { if (active_vfs) @@ -47,7 +47,10 @@ namespace kernel::filesystem if (auto boot_device = storage_mgmt.determine_boot_device()) { auto boot_root_fs = kernel::filesystem::filesystem::probe_and_mount(boot_device); - do_mount_internal("/", root_fs_root_dentry, boot_root_fs); + if (boot_root_fs) + { + do_mount_internal("/", root_fs_root_dentry, boot_root_fs); + } } auto device_fs = kstd::make_shared(); @@ -172,5 +175,12 @@ namespace kernel::filesystem return current_dentry; } +} // namespace kernel::filesystem -} // namespace kernel::filesystem \ No newline at end of file +namespace kernel::tests::filesystem::vfs +{ + auto deinit() -> void + { + active_vfs.reset(); + } +} // namespace kernel::tests::filesystem::vfs diff --git a/kernel/src/test_support/state_reset_listener.cpp b/kernel/src/test_support/state_reset_listener.cpp index 8c95cc8..af1091c 100644 --- a/kernel/src/test_support/state_reset_listener.cpp +++ b/kernel/src/test_support/state_reset_listener.cpp @@ -2,8 +2,13 @@ #include "kapi/cpu.hpp" #include "kapi/memory.hpp" +#include "kernel/filesystem/file_descriptor_table.hpp" +#include "kernel/test_support/boot_modules.hpp" #include "kernel/test_support/cio.hpp" #include "kernel/test_support/cpu.hpp" +#include "kernel/test_support/devices/storage/management.hpp" +#include "kernel/test_support/filesystem/file_descriptor_table.hpp" +#include "kernel/test_support/filesystem/vfs.hpp" #include "kernel/test_support/memory.hpp" #include @@ -17,6 +22,8 @@ struct state_reset_listener : Catch::EventListenerBase void testCaseStarting(Catch::TestCaseInfo const &) override { + kernel::filesystem::file_descriptor_table::init(); + kapi::cio::init(); kapi::cpu::init(); kapi::memory::init(); @@ -24,6 +31,11 @@ struct state_reset_listener : Catch::EventListenerBase void testCaseEnded(Catch::TestCaseStats const &) override { + kernel::tests::filesystem::file_descriptor_table::deinit(); + kernel::tests::filesystem::vfs::deinit(); + kernel::tests::devices::storage::deinit(); + kernel::tests::boot_modules::deinit(); + kernel::tests::memory::deinit(); kernel::tests::cpu::deinit(); kernel::tests::cio::deinit(); -- 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/CMakeLists.txt | 2 + .../test_support/devices/storage/management.hpp | 4 +- .../filesystem/storage_boot_module_fixture.hpp | 23 ++++++++ kernel/src/devices/storage/management.cpp | 4 +- kernel/src/filesystem/devfs/filesystem.tests.cpp | 63 ++++++++++++++++++++++ .../filesystem/storage_boot_module_fixture.cpp | 43 +++++++++++++++ kernel/src/test_support/state_reset_listener.cpp | 2 +- 7 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp create mode 100644 kernel/src/filesystem/devfs/filesystem.tests.cpp create mode 100644 kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 1cbb9e4..6a2e4b5 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -105,6 +105,7 @@ else() "src/test_support/devices/character_device.cpp" "src/test_support/filesystem/inode.cpp" "src/test_support/filesystem/filesystem.cpp" + "src/test_support/filesystem/storage_boot_module_fixture.cpp" "src/test_support/log_buffer.cpp" "src/test_support/output_device.cpp" "src/test_support/page_mapper.cpp" @@ -131,6 +132,7 @@ else() "src/memory/block_list_allocator.tests.cpp" # Filesystem Subsystem Tests + "src/filesystem/devfs/filesystem.tests.cpp" "src/filesystem/devfs/inode.tests.cpp" "src/filesystem/rootfs/filesystem.tests.cpp" "src/filesystem/rootfs/inode.tests.cpp" diff --git a/kernel/include/kernel/test_support/devices/storage/management.hpp b/kernel/include/kernel/test_support/devices/storage/management.hpp index 7c0d304..581aa91 100644 --- a/kernel/include/kernel/test_support/devices/storage/management.hpp +++ b/kernel/include/kernel/test_support/devices/storage/management.hpp @@ -1,10 +1,10 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_DEVICES_STORAGE_MANAGEMENT_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_DEVICES_STORAGE_MANAGEMENT_HPP -namespace kernel::tests::devices::storage +namespace kernel::tests::devices::storage::management { //! Deinitialize the storage management singleton. auto deinit() -> void; -} // namespace kernel::tests::devices::storage +} // namespace kernel::tests::devices::storage::management #endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp b/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp new file mode 100644 index 0000000..a57659b --- /dev/null +++ b/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp @@ -0,0 +1,23 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_STORAGE_BOOT_MODULE_FIXTURE_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_STORAGE_BOOT_MODULE_FIXTURE_HPP + +#include "kapi/boot_module/boot_module_registry.hpp" + +#include +#include +#include + +namespace kernel::tests::filesystem +{ + struct storage_boot_module_fixture + { + auto setup_modules(std::size_t module_count, std::size_t module_size = 4096) -> void; + + protected: + kapi::boot_modules::boot_module_registry registry{}; + std::vector module_names{}; + std::vector> module_data{}; + }; +} // namespace kernel::tests::filesystem + +#endif \ No newline at end of file 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 diff --git a/kernel/src/filesystem/devfs/filesystem.tests.cpp b/kernel/src/filesystem/devfs/filesystem.tests.cpp new file mode 100644 index 0000000..1d82bf9 --- /dev/null +++ b/kernel/src/filesystem/devfs/filesystem.tests.cpp @@ -0,0 +1,63 @@ +#include "kernel/filesystem/devfs/filesystem.hpp" + +#include "kernel/filesystem/filesystem.hpp" +#include "kernel/test_support/filesystem/storage_boot_module_fixture.hpp" + +#include + +SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, + "Devfs filesystem lookup uses storage management devices", "[filesystem][devfs][filesystem]") +{ + GIVEN("a boot module registry with one module") + { + setup_modules(1); + + auto fs = kernel::filesystem::devfs::filesystem{}; + auto result = fs.mount(nullptr); + + THEN("mount succeeds") + { + REQUIRE(result == kernel::filesystem::filesystem::operation_result::success); + REQUIRE(fs.root_inode() != nullptr); + } + + THEN("lookup on root finds ram0 device inode") + { + auto inode = fs.lookup(fs.root_inode(), "ram0"); + REQUIRE(inode != nullptr); + REQUIRE(inode->is_device()); + } + + THEN("lookup of an unknown device returns null") + { + auto inode = fs.lookup(fs.root_inode(), "ram99"); + REQUIRE(inode == nullptr); + } + + THEN("lookup with a non-directory parent returns null") + { + auto non_directory_inode = fs.lookup(fs.root_inode(), "ram0"); + REQUIRE(non_directory_inode != nullptr); + REQUIRE(!non_directory_inode->is_directory()); + + auto result = fs.lookup(non_directory_inode, "anything"); + REQUIRE(result == nullptr); + } + } + + GIVEN("a boot module registry with three modules") + { + setup_modules(3, 2048); + + auto fs = kernel::filesystem::devfs::filesystem{}; + auto result = fs.mount(nullptr); + REQUIRE(result == kernel::filesystem::filesystem::operation_result::success); + + THEN("lookup finds all generated RAM devices") + { + REQUIRE(fs.lookup(fs.root_inode(), "ram0") != nullptr); + REQUIRE(fs.lookup(fs.root_inode(), "ram16") != nullptr); + REQUIRE(fs.lookup(fs.root_inode(), "ram32") != nullptr); + } + } +} diff --git a/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp b/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp new file mode 100644 index 0000000..8bbf194 --- /dev/null +++ b/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp @@ -0,0 +1,43 @@ +#include "kernel/test_support/filesystem/storage_boot_module_fixture.hpp" + +#include "kapi/boot_module/boot_module.hpp" +#include "kapi/boot_modules.hpp" +#include "kapi/memory.hpp" + +#include "kernel/devices/storage/management.hpp" +#include "kernel/test_support/boot_modules.hpp" +#include "kernel/test_support/devices/storage/management.hpp" + +#include +#include + +namespace kernel::tests::filesystem +{ + auto storage_boot_module_fixture::setup_modules(std::size_t module_count, std::size_t module_size) -> void + { + kernel::tests::devices::storage::management::deinit(); + kernel::tests::boot_modules::deinit(); + + module_names.clear(); + module_data.clear(); + registry = {}; + + module_names.reserve(module_count); + module_data.reserve(module_count); + + for (std::size_t i = 0; i < module_count; ++i) + { + module_names.push_back("test_mod" + std::to_string(i)); + module_data.emplace_back(module_size, std::byte{static_cast(0x40 + (i % 16))}); + } + + for (std::size_t i = 0; i < module_count; ++i) + { + registry.add_boot_module(kapi::boot_modules::boot_module{ + module_names[i], kapi::memory::linear_address{module_data[i].data()}, module_data[i].size()}); + } + + kapi::boot_modules::set_boot_module_registry(registry); + kernel::devices::storage::management::init(); + } +} // namespace kernel::tests::filesystem \ No newline at end of file diff --git a/kernel/src/test_support/state_reset_listener.cpp b/kernel/src/test_support/state_reset_listener.cpp index af1091c..9120c89 100644 --- a/kernel/src/test_support/state_reset_listener.cpp +++ b/kernel/src/test_support/state_reset_listener.cpp @@ -33,8 +33,8 @@ struct state_reset_listener : Catch::EventListenerBase { kernel::tests::filesystem::file_descriptor_table::deinit(); kernel::tests::filesystem::vfs::deinit(); - kernel::tests::devices::storage::deinit(); kernel::tests::boot_modules::deinit(); + kernel::tests::devices::storage::management::deinit(); kernel::tests::memory::deinit(); kernel::tests::cpu::deinit(); -- cgit v1.2.3 From 186bc5c9a08c5d6e0d306ce8b4fe3d75f4782cd2 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 9 Apr 2026 09:19:40 +0200 Subject: add test for devfs edge case --- kernel/src/filesystem/devfs/filesystem.tests.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'kernel') diff --git a/kernel/src/filesystem/devfs/filesystem.tests.cpp b/kernel/src/filesystem/devfs/filesystem.tests.cpp index 1d82bf9..f8c4764 100644 --- a/kernel/src/filesystem/devfs/filesystem.tests.cpp +++ b/kernel/src/filesystem/devfs/filesystem.tests.cpp @@ -34,6 +34,15 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, REQUIRE(inode == nullptr); } + THEN("lookup with wrong parent returns null") + { + auto other_fs = kernel::filesystem::devfs::filesystem{}; + other_fs.mount(nullptr); + + auto inode = fs.lookup(other_fs.root_inode(), "ram0"); + REQUIRE(inode == nullptr); + } + THEN("lookup with a non-directory parent returns null") { auto non_directory_inode = fs.lookup(fs.root_inode(), "ram0"); -- cgit v1.2.3 From 787671aac288590e40c5cabfc9f82a31f21629fe Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 9 Apr 2026 10:33:38 +0200 Subject: add vfs tests with real ext2 images --- kernel/CMakeLists.txt | 9 +- .../filesystem/storage_boot_module_fixture.hpp | 19 ++- .../filesystem/storage_boot_module_vfs_fixture.hpp | 24 +++ kernel/src/filesystem/vfs.tests.cpp | 166 +++++++++++++++++++++ .../filesystem/storage_boot_module_fixture.cpp | 90 +++++++++-- .../filesystem/storage_boot_module_vfs_fixture.cpp | 32 ++++ .../filesystem/test_assets/ext2_1KB_fs.img | 3 + .../filesystem/test_assets/ext2_2KB_fs.img | 3 + .../filesystem/test_assets/ext2_4KB_fs.img | 3 + 9 files changed, 330 insertions(+), 19 deletions(-) create mode 100644 kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp create mode 100644 kernel/src/filesystem/vfs.tests.cpp create mode 100644 kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp create mode 100644 kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img create mode 100644 kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img create mode 100644 kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 6a2e4b5..88d420b 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -106,7 +106,7 @@ else() "src/test_support/filesystem/inode.cpp" "src/test_support/filesystem/filesystem.cpp" "src/test_support/filesystem/storage_boot_module_fixture.cpp" - "src/test_support/log_buffer.cpp" + "src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp" "src/test_support/log_buffer.cpp" "src/test_support/output_device.cpp" "src/test_support/page_mapper.cpp" "src/test_support/simulated_memory.cpp" @@ -142,7 +142,8 @@ else() "src/filesystem/mount_table.tests.cpp" "src/filesystem/mount.tests.cpp" "src/filesystem/open_file_description.tests.cpp" - + "src/filesystem/vfs.tests.cpp" + # Storage Subsystem Tests "src/devices/block_device_utils.tests.cpp" "src/devices/block_device.tests.cpp" @@ -155,6 +156,10 @@ else() "os::kernel_test_support" ) + target_compile_definitions("kernel_tests" PRIVATE + KERNEL_TEST_ASSETS_DIR="${CMAKE_CURRENT_SOURCE_DIR}/src/test_support/filesystem/test_assets" + ) + set_target_properties("kernel_tests" PROPERTIES C_CLANG_TIDY "" CXX_CLANG_TIDY "" diff --git a/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp b/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp index a57659b..ee658e2 100644 --- a/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp +++ b/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp @@ -3,20 +3,29 @@ #include "kapi/boot_module/boot_module_registry.hpp" +#include +#include + #include -#include -#include +#include namespace kernel::tests::filesystem { struct storage_boot_module_fixture { + ~storage_boot_module_fixture(); + auto setup_modules(std::size_t module_count, std::size_t module_size = 4096) -> void; + auto setup_modules_from_img(kstd::vector const & module_names, + kstd::vector const & img_paths) -> void; protected: - kapi::boot_modules::boot_module_registry registry{}; - std::vector module_names{}; - std::vector> module_data{}; + kapi::boot_modules::boot_module_registry m_registry{}; + kstd::vector m_module_names{}; + kstd::vector> m_module_data{}; + + private: + auto setup_module_from_img(kstd::string const & module_name, std::filesystem::path const & img_path) -> void; }; } // namespace kernel::tests::filesystem diff --git a/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp b/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp new file mode 100644 index 0000000..98012b0 --- /dev/null +++ b/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp @@ -0,0 +1,24 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_STORAGE_BOOT_MODULE_VFS_FIXTURE_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_STORAGE_BOOT_MODULE_VFS_FIXTURE_HPP + +#include "kernel/test_support/filesystem/storage_boot_module_fixture.hpp" + +#include +#include + +#include +#include + +namespace kernel::tests::filesystem +{ + struct storage_boot_module_vfs_fixture : storage_boot_module_fixture + { + ~storage_boot_module_vfs_fixture(); + + auto setup_modules_and_init_vfs(std::size_t module_count, std::size_t module_size = 4096) -> void; + auto setup_modules_from_img_and_init_vfs(kstd::vector const & module_names, + kstd::vector const & img_paths) -> void; + }; +} // namespace kernel::tests::filesystem + +#endif \ No newline at end of file diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp new file mode 100644 index 0000000..fec32e1 --- /dev/null +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -0,0 +1,166 @@ +#include "kernel/filesystem/vfs.hpp" + +#include "kernel/devices/storage/management.hpp" +#include "kernel/filesystem/filesystem.hpp" +#include "kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp" + +#include + +#include + +SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS with dummy modules", + "[filesystem][vfs]") +{ + GIVEN("an initialized boot module registry with multiple modules") + { + REQUIRE_NOTHROW(setup_modules_and_init_vfs(5)); + + THEN("vfs initializes and provides /dev mount") + { + auto & vfs = kernel::filesystem::vfs::get(); + auto dev = vfs.open("/dev"); + + REQUIRE(dev != nullptr); + } + + THEN("vfs initializes root filesystem with boot device if boot module is present") + { + auto & vfs = kernel::filesystem::vfs::get(); + auto root_file = vfs.open("/"); + + REQUIRE(root_file != nullptr); + } + } +} + +SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS with file backed image", + "[filesystem][vfs][img]") +{ + auto const image_path_1 = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_1KB_fs.img"; + auto const image_path_2 = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_2KB_fs.img"; + auto const image_path_3 = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_4KB_fs.img"; + + GIVEN("a real image file") + { + REQUIRE(std::filesystem::exists(image_path_1)); + REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module"}, {image_path_1})); + + THEN("vfs initializes and provides expected mount points") + { + auto & volatilefs = kernel::filesystem::vfs::get(); + auto root = volatilefs.open("/"); + auto dev = volatilefs.open("/dev"); + auto information = volatilefs.open("/information/info_1.txt"); + + REQUIRE(root != nullptr); + REQUIRE(dev != nullptr); + REQUIRE(information != nullptr); + } + } + + GIVEN("three real image files") + { + REQUIRE(std::filesystem::exists(image_path_1)); + REQUIRE(std::filesystem::exists(image_path_2)); + REQUIRE(std::filesystem::exists(image_path_3)); + REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module_1", "test_img_module_2", "test_img_module_3"}, + {image_path_1, image_path_2, image_path_3})); + + auto & vfs = kernel::filesystem::vfs::get(); + auto storage_mgmt = kernel::devices::storage::management::get(); + auto device_1 = storage_mgmt.device_by_major_minor(1, 16); + auto fs_1 = kernel::filesystem::filesystem::probe_and_mount(device_1); + auto device_2 = storage_mgmt.device_by_major_minor(1, 32); + auto fs_2 = kernel::filesystem::filesystem::probe_and_mount(device_2); + + THEN("vfs initializes first module as root") + { + auto & vfs = kernel::filesystem::vfs::get(); + auto info1 = vfs.open("/information/info_1.txt"); + auto info2 = vfs.open("/information/info_2.txt"); + + REQUIRE(info1 != nullptr); + REQUIRE(info2 != nullptr); + } + + THEN("second image can be mounted, data retrieved and unmounted again") + { + REQUIRE(vfs.do_mount("/information", fs_1) == kernel::filesystem::vfs::operation_result::success); + + auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); + REQUIRE(mounted_monkey_1 != nullptr); + + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); + auto unmounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); + REQUIRE(unmounted_monkey_1 == nullptr); + + auto info_1 = vfs.open("/information/info_1.txt"); + REQUIRE(info_1 != nullptr); + } + + THEN("third image can be mounted in a mounted file system, unmount only if no child mount exists") + { + REQUIRE(vfs.do_mount("/information", fs_1) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/information/monkey_house/infrastructure", fs_2) == + kernel::filesystem::vfs::operation_result::success); + + auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); + auto mounted_fish1 = vfs.open("/information/monkey_house/infrastructure/enclosures/aquarium/tank_1/fish_1.txt"); + + REQUIRE(mounted_monkey_1 != nullptr); + REQUIRE(mounted_fish1 != nullptr); + + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); + REQUIRE(vfs.unmount("/information/monkey_house/infrastructure") == + kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); + } + + THEN("images can be stacked mounted and correct file system is unmounted again") + { + REQUIRE(vfs.do_mount("/information", fs_1) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/information", fs_2) == kernel::filesystem::vfs::operation_result::success); + + auto mounted_tickets = vfs.open("/information/entrance/tickets.txt"); + REQUIRE(mounted_tickets != nullptr); + + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); + mounted_tickets = vfs.open("/information/entrance/tickets.txt"); + REQUIRE(mounted_tickets == nullptr); + + auto mounted_monkey = vfs.open("/information/monkey_house/monkey_1.txt"); + REQUIRE(mounted_monkey != nullptr); + } + + THEN("mount with null file system fails") + { + REQUIRE(vfs.do_mount("/information", nullptr) == kernel::filesystem::vfs::operation_result::filesystem_null); + } + + THEN("mount with invalid path fails") + { + REQUIRE(vfs.do_mount("", fs_1) == kernel::filesystem::vfs::operation_result::invalid_path); + REQUIRE(vfs.do_mount("information", fs_1) == kernel::filesystem::vfs::operation_result::invalid_path); + REQUIRE(vfs.do_mount("/information/", fs_1) == kernel::filesystem::vfs::operation_result::invalid_path); + } + + THEN("mount with non-existent mount point fails") + { + REQUIRE(vfs.do_mount("/information/nonexistent", fs_1) == + kernel::filesystem::vfs::operation_result::mount_point_not_found); + } + + THEN("unmount with invalid path fails") + { + REQUIRE(vfs.unmount("") == kernel::filesystem::vfs::operation_result::invalid_path); + REQUIRE(vfs.unmount("information") == kernel::filesystem::vfs::operation_result::invalid_path); + REQUIRE(vfs.unmount("/information/") == kernel::filesystem::vfs::operation_result::invalid_path); + } + + THEN("unmounting non-existent mount point returns expected error code") + { + REQUIRE(vfs.unmount("/information/nonexistent") == + kernel::filesystem::vfs::operation_result::mount_point_not_found); + } + } +} diff --git a/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp b/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp index 8bbf194..a139f63 100644 --- a/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp +++ b/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp @@ -8,36 +8,102 @@ #include "kernel/test_support/boot_modules.hpp" #include "kernel/test_support/devices/storage/management.hpp" +#include +#include + #include -#include +#include +#include +#include +#include namespace kernel::tests::filesystem { - auto storage_boot_module_fixture::setup_modules(std::size_t module_count, std::size_t module_size) -> void + storage_boot_module_fixture::~storage_boot_module_fixture() { kernel::tests::devices::storage::management::deinit(); kernel::tests::boot_modules::deinit(); + } - module_names.clear(); - module_data.clear(); - registry = {}; + auto storage_boot_module_fixture::setup_modules(std::size_t module_count, std::size_t module_size) -> void + { + m_module_names.clear(); + m_module_data.clear(); + m_registry = {}; - module_names.reserve(module_count); - module_data.reserve(module_count); + m_module_names.reserve(module_count); + m_module_data.reserve(module_count); for (std::size_t i = 0; i < module_count; ++i) { - module_names.push_back("test_mod" + std::to_string(i)); - module_data.emplace_back(module_size, std::byte{static_cast(0x40 + (i % 16))}); + m_module_names.push_back("test_mod" + kstd::to_string(i)); + m_module_data.emplace_back(module_size, std::byte{static_cast(0x40 + (i % 16))}); } for (std::size_t i = 0; i < module_count; ++i) { - registry.add_boot_module(kapi::boot_modules::boot_module{ - module_names[i], kapi::memory::linear_address{module_data[i].data()}, module_data[i].size()}); + m_registry.add_boot_module(kapi::boot_modules::boot_module{ + m_module_names[i].view(), kapi::memory::linear_address{m_module_data[i].data()}, m_module_data[i].size()}); + } + + kapi::boot_modules::set_boot_module_registry(m_registry); + kernel::devices::storage::management::init(); + } + + auto storage_boot_module_fixture::setup_modules_from_img(kstd::vector const & module_names, + kstd::vector const & img_paths) + -> void + { + m_module_names.clear(); + m_module_data.clear(); + m_registry = {}; + + if (module_names.size() != img_paths.size()) + { + throw std::invalid_argument{"Module names and image paths vectors must have the same size."}; + } + + for (size_t i = 0; i < module_names.size(); ++i) + { + setup_module_from_img(module_names[i], img_paths[i]); } - kapi::boot_modules::set_boot_module_registry(registry); + kapi::boot_modules::set_boot_module_registry(m_registry); kernel::devices::storage::management::init(); } + + auto storage_boot_module_fixture::setup_module_from_img(kstd::string const & module_name, + std::filesystem::path const & img_path) -> void + { + auto file = std::ifstream{img_path, std::ios::binary | std::ios::ate}; + if (!file) + { + throw std::runtime_error{"Failed to open image file for test boot module: " + img_path.string()}; + } + + auto const end_pos = file.tellg(); + if (end_pos < 0) + { + throw std::runtime_error{"Failed to determine image file size for test boot module: " + img_path.string()}; + } + + auto const size = static_cast(end_pos); + file.seekg(0, std::ios::beg); + + m_module_names.push_back(module_name); + m_module_data.emplace_back(size); + + if (size > 0) + { + file.read(reinterpret_cast(m_module_data.back().data()), static_cast(size)); + if (!file) + { + throw std::runtime_error{"Failed to read image file content for test boot module: " + img_path.string()}; + } + } + + m_registry.add_boot_module(kapi::boot_modules::boot_module{ + m_module_names.back().view(), kapi::memory::linear_address{m_module_data.back().data()}, + m_module_data.back().size()}); + } } // namespace kernel::tests::filesystem \ No newline at end of file diff --git a/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp b/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp new file mode 100644 index 0000000..cba7278 --- /dev/null +++ b/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp @@ -0,0 +1,32 @@ +#include "kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp" + +#include "kernel/filesystem/vfs.hpp" +#include "kernel/test_support/filesystem/vfs.hpp" + +#include +#include + +#include +#include + +namespace kernel::tests::filesystem +{ + storage_boot_module_vfs_fixture::~storage_boot_module_vfs_fixture() + { + kernel::tests::filesystem::vfs::deinit(); + } + + auto storage_boot_module_vfs_fixture::setup_modules_and_init_vfs(std::size_t module_count, std::size_t module_size) + -> void + { + setup_modules(module_count, module_size); + kernel::filesystem::vfs::init(); + } + + auto storage_boot_module_vfs_fixture::setup_modules_from_img_and_init_vfs( + kstd::vector const & module_names, kstd::vector const & img_paths) -> void + { + setup_modules_from_img(module_names, img_paths); + kernel::filesystem::vfs::init(); + } +} // namespace kernel::tests::filesystem \ No newline at end of file diff --git a/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img b/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img new file mode 100644 index 0000000..9f1ee4a --- /dev/null +++ b/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:94d3988bc309eb9e81f06042c72bf4c4fb5991cd7fdd597eb00c518a96c792d8 +size 10485760 diff --git a/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img b/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img new file mode 100644 index 0000000..1880911 --- /dev/null +++ b/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a13da5abb9c65c737105b1da0d4344c7cd7604c7952c762c4f4e3d3f96fd42d +size 5242880 diff --git a/kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img b/kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img new file mode 100644 index 0000000..3aaceb8 --- /dev/null +++ b/kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ce6a1aea277906e1af6de223c017ff900b96569f076b4d99fc04eaa1ee986f4 +size 10485760 -- cgit v1.2.3 From a03d4d9acc5115ec3f651b06f94ced9a7c0e192f Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 9 Apr 2026 10:56:25 +0200 Subject: add open_file_description tests with real image --- .../src/filesystem/open_file_description.tests.cpp | 54 ++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'kernel') diff --git a/kernel/src/filesystem/open_file_description.tests.cpp b/kernel/src/filesystem/open_file_description.tests.cpp index f045094..db8eb49 100644 --- a/kernel/src/filesystem/open_file_description.tests.cpp +++ b/kernel/src/filesystem/open_file_description.tests.cpp @@ -1,6 +1,8 @@ #include "kernel/filesystem/open_file_description.hpp" +#include "kernel/filesystem/vfs.hpp" #include "kernel/test_support/filesystem/inode.hpp" +#include "kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp" #include #include @@ -8,6 +10,10 @@ #include +#include +#include +#include + SCENARIO("Open file description construction", "[filesystem][open_file_description]") { GIVEN("an inode and an open file description for that inode") @@ -58,3 +64,51 @@ SCENARIO("Open file description read/write offset management", "[filesystem][ope } } } + +SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, + "Open file description read with real image", "[filesystem][open_file_description][img]") +{ + auto const image_path = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_1KB_fs.img"; + + GIVEN("an open file description for a file in a real image") + { + REQUIRE(std::filesystem::exists(image_path)); + REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module"}, {image_path})); + + auto & vfs = kernel::filesystem::vfs::get(); + auto ofd = vfs.open("/information/info_1.txt"); + REQUIRE(ofd != nullptr); + + THEN("the file can be read and the offset is updated") + { + kstd::vector buffer(32); + auto bytes_read = ofd->read(buffer.data(), buffer.size()); + REQUIRE(bytes_read == 32); + REQUIRE(ofd->offset() == 32); + + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(bytes_read)}; + auto const content_end = buffer_as_str.find('\0'); + REQUIRE(buffer_as_str.substr(0, content_end) == "info_1\n"); + + for (auto i = content_end; i < buffer_as_str.size(); ++i) + { + REQUIRE(buffer_as_str[i] == '\0'); + } + } + + THEN("the file can be read multiple times") + { + kstd::vector buffer(4); + auto bytes_read_1 = ofd->read(buffer.data(), buffer.size() / 2); + REQUIRE(bytes_read_1 == buffer.size() / 2); + REQUIRE(ofd->offset() == buffer.size() / 2); + + auto bytes_read_2 = ofd->read(buffer.data() + buffer.size() / 2, buffer.size() / 2); + REQUIRE(bytes_read_2 == buffer.size() / 2); + REQUIRE(ofd->offset() == buffer.size()); + + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), bytes_read_1 + bytes_read_2}; + REQUIRE(buffer_as_str == "info"); + } + } +} -- cgit v1.2.3 From 01d5f1b29fa04c69ac9f942a1075354ce5b25da2 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 9 Apr 2026 12:32:50 +0200 Subject: add ext2 inode and filesystem tests --- kernel/CMakeLists.txt | 3 + .../include/kernel/filesystem/ext2/filesystem.hpp | 21 +++ .../kernel/test_support/filesystem/ext2.hpp | 17 +++ kernel/src/filesystem/ext2/filesystem.cpp | 38 ++--- kernel/src/filesystem/ext2/filesystem.tests.cpp | 132 +++++++++++++++++ kernel/src/filesystem/ext2/inode.tests.cpp | 159 +++++++++++++++++++++ kernel/src/test_support/filesystem/ext2.cpp | 62 ++++++++ 7 files changed, 406 insertions(+), 26 deletions(-) create mode 100644 kernel/include/kernel/test_support/filesystem/ext2.hpp create mode 100644 kernel/src/filesystem/ext2/filesystem.tests.cpp create mode 100644 kernel/src/filesystem/ext2/inode.tests.cpp create mode 100644 kernel/src/test_support/filesystem/ext2.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 88d420b..2f6113a 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -105,6 +105,7 @@ else() "src/test_support/devices/character_device.cpp" "src/test_support/filesystem/inode.cpp" "src/test_support/filesystem/filesystem.cpp" + "src/test_support/filesystem/ext2.cpp" "src/test_support/filesystem/storage_boot_module_fixture.cpp" "src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp" "src/test_support/log_buffer.cpp" "src/test_support/output_device.cpp" @@ -134,6 +135,8 @@ else() # Filesystem Subsystem Tests "src/filesystem/devfs/filesystem.tests.cpp" "src/filesystem/devfs/inode.tests.cpp" + "src/filesystem/ext2/filesystem.tests.cpp" + "src/filesystem/ext2/inode.tests.cpp" "src/filesystem/rootfs/filesystem.tests.cpp" "src/filesystem/rootfs/inode.tests.cpp" "src/filesystem/dentry.tests.cpp" diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index 65324c8..a71385f 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -18,6 +18,27 @@ namespace kernel::filesystem::ext2 { + /** + @brief Constants related to the ext2 filesystem. + */ + namespace constants + { + constexpr size_t inline base_block_size = 1024; + constexpr size_t inline superblock_offset = base_block_size; + constexpr uint16_t inline magic_number = 0xEF53; + + constexpr uint32_t inline root_inode_number = 2; + + constexpr size_t inline direct_block_count = 12; + constexpr size_t inline singly_indirect_block_index = direct_block_count; + constexpr size_t inline doubly_indirect_block_index = singly_indirect_block_index + 1; + constexpr size_t inline triply_indirect_block_index = doubly_indirect_block_index + 1; + + constexpr uint16_t inline mode_mask = 0xF000; + constexpr uint16_t inline mode_regular = 0x8000; + constexpr uint16_t inline mode_directory = 0x4000; + } // namespace constants + /** @brief A filesystem implementation for the ext2 filesystem format. This class provides methods for mounting an ext2 filesystem, and looking up inodes. diff --git a/kernel/include/kernel/test_support/filesystem/ext2.hpp b/kernel/include/kernel/test_support/filesystem/ext2.hpp new file mode 100644 index 0000000..edbda29 --- /dev/null +++ b/kernel/include/kernel/test_support/filesystem/ext2.hpp @@ -0,0 +1,17 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_EXT2_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_EXT2_HPP + +#include "kernel/test_support/devices/block_device.hpp" + +#include +#include + +namespace kernel::tests::filesystem::ext2 +{ + auto write_bytes(kernel::tests::devices::block_device & device, size_t offset, void const * source, size_t size) + -> void; + auto write_u32(kernel::tests::devices::block_device & device, size_t offset, uint32_t value) -> void; + auto setup_mock_ext2_layout(kernel::tests::devices::block_device & device) -> void; +} // namespace kernel::tests::filesystem::ext2 + +#endif \ No newline at end of file diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 6d5960e..0ad5c97 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -21,29 +21,14 @@ namespace kernel::filesystem::ext2 { namespace { - constexpr size_t SUPERBLOCK_OFFSET = 1024; - constexpr uint16_t MAGIC_NUMBER = 0xEF53; - - constexpr uint32_t ROOT_INODE_NUMBER = 2; - - constexpr size_t DIRECT_BLOCK_COUNT = 12; - constexpr size_t SINGLY_INDIRECT_BLOCK_INDEX = DIRECT_BLOCK_COUNT; - constexpr size_t DOUBLY_INDIRECT_BLOCK_INDEX = SINGLY_INDIRECT_BLOCK_INDEX + 1; - constexpr size_t TRIPLY_INDIRECT_BLOCK_INDEX = DOUBLY_INDIRECT_BLOCK_INDEX + 1; - - // Mode bits - constexpr uint16_t S_IFMT = 0xF000; - constexpr uint16_t S_IFREG = 0x8000; - constexpr uint16_t S_IFDIR = 0x4000; - auto S_ISREG(uint16_t mode) -> bool { - return (mode & S_IFMT) == S_IFREG; + return (mode & constants::mode_mask) == constants::mode_regular; } auto S_ISDIR(uint16_t mode) -> bool { - return (mode & S_IFMT) == S_IFDIR; + return (mode & constants::mode_mask) == constants::mode_directory; } } // namespace @@ -51,9 +36,10 @@ namespace kernel::filesystem::ext2 { kernel::filesystem::filesystem::mount(device); - kernel::devices::block_device_utils::read(m_device, &m_superblock, SUPERBLOCK_OFFSET, sizeof(m_superblock)); + kernel::devices::block_device_utils::read(m_device, &m_superblock, constants::superblock_offset, + sizeof(m_superblock)); - if (m_superblock.magic != MAGIC_NUMBER) + if (m_superblock.magic != constants::magic_number) { return operation_result::invalid_magic_number; } @@ -69,7 +55,7 @@ namespace kernel::filesystem::ext2 block_group_descriptor_table_offset, num_block_groups * sizeof(block_group_descriptor)); - m_root_inode = read_inode(ROOT_INODE_NUMBER); + m_root_inode = read_inode(constants::root_inode_number); if (!m_root_inode || !m_root_inode->is_directory()) { @@ -161,11 +147,11 @@ namespace kernel::filesystem::ext2 auto filesystem::map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) -> uint32_t { - if (inode_block_index < DIRECT_BLOCK_COUNT) + if (inode_block_index < constants::direct_block_count) { return data.block.at(inode_block_index); } - inode_block_index -= DIRECT_BLOCK_COUNT; + inode_block_index -= constants::direct_block_count; auto const block_size = get_block_size(); auto const numbers_per_block = block_size / sizeof(uint32_t); @@ -176,14 +162,14 @@ namespace kernel::filesystem::ext2 if (inode_block_index < block_numbers_per_singly_indirect_block) { - auto const singly_indirect_block_number = data.block.at(SINGLY_INDIRECT_BLOCK_INDEX); + auto const singly_indirect_block_number = data.block.at(constants::singly_indirect_block_index); return read_block_number_at_index(singly_indirect_block_number, inode_block_index); } inode_block_index -= block_numbers_per_singly_indirect_block; if (inode_block_index < block_numbers_per_doubly_indirect_block) { - auto const doubly_indirect_block_number = data.block.at(DOUBLY_INDIRECT_BLOCK_INDEX); + auto const doubly_indirect_block_number = data.block.at(constants::doubly_indirect_block_index); auto const singly_indirect_block_index_in_doubly_indirect_block = inode_block_index / block_numbers_per_singly_indirect_block; auto const singly_indirect_block_number = read_block_number_at_index( @@ -196,7 +182,7 @@ namespace kernel::filesystem::ext2 if (inode_block_index < block_numbers_per_triply_indirect_block) { - auto const triply_indirect_block_number = data.block.at(TRIPLY_INDIRECT_BLOCK_INDEX); + auto const triply_indirect_block_number = data.block.at(constants::triply_indirect_block_index); auto const doubly_indirect_block_index_in_triply_indirect_block = inode_block_index / block_numbers_per_doubly_indirect_block; auto const doubly_indirect_block_number = read_block_number_at_index( @@ -230,7 +216,7 @@ namespace kernel::filesystem::ext2 auto filesystem::get_block_size() -> size_t { - return 1024U << m_superblock.log_block_size; + return constants::base_block_size << m_superblock.log_block_size; } auto filesystem::get_inode_size() -> size_t diff --git a/kernel/src/filesystem/ext2/filesystem.tests.cpp b/kernel/src/filesystem/ext2/filesystem.tests.cpp new file mode 100644 index 0000000..b13ebf3 --- /dev/null +++ b/kernel/src/filesystem/ext2/filesystem.tests.cpp @@ -0,0 +1,132 @@ +#include "kernel/filesystem/ext2/filesystem.hpp" + +#include "kernel/devices/storage/management.hpp" +#include "kernel/filesystem/ext2/inode.hpp" +#include "kernel/filesystem/filesystem.hpp" +#include "kernel/test_support/devices/block_device.hpp" +#include "kernel/test_support/filesystem/ext2.hpp" +#include "kernel/test_support/filesystem/storage_boot_module_fixture.hpp" + +#include +#include + +#include + +#include +#include +#include + +SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, + "Ext2 filesystem mount and lookup with real image", "[filesystem][ext2][filesystem][img]") +{ + auto const image_path = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_1KB_fs.img"; + + GIVEN("a mounted ext2 filesystem from a real image") + { + REQUIRE(std::filesystem::exists(image_path)); + REQUIRE_NOTHROW(setup_modules_from_img({"test_img_module"}, {image_path})); + + auto boot_device = kernel::devices::storage::management::get().determine_boot_device(); + REQUIRE(boot_device != nullptr); + + auto fs = kernel::filesystem::ext2::filesystem{}; + REQUIRE(fs.mount(boot_device) == kernel::filesystem::filesystem::operation_result::success); + + THEN("the root inode is available and is a directory") + { + REQUIRE(fs.root_inode() != nullptr); + REQUIRE(fs.root_inode()->is_directory()); + } + + THEN("lookup resolves known entries from the image") + { + auto information = fs.lookup(fs.root_inode(), "information"); + REQUIRE(information != nullptr); + REQUIRE(information->is_directory()); + + auto info_1 = fs.lookup(information, "info_1.txt"); + REQUIRE(info_1 != nullptr); + REQUIRE(info_1->is_regular()); + } + + THEN("lookup returns null for invalid inputs") + { + REQUIRE(fs.lookup(nullptr, "information") == nullptr); + + auto information = fs.lookup(fs.root_inode(), "information"); + REQUIRE(information != nullptr); + auto info_1 = fs.lookup(information, "info_1.txt"); + REQUIRE(info_1 != nullptr); + + REQUIRE(fs.lookup(info_1, "anything") == nullptr); + REQUIRE(fs.lookup(fs.root_inode(), "does_not_exist") == nullptr); + } + } +} + +SCENARIO("Ext2 filesystem rejects invalid magic", "[filesystem][ext2][filesystem]") +{ + auto const block_size = 1024; + GIVEN("a block device that does not contain an ext2 superblock") + { + auto device = kstd::make_shared(0, 0, "mock", block_size, 2 * block_size); + REQUIRE(device != nullptr); + + auto fs = kernel::filesystem::ext2::filesystem{}; + + THEN("mount fails with invalid_magic_number") + { + REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::invalid_magic_number); + } + } +} + +SCENARIO("Ext2 block mapping includes direct and all indirect levels", "[filesystem][ext2][filesystem]") +{ + auto const block_size = 1024; + + GIVEN("a minimally valid ext2 layout with configured indirect block tables") + { + auto device = kstd::make_shared(0, 0, "mock", block_size, 128 * block_size); + REQUIRE(device != nullptr); + + kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device); + + auto fs = kernel::filesystem::ext2::filesystem{}; + REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::success); + + auto inode_data = kernel::filesystem::ext2::inode_data{}; + inode_data.block[0] = 7; + + inode_data.block[12] = 30; + kernel::tests::filesystem::ext2::write_u32(*device, 30 * block_size, 31); + + inode_data.block[13] = 40; + kernel::tests::filesystem::ext2::write_u32(*device, 40 * block_size, 41); + kernel::tests::filesystem::ext2::write_u32(*device, 41 * block_size, 42); + + inode_data.block[14] = 50; + kernel::tests::filesystem::ext2::write_u32(*device, 50 * block_size, 51); + kernel::tests::filesystem::ext2::write_u32(*device, 51 * block_size, 52); + kernel::tests::filesystem::ext2::write_u32(*device, 52 * block_size, 53); + + auto const numbers_per_block = static_cast(block_size / sizeof(uint32_t)); + auto const singly_start = static_cast(kernel::filesystem::ext2::constants::direct_block_count); + auto const doubly_start = singly_start + numbers_per_block; + auto const triply_start = doubly_start + numbers_per_block * numbers_per_block; + + THEN("mapping resolves direct, singly, doubly and triply indirect indexes") + { + REQUIRE(fs.map_inode_block_index_to_global_block_number(0, inode_data) == 7); + REQUIRE(fs.map_inode_block_index_to_global_block_number(singly_start, inode_data) == 31); + REQUIRE(fs.map_inode_block_index_to_global_block_number(doubly_start, inode_data) == 42); + REQUIRE(fs.map_inode_block_index_to_global_block_number(triply_start, inode_data) == 53); + } + + THEN("mapping returns zero for out-of-range indexes") + { + auto const beyond_triply = triply_start + numbers_per_block * numbers_per_block * numbers_per_block; + REQUIRE(fs.map_inode_block_index_to_global_block_number(beyond_triply, inode_data) == 0); + } + } +} diff --git a/kernel/src/filesystem/ext2/inode.tests.cpp b/kernel/src/filesystem/ext2/inode.tests.cpp new file mode 100644 index 0000000..795ff10 --- /dev/null +++ b/kernel/src/filesystem/ext2/inode.tests.cpp @@ -0,0 +1,159 @@ +#include "kernel/filesystem/ext2/inode.hpp" + +#include "kernel/devices/storage/management.hpp" +#include "kernel/filesystem/ext2/filesystem.hpp" +#include "kernel/filesystem/filesystem.hpp" +#include "kernel/test_support/cpu.hpp" +#include "kernel/test_support/devices/block_device.hpp" +#include "kernel/test_support/filesystem/ext2.hpp" +#include "kernel/test_support/filesystem/storage_boot_module_fixture.hpp" + +#include +#include + +#include + +#include +#include +#include + +SCENARIO("Ext2 inode initialization and properties", "[filesystem][ext2][inode]") +{ + GIVEN("an ext2 filesystem") + { + auto fs = kernel::filesystem::ext2::filesystem{}; + + THEN("the inode is initialized and has the kind regular") + { + auto inode = kernel::filesystem::ext2::inode{&fs}; + REQUIRE(inode.is_regular()); + REQUIRE(!inode.is_directory()); + REQUIRE(!inode.is_device()); + } + } + + GIVEN("no filesystem (null pointer)") + { + THEN("constructing an inode with a null filesystem pointer panics") + { + REQUIRE_THROWS_AS(kernel::filesystem::ext2::inode{nullptr}, kernel::tests::cpu::halt); + } + } +} + +SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 inode reads from real image", + "[filesystem][ext2][inode][img]") +{ + auto const image_path = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_1KB_fs.img"; + + GIVEN("a mounted ext2 filesystem and a regular file inode") + { + REQUIRE(std::filesystem::exists(image_path)); + REQUIRE_NOTHROW(setup_modules_from_img({"test_img_module"}, {image_path})); + + auto boot_device = kernel::devices::storage::management::get().determine_boot_device(); + REQUIRE(boot_device != nullptr); + + auto fs = kernel::filesystem::ext2::filesystem{}; + REQUIRE(fs.mount(boot_device) == kernel::filesystem::filesystem::operation_result::success); + + auto information = fs.lookup(fs.root_inode(), "information"); + REQUIRE(information != nullptr); + auto file = fs.lookup(information, "info_1.txt"); + REQUIRE(file != nullptr); + REQUIRE(file->is_regular()); + + THEN("reading from offset zero returns expected file prefix") + { + auto buffer = kstd::vector(6); + auto const bytes_read = file->read(buffer.data(), 0, buffer.size()); + + REQUIRE(bytes_read == 6); + + auto const text = std::string_view{reinterpret_cast(buffer.data()), bytes_read}; + REQUIRE(text == "info_1"); + } + + THEN("reading with an offset returns the expected byte") + { + auto buffer = kstd::vector(1); + auto const bytes_read = file->read(buffer.data(), 5, buffer.size()); + + REQUIRE(bytes_read == 1); + REQUIRE(static_cast(buffer[0]) == '1'); + } + } +} + +SCENARIO("Ext2 inode read stops when block mapping resolves to zero", "[filesystem][ext2][inode]") +{ + auto const block_size = 1024; + GIVEN("an ext2 inode without mapped data blocks") + { + auto device = kstd::make_shared(0, 0, "mock", block_size, 64 * block_size); + REQUIRE(device != nullptr); + kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device); + + auto fs = kernel::filesystem::ext2::filesystem{}; + REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::success); + + auto inode = kernel::filesystem::ext2::inode{&fs}; + inode.m_data.blocks = 2; + inode.m_data.block[0] = 0; + + auto buffer = kstd::vector(32, std::byte{0xAB}); + + THEN("no bytes are read") + { + auto const bytes_read = inode.read(buffer.data(), 0, buffer.size()); + REQUIRE(bytes_read == 0); + } + } +} + +SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]") +{ + auto const block_size = 1024; + GIVEN("an ext2 inode with two direct blocks and a block size of 1024 bytes") + { + auto device = kstd::make_shared(0, 0, "mock", block_size, 64 * block_size); + REQUIRE(device != nullptr); + kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device); + + auto fs = kernel::filesystem::ext2::filesystem{}; + REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::success); + + auto inode = kernel::filesystem::ext2::inode{&fs}; + inode.m_data.blocks = 2; + inode.m_data.block[0] = 20; + kernel::tests::filesystem::ext2::write_bytes(*device, 21 * block_size - 6, "Hello ", 6); + inode.m_data.block[1] = 21; + kernel::tests::filesystem::ext2::write_bytes(*device, 21 * block_size, "World!", 6); + + auto buffer = kstd::vector(12, std::byte{0x00}); + + THEN("reading across the block boundary returns the combined content") + { + auto const bytes_read = inode.read(buffer.data(), block_size - 6, buffer.size()); + REQUIRE(bytes_read == 12); + + auto const text = std::string_view{reinterpret_cast(buffer.data()), bytes_read}; + REQUIRE(text == "Hello World!"); + } + } +} + +SCENARIO("Ext2 inode write is not implemented", "[filesystem][ext2][inode]") +{ + GIVEN("an ext2 inode") + { + auto fs = kernel::filesystem::ext2::filesystem{}; + auto inode = kernel::filesystem::ext2::inode{&fs}; + + THEN("writing to the inode panics") + { + auto buffer = kstd::vector(32, std::byte{0x00}); + REQUIRE_THROWS_AS(inode.write(buffer.data(), 0, buffer.size()), kernel::tests::cpu::halt); + } + } +} diff --git a/kernel/src/test_support/filesystem/ext2.cpp b/kernel/src/test_support/filesystem/ext2.cpp new file mode 100644 index 0000000..3627373 --- /dev/null +++ b/kernel/src/test_support/filesystem/ext2.cpp @@ -0,0 +1,62 @@ +#include "kernel/test_support/filesystem/ext2.hpp" + +#include "kernel/filesystem/ext2/block_group_descriptor.hpp" +#include "kernel/filesystem/ext2/filesystem.hpp" +#include "kernel/filesystem/ext2/inode.hpp" +#include "kernel/filesystem/ext2/superblock.hpp" +#include "kernel/test_support/devices/block_device.hpp" + +#include +#include + +namespace kernel::tests::filesystem::ext2 +{ + namespace + { + constexpr uint32_t root_directory_data_block = 20; + } // namespace + + auto write_bytes(kernel::tests::devices::block_device & device, size_t offset, void const * source, size_t size) + -> void + { + auto const required_size = offset + size; + if (device.data.size() < required_size) + { + device.data.resize(required_size, 0); + } + + std::memcpy(device.data.data() + offset, source, size); + } + + auto write_u32(kernel::tests::devices::block_device & device, size_t offset, uint32_t value) -> void + { + write_bytes(device, offset, &value, sizeof(value)); + } + + auto setup_mock_ext2_layout(kernel::tests::devices::block_device & device) -> void + { + auto superblock = kernel::filesystem::ext2::superblock{}; + superblock.magic = kernel::filesystem::ext2::constants::magic_number; + superblock.log_block_size = 0; + superblock.blocks_count = 64; + superblock.blocks_per_group = 64; + superblock.inodes_per_group = 32; + superblock.rev_level = 1; + superblock.inode_size = 128; + write_bytes(device, kernel::filesystem::ext2::constants::superblock_offset, &superblock, sizeof(superblock)); + + auto group_descriptor = kernel::filesystem::ext2::block_group_descriptor{}; + group_descriptor.inode_table = 5; + write_bytes(device, 2048, &group_descriptor, sizeof(group_descriptor)); + + auto root_inode_data = kernel::filesystem::ext2::inode_data{}; + root_inode_data.mode = kernel::filesystem::ext2::constants::mode_directory; + root_inode_data.blocks = 2; + root_inode_data.block[0] = root_directory_data_block; + + auto const root_inode_offset = + static_cast(group_descriptor.inode_table) * kernel::filesystem::ext2::constants::base_block_size + + (kernel::filesystem::ext2::constants::root_inode_number - 1) * superblock.inode_size; + write_bytes(device, root_inode_offset, &root_inode_data, sizeof(root_inode_data)); + } +} // namespace kernel::tests::filesystem::ext2 \ No newline at end of file -- cgit v1.2.3 From 48d01e976cc250c2630c1b599a02cea60b56d32d Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Sun, 12 Apr 2026 19:08:50 +0200 Subject: Rename --- kernel/src/filesystem/vfs.tests.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index fec32e1..f363041 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -47,10 +47,10 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("vfs initializes and provides expected mount points") { - auto & volatilefs = kernel::filesystem::vfs::get(); - auto root = volatilefs.open("/"); - auto dev = volatilefs.open("/dev"); - auto information = volatilefs.open("/information/info_1.txt"); + auto & vfs = kernel::filesystem::vfs::get(); + auto root = vfs.open("/"); + auto dev = vfs.open("/dev"); + auto information = vfs.open("/information/info_1.txt"); REQUIRE(root != nullptr); REQUIRE(dev != nullptr); -- cgit v1.2.3 From cb7edbe6d4454ee5b217b522f62f4a7b92475a32 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Sun, 12 Apr 2026 19:12:15 +0200 Subject: Add comment --- kernel/include/kernel/filesystem/inode.hpp | 1 + 1 file changed, 1 insertion(+) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp index 072f198..5208be2 100644 --- a/kernel/include/kernel/filesystem/inode.hpp +++ b/kernel/include/kernel/filesystem/inode.hpp @@ -69,6 +69,7 @@ namespace kernel::filesystem */ [[nodiscard]] auto is_device() const -> bool; + // TODO BA-FS26 avoid public member public: inode_kind m_kind{inode_kind::regular}; }; -- cgit v1.2.3 From bb01b9f2d29524974881e9a88ffb6c229836ddba Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Sun, 12 Apr 2026 20:45:23 +0200 Subject: Add fs syscall handler --- .../kernel/filesystem/file_descriptor_table.hpp | 3 +- kernel/kapi/syscall_handler/filesystem.cpp | 59 ++++++++++++++++++++++ kernel/src/filesystem/file_descriptor_table.cpp | 8 +-- 3 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 kernel/kapi/syscall_handler/filesystem.cpp (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/filesystem/file_descriptor_table.hpp index 5d52c19..5dd91e7 100644 --- a/kernel/include/kernel/filesystem/file_descriptor_table.hpp +++ b/kernel/include/kernel/filesystem/file_descriptor_table.hpp @@ -50,8 +50,9 @@ namespace kernel::filesystem /** @brief Remove a file from the descriptor table. @param fd The file descriptor index to remove. + @return 0 on success, or -1 on failure. */ - auto remove_file(int fd) -> void; + auto remove_file(int fd) -> int; private: file_descriptor_table() = default; diff --git a/kernel/kapi/syscall_handler/filesystem.cpp b/kernel/kapi/syscall_handler/filesystem.cpp new file mode 100644 index 0000000..a6e8027 --- /dev/null +++ b/kernel/kapi/syscall_handler/filesystem.cpp @@ -0,0 +1,59 @@ +#include "kapi/syscall_handler/filesystem.hpp" + +#include "kernel/filesystem/file_descriptor_table.hpp" +#include "kernel/filesystem/vfs.hpp" + +#include +#include + +namespace kapi::syscall_handler::filesystem +{ + auto mount(char const * source, char const * target) -> int + { + // TODO BA-FS26 + } + + auto umount(char const * target) -> int + { + if (kernel::filesystem::vfs::get().unmount(target) == kernel::filesystem::vfs::operation_result::success) + { + return 0; + } + return -1; + } + + auto open(char const * path) -> int + { + if (auto open_file_description = kernel::filesystem::vfs::get().open(path)) + { + return kernel::filesystem::file_descriptor_table::get().add_file(open_file_description); + } + + return -1; + } + + auto close(int fd) -> int + { + return kernel::filesystem::file_descriptor_table::get().remove_file(fd); + } + + auto read(int fd, void * buffer, size_t size) -> ssize_t + { + if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(fd)) + { + return open_file_description->read(buffer, size); + } + + return -1; + } + + auto write(int fd, void const * buffer, size_t size) -> ssize_t + { + if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(fd)) + { + return open_file_description->write(buffer, size); + } + + return -1; + } +} // namespace kapi::syscall_handler::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp index 1c062a1..7569cea 100644 --- a/kernel/src/filesystem/file_descriptor_table.cpp +++ b/kernel/src/filesystem/file_descriptor_table.cpp @@ -41,7 +41,6 @@ namespace kernel::filesystem { if (!file_description) { - // TODO BA-FS26 panic or errorcode? return -1; } @@ -72,20 +71,21 @@ namespace kernel::filesystem return m_open_files.at(index); } - auto file_descriptor_table::remove_file(int fd) -> void + auto file_descriptor_table::remove_file(int fd) -> int { if (fd < 0) { - return; + return -1; } auto const index = static_cast(fd); if (index >= m_open_files.size()) { - return; + return -1; } m_open_files.at(index) = nullptr; + return 0; } } // namespace kernel::filesystem -- cgit v1.2.3 From 98fc294deb6f7c27eda3f9ed3b616572a1ab2009 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Apr 2026 14:37:20 +0200 Subject: kstd/format: hook up vformat_to --- kernel/kstd/print.cpp | 381 +++++++++++++++++++++++++------------------------- 1 file changed, 192 insertions(+), 189 deletions(-) (limited to 'kernel') diff --git a/kernel/kstd/print.cpp b/kernel/kstd/print.cpp index beee2e5..a0bb7d6 100644 --- a/kernel/kstd/print.cpp +++ b/kernel/kstd/print.cpp @@ -1,12 +1,13 @@ #include "kapi/cio.hpp" +#include #include #include #include +#include #include #include -#include #include namespace kstd::os @@ -14,7 +15,7 @@ namespace kstd::os namespace { - struct write_buffer + struct write_buffer final : kstd::bits::format::output_buffer { using output_stream = kapi::cio::output_stream; @@ -29,7 +30,7 @@ namespace kstd::os : m_stream{stream} {} - ~write_buffer() noexcept + ~write_buffer() noexcept final { flush(); } @@ -44,17 +45,18 @@ namespace kstd::os } } - auto static callback(void * object, std::string_view text) -> void + auto push(std::string_view text) -> void final { - auto * self = static_cast(object); - for (char const character : text) + std::ranges::for_each(text, [this](auto c) { this->push(c); }); + } + + auto push(char character) -> void final + { + if (m_position >= size) { - if (self->m_position >= size) - { - self->flush(); - } - self->m_buffer.at(self->m_position++) = character; + flush(); } + m_buffer.at(m_position++) = character; } private: @@ -69,184 +71,185 @@ namespace kstd::os { auto writer = write_buffer{(sink == print_sink::stderr) ? kapi::cio::output_stream::stderr : kapi::cio::output_stream::stdout}; - auto context = kstd::format_context{.writer = write_buffer::callback, .user_data = &writer, .args = args}; - auto parse_context = kstd::format_parse_context{format, args.size()}; - - auto it = parse_context.begin(); - auto end = parse_context.end(); - - while (it != end) - { - if (*it != '{' && *it != '}') - { - auto start = it; - while (it != end && *it != '{' && *it != '}') - { - std::advance(it, 1); - } - parse_context.advance_to(it); - context.push(std::string_view(start, it - start)); - continue; - } - - if (*it == '{') - { - std::advance(it, 1); - if (it != end && *it == '{') - { - context.push('{'); - std::advance(it, 1); - parse_context.advance_to(it); - continue; - } - - parse_context.advance_to(it); - auto index = 0uz; - - if (it != end && *it >= '0' && *it <= '9') - { - while (it != end && *it >= '0' && *it <= '9') - { - index = index * 10 + static_cast(*it - '0'); - std::advance(it, 1); - } - parse_context.check_arg_id(index); - } - else - { - index = parse_context.next_arg_id(); - } - - if (it != end && *it == ':') - { - std::advance(it, 1); - } - - parse_context.advance_to(it); - - if (index < args.size()) - { - auto const & arg = args[index]; - switch (arg.type) - { - case kstd::bits::format::arg_type::boolean: - { - auto fmt = kstd::formatter{}; - auto const parsed = fmt.parse(parse_context); - parse_context.advance_to(parsed); - fmt.format(arg.value.boolean, context); - break; - } - case kstd::bits::format::arg_type::character: - { - auto fmt = kstd::formatter{}; - auto const parsed = fmt.parse(parse_context); - parse_context.advance_to(parsed); - fmt.format(arg.value.character, context); - break; - } - case kstd::bits::format::arg_type::integer: - { - auto fmt = kstd::formatter{}; - auto const parsed = fmt.parse(parse_context); - parse_context.advance_to(parsed); - fmt.format(arg.value.integer, context); - break; - } - case kstd::bits::format::arg_type::unsigned_integer: - { - auto fmt = kstd::formatter{}; - auto const parsed = fmt.parse(parse_context); - parse_context.advance_to(parsed); - fmt.format(arg.value.unsigned_integer, context); - break; - } - case kstd::bits::format::arg_type::string_view: - { - auto fmt = kstd::formatter{}; - auto const parsed = fmt.parse(parse_context); - parse_context.advance_to(parsed); - fmt.format(arg.value.string_view, context); - break; - } - case kstd::bits::format::arg_type::c_string: - { - auto fmt = kstd::formatter{}; - auto const parsed = fmt.parse(parse_context); - parse_context.advance_to(parsed); - fmt.format(arg.value.c_string, context); - break; - } - case kstd::bits::format::arg_type::pointer: - { - auto fmt = kstd::formatter{}; - auto const parsed = fmt.parse(parse_context); - parse_context.advance_to(parsed); - fmt.format(arg.value.pointer, context); - break; - } - case kstd::bits::format::arg_type::user_defined: - { - if (arg.value.user_defined.format) - { - arg.value.user_defined.format(arg.value.user_defined.pointer, parse_context, context); - } - else - { - context.push("{?}"); - } - break; - } - default: - { - context.push("{fmt-err: unknown-type}"); - break; - } - } - } - else - { - context.push("{fmt-err: bound}"); - } - - it = parse_context.begin(); - - if (it != end && *it == '}') - { - std::advance(it, 1); - parse_context.advance_to(it); - } - else - { - context.push("{fmt-err: unconsumed}"); - while (it != end && *it != '}') - { - std::advance(it, 1); - } - - if (it != end) - { - std::advance(it, 1); - parse_context.advance_to(it); - } - } - } - else if (*it == '}') - { - std::advance(it, 1); - if (it != end && *it == '}') - { - context.push('}'); - std::advance(it, 1); - parse_context.advance_to(it); - } - else - { - context.push("{fmt-err: unescaped}"); - parse_context.advance_to(it); - } - } - } + kstd::bits::format::vformat_to(writer, format, args); + // auto context = kstd::format_context{.writer = write_buffer::callback, .user_data = &writer, .args = args}; + // auto parse_context = kstd::format_parse_context{format, args.size()}; + + // auto it = parse_context.begin(); + // auto end = parse_context.end(); + + // while (it != end) + // { + // if (*it != '{' && *it != '}') + // { + // auto start = it; + // while (it != end && *it != '{' && *it != '}') + // { + // std::advance(it, 1); + // } + // parse_context.advance_to(it); + // context.push(std::string_view(start, it - start)); + // continue; + // } + + // if (*it == '{') + // { + // std::advance(it, 1); + // if (it != end && *it == '{') + // { + // context.push('{'); + // std::advance(it, 1); + // parse_context.advance_to(it); + // continue; + // } + + // parse_context.advance_to(it); + // auto index = 0uz; + + // if (it != end && *it >= '0' && *it <= '9') + // { + // while (it != end && *it >= '0' && *it <= '9') + // { + // index = index * 10 + static_cast(*it - '0'); + // std::advance(it, 1); + // } + // parse_context.check_arg_id(index); + // } + // else + // { + // index = parse_context.next_arg_id(); + // } + + // if (it != end && *it == ':') + // { + // std::advance(it, 1); + // } + + // parse_context.advance_to(it); + + // if (index < args.size()) + // { + // auto const & arg = args[index]; + // switch (arg.type) + // { + // case kstd::bits::format::arg_type::boolean: + // { + // auto fmt = kstd::formatter{}; + // auto const parsed = fmt.parse(parse_context); + // parse_context.advance_to(parsed); + // fmt.format(arg.value.boolean, context); + // break; + // } + // case kstd::bits::format::arg_type::character: + // { + // auto fmt = kstd::formatter{}; + // auto const parsed = fmt.parse(parse_context); + // parse_context.advance_to(parsed); + // fmt.format(arg.value.character, context); + // break; + // } + // case kstd::bits::format::arg_type::integer: + // { + // auto fmt = kstd::formatter{}; + // auto const parsed = fmt.parse(parse_context); + // parse_context.advance_to(parsed); + // fmt.format(arg.value.integer, context); + // break; + // } + // case kstd::bits::format::arg_type::unsigned_integer: + // { + // auto fmt = kstd::formatter{}; + // auto const parsed = fmt.parse(parse_context); + // parse_context.advance_to(parsed); + // fmt.format(arg.value.unsigned_integer, context); + // break; + // } + // case kstd::bits::format::arg_type::string_view: + // { + // auto fmt = kstd::formatter{}; + // auto const parsed = fmt.parse(parse_context); + // parse_context.advance_to(parsed); + // fmt.format(arg.value.string_view, context); + // break; + // } + // case kstd::bits::format::arg_type::c_string: + // { + // auto fmt = kstd::formatter{}; + // auto const parsed = fmt.parse(parse_context); + // parse_context.advance_to(parsed); + // fmt.format(arg.value.c_string, context); + // break; + // } + // case kstd::bits::format::arg_type::pointer: + // { + // auto fmt = kstd::formatter{}; + // auto const parsed = fmt.parse(parse_context); + // parse_context.advance_to(parsed); + // fmt.format(arg.value.pointer, context); + // break; + // } + // case kstd::bits::format::arg_type::user_defined: + // { + // if (arg.value.user_defined.format) + // { + // arg.value.user_defined.format(arg.value.user_defined.pointer, parse_context, context); + // } + // else + // { + // context.push("{?}"); + // } + // break; + // } + // default: + // { + // context.push("{fmt-err: unknown-type}"); + // break; + // } + // } + // } + // else + // { + // context.push("{fmt-err: bound}"); + // } + + // it = parse_context.begin(); + + // if (it != end && *it == '}') + // { + // std::advance(it, 1); + // parse_context.advance_to(it); + // } + // else + // { + // context.push("{fmt-err: unconsumed}"); + // while (it != end && *it != '}') + // { + // std::advance(it, 1); + // } + + // if (it != end) + // { + // std::advance(it, 1); + // parse_context.advance_to(it); + // } + // } + // } + // else if (*it == '}') + // { + // std::advance(it, 1); + // if (it != end && *it == '}') + // { + // context.push('}'); + // std::advance(it, 1); + // parse_context.advance_to(it); + // } + // else + // { + // context.push("{fmt-err: unescaped}"); + // parse_context.advance_to(it); + // } + // } + // } } } // namespace kstd::os -- cgit v1.2.3 From 45091789eb9e49856ea6c2f3606639d43f4584e7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Apr 2026 14:56:39 +0200 Subject: kstd: move formatting implementation to kstd --- kernel/kstd/print.cpp | 198 +++----------------------------------------------- 1 file changed, 10 insertions(+), 188 deletions(-) (limited to 'kernel') diff --git a/kernel/kstd/print.cpp b/kernel/kstd/print.cpp index a0bb7d6..7854027 100644 --- a/kernel/kstd/print.cpp +++ b/kernel/kstd/print.cpp @@ -35,16 +35,6 @@ namespace kstd::os flush(); } - auto flush() noexcept -> void - { - if (m_position > 0) - { - std::string_view chunk{m_buffer.data(), m_position}; - kapi::cio::write(m_stream, chunk); - m_position = 0; - } - } - auto push(std::string_view text) -> void final { std::ranges::for_each(text, [this](auto c) { this->push(c); }); @@ -60,6 +50,16 @@ namespace kstd::os } private: + auto flush() noexcept -> void + { + if (m_position > 0) + { + std::string_view chunk{m_buffer.data(), m_position}; + kapi::cio::write(m_stream, chunk); + m_position = 0; + } + } + output_stream m_stream; std::array m_buffer{}; std::size_t m_position{}; @@ -72,184 +72,6 @@ namespace kstd::os auto writer = write_buffer{(sink == print_sink::stderr) ? kapi::cio::output_stream::stderr : kapi::cio::output_stream::stdout}; kstd::bits::format::vformat_to(writer, format, args); - // auto context = kstd::format_context{.writer = write_buffer::callback, .user_data = &writer, .args = args}; - // auto parse_context = kstd::format_parse_context{format, args.size()}; - - // auto it = parse_context.begin(); - // auto end = parse_context.end(); - - // while (it != end) - // { - // if (*it != '{' && *it != '}') - // { - // auto start = it; - // while (it != end && *it != '{' && *it != '}') - // { - // std::advance(it, 1); - // } - // parse_context.advance_to(it); - // context.push(std::string_view(start, it - start)); - // continue; - // } - - // if (*it == '{') - // { - // std::advance(it, 1); - // if (it != end && *it == '{') - // { - // context.push('{'); - // std::advance(it, 1); - // parse_context.advance_to(it); - // continue; - // } - - // parse_context.advance_to(it); - // auto index = 0uz; - - // if (it != end && *it >= '0' && *it <= '9') - // { - // while (it != end && *it >= '0' && *it <= '9') - // { - // index = index * 10 + static_cast(*it - '0'); - // std::advance(it, 1); - // } - // parse_context.check_arg_id(index); - // } - // else - // { - // index = parse_context.next_arg_id(); - // } - - // if (it != end && *it == ':') - // { - // std::advance(it, 1); - // } - - // parse_context.advance_to(it); - - // if (index < args.size()) - // { - // auto const & arg = args[index]; - // switch (arg.type) - // { - // case kstd::bits::format::arg_type::boolean: - // { - // auto fmt = kstd::formatter{}; - // auto const parsed = fmt.parse(parse_context); - // parse_context.advance_to(parsed); - // fmt.format(arg.value.boolean, context); - // break; - // } - // case kstd::bits::format::arg_type::character: - // { - // auto fmt = kstd::formatter{}; - // auto const parsed = fmt.parse(parse_context); - // parse_context.advance_to(parsed); - // fmt.format(arg.value.character, context); - // break; - // } - // case kstd::bits::format::arg_type::integer: - // { - // auto fmt = kstd::formatter{}; - // auto const parsed = fmt.parse(parse_context); - // parse_context.advance_to(parsed); - // fmt.format(arg.value.integer, context); - // break; - // } - // case kstd::bits::format::arg_type::unsigned_integer: - // { - // auto fmt = kstd::formatter{}; - // auto const parsed = fmt.parse(parse_context); - // parse_context.advance_to(parsed); - // fmt.format(arg.value.unsigned_integer, context); - // break; - // } - // case kstd::bits::format::arg_type::string_view: - // { - // auto fmt = kstd::formatter{}; - // auto const parsed = fmt.parse(parse_context); - // parse_context.advance_to(parsed); - // fmt.format(arg.value.string_view, context); - // break; - // } - // case kstd::bits::format::arg_type::c_string: - // { - // auto fmt = kstd::formatter{}; - // auto const parsed = fmt.parse(parse_context); - // parse_context.advance_to(parsed); - // fmt.format(arg.value.c_string, context); - // break; - // } - // case kstd::bits::format::arg_type::pointer: - // { - // auto fmt = kstd::formatter{}; - // auto const parsed = fmt.parse(parse_context); - // parse_context.advance_to(parsed); - // fmt.format(arg.value.pointer, context); - // break; - // } - // case kstd::bits::format::arg_type::user_defined: - // { - // if (arg.value.user_defined.format) - // { - // arg.value.user_defined.format(arg.value.user_defined.pointer, parse_context, context); - // } - // else - // { - // context.push("{?}"); - // } - // break; - // } - // default: - // { - // context.push("{fmt-err: unknown-type}"); - // break; - // } - // } - // } - // else - // { - // context.push("{fmt-err: bound}"); - // } - - // it = parse_context.begin(); - - // if (it != end && *it == '}') - // { - // std::advance(it, 1); - // parse_context.advance_to(it); - // } - // else - // { - // context.push("{fmt-err: unconsumed}"); - // while (it != end && *it != '}') - // { - // std::advance(it, 1); - // } - - // if (it != end) - // { - // std::advance(it, 1); - // parse_context.advance_to(it); - // } - // } - // } - // else if (*it == '}') - // { - // std::advance(it, 1); - // if (it != end && *it == '}') - // { - // context.push('}'); - // std::advance(it, 1); - // parse_context.advance_to(it); - // } - // else - // { - // context.push("{fmt-err: unescaped}"); - // parse_context.advance_to(it); - // } - // } - // } } } // namespace kstd::os -- cgit v1.2.3 From eb36544624c18a284debdf78b43fe627f40a8371 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 13 Apr 2026 18:49:21 +0200 Subject: Rename and refactor --- kernel/kapi/filesystem.cpp | 60 ++++++++++++++++++++++++++++++ kernel/kapi/syscall_handler/filesystem.cpp | 59 ----------------------------- 2 files changed, 60 insertions(+), 59 deletions(-) create mode 100644 kernel/kapi/filesystem.cpp delete mode 100644 kernel/kapi/syscall_handler/filesystem.cpp (limited to 'kernel') diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp new file mode 100644 index 0000000..a734ac0 --- /dev/null +++ b/kernel/kapi/filesystem.cpp @@ -0,0 +1,60 @@ +#include "kapi/filesystem.hpp" + +#include "kernel/filesystem/file_descriptor_table.hpp" +#include "kernel/filesystem/vfs.hpp" + +#include +#include +#include + +namespace kapi::filesystem +{ + auto mount(std::string_view source, std::string_view target) -> int + { + // TODO BA-FS26 + } + + auto umount(std::string_view target) -> int + { + if (kernel::filesystem::vfs::get().unmount(target) == kernel::filesystem::vfs::operation_result::success) + { + return 0; + } + return -1; + } + + auto open(std::string_view path) -> int + { + if (auto open_file_description = kernel::filesystem::vfs::get().open(path)) + { + return kernel::filesystem::file_descriptor_table::get().add_file(open_file_description); + } + + return -1; + } + + auto close(int fd) -> int + { + return kernel::filesystem::file_descriptor_table::get().remove_file(fd); + } + + auto read(int fd, void * buffer, size_t size) -> ssize_t + { + if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(fd)) + { + return open_file_description->read(buffer, size); + } + + return -1; + } + + auto write(int fd, void const * buffer, size_t size) -> ssize_t + { + if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(fd)) + { + return open_file_description->write(buffer, size); + } + + return -1; + } +} // namespace kapi::filesystem \ No newline at end of file diff --git a/kernel/kapi/syscall_handler/filesystem.cpp b/kernel/kapi/syscall_handler/filesystem.cpp deleted file mode 100644 index a6e8027..0000000 --- a/kernel/kapi/syscall_handler/filesystem.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "kapi/syscall_handler/filesystem.hpp" - -#include "kernel/filesystem/file_descriptor_table.hpp" -#include "kernel/filesystem/vfs.hpp" - -#include -#include - -namespace kapi::syscall_handler::filesystem -{ - auto mount(char const * source, char const * target) -> int - { - // TODO BA-FS26 - } - - auto umount(char const * target) -> int - { - if (kernel::filesystem::vfs::get().unmount(target) == kernel::filesystem::vfs::operation_result::success) - { - return 0; - } - return -1; - } - - auto open(char const * path) -> int - { - if (auto open_file_description = kernel::filesystem::vfs::get().open(path)) - { - return kernel::filesystem::file_descriptor_table::get().add_file(open_file_description); - } - - return -1; - } - - auto close(int fd) -> int - { - return kernel::filesystem::file_descriptor_table::get().remove_file(fd); - } - - auto read(int fd, void * buffer, size_t size) -> ssize_t - { - if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(fd)) - { - return open_file_description->read(buffer, size); - } - - return -1; - } - - auto write(int fd, void const * buffer, size_t size) -> ssize_t - { - if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(fd)) - { - return open_file_description->write(buffer, size); - } - - return -1; - } -} // namespace kapi::syscall_handler::filesystem \ No newline at end of file -- cgit v1.2.3 From 5e183b418b0e65dcdffa02a43702a0d6deb43b04 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 13 Apr 2026 21:17:50 +0200 Subject: Back filesystem by inode and not device --- .../include/kernel/filesystem/devfs/filesystem.hpp | 6 ++-- .../include/kernel/filesystem/ext2/filesystem.hpp | 8 ++--- kernel/include/kernel/filesystem/filesystem.hpp | 29 ++++++++-------- .../kernel/filesystem/rootfs/filesystem.hpp | 8 ++--- kernel/include/kernel/filesystem/vfs.hpp | 15 +++++---- kernel/kapi/filesystem.cpp | 6 +++- kernel/src/filesystem/devfs/filesystem.cpp | 2 +- kernel/src/filesystem/ext2/filesystem.cpp | 21 +++++------- kernel/src/filesystem/ext2/filesystem.tests.cpp | 13 ++++++-- kernel/src/filesystem/ext2/inode.cpp | 7 ++-- kernel/src/filesystem/ext2/inode.tests.cpp | 13 ++++++-- kernel/src/filesystem/filesystem.cpp | 22 ++++++------ kernel/src/filesystem/rootfs/filesystem.cpp | 4 +-- kernel/src/filesystem/vfs.cpp | 39 +++++++++++----------- kernel/src/filesystem/vfs.tests.cpp | 32 +++++++++--------- kernel/src/main.cpp | 14 ++------ 16 files changed, 117 insertions(+), 122 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/devfs/filesystem.hpp b/kernel/include/kernel/filesystem/devfs/filesystem.hpp index 137eca3..3a52403 100644 --- a/kernel/include/kernel/filesystem/devfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/devfs/filesystem.hpp @@ -1,8 +1,6 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVFS_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_FILESYSTEM_HPP -#include "kapi/devices/device.hpp" - #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" @@ -23,10 +21,10 @@ namespace kernel::filesystem::devfs { /** @brief Initializes the devfs instance and builds the device inode table. - @param device Backing device passed by the generic filesystem interface (not required by devfs). + @param backing_inode Backing inode passed by the vfs (not required by devfs). @return The result of the mount operation. */ - auto mount(kstd::shared_ptr const & device) -> operation_result override; + auto mount(kstd::shared_ptr const & backing_inode) -> operation_result override; /** @brief Looks up an inode by @p name within a @p parent directory. diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index a71385f..9112866 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -1,8 +1,6 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP -#include "kapi/devices/device.hpp" - #include "kernel/filesystem/ext2/block_group_descriptor.hpp" #include "kernel/filesystem/ext2/inode.hpp" #include "kernel/filesystem/ext2/superblock.hpp" @@ -46,11 +44,11 @@ namespace kernel::filesystem::ext2 struct filesystem : kernel::filesystem::filesystem { /** - @brief Initializes the ext2 filesystem with the given @p device. - @param device The device to mount. + @brief Initializes the ext2 filesystem with the given @p backing_inode. + @param backing_inode The backing inode to mount. @return The result of the mount operation. */ - auto mount(kstd::shared_ptr const & device) -> operation_result override; + auto mount(kstd::shared_ptr const & backing_inode) -> operation_result override; /** @brief Looks up an inode by @p name within a @p parent directory. diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index ef6929a..099caee 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -1,8 +1,6 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP -#include "kapi/devices/device.hpp" - #include "kernel/filesystem/inode.hpp" #include @@ -32,22 +30,23 @@ namespace kernel::filesystem virtual ~filesystem() = default; /** - @brief Probes the given @p device to determine if it contains a recognizable filesystem, and if so, mounts it and - returns a pointer to the mounted filesystem instance. This method iterates through known filesystem types and - attempts to initialize it with the device until the mount was successful or all types have been tried. - @param device The device to probe and mount. + @brief Probes the given @p backing_inode to determine if it contains a recognizable filesystem, and if so, mounts it + and returns a pointer to the mounted filesystem instance. This method iterates through known filesystem types and + attempts to initialize it with the backing inode until the mount was successful or all types have been tried. + @param backing_inode The inode to probe and mount. @return A pointer to the mounted filesystem instance if successful, or a null pointer if no recognizable filesystem - is found on the device. - @warning Panics if @p device is null. + is found on the backing inode. + @warning Panics if @p backing_inode is null. */ - auto static probe_and_mount(kstd::shared_ptr const & device) -> kstd::shared_ptr; + auto static probe_and_mount(kstd::shared_ptr const & backing_inode) -> kstd::shared_ptr; /** - @brief Initializes the filesystem with the given @p device. - @param device The device to mount. + @brief Initializes the filesystem with the given @p backing_inode. + @param backing_inode The inode to use as the backing inode for the filesystem. (This is typically the inode + representing the block device or another inode which contains the filesystem data.) @return The result of the mount operation. */ - virtual auto mount(kstd::shared_ptr const & device) -> operation_result; + virtual auto mount(kstd::shared_ptr const & backing_inode) -> operation_result; /** @brief Looks up a child inode within the given @p parent inode with the specified @p name. This method must be @@ -65,13 +64,13 @@ namespace kernel::filesystem [[nodiscard]] auto root_inode() const -> kstd::shared_ptr const &; /** - @brief Returns a reference to the device associated with the filesystem. + @brief Returns a reference to the backing inode of the filesystem. */ - [[nodiscard]] auto device() const -> kstd::shared_ptr const &; + [[nodiscard]] auto backing_inode() const -> kstd::shared_ptr const &; protected: kstd::shared_ptr m_root_inode{}; - kstd::shared_ptr m_device{}; + kstd::shared_ptr m_backing_inode{}; kstd::vector> m_inodes{}; }; diff --git a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp index 0155c41..e14a1ee 100644 --- a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp @@ -1,8 +1,6 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_FILESYSTEM_HPP -#include "kapi/devices/device.hpp" - #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" @@ -23,11 +21,11 @@ namespace kernel::filesystem::rootfs struct filesystem : kernel::filesystem::filesystem { /** - @brief Initializes the rootfs filesystem with the given @p device. - @param device The device to mount (not required by rootfs). + @brief Initializes the rootfs filesystem with the given @p backing_inode. + @param backing_inode The backing inode to mount (not required by rootfs). @return The result of the mount operation. */ - auto mount(kstd::shared_ptr const & device) -> operation_result override; + auto mount(kstd::shared_ptr const & backing_inode) -> operation_result override; /** @brief Looks up an inode by @p name within a @p parent directory. diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 4dd2a83..2a9d5f7 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -27,9 +27,10 @@ namespace kernel::filesystem { success = 0, invalid_path = -1, - mount_point_not_found = -2, - filesystem_null = -3, - unmount_failed = -4 + non_existent_path = -2, + mount_point_not_found = -3, + unmount_failed = -4, + invalid_filesystem = -5, }; /** @@ -58,12 +59,12 @@ namespace kernel::filesystem auto open(std::string_view path) -> kstd::shared_ptr; /** - @brief Mount a @p filesystem at a specific @p path. - @param path The path where the filesystem should be mounted. - @param filesystem The filesystem to mount. + @brief Mount a @p source path to a specific @p target path. + @param source The source of the filesystem to mount. + @param target The path where the filesystem should be mounted. @return The result of the mount operation. */ - auto do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> operation_result; + auto do_mount(std::string_view source, std::string_view target) -> operation_result; /** @brief Unmount the filesystem mounted at the specified @p path. diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index a734ac0..30201b7 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -11,7 +11,11 @@ namespace kapi::filesystem { auto mount(std::string_view source, std::string_view target) -> int { - // TODO BA-FS26 + if (kernel::filesystem::vfs::get().do_mount(source, target) == kernel::filesystem::vfs::operation_result::success) + { + return 0; + } + return -1; } auto umount(std::string_view target) -> int diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp index 03b4218..dd60c5d 100644 --- a/kernel/src/filesystem/devfs/filesystem.cpp +++ b/kernel/src/filesystem/devfs/filesystem.cpp @@ -14,7 +14,7 @@ namespace kernel::filesystem::devfs { - auto filesystem::mount(kstd::shared_ptr const &) -> operation_result + auto filesystem::mount(kstd::shared_ptr const &) -> operation_result { m_root_inode = kstd::make_shared(); build_device_inode_table(); diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 0ad5c97..c0f97ed 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -1,8 +1,5 @@ #include "kernel/filesystem/ext2/filesystem.hpp" -#include "kapi/devices/device.hpp" - -#include "kernel/devices/block_device_utils.hpp" #include "kernel/filesystem/ext2/block_group_descriptor.hpp" #include "kernel/filesystem/ext2/inode.hpp" #include "kernel/filesystem/ext2/linked_directory_entry.hpp" @@ -32,12 +29,11 @@ namespace kernel::filesystem::ext2 } } // namespace - auto filesystem::mount(kstd::shared_ptr const & device) -> operation_result + auto filesystem::mount(kstd::shared_ptr const & backing_inode) -> operation_result { - kernel::filesystem::filesystem::mount(device); + kernel::filesystem::filesystem::mount(backing_inode); - kernel::devices::block_device_utils::read(m_device, &m_superblock, constants::superblock_offset, - sizeof(m_superblock)); + m_backing_inode->read(&m_superblock, constants::superblock_offset, sizeof(m_superblock)); if (m_superblock.magic != constants::magic_number) { @@ -51,9 +47,8 @@ namespace kernel::filesystem::ext2 m_block_group_descriptors = kstd::vector(num_block_groups); auto const block_group_descriptor_table_offset = block_size == 1024 ? 2 * block_size : block_size; - kernel::devices::block_device_utils::read(m_device, m_block_group_descriptors.data(), - block_group_descriptor_table_offset, - num_block_groups * sizeof(block_group_descriptor)); + m_backing_inode->read(m_block_group_descriptors.data(), block_group_descriptor_table_offset, + num_block_groups * sizeof(block_group_descriptor)); m_root_inode = read_inode(constants::root_inode_number); @@ -86,7 +81,7 @@ namespace kernel::filesystem::ext2 { auto const global_block_number = map_inode_block_index_to_global_block_number(i, inode_data); auto const block_offset = global_block_number * block_size; - kernel::devices::block_device_utils::read(m_device, buffer.data(), block_offset, block_size); + m_backing_inode->read(buffer.data(), block_offset, block_size); auto const * entry = reinterpret_cast(buffer.data()); auto bytes_read = 0uz; @@ -125,7 +120,7 @@ namespace kernel::filesystem::ext2 auto const inode_offset = inode_table_offset + inode_index_within_group * get_inode_size(); auto new_inode = kstd::make_shared(this); - kernel::devices::block_device_utils::read(m_device, &new_inode->m_data, inode_offset, sizeof(inode_data)); + m_backing_inode->read(&new_inode->m_data, inode_offset, sizeof(inode_data)); // TODO BA-FS26 improve inode_kind really needed? or just map it to the mode bits? if (S_ISREG(new_inode->m_data.mode)) @@ -209,7 +204,7 @@ namespace kernel::filesystem::ext2 auto const block_start_offset = block_number * get_block_size(); auto const number_start_address = block_start_offset + index * sizeof(uint32_t); - kernel::devices::block_device_utils::read(m_device, &block_number_buffer, number_start_address, sizeof(uint32_t)); + m_backing_inode->read(&block_number_buffer, number_start_address, sizeof(uint32_t)); return block_number_buffer; } diff --git a/kernel/src/filesystem/ext2/filesystem.tests.cpp b/kernel/src/filesystem/ext2/filesystem.tests.cpp index b13ebf3..a7b8d5b 100644 --- a/kernel/src/filesystem/ext2/filesystem.tests.cpp +++ b/kernel/src/filesystem/ext2/filesystem.tests.cpp @@ -1,6 +1,7 @@ #include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/devices/storage/management.hpp" +#include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/ext2/inode.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/test_support/devices/block_device.hpp" @@ -29,8 +30,10 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, auto boot_device = kernel::devices::storage::management::get().determine_boot_device(); REQUIRE(boot_device != nullptr); + auto dev_inode = kstd::make_shared(boot_device); + auto fs = kernel::filesystem::ext2::filesystem{}; - REQUIRE(fs.mount(boot_device) == kernel::filesystem::filesystem::operation_result::success); + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); THEN("the root inode is available and is a directory") { @@ -72,11 +75,13 @@ SCENARIO("Ext2 filesystem rejects invalid magic", "[filesystem][ext2][filesystem auto device = kstd::make_shared(0, 0, "mock", block_size, 2 * block_size); REQUIRE(device != nullptr); + auto dev_inode = kstd::make_shared(device); + auto fs = kernel::filesystem::ext2::filesystem{}; THEN("mount fails with invalid_magic_number") { - REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::invalid_magic_number); + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::invalid_magic_number); } } } @@ -92,8 +97,10 @@ SCENARIO("Ext2 block mapping includes direct and all indirect levels", "[filesys kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device); + auto dev_inode = kstd::make_shared(device); + auto fs = kernel::filesystem::ext2::filesystem{}; - REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::success); + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); auto inode_data = kernel::filesystem::ext2::inode_data{}; inode_data.block[0] = 7; diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index a29bb3b..bf3f0cf 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -2,7 +2,6 @@ #include "kapi/system.hpp" -#include "kernel/devices/block_device_utils.hpp" #include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/filesystem/inode.hpp" @@ -41,8 +40,8 @@ namespace kernel::filesystem::ext2 auto const read_offset = block_start_offset + in_block_offset; auto const bytes_to_read = std::min(size - bytes_read, m_filesystem->get_block_size() - in_block_offset); - bytes_read += kernel::devices::block_device_utils::read( - m_filesystem->device(), static_cast(buffer) + bytes_read, read_offset, bytes_to_read); + bytes_read += + m_filesystem->backing_inode()->read(static_cast(buffer) + bytes_read, read_offset, bytes_to_read); block_index++; in_block_offset = 0; // After the first block, we always start at the beginning of the block @@ -56,4 +55,4 @@ namespace kernel::filesystem::ext2 kapi::system::panic("[EXT2] inode::write is not implemented yet"); return 0; } -} // namespace kernel::filesystem::ext2 \ No newline at end of file +} // namespace kernel::filesystem::ext2 diff --git a/kernel/src/filesystem/ext2/inode.tests.cpp b/kernel/src/filesystem/ext2/inode.tests.cpp index 795ff10..ae66aff 100644 --- a/kernel/src/filesystem/ext2/inode.tests.cpp +++ b/kernel/src/filesystem/ext2/inode.tests.cpp @@ -1,6 +1,7 @@ #include "kernel/filesystem/ext2/inode.hpp" #include "kernel/devices/storage/management.hpp" +#include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/test_support/cpu.hpp" @@ -54,8 +55,10 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in auto boot_device = kernel::devices::storage::management::get().determine_boot_device(); REQUIRE(boot_device != nullptr); + auto dev_inode = kstd::make_shared(boot_device); + auto fs = kernel::filesystem::ext2::filesystem{}; - REQUIRE(fs.mount(boot_device) == kernel::filesystem::filesystem::operation_result::success); + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); auto information = fs.lookup(fs.root_inode(), "information"); REQUIRE(information != nullptr); @@ -94,8 +97,10 @@ SCENARIO("Ext2 inode read stops when block mapping resolves to zero", "[filesyst REQUIRE(device != nullptr); kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device); + auto dev_inode = kstd::make_shared(device); + auto fs = kernel::filesystem::ext2::filesystem{}; - REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::success); + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); auto inode = kernel::filesystem::ext2::inode{&fs}; inode.m_data.blocks = 2; @@ -120,8 +125,10 @@ SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]") REQUIRE(device != nullptr); kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device); + auto dev_inode = kstd::make_shared(device); + auto fs = kernel::filesystem::ext2::filesystem{}; - REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::success); + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); auto inode = kernel::filesystem::ext2::inode{&fs}; inode.m_data.blocks = 2; diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index d8b04eb..99e7456 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -1,6 +1,5 @@ #include "kernel/filesystem/filesystem.hpp" -#include "kapi/devices/device.hpp" #include "kapi/system.hpp" #include "kernel/filesystem/ext2/filesystem.hpp" @@ -19,18 +18,17 @@ namespace kernel::filesystem }; } // namespace - auto filesystem::probe_and_mount(kstd::shared_ptr const & device) - -> kstd::shared_ptr + auto filesystem::probe_and_mount(kstd::shared_ptr const & backing_inode) -> kstd::shared_ptr { - if (!device) + if (!backing_inode) { - kapi::system::panic("[FILESYSTEM] cannot mount filesystem: device is null."); + kapi::system::panic("[FILESYSTEM] cannot mount filesystem: backing inode is null."); } for (auto & factory : filesystem_factories) { auto fs = factory(); - if (fs->mount(device) == operation_result::success) + if (fs->mount(backing_inode) == operation_result::success) { return fs; } @@ -39,14 +37,14 @@ namespace kernel::filesystem return nullptr; } - auto filesystem::mount(kstd::shared_ptr const & device) -> operation_result + auto filesystem::mount(kstd::shared_ptr const & backing_inode) -> operation_result { - if (!device) + if (!backing_inode) { - kapi::system::panic("[FILESYSTEM] cannot mount filesystem: device is null."); + kapi::system::panic("[FILESYSTEM] cannot mount filesystem: backing inode is null."); } - m_device = device; + m_backing_inode = backing_inode; return operation_result::success; } @@ -55,8 +53,8 @@ namespace kernel::filesystem return m_root_inode; } - auto filesystem::device() const -> kstd::shared_ptr const & + auto filesystem::backing_inode() const -> kstd::shared_ptr const & { - return m_device; + return m_backing_inode; } } // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/rootfs/filesystem.cpp b/kernel/src/filesystem/rootfs/filesystem.cpp index dffef99..f718c72 100644 --- a/kernel/src/filesystem/rootfs/filesystem.cpp +++ b/kernel/src/filesystem/rootfs/filesystem.cpp @@ -1,7 +1,5 @@ #include "kernel/filesystem/rootfs/filesystem.hpp" -#include "kapi/devices/device.hpp" - #include "kernel/filesystem/inode.hpp" #include "kernel/filesystem/rootfs/inode.hpp" @@ -11,7 +9,7 @@ namespace kernel::filesystem::rootfs { - auto filesystem::mount(kstd::shared_ptr const &) -> operation_result + auto filesystem::mount(kstd::shared_ptr const &) -> operation_result { auto rfs_inode = kstd::make_shared(); rfs_inode->add_child("dev"); diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 67d1af2..394e926 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -2,7 +2,6 @@ #include "kapi/system.hpp" -#include "kernel/devices/storage/management.hpp" #include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/devfs/filesystem.hpp" #include "kernel/filesystem/filesystem.hpp" @@ -43,19 +42,17 @@ namespace kernel::filesystem auto root_fs_root_dentry = kstd::make_shared(nullptr, root_fs->root_inode()); m_mount_table.add_mount(kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, "", nullptr)); - auto storage_mgmt = devices::storage::management::get(); - if (auto boot_device = storage_mgmt.determine_boot_device()) + auto device_fs = kstd::make_shared(); + device_fs->mount(nullptr); + do_mount_internal("/dev", root_fs_root_dentry, device_fs); + + if (auto boot_device_dentry = resolve_path("/dev/ram0")) // TODO BA-FS26 better boot device detection { - auto boot_root_fs = kernel::filesystem::filesystem::probe_and_mount(boot_device); - if (boot_root_fs) + if (auto boot_root_fs = kernel::filesystem::filesystem::probe_and_mount(boot_device_dentry->get_inode())) { do_mount_internal("/", root_fs_root_dentry, boot_root_fs); } } - - auto device_fs = kstd::make_shared(); - device_fs->mount(nullptr); - do_mount_internal("/dev", root_fs_root_dentry, device_fs); } auto vfs::get() -> vfs & @@ -78,24 +75,26 @@ namespace kernel::filesystem return nullptr; } - auto vfs::do_mount(std::string_view path, kstd::shared_ptr const & filesystem) -> operation_result + auto vfs::do_mount(std::string_view source, std::string_view target) -> operation_result { - if (!filesystem) - { - return operation_result::filesystem_null; - } - - if (path.empty() || path.front() != '/' || (path.size() > 1 && path.back() == '/')) + if (target.empty() || target.front() != '/' || (target.size() > 1 && target.back() == '/')) { return operation_result::invalid_path; } - if (auto mount_point_dentry = resolve_path(path)) + if (auto mount_point_dentry = resolve_path(target)) { - do_mount_internal(path, mount_point_dentry, filesystem); - return operation_result::success; + if (auto source_dentry = resolve_path(source)) + { + if (auto fs = kernel::filesystem::filesystem::probe_and_mount(source_dentry->get_inode())) + { + do_mount_internal(target, mount_point_dentry, fs); + return operation_result::success; + } + return operation_result::invalid_filesystem; + } + return operation_result::non_existent_path; } - return operation_result::mount_point_not_found; } diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index f363041..8c963c6 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -67,11 +67,6 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS {image_path_1, image_path_2, image_path_3})); auto & vfs = kernel::filesystem::vfs::get(); - auto storage_mgmt = kernel::devices::storage::management::get(); - auto device_1 = storage_mgmt.device_by_major_minor(1, 16); - auto fs_1 = kernel::filesystem::filesystem::probe_and_mount(device_1); - auto device_2 = storage_mgmt.device_by_major_minor(1, 32); - auto fs_2 = kernel::filesystem::filesystem::probe_and_mount(device_2); THEN("vfs initializes first module as root") { @@ -85,7 +80,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("second image can be mounted, data retrieved and unmounted again") { - REQUIRE(vfs.do_mount("/information", fs_1) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); REQUIRE(mounted_monkey_1 != nullptr); @@ -100,8 +95,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("third image can be mounted in a mounted file system, unmount only if no child mount exists") { - REQUIRE(vfs.do_mount("/information", fs_1) == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.do_mount("/information/monkey_house/infrastructure", fs_2) == + REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram32", "/information/monkey_house/infrastructure") == kernel::filesystem::vfs::operation_result::success); auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); @@ -118,8 +113,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("images can be stacked mounted and correct file system is unmounted again") { - REQUIRE(vfs.do_mount("/information", fs_1) == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.do_mount("/information", fs_2) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram32", "/information") == kernel::filesystem::vfs::operation_result::success); auto mounted_tickets = vfs.open("/information/entrance/tickets.txt"); REQUIRE(mounted_tickets != nullptr); @@ -134,19 +129,26 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("mount with null file system fails") { - REQUIRE(vfs.do_mount("/information", nullptr) == kernel::filesystem::vfs::operation_result::filesystem_null); + REQUIRE(vfs.do_mount("/closed.txt", "/information") == + kernel::filesystem::vfs::operation_result::invalid_filesystem); } THEN("mount with invalid path fails") { - REQUIRE(vfs.do_mount("", fs_1) == kernel::filesystem::vfs::operation_result::invalid_path); - REQUIRE(vfs.do_mount("information", fs_1) == kernel::filesystem::vfs::operation_result::invalid_path); - REQUIRE(vfs.do_mount("/information/", fs_1) == kernel::filesystem::vfs::operation_result::invalid_path); + REQUIRE(vfs.do_mount("/dev/ram16", "") == kernel::filesystem::vfs::operation_result::invalid_path); + REQUIRE(vfs.do_mount("/dev/ram16", "information") == kernel::filesystem::vfs::operation_result::invalid_path); + REQUIRE(vfs.do_mount("/dev/ram16", "/information/") == kernel::filesystem::vfs::operation_result::invalid_path); + } + + THEN("mount with non-existent source path fails") + { + REQUIRE(vfs.do_mount("/dev/nonexistent", "/information") == + kernel::filesystem::vfs::operation_result::non_existent_path); } THEN("mount with non-existent mount point fails") { - REQUIRE(vfs.do_mount("/information/nonexistent", fs_1) == + REQUIRE(vfs.do_mount("/dev/ram16", "/information/nonexistent") == kernel::filesystem::vfs::operation_result::mount_point_not_found); } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 79ed703..e296bd5 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -9,7 +9,6 @@ #include "kernel/devices/storage/management.hpp" #include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/file_descriptor_table.hpp" -#include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/open_file_description.hpp" #include "kernel/filesystem/vfs.hpp" #include "kernel/memory.hpp" @@ -138,24 +137,17 @@ auto test_file_lookup() -> void "this_is_a_very_very_long_fish_filename_that_keeps_going_and_going_until_it_almost_breaks_linux_filesystem_" "limits_for_testing_purposes_and_we_add_more_characters_to_make_it_even_longer_30.txt"); - auto storage_mgmt = kernel::devices::storage::management::get(); - auto device_1 = storage_mgmt.device_by_major_minor(1, 16); - auto fs_1 = kernel::filesystem::filesystem::probe_and_mount(device_1); - - vfs.do_mount("/enclosures/aquarium", fs_1); + vfs.do_mount("/dev/ram16", "/enclosures/aquarium"); read_and_write_file("/enclosures/aquarium/closed.txt"); read_and_write_file("/enclosures/aquarium/information/info_2.txt"); vfs.unmount("/enclosures/aquarium"); read_and_write_file("/enclosures/aquarium/tank_1/fish_4.txt"); - auto device_2 = storage_mgmt.device_by_major_minor(1, 32); - auto fs_2 = kernel::filesystem::filesystem::probe_and_mount(device_2); - - vfs.do_mount("/enclosures/elephant_house", fs_2); + vfs.do_mount("/dev/ram32", "/enclosures/elephant_house"); read_and_write_file("/enclosures/elephant_house/monkey_house/infrastructure/info.txt"); - vfs.do_mount("/enclosures/elephant_house/monkey_house", fs_1); + vfs.do_mount("/dev/ram16", "/enclosures/elephant_house/monkey_house"); read_and_write_file("/enclosures/elephant_house/monkey_house/information/info_2.txt"); auto result = vfs.unmount("/enclosures/elephant_house"); -- cgit v1.2.3 From 5354654a486296be674ecc7ba5e92ca01cc29107 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 14 Apr 2026 08:44:41 +0200 Subject: add tests to mount filesystems backed by a file --- kernel/src/filesystem/vfs.tests.cpp | 67 +++++++++++++++++++++- .../filesystem/test_assets/ext2_1KB_fs.img | 2 +- 2 files changed, 66 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 8c963c6..12dce84 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -1,12 +1,14 @@ #include "kernel/filesystem/vfs.hpp" -#include "kernel/devices/storage/management.hpp" -#include "kernel/filesystem/filesystem.hpp" #include "kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp" +#include + #include +#include #include +#include SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS with dummy modules", "[filesystem][vfs]") @@ -165,4 +167,65 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS kernel::filesystem::vfs::operation_result::mount_point_not_found); } } + + GIVEN("A real image file containing as filesystem formatted files") + { + REQUIRE(std::filesystem::exists(image_path_1)); + REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module_1"}, {image_path_1})); + + THEN("the file-filesystem in the image can be mounted, files can be read and unmounted again") + { + auto & vfs = kernel::filesystem::vfs::get(); + REQUIRE(vfs.do_mount("/archiv/2024.img", "/information") == kernel::filesystem::vfs::operation_result::success); + + auto sheep_1 = vfs.open("/information/sheep_1.txt"); + REQUIRE(sheep_1 != nullptr); + + kstd::vector buffer(7); + auto bytes_read = sheep_1->read(buffer.data(), buffer.size()); + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), bytes_read}; + REQUIRE(buffer_as_str == "sheep_1"); + + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); + auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); + REQUIRE(unmounted_sheep_1 == nullptr); + } + + THEN("the file-filesystem in the image can be mounted and in this filesystem can another file-filesystem be " + "mounted, files can be read and unmounted again") + { + auto & vfs = kernel::filesystem::vfs::get(); + REQUIRE(vfs.do_mount("/archiv/2024.img", "/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/archiv/2025.img", "/information/stable") == + kernel::filesystem::vfs::operation_result::success); + + auto sheep_1 = vfs.open("/information/sheep_1.txt"); + auto goat_1 = vfs.open("/information/stable/petting_zoo/goat_1.txt"); + REQUIRE(sheep_1 != nullptr); + REQUIRE(goat_1 != nullptr); + + kstd::vector sheep_buffer(7); + auto bytes_read = sheep_1->read(sheep_buffer.data(), sheep_buffer.size()); + std::string_view buffer_as_str{reinterpret_cast(sheep_buffer.data()), bytes_read}; + REQUIRE(buffer_as_str == "sheep_1"); + + kstd::vector goat_buffer(6); + bytes_read = goat_1->read(goat_buffer.data(), goat_buffer.size()); + buffer_as_str = std::string_view{reinterpret_cast(goat_buffer.data()), bytes_read}; + REQUIRE(buffer_as_str == "goat_1"); + + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); + + REQUIRE(vfs.unmount("/information/stable") == kernel::filesystem::vfs::operation_result::success); + auto unmounted_goat_1 = vfs.open("/information/stable/petting_zoo/goat_1.txt"); + REQUIRE(unmounted_goat_1 == nullptr); + + auto still_mounted_sheep_1 = vfs.open("/information/sheep_1.txt"); + REQUIRE(still_mounted_sheep_1 != nullptr); + + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); + auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); + REQUIRE(unmounted_sheep_1 == nullptr); + } + } } diff --git a/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img b/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img index 9f1ee4a..5bbb76d 100644 --- a/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img +++ b/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:94d3988bc309eb9e81f06042c72bf4c4fb5991cd7fdd597eb00c518a96c792d8 +oid sha256:c2ef9536a439825520d9e230eedaa9ae327f9763350eddbc0f24bf5b9b5d2bf2 size 10485760 -- cgit v1.2.3 From e70ea2357a80386b0a12138201b353d942910296 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 14 Apr 2026 09:43:45 +0200 Subject: add kapi filesystem tests --- kernel/CMakeLists.txt | 2 + kernel/kapi/filesystem.tests.cpp | 128 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 kernel/kapi/filesystem.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 2f6113a..e83e529 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -8,6 +8,7 @@ add_library("kernel_objs" OBJECT "kapi/devices/bus.cpp" "kapi/devices/cpu.cpp" "kapi/devices/device.cpp" + "kapi/filesystem.cpp" "kapi/interrupts.cpp" "kapi/memory.cpp" "kapi/system.cpp" @@ -124,6 +125,7 @@ else() # KAPI Shim Tests "kapi/cpu.tests.cpp" "kapi/system.tests.cpp" + "kapi/filesystem.tests.cpp" # KSTD Shim Tests "kstd/print.tests.cpp" diff --git a/kernel/kapi/filesystem.tests.cpp b/kernel/kapi/filesystem.tests.cpp new file mode 100644 index 0000000..aa24aed --- /dev/null +++ b/kernel/kapi/filesystem.tests.cpp @@ -0,0 +1,128 @@ +#include "kapi/filesystem.hpp" + +#include "kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp" + +#include + +#include +#include +#include +#include +#include + +SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kapi filesystem with real images", + "[kapi][filesystem]") +{ + auto const image_path_1 = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_1KB_fs.img"; + auto const image_path_2 = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_2KB_fs.img"; + + GIVEN("a real image file") + { + REQUIRE(std::filesystem::exists(image_path_1)); + REQUIRE(std::filesystem::exists(image_path_2)); + REQUIRE_NOTHROW( + setup_modules_from_img_and_init_vfs({"test_img_module_1", "test_img_module_2"}, {image_path_1, image_path_2})); + + THEN("files can be opened, read and closed again") + { + auto fd = kapi::filesystem::open("/information/info_1.txt"); + REQUIRE(fd >= 0); + + auto buffer = std::vector(6); + auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size()); + REQUIRE(bytes_read >= 0); + + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(bytes_read)}; + REQUIRE(buffer_as_str == "info_1"); + + REQUIRE(kapi::filesystem::close(fd) == 0); + } + + THEN("a filesystem can be mounted, files can be opened, read and closed again and unmounted") + { + REQUIRE(kapi::filesystem::mount("/dev/ram16", "/information") == 0); + + auto fd = kapi::filesystem::open("/information/monkey_house/monkey_1.txt"); + REQUIRE(fd >= 0); + + auto buffer = std::vector(8); + auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size()); + REQUIRE(bytes_read >= 0); + + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(bytes_read)}; + REQUIRE(buffer_as_str == "monkey_1"); + + REQUIRE(kapi::filesystem::close(fd) == 0); + REQUIRE(kapi::filesystem::umount("/information") == 0); + } + + THEN("device can be opened as file and read from") + { + auto fd = kapi::filesystem::open("/dev/ram0"); + REQUIRE(fd >= 0); + + auto buffer = std::vector(512); + auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size()); + REQUIRE(bytes_read >= 0); + + REQUIRE(kapi::filesystem::close(fd) == 0); + } + + THEN("device can be opened as file and written to and read from again") + { + auto read_fd = kapi::filesystem::open("/dev/ram16"); + REQUIRE(read_fd >= 0); + + auto buffer = std::vector(512, std::byte{0xAB}); + auto bytes_written = kapi::filesystem::write(read_fd, buffer.data(), buffer.size()); + REQUIRE(bytes_written >= 0); + + auto write_fd = kapi::filesystem::open("/dev/ram16"); + REQUIRE(write_fd >= 0); + + auto read_buffer = std::vector(512); + auto bytes_read = kapi::filesystem::read(write_fd, read_buffer.data(), read_buffer.size()); + REQUIRE(bytes_read >= 0); + + REQUIRE(std::equal(buffer.begin(), buffer.end(), read_buffer.begin())); + + REQUIRE(kapi::filesystem::close(write_fd) == 0); + REQUIRE(kapi::filesystem::close(read_fd) == 0); + } + + THEN("invalid paths cannot be mounted or unmounted") + { + REQUIRE(kapi::filesystem::mount("/dev/ram16", "invalid_path") < 0); + } + + THEN("invalid paths cannot be unmounted") + { + REQUIRE(kapi::filesystem::umount("invalid_path") < 0); + } + + THEN("non existent files cannot be opened") + { + auto fd = kapi::filesystem::open("/information/non_existent.txt"); + REQUIRE(fd < 0); + } + + THEN("not opened files cannot closed") + { + REQUIRE(kapi::filesystem::close(999) < 0); + } + + THEN("not opened files cannot be read from") + { + std::vector buffer(10); + auto bytes_read = kapi::filesystem::read(999, buffer.data(), buffer.size()); + REQUIRE(bytes_read < 0); + } + + THEN("not opened files cannot be written to") + { + std::vector buffer(10); + auto bytes_written = kapi::filesystem::write(999, buffer.data(), buffer.size()); + REQUIRE(bytes_written < 0); + } + } +} -- cgit v1.2.3 From 69068165f49ca204025410ab02546318997edaa3 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 15 Apr 2026 16:53:36 +0200 Subject: kernel: improve bht speed using memory mapping --- .../filesystem/storage_boot_module_fixture.hpp | 32 +++++-- .../filesystem/storage_boot_module_vfs_fixture.hpp | 9 +- .../filesystem/storage_boot_module_fixture.cpp | 105 +++++++++++++-------- .../filesystem/storage_boot_module_vfs_fixture.cpp | 7 +- 4 files changed, 98 insertions(+), 55 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp b/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp index ee658e2..4b49684 100644 --- a/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp +++ b/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp @@ -3,11 +3,10 @@ #include "kapi/boot_module/boot_module_registry.hpp" -#include -#include - #include #include +#include +#include namespace kernel::tests::filesystem { @@ -16,16 +15,33 @@ namespace kernel::tests::filesystem ~storage_boot_module_fixture(); auto setup_modules(std::size_t module_count, std::size_t module_size = 4096) -> void; - auto setup_modules_from_img(kstd::vector const & module_names, - kstd::vector const & img_paths) -> void; + auto setup_modules_from_img(std::vector const & module_names, + std::vector const & img_paths) -> void; protected: + struct mapped_image + { + explicit mapped_image(std::filesystem::path path); + ~mapped_image(); + + mapped_image(mapped_image const &) = delete; + auto operator=(mapped_image const &) -> mapped_image & = delete; + + mapped_image(mapped_image &&) noexcept; + auto operator=(mapped_image &&) noexcept -> mapped_image &; + + int file_descriptor; + std::byte * mapping; + std::size_t size; + }; + kapi::boot_modules::boot_module_registry m_registry{}; - kstd::vector m_module_names{}; - kstd::vector> m_module_data{}; + std::vector m_module_names{}; + std::vector> m_module_data{}; + std::vector m_mapped_images{}; private: - auto setup_module_from_img(kstd::string const & module_name, std::filesystem::path const & img_path) -> void; + auto setup_module_from_img(std::string const & module_name, std::filesystem::path const & img_path) -> void; }; } // namespace kernel::tests::filesystem diff --git a/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp b/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp index 98012b0..bd1c289 100644 --- a/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp +++ b/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp @@ -3,11 +3,10 @@ #include "kernel/test_support/filesystem/storage_boot_module_fixture.hpp" -#include -#include - #include #include +#include +#include namespace kernel::tests::filesystem { @@ -16,8 +15,8 @@ namespace kernel::tests::filesystem ~storage_boot_module_vfs_fixture(); auto setup_modules_and_init_vfs(std::size_t module_count, std::size_t module_size = 4096) -> void; - auto setup_modules_from_img_and_init_vfs(kstd::vector const & module_names, - kstd::vector const & img_paths) -> void; + auto setup_modules_from_img_and_init_vfs(std::vector const & module_names, + std::vector const & img_paths) -> void; }; } // namespace kernel::tests::filesystem diff --git a/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp b/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp index a139f63..cd8360b 100644 --- a/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp +++ b/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp @@ -8,17 +8,72 @@ #include "kernel/test_support/boot_modules.hpp" #include "kernel/test_support/devices/storage/management.hpp" -#include -#include - #include +#include #include -#include -#include +#include #include +#include +#include +#include +#include +#include +#include namespace kernel::tests::filesystem { + storage_boot_module_fixture::mapped_image::mapped_image(std::filesystem::path path) + : file_descriptor(::open(path.c_str(), O_RDWR)) + { + if (file_descriptor < 0) + { + throw std::runtime_error{"Failed to open image file for test boot module: " + path.string()}; + } + + struct stat statistics{}; + if (::fstat(file_descriptor, &statistics) < 0) + { + throw std::runtime_error{"Failed to get statistics for image file: " + path.string()}; + } + + size = static_cast(statistics.st_size); + + mapping = static_cast(::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, file_descriptor, 0)); + if (mapping == MAP_FAILED) + { + throw std::runtime_error{"Failed to map image file for test boot module: " + path.string()}; + } + } + + storage_boot_module_fixture::mapped_image::~mapped_image() + { + if (mapping != nullptr) + { + ::munmap(mapping, size); + } + if (file_descriptor >= 0) + { + ::close(file_descriptor); + } + } + + storage_boot_module_fixture::mapped_image::mapped_image(mapped_image && other) noexcept + : file_descriptor{std::exchange(other.file_descriptor, -1)} + , mapping{std::exchange(other.mapping, nullptr)} + , size{std::exchange(other.size, 0)} + {} + + auto storage_boot_module_fixture::mapped_image::operator=(mapped_image && other) noexcept -> mapped_image & + { + if (this != &other) + { + file_descriptor = std::exchange(other.file_descriptor, -1); + mapping = std::exchange(other.mapping, nullptr); + size = std::exchange(other.size, 0); + } + return *this; + } + storage_boot_module_fixture::~storage_boot_module_fixture() { kernel::tests::devices::storage::management::deinit(); @@ -36,23 +91,22 @@ namespace kernel::tests::filesystem for (std::size_t i = 0; i < module_count; ++i) { - m_module_names.push_back("test_mod" + kstd::to_string(i)); + m_module_names.push_back(std::format("test_mod{}", i)); m_module_data.emplace_back(module_size, std::byte{static_cast(0x40 + (i % 16))}); } for (std::size_t i = 0; i < module_count; ++i) { m_registry.add_boot_module(kapi::boot_modules::boot_module{ - m_module_names[i].view(), kapi::memory::linear_address{m_module_data[i].data()}, m_module_data[i].size()}); + m_module_names[i].c_str(), kapi::memory::linear_address{m_module_data[i].data()}, m_module_data[i].size()}); } kapi::boot_modules::set_boot_module_registry(m_registry); kernel::devices::storage::management::init(); } - auto storage_boot_module_fixture::setup_modules_from_img(kstd::vector const & module_names, - kstd::vector const & img_paths) - -> void + auto storage_boot_module_fixture::setup_modules_from_img(std::vector const & module_names, + std::vector const & img_paths) -> void { m_module_names.clear(); m_module_data.clear(); @@ -72,38 +126,13 @@ namespace kernel::tests::filesystem kernel::devices::storage::management::init(); } - auto storage_boot_module_fixture::setup_module_from_img(kstd::string const & module_name, + auto storage_boot_module_fixture::setup_module_from_img(std::string const & module_name, std::filesystem::path const & img_path) -> void { - auto file = std::ifstream{img_path, std::ios::binary | std::ios::ate}; - if (!file) - { - throw std::runtime_error{"Failed to open image file for test boot module: " + img_path.string()}; - } - - auto const end_pos = file.tellg(); - if (end_pos < 0) - { - throw std::runtime_error{"Failed to determine image file size for test boot module: " + img_path.string()}; - } - - auto const size = static_cast(end_pos); - file.seekg(0, std::ios::beg); - m_module_names.push_back(module_name); - m_module_data.emplace_back(size); - - if (size > 0) - { - file.read(reinterpret_cast(m_module_data.back().data()), static_cast(size)); - if (!file) - { - throw std::runtime_error{"Failed to read image file content for test boot module: " + img_path.string()}; - } - } + auto & mapped_image = m_mapped_images.emplace_back(img_path); m_registry.add_boot_module(kapi::boot_modules::boot_module{ - m_module_names.back().view(), kapi::memory::linear_address{m_module_data.back().data()}, - m_module_data.back().size()}); + m_module_names.back().c_str(), kapi::memory::linear_address{mapped_image.mapping}, mapped_image.size}); } } // namespace kernel::tests::filesystem \ No newline at end of file diff --git a/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp b/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp index cba7278..1a71b57 100644 --- a/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp +++ b/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp @@ -3,11 +3,10 @@ #include "kernel/filesystem/vfs.hpp" #include "kernel/test_support/filesystem/vfs.hpp" -#include -#include - #include #include +#include +#include namespace kernel::tests::filesystem { @@ -24,7 +23,7 @@ namespace kernel::tests::filesystem } auto storage_boot_module_vfs_fixture::setup_modules_from_img_and_init_vfs( - kstd::vector const & module_names, kstd::vector const & img_paths) -> void + std::vector const & module_names, std::vector const & img_paths) -> void { setup_modules_from_img(module_names, img_paths); kernel::filesystem::vfs::init(); -- cgit v1.2.3 From 252df23b061b2bf54206da73e41faca600541ccc Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 16 Apr 2026 09:26:52 +0200 Subject: acpi: introduce VLA table --- kernel/include/kernel/acpi/manager.hpp | 6 +++--- kernel/kapi/acpi.cpp | 2 +- kernel/src/acpi/manager.cpp | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/acpi/manager.hpp b/kernel/include/kernel/acpi/manager.hpp index 420b44a..860d609 100644 --- a/kernel/include/kernel/acpi/manager.hpp +++ b/kernel/include/kernel/acpi/manager.hpp @@ -18,12 +18,12 @@ namespace kernel::acpi auto load_tables() -> bool; - auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const>; + auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::table_header const>; private: ::acpi::rsdp const * m_sdp{}; - ::acpi::sdt const * m_rsdt{}; - kstd::flat_map m_tables{}; + ::acpi::table_header const * m_rsdt{}; + kstd::flat_map m_tables{}; bool m_extended{}; }; diff --git a/kernel/kapi/acpi.cpp b/kernel/kapi/acpi.cpp index df2bf05..5a2f227 100644 --- a/kernel/kapi/acpi.cpp +++ b/kernel/kapi/acpi.cpp @@ -32,7 +32,7 @@ namespace kapi::acpi return manager->load_tables(); } - auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const> + auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::table_header const> { return manager->get_table(signature); } diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 501ce92..41469c2 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -32,7 +32,7 @@ namespace kernel::acpi } auto physical_extended_table_address = kapi::memory::physical_address{xsdp->table_address()}; auto linear_extended_table_address = kapi::memory::hhdm_to_linear(physical_extended_table_address); - m_rsdt = static_cast<::acpi::sdt const *>(linear_extended_table_address); + m_rsdt = static_cast<::acpi::table_header const *>(linear_extended_table_address); m_extended = true; } else @@ -43,7 +43,7 @@ namespace kernel::acpi } auto physical_root_table_address = kapi::memory::physical_address{m_sdp->table_address()}; auto linear_root_table_address = kapi::memory::hhdm_to_linear(physical_root_table_address); - m_rsdt = static_cast<::acpi::sdt const *>(linear_root_table_address); + m_rsdt = static_cast<::acpi::table_header const *>(linear_root_table_address); } } @@ -55,8 +55,8 @@ namespace kernel::acpi } auto entry_size = m_extended ? sizeof(std::uint64_t) : sizeof(std::uint32_t); - auto entry_count = (m_rsdt->length().value - sizeof(::acpi::sdt)) / entry_size; - auto entries_base = reinterpret_cast(m_rsdt) + sizeof(::acpi::sdt); + auto entry_count = (m_rsdt->length().value - sizeof(::acpi::table_header)) / entry_size; + auto entries_base = reinterpret_cast(m_rsdt) + sizeof(::acpi::table_header); for (std::size_t i = 0; i < entry_count; ++i) { @@ -74,7 +74,7 @@ namespace kernel::acpi } auto linear_table_address = kapi::memory::hhdm_to_linear(physical_table_address); - auto table = static_cast<::acpi::sdt const *>(linear_table_address); + auto table = static_cast<::acpi::table_header const *>(linear_table_address); if (!::acpi::validate_checksum({reinterpret_cast(table), table->length().value})) { @@ -90,7 +90,7 @@ namespace kernel::acpi return !m_tables.empty(); } - auto manager::get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const> + auto manager::get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::table_header const> { if (m_tables.contains(signature)) { -- cgit v1.2.3 From 28cae58fe117e5fcfc46fd6378e19387cd73b2fe Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 16 Apr 2026 09:40:12 +0200 Subject: acpi: derive basic table from table header --- kernel/src/acpi/manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 41469c2..2f2a1bd 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -43,7 +43,7 @@ namespace kernel::acpi } auto physical_root_table_address = kapi::memory::physical_address{m_sdp->table_address()}; auto linear_root_table_address = kapi::memory::hhdm_to_linear(physical_root_table_address); - m_rsdt = static_cast<::acpi::table_header const *>(linear_root_table_address); + m_rsdt = static_cast<::acpi::rsdt const *>(linear_root_table_address); } } -- cgit v1.2.3 From 776ab2749d5af0a34fd2aa6103a377ddc04d4c53 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 16 Apr 2026 10:03:35 +0200 Subject: acpi: introduce XSDT type --- kernel/src/acpi/manager.cpp | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) (limited to 'kernel') diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 2f2a1bd..5876799 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -8,8 +8,10 @@ #include +#include #include #include +#include #include namespace kernel::acpi @@ -32,7 +34,7 @@ namespace kernel::acpi } auto physical_extended_table_address = kapi::memory::physical_address{xsdp->table_address()}; auto linear_extended_table_address = kapi::memory::hhdm_to_linear(physical_extended_table_address); - m_rsdt = static_cast<::acpi::table_header const *>(linear_extended_table_address); + m_rsdt = static_cast<::acpi::xsdt const *>(linear_extended_table_address); m_extended = true; } else @@ -54,29 +56,12 @@ namespace kernel::acpi kapi::system::panic("[OS:ACPI] Invalid RSDT checksum!"); } - auto entry_size = m_extended ? sizeof(std::uint64_t) : sizeof(std::uint32_t); - auto entry_count = (m_rsdt->length().value - sizeof(::acpi::table_header)) / entry_size; - auto entries_base = reinterpret_cast(m_rsdt) + sizeof(::acpi::table_header); + auto check_and_register_table = [&](auto table_address) -> void { + auto physical_table_address = kapi::memory::physical_address{reinterpret_cast(table_address)}; + auto mapped_table = kapi::memory::hhdm_to_linear(physical_table_address); + auto table = static_cast<::acpi::table_header const *>(mapped_table); - for (std::size_t i = 0; i < entry_count; ++i) - { - auto physical_table_address = kapi::memory::physical_address{}; - - if (m_extended) - { - auto entry = reinterpret_cast(entries_base + (i * entry_size)); - physical_table_address = kapi::memory::physical_address{*entry}; - } - else - { - auto entry = reinterpret_cast(entries_base + (i * entry_size)); - physical_table_address = kapi::memory::physical_address{*entry}; - } - - auto linear_table_address = kapi::memory::hhdm_to_linear(physical_table_address); - auto table = static_cast<::acpi::table_header const *>(linear_table_address); - - if (!::acpi::validate_checksum({reinterpret_cast(table), table->length().value})) + if (!::acpi::validate_checksum({static_cast(mapped_table), table->length().value})) { kstd::println(kstd::print_sink::stderr, "[OS:ACPI] Invalid table checksum!"); } @@ -85,6 +70,19 @@ namespace kernel::acpi kstd::println("[OS:ACPI] Found '{}' ACPI table", table->signature()); m_tables.emplace(table->signature(), table); } + }; + + if (m_extended) + { + auto xsdt = static_cast<::acpi::xsdt const *>(m_rsdt); + std::ranges::for_each(*xsdt | std::views::transform([](auto const & entry) { return entry.address(); }), + check_and_register_table); + } + else + { + auto rsdt = static_cast<::acpi::rsdt const *>(m_rsdt); + std::ranges::for_each(*rsdt | std::views::transform([](auto const & entry) { return entry.address(); }), + check_and_register_table); } return !m_tables.empty(); -- cgit v1.2.3 From 44b5f84ac7d563be0e2f518db71c273760aba8a3 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 19 Apr 2026 09:40:09 +0200 Subject: add todo to support sparse files --- kernel/src/filesystem/ext2/inode.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index bf3f0cf..07a5525 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -31,7 +31,9 @@ namespace kernel::filesystem::ext2 while (bytes_read < size) { auto const block_number = m_filesystem->map_inode_block_index_to_global_block_number(block_index, m_data); - if (block_number == 0) // TODO BA-FS26 really correct? + // TODO BA-FS26 really correct? sparse files -> 0 means a full block with zeros --> function + // map_inode_block_index_to_global_block_number should return 0 if not possible to find an block + if (block_number == 0) { break; } -- cgit v1.2.3 From 3d4d65e2c1cb869755f9033376545785d37ad5a3 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 19 Apr 2026 09:40:43 +0200 Subject: move m_inodes member into subclass --- kernel/include/kernel/filesystem/devfs/filesystem.hpp | 3 +++ kernel/include/kernel/filesystem/filesystem.hpp | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/devfs/filesystem.hpp b/kernel/include/kernel/filesystem/devfs/filesystem.hpp index 3a52403..53bb87d 100644 --- a/kernel/include/kernel/filesystem/devfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/devfs/filesystem.hpp @@ -1,6 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVFS_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_FILESYSTEM_HPP +#include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/inode.hpp" @@ -37,6 +38,8 @@ namespace kernel::filesystem::devfs private: auto build_device_inode_table() -> void; + + kstd::vector> m_inodes{}; }; } // namespace kernel::filesystem::devfs diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index 099caee..16c07ad 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -71,7 +71,6 @@ namespace kernel::filesystem protected: kstd::shared_ptr m_root_inode{}; kstd::shared_ptr m_backing_inode{}; - kstd::vector> m_inodes{}; }; } // namespace kernel::filesystem -- cgit v1.2.3 From e9837b17eeee5ba69f5067e5bfe3f40aca0a9277 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 19 Apr 2026 09:41:45 +0200 Subject: check that after mount the old file isn't available anymore --- kernel/src/filesystem/vfs.tests.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 12dce84..0a7b6c7 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -178,6 +178,9 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto & vfs = kernel::filesystem::vfs::get(); REQUIRE(vfs.do_mount("/archiv/2024.img", "/information") == kernel::filesystem::vfs::operation_result::success); + auto info_1 = vfs.open("/information/info_1.txt"); + REQUIRE(info_1 == nullptr); + auto sheep_1 = vfs.open("/information/sheep_1.txt"); REQUIRE(sheep_1 != nullptr); -- cgit v1.2.3 From 1356405c9fc6d54cf9da4d5f6fd54c55d51ce66d Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 19 Apr 2026 10:01:52 +0200 Subject: vfs open returns the dentry not the open file description --- kernel/include/kernel/filesystem/vfs.hpp | 6 +++--- kernel/kapi/filesystem.cpp | 6 +++++- kernel/src/filesystem/open_file_description.tests.cpp | 5 +++-- kernel/src/filesystem/vfs.cpp | 10 ++-------- kernel/src/filesystem/vfs.tests.cpp | 16 +++++++++++----- kernel/src/main.cpp | 10 ++++++---- 6 files changed, 30 insertions(+), 23 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 2a9d5f7..678e645 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -52,11 +52,11 @@ namespace kernel::filesystem ~vfs() = default; /** - @brief Open a file by its @p path. This method resolves the path and creates an open file description. + @brief Open a file by its @p path. This method resolves the path and returns the corresponding dentry. @param path The path to the file to open. - @return A shared pointer to the open file description or a null pointer if the file could not be opened. + @return A shared pointer to the dentry or a null pointer if the file could not be opened. */ - auto open(std::string_view path) -> kstd::shared_ptr; + auto open(std::string_view path) -> kstd::shared_ptr; /** @brief Mount a @p source path to a specific @p target path. diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index 30201b7..d3aa617 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -1,8 +1,11 @@ #include "kapi/filesystem.hpp" #include "kernel/filesystem/file_descriptor_table.hpp" +#include "kernel/filesystem/open_file_description.hpp" #include "kernel/filesystem/vfs.hpp" +#include + #include #include #include @@ -29,8 +32,9 @@ namespace kapi::filesystem auto open(std::string_view path) -> int { - if (auto open_file_description = kernel::filesystem::vfs::get().open(path)) + if (auto dentry = kernel::filesystem::vfs::get().open(path)) { + auto open_file_description = kstd::make_shared(dentry->get_inode()); return kernel::filesystem::file_descriptor_table::get().add_file(open_file_description); } diff --git a/kernel/src/filesystem/open_file_description.tests.cpp b/kernel/src/filesystem/open_file_description.tests.cpp index db8eb49..ec35546 100644 --- a/kernel/src/filesystem/open_file_description.tests.cpp +++ b/kernel/src/filesystem/open_file_description.tests.cpp @@ -76,8 +76,9 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module"}, {image_path})); auto & vfs = kernel::filesystem::vfs::get(); - auto ofd = vfs.open("/information/info_1.txt"); - REQUIRE(ofd != nullptr); + auto dentry = vfs.open("/information/info_1.txt"); + REQUIRE(dentry != nullptr); + auto ofd = kstd::make_shared(dentry->get_inode()); THEN("the file can be read and the offset is updated") { diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 394e926..84c8047 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -7,7 +7,6 @@ #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/mount.hpp" #include "kernel/filesystem/mount_table.hpp" -#include "kernel/filesystem/open_file_description.hpp" #include "kernel/filesystem/rootfs/filesystem.hpp" #include @@ -65,14 +64,9 @@ namespace kernel::filesystem return *active_vfs; } - auto vfs::open(std::string_view path) -> kstd::shared_ptr + auto vfs::open(std::string_view path) -> kstd::shared_ptr { - if (auto dentry = resolve_path(path)) - { - return kstd::make_shared(dentry->get_inode()); - } - - return nullptr; + return resolve_path(path); } auto vfs::do_mount(std::string_view source, std::string_view target) -> operation_result diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 0a7b6c7..eba157d 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -1,7 +1,9 @@ #include "kernel/filesystem/vfs.hpp" +#include "kernel/filesystem/open_file_description.hpp" #include "kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp" +#include #include #include @@ -181,11 +183,12 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1 == nullptr); - auto sheep_1 = vfs.open("/information/sheep_1.txt"); - REQUIRE(sheep_1 != nullptr); + auto dentry = vfs.open("/information/sheep_1.txt"); + REQUIRE(dentry != nullptr); + auto sheep_1_ofd = kstd::make_shared(dentry->get_inode()); kstd::vector buffer(7); - auto bytes_read = sheep_1->read(buffer.data(), buffer.size()); + auto bytes_read = sheep_1_ofd->read(buffer.data(), buffer.size()); std::string_view buffer_as_str{reinterpret_cast(buffer.data()), bytes_read}; REQUIRE(buffer_as_str == "sheep_1"); @@ -207,13 +210,16 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(sheep_1 != nullptr); REQUIRE(goat_1 != nullptr); + auto sheep_1_ofd = kstd::make_shared(sheep_1->get_inode()); + auto goat_1_ofd = kstd::make_shared(goat_1->get_inode()); + kstd::vector sheep_buffer(7); - auto bytes_read = sheep_1->read(sheep_buffer.data(), sheep_buffer.size()); + auto bytes_read = sheep_1_ofd->read(sheep_buffer.data(), sheep_buffer.size()); std::string_view buffer_as_str{reinterpret_cast(sheep_buffer.data()), bytes_read}; REQUIRE(buffer_as_str == "sheep_1"); kstd::vector goat_buffer(6); - bytes_read = goat_1->read(goat_buffer.data(), goat_buffer.size()); + bytes_read = goat_1_ofd->read(goat_buffer.data(), goat_buffer.size()); buffer_as_str = std::string_view{reinterpret_cast(goat_buffer.data()), bytes_read}; REQUIRE(buffer_as_str == "goat_1"); diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index e296bd5..aee3579 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -88,13 +88,14 @@ auto test_file_description_manually() -> void auto test_device_with_vfs() -> void { auto vfs = kernel::filesystem::vfs::get(); - auto ofd = vfs.open("/dev/ram0"); - if (!ofd) + auto dentry = vfs.open("/dev/ram0"); + if (!dentry) { kstd::os::panic("test code failed"); } auto fd_table = kernel::filesystem::file_descriptor_table::get(); + auto ofd = kstd::make_shared(dentry->get_inode()); auto fd = fd_table.add_file(ofd); kstd::vector buffer{2}; auto file = fd_table.get_file(fd); @@ -113,13 +114,14 @@ auto test_file_lookup() -> void auto vfs = kernel::filesystem::vfs::get(); auto read_and_write_file = [&vfs](std::string_view path) { kstd::println("[TEST] Reading and writing file at path: {}", path); - auto ofd = vfs.open(path); - if (!ofd) + auto dentry = vfs.open(path); + if (!dentry) { kstd::os::panic("test code failed"); } kstd::vector buffer{32}; + auto ofd = kstd::make_shared(dentry->get_inode()); auto number_of_read_bytes = ofd->read(buffer.data(), buffer.size()); kstd::println("read bytes: {}", number_of_read_bytes); kstd::println("buffer: {::#04x}", buffer); -- cgit v1.2.3 From 9b4cbc6ba3f8059278a20a4893780717851ce8e4 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 21 Apr 2026 13:06:35 +0200 Subject: build: clean up configuration --- kernel/CMakeLists.txt | 147 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 97 insertions(+), 50 deletions(-) (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index e83e529..d4484cd 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,5 +1,12 @@ -add_library("kernel_objs" OBJECT - # Platform-independent KAPI implementation +#[============================================================================[ +# Library +#]============================================================================] + +add_library("kernel_lib" OBJECT) +add_library("kernel::lib" ALIAS "kernel_lib") + +target_sources("kernel_lib" PRIVATE + # Kernel-defined KAPI Implementation "kapi/acpi.cpp" "kapi/boot_modules.cpp" "kapi/cio.cpp" @@ -13,27 +20,31 @@ add_library("kernel_objs" OBJECT "kapi/memory.cpp" "kapi/system.cpp" - # KSTD OS Implementation + # Kernel-defined KSTD Implementation "kstd/os.cpp" "kstd/print.cpp" - # Kernel Implementation + # ACPI Subsystem "src/acpi/manager.cpp" + + # Memory Subsystem "src/memory/bitmap_allocator.cpp" "src/memory/block_list_allocator.cpp" "src/memory/mmio_allocator.cpp" "src/memory.cpp" + + # Device Subsystem "src/devices/block_device.cpp" "src/devices/block_device_utils.cpp" "src/devices/root_bus.cpp" + + # Storage Device Subsystem "src/devices/storage/controller.cpp" "src/devices/storage/management.cpp" "src/devices/storage/ram_disk/controller.cpp" "src/devices/storage/ram_disk/device.cpp" - "src/filesystem/devfs/filesystem.cpp" - "src/filesystem/devfs/inode.cpp" - "src/filesystem/ext2/filesystem.cpp" - "src/filesystem/ext2/inode.cpp" + + # Filesystem Subsystem "src/filesystem/dentry.cpp" "src/filesystem/device_inode.cpp" "src/filesystem/file_descriptor_table.cpp" @@ -42,86 +53,124 @@ add_library("kernel_objs" OBJECT "src/filesystem/mount_table.cpp" "src/filesystem/mount.cpp" "src/filesystem/open_file_description.cpp" - "src/filesystem/rootfs/filesystem.cpp" - "src/filesystem/rootfs/inode.cpp" "src/filesystem/vfs.cpp" -) -target_include_directories("kernel_objs" PUBLIC - "include" -) + # DevFS Filesystem + "src/filesystem/devfs/filesystem.cpp" + "src/filesystem/devfs/inode.cpp" -target_link_libraries("kernel_objs" PUBLIC - "os::kapi" + # ext2 Filesystem + "src/filesystem/ext2/filesystem.cpp" + "src/filesystem/ext2/inode.cpp" + + # Rootfs Filesystem + "src/filesystem/rootfs/filesystem.cpp" + "src/filesystem/rootfs/inode.cpp" ) -file(GLOB_RECURSE KERNEL_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "include/**.hpp") +file(GLOB_RECURSE KERNEL_HEADERS + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + CONFIGURE_DEPENDS + "include/**.hpp" +) -target_sources("kernel_objs" PUBLIC +target_sources("kernel_lib" PUBLIC FILE_SET HEADERS BASE_DIRS "include" FILES ${KERNEL_HEADERS} ) -add_library("os::kernel" ALIAS "kernel_objs") +target_include_directories("kernel_lib" PUBLIC + "include" +) + +target_link_libraries("kernel_lib" PUBLIC + "kapi::lib" + "kstd::lib" + "acpi::lib" +) + +set_target_properties("kernel_lib" PROPERTIES + VERIFY_INTERFACE_HEADER_SETS YES +) -if(CMAKE_CROSSCOMPILING) - add_executable("kernel" +#[============================================================================[ +# Executable +#]============================================================================] + +if(NOT BUILD_TESTING) + add_executable("kernel") + add_executable(kernel::exe ALIAS "kernel") + + target_sources("kernel" PRIVATE "src/main.cpp" "src/memory/operators.cpp" ) - target_link_libraries("kernel" PRIVATE - "os::arch" - "os::kernel" + target_link_libraries("kernel" PRIVATE + "kernel::lib" + "arch::lib" ) - target_link_options("kernel" PRIVATE + target_link_options("kernel" PRIVATE "-T${KERNEL_LINKER_SCRIPT}" "-no-pie" "-nostdlib" ) - set_property(TARGET "kernel" + set_property(TARGET "kernel" APPEND PROPERTY LINK_DEPENDS "${KERNEL_LINKER_SCRIPT}" ) - target_disassemble("kernel") - target_extract_debug_symbols("kernel") - target_strip("kernel") + target_disassemble("kernel") + target_extract_debug_symbols("kernel") + target_strip("kernel") + + target_generate_bootable_iso("kernel") +endif() + +#[============================================================================[ +# Tests +#]============================================================================] + +if(BUILD_TESTING) + enable_coverage("kernel_lib") - target_generate_bootable_iso("kernel") -else() - enable_coverage("kernel_objs") + add_executable("kernel_tests") + add_executable("kernel::tests" ALIAS "kernel_tests") - add_library("kernel_test_support" OBJECT + target_sources("kernel_tests" PRIVATE + # Platform-defined KAPI "src/test_support/kapi/cpu.cpp" "src/test_support/kapi/cio.cpp" "src/test_support/kapi/interrupts.cpp" "src/test_support/kapi/memory.cpp" + + # Device Subsystem Support "src/test_support/devices/block_device.cpp" "src/test_support/devices/character_device.cpp" + + # Filesystem Subsystem Support "src/test_support/filesystem/inode.cpp" "src/test_support/filesystem/filesystem.cpp" "src/test_support/filesystem/ext2.cpp" "src/test_support/filesystem/storage_boot_module_fixture.cpp" - "src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp" "src/test_support/log_buffer.cpp" + "src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp" + + # I/O Support + "src/test_support/log_buffer.cpp" "src/test_support/output_device.cpp" + + # Memory Support "src/test_support/page_mapper.cpp" "src/test_support/simulated_memory.cpp" - "src/test_support/state_reset_listener.cpp" - ) - add_library("os::kernel_test_support" ALIAS "kernel_test_support") - target_link_libraries("kernel_test_support" PUBLIC - "os::kernel" - "Catch2::Catch2WithMain" - ) + # Support System Listener + "src/test_support/state_reset_listener.cpp" - add_executable("kernel_tests" # KAPI Shim Tests "kapi/cpu.tests.cpp" "kapi/system.tests.cpp" @@ -154,23 +203,21 @@ else() "src/devices/block_device.tests.cpp" "src/devices/storage/ram_disk/device.tests.cpp" ) - add_executable("os::kernel_tests" ALIAS "kernel_tests") - target_link_libraries("kernel_tests" PRIVATE - "os::kernel" - "os::kernel_test_support" + target_link_libraries("kernel_tests" PRIVATE + "kernel::lib" + "Catch2::Catch2WithMain" ) target_compile_definitions("kernel_tests" PRIVATE KERNEL_TEST_ASSETS_DIR="${CMAKE_CURRENT_SOURCE_DIR}/src/test_support/filesystem/test_assets" ) - set_target_properties("kernel_tests" PROPERTIES + set_target_properties("kernel_tests" PROPERTIES C_CLANG_TIDY "" CXX_CLANG_TIDY "" ) - enable_coverage("kernel_tests") - catch_discover_tests("os::kernel_tests") + enable_coverage("kernel_tests") + catch_discover_tests("kernel_tests") endif() - -- 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/include/kernel/acpi/manager.hpp | 4 ++-- kernel/include/kernel/devices/storage/management.hpp | 3 ++- .../include/kernel/devices/storage/ram_disk/controller.hpp | 4 ++-- kernel/include/kernel/devices/storage/ram_disk/device.hpp | 4 ++-- kernel/include/kernel/filesystem/device_inode.hpp | 4 ++-- kernel/include/kernel/memory.hpp | 4 ++-- kernel/include/kernel/memory/block_list_allocator.hpp | 4 ++-- kernel/include/kernel/test_support/cio.hpp | 4 ++-- kernel/include/kernel/test_support/page_mapper.hpp | 4 ++-- kernel/include/kernel/test_support/simulated_memory.hpp | 1 + kernel/kapi/acpi.cpp | 6 +++--- kernel/kapi/devices.cpp | 4 ++-- kernel/kapi/filesystem.cpp | 1 + kernel/kapi/memory.cpp | 4 ++-- kernel/kstd/print.cpp | 3 ++- kernel/src/acpi/manager.cpp | 4 ++-- 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 ++--- kernel/src/filesystem/dentry.cpp | 4 ++-- kernel/src/filesystem/devfs/filesystem.cpp | 4 ++-- kernel/src/filesystem/device_inode.cpp | 6 +++--- kernel/src/filesystem/ext2/inode.cpp | 4 ++-- kernel/src/filesystem/file_descriptor_table.cpp | 4 ++-- kernel/src/filesystem/filesystem.cpp | 4 ++-- kernel/src/filesystem/mount.cpp | 8 ++++---- kernel/src/filesystem/vfs.cpp | 4 ++-- kernel/src/main.cpp | 14 +++++++------- kernel/src/memory.cpp | 6 +++--- kernel/src/memory/bitmap_allocator.tests.cpp | 1 - kernel/src/memory/block_list_allocator.cpp | 4 ++-- kernel/src/memory/block_list_allocator.tests.cpp | 4 ++-- kernel/src/memory/operators.cpp | 4 ++-- .../filesystem/storage_boot_module_fixture.cpp | 13 +++++++------ kernel/src/test_support/kapi/cio.cpp | 4 ++-- kernel/src/test_support/kapi/memory.cpp | 4 ++-- kernel/src/test_support/output_device.cpp | 4 ++-- kernel/src/test_support/simulated_memory.cpp | 3 ++- kernel/src/test_support/state_reset_listener.cpp | 8 ++++---- 41 files changed, 96 insertions(+), 92 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/acpi/manager.hpp b/kernel/include/kernel/acpi/manager.hpp index 860d609..1e8c1e8 100644 --- a/kernel/include/kernel/acpi/manager.hpp +++ b/kernel/include/kernel/acpi/manager.hpp @@ -1,12 +1,12 @@ #ifndef TEACHOS_KERNEL_ACPI_MANAGER_HPP #define TEACHOS_KERNEL_ACPI_MANAGER_HPP +#include + #include #include #include -#include - #include namespace kernel::acpi diff --git a/kernel/include/kernel/devices/storage/management.hpp b/kernel/include/kernel/devices/storage/management.hpp index 0176ce1..b2f42d1 100644 --- a/kernel/include/kernel/devices/storage/management.hpp +++ b/kernel/include/kernel/devices/storage/management.hpp @@ -1,9 +1,10 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_MANAGEMENT_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_MANAGEMENT_HPP -#include "kapi/devices/device.hpp" #include "kernel/devices/storage/controller.hpp" +#include "kapi/devices/device.hpp" + #include #include diff --git a/kernel/include/kernel/devices/storage/ram_disk/controller.hpp b/kernel/include/kernel/devices/storage/ram_disk/controller.hpp index ad8b29f..febec95 100644 --- a/kernel/include/kernel/devices/storage/ram_disk/controller.hpp +++ b/kernel/include/kernel/devices/storage/ram_disk/controller.hpp @@ -1,10 +1,10 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP -#include "kapi/boot_module/boot_module_registry.hpp" - #include "kernel/devices/storage/controller.hpp" +#include "kapi/boot_module/boot_module_registry.hpp" + namespace kernel::devices::storage::ram_disk { /** diff --git a/kernel/include/kernel/devices/storage/ram_disk/device.hpp b/kernel/include/kernel/devices/storage/ram_disk/device.hpp index e17416e..0ee0f8f 100644 --- a/kernel/include/kernel/devices/storage/ram_disk/device.hpp +++ b/kernel/include/kernel/devices/storage/ram_disk/device.hpp @@ -1,10 +1,10 @@ #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 "kernel/devices/block_device.hpp" +#include "kapi/boot_module/boot_module.hpp" + #include namespace kernel::devices::storage::ram_disk diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index c33be2a..6afe5bc 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -1,10 +1,10 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP -#include "kapi/devices/device.hpp" - #include "kernel/filesystem/inode.hpp" +#include "kapi/devices/device.hpp" + #include #include diff --git a/kernel/include/kernel/memory.hpp b/kernel/include/kernel/memory.hpp index f09c519..568dd24 100644 --- a/kernel/include/kernel/memory.hpp +++ b/kernel/include/kernel/memory.hpp @@ -1,10 +1,10 @@ #ifndef TEACHOS_KERNEL_MEMORY_HPP #define TEACHOS_KERNEL_MEMORY_HPP -#include "kapi/memory.hpp" - #include "kernel/memory/heap_allocator.hpp" // IWYU pragma: export +#include "kapi/memory.hpp" + namespace kernel::memory { diff --git a/kernel/include/kernel/memory/block_list_allocator.hpp b/kernel/include/kernel/memory/block_list_allocator.hpp index de89f3b..c2cb468 100644 --- a/kernel/include/kernel/memory/block_list_allocator.hpp +++ b/kernel/include/kernel/memory/block_list_allocator.hpp @@ -1,10 +1,10 @@ #ifndef TEACHOS_KERNEL_MEMORY_BLOCK_LIST_ALLOCATOR_HPP #define TEACHOS_KERNEL_MEMORY_BLOCK_LIST_ALLOCATOR_HPP -#include "kapi/memory.hpp" - #include "kernel/memory/heap_allocator.hpp" +#include "kapi/memory.hpp" + #include #include diff --git a/kernel/include/kernel/test_support/cio.hpp b/kernel/include/kernel/test_support/cio.hpp index f7bac2d..e990825 100644 --- a/kernel/include/kernel/test_support/cio.hpp +++ b/kernel/include/kernel/test_support/cio.hpp @@ -1,10 +1,10 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_CIO_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_CIO_HPP -#include "kapi/cio.hpp" - #include "kernel/test_support/log_buffer.hpp" +#include "kapi/cio.hpp" + #include namespace kernel::tests::cio diff --git a/kernel/include/kernel/test_support/page_mapper.hpp b/kernel/include/kernel/test_support/page_mapper.hpp index 7ae9a4f..05f4359 100644 --- a/kernel/include/kernel/test_support/page_mapper.hpp +++ b/kernel/include/kernel/test_support/page_mapper.hpp @@ -1,10 +1,10 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_PAGE_MAPPER_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_PAGE_MAPPER_HPP -#include "kapi/memory.hpp" - #include "kernel/test_support/simulated_memory.hpp" +#include "kapi/memory.hpp" + #include #include diff --git a/kernel/include/kernel/test_support/simulated_memory.hpp b/kernel/include/kernel/test_support/simulated_memory.hpp index fa78aed..ef4e3ec 100644 --- a/kernel/include/kernel/test_support/simulated_memory.hpp +++ b/kernel/include/kernel/test_support/simulated_memory.hpp @@ -6,6 +6,7 @@ #include #include + #include namespace kernel::tests diff --git a/kernel/kapi/acpi.cpp b/kernel/kapi/acpi.cpp index 5a2f227..fc9ff31 100644 --- a/kernel/kapi/acpi.cpp +++ b/kernel/kapi/acpi.cpp @@ -1,13 +1,13 @@ #include "kapi/acpi.hpp" -#include "kapi/system.hpp" - #include "kernel/acpi/manager.hpp" -#include +#include "kapi/system.hpp" #include +#include + #include #include #include diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp index 2250319..53bab8c 100644 --- a/kernel/kapi/devices.cpp +++ b/kernel/kapi/devices.cpp @@ -1,9 +1,9 @@ #include "kapi/devices.hpp" -#include "kapi/system.hpp" - #include "kernel/devices/root_bus.hpp" +#include "kapi/system.hpp" + #include #include #include diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index d3aa617..eee3b8b 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -8,6 +8,7 @@ #include #include + #include namespace kapi::filesystem diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp index 31cd1f4..66ccb9c 100644 --- a/kernel/kapi/memory.cpp +++ b/kernel/kapi/memory.cpp @@ -1,10 +1,10 @@ #include "kapi/memory.hpp" -#include "kapi/system.hpp" - #include "kernel/memory/bitmap_allocator.hpp" #include "kernel/memory/mmio_allocator.hpp" +#include "kapi/system.hpp" + #include #include diff --git a/kernel/kstd/print.cpp b/kernel/kstd/print.cpp index 7854027..a2e7fe7 100644 --- a/kernel/kstd/print.cpp +++ b/kernel/kstd/print.cpp @@ -1,8 +1,9 @@ +#include + #include "kapi/cio.hpp" #include #include -#include #include #include diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 5876799..f17c9cb 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -3,11 +3,11 @@ #include "kapi/memory.hpp" #include "kapi/system.hpp" +#include + #include #include -#include - #include #include #include 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 diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index 6591011..af5ceab 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -1,9 +1,9 @@ #include "kernel/filesystem/dentry.hpp" -#include "kapi/system.hpp" - #include "kernel/filesystem/inode.hpp" +#include "kapi/system.hpp" + #include #include diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp index dd60c5d..76b9489 100644 --- a/kernel/src/filesystem/devfs/filesystem.cpp +++ b/kernel/src/filesystem/devfs/filesystem.cpp @@ -1,12 +1,12 @@ #include "kernel/filesystem/devfs/filesystem.hpp" -#include "kapi/devices/device.hpp" - #include "kernel/devices/storage/management.hpp" #include "kernel/filesystem/devfs/inode.hpp" #include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/inode.hpp" +#include "kapi/devices/device.hpp" + #include #include diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp index 397a0fd..5793bfc 100644 --- a/kernel/src/filesystem/device_inode.cpp +++ b/kernel/src/filesystem/device_inode.cpp @@ -1,11 +1,11 @@ #include "kernel/filesystem/device_inode.hpp" -#include "kapi/devices/device.hpp" -#include "kapi/system.hpp" - #include "kernel/devices/block_device_utils.hpp" #include "kernel/filesystem/inode.hpp" +#include "kapi/devices/device.hpp" +#include "kapi/system.hpp" + #include #include diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index 07a5525..6b42db6 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -1,10 +1,10 @@ #include "kernel/filesystem/ext2/inode.hpp" -#include "kapi/system.hpp" - #include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/filesystem/inode.hpp" +#include "kapi/system.hpp" + #include #include #include diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp index 7569cea..4160429 100644 --- a/kernel/src/filesystem/file_descriptor_table.cpp +++ b/kernel/src/filesystem/file_descriptor_table.cpp @@ -1,9 +1,9 @@ #include "kernel/filesystem/file_descriptor_table.hpp" -#include "kapi/system.hpp" - #include "kernel/filesystem/open_file_description.hpp" +#include "kapi/system.hpp" + #include #include diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index 99e7456..f958660 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -1,10 +1,10 @@ #include "kernel/filesystem/filesystem.hpp" -#include "kapi/system.hpp" - #include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/filesystem/inode.hpp" +#include "kapi/system.hpp" + #include #include diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index d165385..9c8584b 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -1,10 +1,10 @@ #include "kernel/filesystem/mount.hpp" -#include "kapi/system.hpp" - #include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/filesystem.hpp" +#include "kapi/system.hpp" + #include #include @@ -13,8 +13,8 @@ namespace kernel::filesystem { mount::mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & root_dentry, - kstd::shared_ptr const & fs, std::string_view mount_path, - kstd::shared_ptr const & parent_mount) + kstd::shared_ptr const & fs, std::string_view mount_path, + kstd::shared_ptr const & parent_mount) : m_mount_path(mount_path) , m_mount_dentry(mount_dentry) , m_root_dentry(root_dentry) diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 84c8047..23ced4c 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -1,7 +1,5 @@ #include "kernel/filesystem/vfs.hpp" -#include "kapi/system.hpp" - #include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/devfs/filesystem.hpp" #include "kernel/filesystem/filesystem.hpp" @@ -9,6 +7,8 @@ #include "kernel/filesystem/mount_table.hpp" #include "kernel/filesystem/rootfs/filesystem.hpp" +#include "kapi/system.hpp" + #include #include diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index aee3579..52cbe2e 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,3 +1,10 @@ +#include "kernel/devices/storage/management.hpp" +#include "kernel/filesystem/device_inode.hpp" +#include "kernel/filesystem/file_descriptor_table.hpp" +#include "kernel/filesystem/open_file_description.hpp" +#include "kernel/filesystem/vfs.hpp" +#include "kernel/memory.hpp" + #include "kapi/boot_modules.hpp" #include "kapi/cio.hpp" #include "kapi/cpu.hpp" @@ -6,13 +13,6 @@ #include "kapi/memory.hpp" #include "kapi/system.hpp" -#include "kernel/devices/storage/management.hpp" -#include "kernel/filesystem/device_inode.hpp" -#include "kernel/filesystem/file_descriptor_table.hpp" -#include "kernel/filesystem/open_file_description.hpp" -#include "kernel/filesystem/vfs.hpp" -#include "kernel/memory.hpp" - #include #include #include diff --git a/kernel/src/memory.cpp b/kernel/src/memory.cpp index 4a8e203..b5f65fa 100644 --- a/kernel/src/memory.cpp +++ b/kernel/src/memory.cpp @@ -1,11 +1,11 @@ #include "kernel/memory.hpp" -#include "kapi/memory.hpp" -#include "kapi/system.hpp" - #include "kernel/memory/block_list_allocator.hpp" #include "kernel/memory/heap_allocator.hpp" +#include "kapi/memory.hpp" +#include "kapi/system.hpp" + #include #include diff --git a/kernel/src/memory/bitmap_allocator.tests.cpp b/kernel/src/memory/bitmap_allocator.tests.cpp index 56ec0a4..eff6d85 100644 --- a/kernel/src/memory/bitmap_allocator.tests.cpp +++ b/kernel/src/memory/bitmap_allocator.tests.cpp @@ -4,7 +4,6 @@ #include "catch2/matchers/catch_matchers.hpp" #include "catch2/matchers/catch_matchers_range_equals.hpp" - #include #include diff --git a/kernel/src/memory/block_list_allocator.cpp b/kernel/src/memory/block_list_allocator.cpp index fbc5945..5c416fa 100644 --- a/kernel/src/memory/block_list_allocator.cpp +++ b/kernel/src/memory/block_list_allocator.cpp @@ -1,10 +1,10 @@ #include "kernel/memory/block_list_allocator.hpp" +#include "kernel/memory/heap_allocator.hpp" + #include "kapi/memory.hpp" #include "kapi/system.hpp" -#include "kernel/memory/heap_allocator.hpp" - #include #include diff --git a/kernel/src/memory/block_list_allocator.tests.cpp b/kernel/src/memory/block_list_allocator.tests.cpp index 0571441..fccdad5 100644 --- a/kernel/src/memory/block_list_allocator.tests.cpp +++ b/kernel/src/memory/block_list_allocator.tests.cpp @@ -1,9 +1,9 @@ #include "kernel/memory/block_list_allocator.hpp" -#include "kapi/memory.hpp" - #include "kernel/test_support/memory.hpp" +#include "kapi/memory.hpp" + #include #include diff --git a/kernel/src/memory/operators.cpp b/kernel/src/memory/operators.cpp index 25b5f24..dd3b4fa 100644 --- a/kernel/src/memory/operators.cpp +++ b/kernel/src/memory/operators.cpp @@ -1,7 +1,7 @@ -#include "kapi/system.hpp" - #include "kernel/memory.hpp" +#include "kapi/system.hpp" + #include #include diff --git a/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp b/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp index cd8360b..7fa2cb8 100644 --- a/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp +++ b/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp @@ -1,25 +1,26 @@ #include "kernel/test_support/filesystem/storage_boot_module_fixture.hpp" -#include "kapi/boot_module/boot_module.hpp" -#include "kapi/boot_modules.hpp" -#include "kapi/memory.hpp" - #include "kernel/devices/storage/management.hpp" #include "kernel/test_support/boot_modules.hpp" #include "kernel/test_support/devices/storage/management.hpp" +#include "kapi/boot_module/boot_module.hpp" +#include "kapi/boot_modules.hpp" +#include "kapi/memory.hpp" + #include #include #include #include #include #include -#include -#include #include #include #include +#include +#include + namespace kernel::tests::filesystem { storage_boot_module_fixture::mapped_image::mapped_image(std::filesystem::path path) diff --git a/kernel/src/test_support/kapi/cio.cpp b/kernel/src/test_support/kapi/cio.cpp index 4a1cd1f..5cdd462 100644 --- a/kernel/src/test_support/kapi/cio.cpp +++ b/kernel/src/test_support/kapi/cio.cpp @@ -1,9 +1,9 @@ #include "kernel/test_support/cio.hpp" -#include - #include "kernel/test_support/log_buffer.hpp" +#include + #include #include #include diff --git a/kernel/src/test_support/kapi/memory.cpp b/kernel/src/test_support/kapi/memory.cpp index e926ba6..3b4a1bd 100644 --- a/kernel/src/test_support/kapi/memory.cpp +++ b/kernel/src/test_support/kapi/memory.cpp @@ -1,10 +1,10 @@ #include "kapi/memory.hpp" -#include - #include "kernel/test_support/bump_frame_allocator.hpp" #include "kernel/test_support/page_mapper.hpp" +#include + #include #include diff --git a/kernel/src/test_support/output_device.cpp b/kernel/src/test_support/output_device.cpp index 83dcbcc..505e385 100644 --- a/kernel/src/test_support/output_device.cpp +++ b/kernel/src/test_support/output_device.cpp @@ -1,8 +1,8 @@ -#include "kapi/cio.hpp" - #include "kernel/test_support/cio.hpp" #include "kernel/test_support/log_buffer.hpp" +#include "kapi/cio.hpp" + #include #include #include diff --git a/kernel/src/test_support/simulated_memory.cpp b/kernel/src/test_support/simulated_memory.cpp index 03dac1d..2a4f15b 100644 --- a/kernel/src/test_support/simulated_memory.cpp +++ b/kernel/src/test_support/simulated_memory.cpp @@ -9,9 +9,10 @@ #include #include #include +#include + #include #include -#include namespace kernel::tests { diff --git a/kernel/src/test_support/state_reset_listener.cpp b/kernel/src/test_support/state_reset_listener.cpp index 9120c89..1967743 100644 --- a/kernel/src/test_support/state_reset_listener.cpp +++ b/kernel/src/test_support/state_reset_listener.cpp @@ -1,7 +1,3 @@ -#include "kapi/cio.hpp" -#include "kapi/cpu.hpp" -#include "kapi/memory.hpp" - #include "kernel/filesystem/file_descriptor_table.hpp" #include "kernel/test_support/boot_modules.hpp" #include "kernel/test_support/cio.hpp" @@ -11,6 +7,10 @@ #include "kernel/test_support/filesystem/vfs.hpp" #include "kernel/test_support/memory.hpp" +#include "kapi/cio.hpp" +#include "kapi/cpu.hpp" +#include "kapi/memory.hpp" + #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/include/kernel/devices/block_device.hpp | 2 +- .../include/kernel/devices/block_device_utils.hpp | 2 +- kernel/include/kernel/devices/root_bus.hpp | 2 +- .../include/kernel/devices/storage/controller.hpp | 2 +- .../include/kernel/devices/storage/management.hpp | 4 ++-- .../kernel/devices/storage/ram_disk/controller.hpp | 4 ++-- .../kernel/devices/storage/ram_disk/device.hpp | 4 ++-- kernel/include/kernel/filesystem/dentry.hpp | 2 +- .../include/kernel/filesystem/devfs/filesystem.hpp | 6 ++--- kernel/include/kernel/filesystem/devfs/inode.hpp | 2 +- kernel/include/kernel/filesystem/device_inode.hpp | 4 ++-- .../include/kernel/filesystem/ext2/filesystem.hpp | 10 ++++---- kernel/include/kernel/filesystem/ext2/inode.hpp | 2 +- .../kernel/filesystem/file_descriptor_table.hpp | 2 +- kernel/include/kernel/filesystem/filesystem.hpp | 2 +- kernel/include/kernel/filesystem/mount.hpp | 4 ++-- kernel/include/kernel/filesystem/mount_table.hpp | 2 +- .../kernel/filesystem/open_file_description.hpp | 2 +- .../kernel/filesystem/rootfs/filesystem.hpp | 4 ++-- kernel/include/kernel/filesystem/rootfs/inode.hpp | 2 +- kernel/include/kernel/filesystem/vfs.hpp | 8 +++---- kernel/include/kernel/memory.hpp | 4 ++-- kernel/include/kernel/memory/bitmap_allocator.hpp | 2 +- .../include/kernel/memory/block_list_allocator.hpp | 4 ++-- kernel/include/kernel/memory/mmio_allocator.hpp | 2 +- .../kernel/test_support/bump_frame_allocator.hpp | 2 +- kernel/include/kernel/test_support/cio.hpp | 4 ++-- .../kernel/test_support/devices/block_device.hpp | 2 +- .../test_support/devices/character_device.hpp | 2 +- .../kernel/test_support/filesystem/ext2.hpp | 2 +- .../kernel/test_support/filesystem/filesystem.hpp | 4 ++-- .../kernel/test_support/filesystem/inode.hpp | 2 +- .../filesystem/storage_boot_module_fixture.hpp | 2 +- .../filesystem/storage_boot_module_vfs_fixture.hpp | 2 +- kernel/include/kernel/test_support/memory.hpp | 2 +- kernel/include/kernel/test_support/page_mapper.hpp | 4 ++-- .../kernel/test_support/simulated_memory.hpp | 2 +- kernel/kapi/acpi.cpp | 6 ++--- kernel/kapi/boot_modules.cpp | 4 ++-- kernel/kapi/cio.cpp | 2 +- kernel/kapi/cpu.cpp | 4 ++-- kernel/kapi/cpu.tests.cpp | 4 ++-- kernel/kapi/devices.cpp | 6 ++--- kernel/kapi/devices/bus.cpp | 6 ++--- kernel/kapi/devices/cpu.cpp | 4 ++-- kernel/kapi/devices/device.cpp | 4 ++-- kernel/kapi/filesystem.cpp | 8 +++---- kernel/kapi/filesystem.tests.cpp | 4 ++-- kernel/kapi/interrupts.cpp | 2 +- kernel/kapi/memory.cpp | 8 +++---- kernel/kapi/system.cpp | 4 ++-- kernel/kapi/system.tests.cpp | 6 ++--- kernel/kstd/os.cpp | 2 +- kernel/kstd/print.cpp | 2 +- kernel/kstd/print.tests.cpp | 4 ++-- kernel/src/acpi/manager.cpp | 6 ++--- 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 +++---- .../src/devices/storage/ram_disk/device.tests.cpp | 6 ++--- kernel/src/filesystem/dentry.cpp | 6 ++--- kernel/src/filesystem/dentry.tests.cpp | 6 ++--- kernel/src/filesystem/devfs/filesystem.cpp | 12 +++++----- kernel/src/filesystem/devfs/filesystem.tests.cpp | 6 ++--- kernel/src/filesystem/devfs/inode.cpp | 4 ++-- kernel/src/filesystem/devfs/inode.tests.cpp | 2 +- kernel/src/filesystem/device_inode.cpp | 10 ++++---- kernel/src/filesystem/device_inode.tests.cpp | 8 +++---- kernel/src/filesystem/ext2/filesystem.cpp | 16 ++++++------- kernel/src/filesystem/ext2/filesystem.tests.cpp | 18 +++++++------- kernel/src/filesystem/ext2/inode.cpp | 8 +++---- kernel/src/filesystem/ext2/inode.tests.cpp | 20 ++++++++-------- kernel/src/filesystem/file_descriptor_table.cpp | 6 ++--- .../src/filesystem/file_descriptor_table.tests.cpp | 6 ++--- kernel/src/filesystem/filesystem.cpp | 8 +++---- kernel/src/filesystem/inode.cpp | 2 +- kernel/src/filesystem/mount.cpp | 8 +++---- kernel/src/filesystem/mount.tests.cpp | 10 ++++---- kernel/src/filesystem/mount_table.cpp | 6 ++--- kernel/src/filesystem/mount_table.tests.cpp | 10 ++++---- kernel/src/filesystem/open_file_description.cpp | 4 ++-- .../src/filesystem/open_file_description.tests.cpp | 8 +++---- kernel/src/filesystem/rootfs/filesystem.cpp | 6 ++--- kernel/src/filesystem/rootfs/filesystem.tests.cpp | 4 ++-- kernel/src/filesystem/rootfs/inode.cpp | 4 ++-- kernel/src/filesystem/rootfs/inode.tests.cpp | 2 +- kernel/src/filesystem/vfs.cpp | 16 ++++++------- kernel/src/filesystem/vfs.tests.cpp | 6 ++--- kernel/src/main.cpp | 28 +++++++++++----------- kernel/src/memory.cpp | 10 ++++---- kernel/src/memory/bitmap_allocator.cpp | 4 ++-- kernel/src/memory/bitmap_allocator.tests.cpp | 8 +++---- kernel/src/memory/block_list_allocator.cpp | 8 +++---- kernel/src/memory/block_list_allocator.tests.cpp | 6 ++--- kernel/src/memory/mmio_allocator.cpp | 6 ++--- kernel/src/memory/operators.cpp | 4 ++-- kernel/src/test_support/devices/block_device.cpp | 4 ++-- .../src/test_support/devices/character_device.cpp | 5 ++-- kernel/src/test_support/filesystem/ext2.cpp | 12 +++++----- kernel/src/test_support/filesystem/filesystem.cpp | 6 ++--- kernel/src/test_support/filesystem/inode.cpp | 4 ++-- .../filesystem/storage_boot_module_fixture.cpp | 14 +++++------ .../filesystem/storage_boot_module_vfs_fixture.cpp | 6 ++--- kernel/src/test_support/kapi/cio.cpp | 4 ++-- kernel/src/test_support/kapi/cpu.cpp | 2 +- kernel/src/test_support/kapi/memory.cpp | 6 ++--- kernel/src/test_support/log_buffer.cpp | 2 +- kernel/src/test_support/output_device.cpp | 6 ++--- kernel/src/test_support/page_mapper.cpp | 4 ++-- kernel/src/test_support/simulated_memory.cpp | 4 ++-- kernel/src/test_support/state_reset_listener.cpp | 24 +++++++++---------- 117 files changed, 332 insertions(+), 333 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/devices/block_device.hpp b/kernel/include/kernel/devices/block_device.hpp index 43e6511..a6d68ee 100644 --- a/kernel/include/kernel/devices/block_device.hpp +++ b/kernel/include/kernel/devices/block_device.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP #define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP -#include "kapi/devices/device.hpp" +#include #include diff --git a/kernel/include/kernel/devices/block_device_utils.hpp b/kernel/include/kernel/devices/block_device_utils.hpp index 7b1daec..8be75b6 100644 --- a/kernel/include/kernel/devices/block_device_utils.hpp +++ b/kernel/include/kernel/devices/block_device_utils.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_UTILS_HPP #define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_UTILS_HPP -#include "kapi/devices/device.hpp" +#include #include diff --git a/kernel/include/kernel/devices/root_bus.hpp b/kernel/include/kernel/devices/root_bus.hpp index 660b715..c8fee52 100644 --- a/kernel/include/kernel/devices/root_bus.hpp +++ b/kernel/include/kernel/devices/root_bus.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KERNEL_DEVICES_ROOT_BUS_HPP #define TEACHOS_KERNEL_DEVICES_ROOT_BUS_HPP -#include "kapi/devices/bus.hpp" +#include namespace kernel::devices { diff --git a/kernel/include/kernel/devices/storage/controller.hpp b/kernel/include/kernel/devices/storage/controller.hpp index a91e452..bea18f3 100644 --- a/kernel/include/kernel/devices/storage/controller.hpp +++ b/kernel/include/kernel/devices/storage/controller.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_CONTROLLER_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_CONTROLLER_HPP -#include "kapi/devices/device.hpp" +#include #include #include diff --git a/kernel/include/kernel/devices/storage/management.hpp b/kernel/include/kernel/devices/storage/management.hpp index b2f42d1..9a84087 100644 --- a/kernel/include/kernel/devices/storage/management.hpp +++ b/kernel/include/kernel/devices/storage/management.hpp @@ -1,9 +1,9 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_MANAGEMENT_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_MANAGEMENT_HPP -#include "kernel/devices/storage/controller.hpp" +#include -#include "kapi/devices/device.hpp" +#include #include #include diff --git a/kernel/include/kernel/devices/storage/ram_disk/controller.hpp b/kernel/include/kernel/devices/storage/ram_disk/controller.hpp index febec95..93cf30d 100644 --- a/kernel/include/kernel/devices/storage/ram_disk/controller.hpp +++ b/kernel/include/kernel/devices/storage/ram_disk/controller.hpp @@ -1,9 +1,9 @@ #ifndef TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP #define TEACH_OS_KERNEL_DEVICES_STORAGE_RAM_DISK_CONTROLLER_HPP -#include "kernel/devices/storage/controller.hpp" +#include -#include "kapi/boot_module/boot_module_registry.hpp" +#include namespace kernel::devices::storage::ram_disk { diff --git a/kernel/include/kernel/devices/storage/ram_disk/device.hpp b/kernel/include/kernel/devices/storage/ram_disk/device.hpp index 0ee0f8f..89789ea 100644 --- a/kernel/include/kernel/devices/storage/ram_disk/device.hpp +++ b/kernel/include/kernel/devices/storage/ram_disk/device.hpp @@ -1,9 +1,9 @@ #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 -#include "kapi/boot_module/boot_module.hpp" +#include #include diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index 58a918f..94fa39a 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_DENTRY_HPP #define TEACH_OS_KERNEL_FILESYSTEM_DENTRY_HPP -#include "kernel/filesystem/inode.hpp" +#include #include #include diff --git a/kernel/include/kernel/filesystem/devfs/filesystem.hpp b/kernel/include/kernel/filesystem/devfs/filesystem.hpp index 53bb87d..8d96555 100644 --- a/kernel/include/kernel/filesystem/devfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/devfs/filesystem.hpp @@ -1,9 +1,9 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVFS_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_FILESYSTEM_HPP -#include "kernel/filesystem/device_inode.hpp" -#include "kernel/filesystem/filesystem.hpp" -#include "kernel/filesystem/inode.hpp" +#include +#include +#include #include #include diff --git a/kernel/include/kernel/filesystem/devfs/inode.hpp b/kernel/include/kernel/filesystem/devfs/inode.hpp index c117bd2..0fab280 100644 --- a/kernel/include/kernel/filesystem/devfs/inode.hpp +++ b/kernel/include/kernel/filesystem/devfs/inode.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVFS_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_INODE_HPP -#include "kernel/filesystem/inode.hpp" +#include #include diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index 6afe5bc..2f79fca 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -1,9 +1,9 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP -#include "kernel/filesystem/inode.hpp" +#include -#include "kapi/devices/device.hpp" +#include #include diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index 9112866..516e71d 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -1,11 +1,11 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP -#include "kernel/filesystem/ext2/block_group_descriptor.hpp" -#include "kernel/filesystem/ext2/inode.hpp" -#include "kernel/filesystem/ext2/superblock.hpp" -#include "kernel/filesystem/filesystem.hpp" -#include "kernel/filesystem/inode.hpp" +#include +#include +#include +#include +#include #include #include diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp index a1645cd..9291eea 100644 --- a/kernel/include/kernel/filesystem/ext2/inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/inode.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_EXT2_INODE_HPP -#include "kernel/filesystem/inode.hpp" +#include #include diff --git a/kernel/include/kernel/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/filesystem/file_descriptor_table.hpp index 5dd91e7..293dc36 100644 --- a/kernel/include/kernel/filesystem/file_descriptor_table.hpp +++ b/kernel/include/kernel/filesystem/file_descriptor_table.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP -#include "open_file_description.hpp" +#include #include #include diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index 16c07ad..2fdc0ed 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP -#include "kernel/filesystem/inode.hpp" +#include #include #include diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index 0ac6b2f..72855a0 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -1,8 +1,8 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_MOUNT_HPP #define TEACH_OS_KERNEL_FILESYSTEM_MOUNT_HPP -#include "kernel/filesystem/dentry.hpp" -#include "kernel/filesystem/filesystem.hpp" +#include +#include #include #include diff --git a/kernel/include/kernel/filesystem/mount_table.hpp b/kernel/include/kernel/filesystem/mount_table.hpp index a5cdde6..00277ea 100644 --- a/kernel/include/kernel/filesystem/mount_table.hpp +++ b/kernel/include/kernel/filesystem/mount_table.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_MOUNT_TABLE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_MOUNT_TABLE_HPP -#include "kernel/filesystem/mount.hpp" +#include #include #include diff --git a/kernel/include/kernel/filesystem/open_file_description.hpp b/kernel/include/kernel/filesystem/open_file_description.hpp index 738afd4..fad41e4 100644 --- a/kernel/include/kernel/filesystem/open_file_description.hpp +++ b/kernel/include/kernel/filesystem/open_file_description.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP #define TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP -#include "kernel/filesystem/inode.hpp" +#include #include diff --git a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp index e14a1ee..cc778d8 100644 --- a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp @@ -1,8 +1,8 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_FILESYSTEM_HPP #define TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_FILESYSTEM_HPP -#include "kernel/filesystem/filesystem.hpp" -#include "kernel/filesystem/inode.hpp" +#include +#include #include #include diff --git a/kernel/include/kernel/filesystem/rootfs/inode.hpp b/kernel/include/kernel/filesystem/rootfs/inode.hpp index 469e47a..37d0a30 100644 --- a/kernel/include/kernel/filesystem/rootfs/inode.hpp +++ b/kernel/include/kernel/filesystem/rootfs/inode.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_INODE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_INODE_HPP -#include "kernel/filesystem/inode.hpp" +#include #include #include diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 678e645..5b5c868 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -1,10 +1,10 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP #define TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP -#include "kernel/filesystem/dentry.hpp" -#include "kernel/filesystem/filesystem.hpp" -#include "kernel/filesystem/mount_table.hpp" -#include "kernel/filesystem/open_file_description.hpp" +#include +#include +#include +#include #include diff --git a/kernel/include/kernel/memory.hpp b/kernel/include/kernel/memory.hpp index 568dd24..17fb82b 100644 --- a/kernel/include/kernel/memory.hpp +++ b/kernel/include/kernel/memory.hpp @@ -1,9 +1,9 @@ #ifndef TEACHOS_KERNEL_MEMORY_HPP #define TEACHOS_KERNEL_MEMORY_HPP -#include "kernel/memory/heap_allocator.hpp" // IWYU pragma: export +#include // IWYU pragma: export -#include "kapi/memory.hpp" +#include namespace kernel::memory { diff --git a/kernel/include/kernel/memory/bitmap_allocator.hpp b/kernel/include/kernel/memory/bitmap_allocator.hpp index fb5bf55..370ce64 100644 --- a/kernel/include/kernel/memory/bitmap_allocator.hpp +++ b/kernel/include/kernel/memory/bitmap_allocator.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KERNEL_MEMORY_BITMAP_ALLOCATOR_HPP #define TEACHOS_KERNEL_MEMORY_BITMAP_ALLOCATOR_HPP -#include "kapi/memory.hpp" +#include #include #include diff --git a/kernel/include/kernel/memory/block_list_allocator.hpp b/kernel/include/kernel/memory/block_list_allocator.hpp index c2cb468..51b226e 100644 --- a/kernel/include/kernel/memory/block_list_allocator.hpp +++ b/kernel/include/kernel/memory/block_list_allocator.hpp @@ -1,9 +1,9 @@ #ifndef TEACHOS_KERNEL_MEMORY_BLOCK_LIST_ALLOCATOR_HPP #define TEACHOS_KERNEL_MEMORY_BLOCK_LIST_ALLOCATOR_HPP -#include "kernel/memory/heap_allocator.hpp" +#include -#include "kapi/memory.hpp" +#include #include #include diff --git a/kernel/include/kernel/memory/mmio_allocator.hpp b/kernel/include/kernel/memory/mmio_allocator.hpp index 4ec6bec..c7a8ed0 100644 --- a/kernel/include/kernel/memory/mmio_allocator.hpp +++ b/kernel/include/kernel/memory/mmio_allocator.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KERNEL_MEMORY_MMIO_ALLOCATOR_HPP #define TEACHOS_KERNEL_MEMORY_MMIO_ALLOCATOR_HPP -#include "kapi/memory.hpp" +#include #include #include diff --git a/kernel/include/kernel/test_support/bump_frame_allocator.hpp b/kernel/include/kernel/test_support/bump_frame_allocator.hpp index 6380294..a8ffd48 100644 --- a/kernel/include/kernel/test_support/bump_frame_allocator.hpp +++ b/kernel/include/kernel/test_support/bump_frame_allocator.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_BUMP_FRAME_ALLOCATOR_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_BUMP_FRAME_ALLOCATOR_HPP -#include "kapi/memory.hpp" +#include #include #include diff --git a/kernel/include/kernel/test_support/cio.hpp b/kernel/include/kernel/test_support/cio.hpp index e990825..afe27e0 100644 --- a/kernel/include/kernel/test_support/cio.hpp +++ b/kernel/include/kernel/test_support/cio.hpp @@ -1,9 +1,9 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_CIO_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_CIO_HPP -#include "kernel/test_support/log_buffer.hpp" +#include -#include "kapi/cio.hpp" +#include #include diff --git a/kernel/include/kernel/test_support/devices/block_device.hpp b/kernel/include/kernel/test_support/devices/block_device.hpp index 110872f..89a2bf1 100644 --- a/kernel/include/kernel/test_support/devices/block_device.hpp +++ b/kernel/include/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 #include #include diff --git a/kernel/include/kernel/test_support/devices/character_device.hpp b/kernel/include/kernel/test_support/devices/character_device.hpp index a106cfb..aba183a 100644 --- a/kernel/include/kernel/test_support/devices/character_device.hpp +++ b/kernel/include/kernel/test_support/devices/character_device.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_DEVICES_CHARACTER_DEVICE_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_DEVICES_CHARACTER_DEVICE_HPP -#include "kapi/devices/device.hpp" +#include #include #include diff --git a/kernel/include/kernel/test_support/filesystem/ext2.hpp b/kernel/include/kernel/test_support/filesystem/ext2.hpp index edbda29..107e5a4 100644 --- a/kernel/include/kernel/test_support/filesystem/ext2.hpp +++ b/kernel/include/kernel/test_support/filesystem/ext2.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_EXT2_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_EXT2_HPP -#include "kernel/test_support/devices/block_device.hpp" +#include #include #include diff --git a/kernel/include/kernel/test_support/filesystem/filesystem.hpp b/kernel/include/kernel/test_support/filesystem/filesystem.hpp index 13aade4..dab0892 100644 --- a/kernel/include/kernel/test_support/filesystem/filesystem.hpp +++ b/kernel/include/kernel/test_support/filesystem/filesystem.hpp @@ -1,8 +1,8 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_FILESYSTEM_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_FILESYSTEM_HPP -#include "kernel/filesystem/filesystem.hpp" -#include "kernel/filesystem/inode.hpp" +#include +#include #include diff --git a/kernel/include/kernel/test_support/filesystem/inode.hpp b/kernel/include/kernel/test_support/filesystem/inode.hpp index 6568f24..9d17917 100644 --- a/kernel/include/kernel/test_support/filesystem/inode.hpp +++ b/kernel/include/kernel/test_support/filesystem/inode.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_INODE_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_INODE_HPP -#include "kernel/filesystem/inode.hpp" +#include #include diff --git a/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp b/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp index 4b49684..94a6668 100644 --- a/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp +++ b/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_STORAGE_BOOT_MODULE_FIXTURE_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_STORAGE_BOOT_MODULE_FIXTURE_HPP -#include "kapi/boot_module/boot_module_registry.hpp" +#include #include #include diff --git a/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp b/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp index bd1c289..55f4b29 100644 --- a/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp +++ b/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_STORAGE_BOOT_MODULE_VFS_FIXTURE_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_STORAGE_BOOT_MODULE_VFS_FIXTURE_HPP -#include "kernel/test_support/filesystem/storage_boot_module_fixture.hpp" +#include #include #include diff --git a/kernel/include/kernel/test_support/memory.hpp b/kernel/include/kernel/test_support/memory.hpp index 6034a1e..21030a4 100644 --- a/kernel/include/kernel/test_support/memory.hpp +++ b/kernel/include/kernel/test_support/memory.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_MEMORY_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_MEMORY_HPP -#include "kapi/memory.hpp" +#include namespace kernel::tests::memory { diff --git a/kernel/include/kernel/test_support/page_mapper.hpp b/kernel/include/kernel/test_support/page_mapper.hpp index 05f4359..be4403b 100644 --- a/kernel/include/kernel/test_support/page_mapper.hpp +++ b/kernel/include/kernel/test_support/page_mapper.hpp @@ -1,9 +1,9 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_PAGE_MAPPER_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_PAGE_MAPPER_HPP -#include "kernel/test_support/simulated_memory.hpp" +#include -#include "kapi/memory.hpp" +#include #include diff --git a/kernel/include/kernel/test_support/simulated_memory.hpp b/kernel/include/kernel/test_support/simulated_memory.hpp index ef4e3ec..a201c3d 100644 --- a/kernel/include/kernel/test_support/simulated_memory.hpp +++ b/kernel/include/kernel/test_support/simulated_memory.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_SIMULATED_MEMORY_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_SIMULATED_MEMORY_HPP -#include "kapi/memory.hpp" +#include #include diff --git a/kernel/kapi/acpi.cpp b/kernel/kapi/acpi.cpp index fc9ff31..b6d5cdf 100644 --- a/kernel/kapi/acpi.cpp +++ b/kernel/kapi/acpi.cpp @@ -1,8 +1,8 @@ -#include "kapi/acpi.hpp" +#include -#include "kernel/acpi/manager.hpp" +#include -#include "kapi/system.hpp" +#include #include diff --git a/kernel/kapi/boot_modules.cpp b/kernel/kapi/boot_modules.cpp index 0549368..1ad541b 100644 --- a/kernel/kapi/boot_modules.cpp +++ b/kernel/kapi/boot_modules.cpp @@ -1,6 +1,6 @@ -#include "kapi/boot_modules.hpp" +#include -#include "kapi/system.hpp" +#include #include diff --git a/kernel/kapi/cio.cpp b/kernel/kapi/cio.cpp index d447a6a..96f043c 100644 --- a/kernel/kapi/cio.cpp +++ b/kernel/kapi/cio.cpp @@ -1,4 +1,4 @@ -#include "kapi/cio.hpp" +#include #include #include diff --git a/kernel/kapi/cpu.cpp b/kernel/kapi/cpu.cpp index 13de584..7b1a43b 100644 --- a/kernel/kapi/cpu.cpp +++ b/kernel/kapi/cpu.cpp @@ -1,6 +1,6 @@ -#include "kapi/cpu.hpp" +#include -#include "kapi/system.hpp" +#include #include diff --git a/kernel/kapi/cpu.tests.cpp b/kernel/kapi/cpu.tests.cpp index 85b20fd..9ce2917 100644 --- a/kernel/kapi/cpu.tests.cpp +++ b/kernel/kapi/cpu.tests.cpp @@ -1,6 +1,6 @@ -#include "kapi/cpu.hpp" +#include -#include "kernel/test_support/cpu.hpp" +#include #include diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp index 53bab8c..572227e 100644 --- a/kernel/kapi/devices.cpp +++ b/kernel/kapi/devices.cpp @@ -1,8 +1,8 @@ -#include "kapi/devices.hpp" +#include -#include "kernel/devices/root_bus.hpp" +#include -#include "kapi/system.hpp" +#include #include #include diff --git a/kernel/kapi/devices/bus.cpp b/kernel/kapi/devices/bus.cpp index 5f0dfcd..59753f7 100644 --- a/kernel/kapi/devices/bus.cpp +++ b/kernel/kapi/devices/bus.cpp @@ -1,7 +1,7 @@ -#include "kapi/devices/bus.hpp" +#include -#include "kapi/devices.hpp" -#include "kapi/system.hpp" +#include +#include #include #include diff --git a/kernel/kapi/devices/cpu.cpp b/kernel/kapi/devices/cpu.cpp index 9de5f94..f0e1d72 100644 --- a/kernel/kapi/devices/cpu.cpp +++ b/kernel/kapi/devices/cpu.cpp @@ -1,6 +1,6 @@ -#include "kapi/devices/cpu.hpp" +#include -#include "kapi/devices.hpp" +#include #include #include diff --git a/kernel/kapi/devices/device.cpp b/kernel/kapi/devices/device.cpp index 41d96dc..8b5d6b9 100644 --- a/kernel/kapi/devices/device.cpp +++ b/kernel/kapi/devices/device.cpp @@ -1,6 +1,6 @@ -#include "kapi/devices/device.hpp" +#include -#include "kapi/devices/bus.hpp" +#include #include #include diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index eee3b8b..c8d4c6d 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -1,8 +1,8 @@ -#include "kapi/filesystem.hpp" +#include -#include "kernel/filesystem/file_descriptor_table.hpp" -#include "kernel/filesystem/open_file_description.hpp" -#include "kernel/filesystem/vfs.hpp" +#include +#include +#include #include diff --git a/kernel/kapi/filesystem.tests.cpp b/kernel/kapi/filesystem.tests.cpp index aa24aed..baa8613 100644 --- a/kernel/kapi/filesystem.tests.cpp +++ b/kernel/kapi/filesystem.tests.cpp @@ -1,6 +1,6 @@ -#include "kapi/filesystem.hpp" +#include -#include "kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp" +#include #include diff --git a/kernel/kapi/interrupts.cpp b/kernel/kapi/interrupts.cpp index 0e37bc3..4efcaa3 100644 --- a/kernel/kapi/interrupts.cpp +++ b/kernel/kapi/interrupts.cpp @@ -1,4 +1,4 @@ -#include "kapi/interrupts.hpp" +#include #include #include diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp index 66ccb9c..5ea08b1 100644 --- a/kernel/kapi/memory.cpp +++ b/kernel/kapi/memory.cpp @@ -1,9 +1,9 @@ -#include "kapi/memory.hpp" +#include -#include "kernel/memory/bitmap_allocator.hpp" -#include "kernel/memory/mmio_allocator.hpp" +#include +#include -#include "kapi/system.hpp" +#include #include #include diff --git a/kernel/kapi/system.cpp b/kernel/kapi/system.cpp index a17d9b9..9819ceb 100644 --- a/kernel/kapi/system.cpp +++ b/kernel/kapi/system.cpp @@ -1,6 +1,6 @@ -#include "kapi/system.hpp" +#include -#include "kapi/cpu.hpp" +#include #include diff --git a/kernel/kapi/system.tests.cpp b/kernel/kapi/system.tests.cpp index 687053e..1e30031 100644 --- a/kernel/kapi/system.tests.cpp +++ b/kernel/kapi/system.tests.cpp @@ -1,7 +1,7 @@ -#include "kapi/system.hpp" +#include -#include "kernel/test_support/cio.hpp" -#include "kernel/test_support/cpu.hpp" +#include +#include #include diff --git a/kernel/kstd/os.cpp b/kernel/kstd/os.cpp index 21254c4..ae69e7e 100644 --- a/kernel/kstd/os.cpp +++ b/kernel/kstd/os.cpp @@ -1,4 +1,4 @@ -#include "kapi/system.hpp" +#include #include diff --git a/kernel/kstd/print.cpp b/kernel/kstd/print.cpp index a2e7fe7..d0611b2 100644 --- a/kernel/kstd/print.cpp +++ b/kernel/kstd/print.cpp @@ -1,6 +1,6 @@ #include -#include "kapi/cio.hpp" +#include #include #include diff --git a/kernel/kstd/print.tests.cpp b/kernel/kstd/print.tests.cpp index 8deeb17..4963f46 100644 --- a/kernel/kstd/print.tests.cpp +++ b/kernel/kstd/print.tests.cpp @@ -1,6 +1,6 @@ -#include "kstd/print" +#include -#include "kernel/test_support/cio.hpp" +#include #include diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index f17c9cb..99c8860 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -1,7 +1,7 @@ -#include "kernel/acpi/manager.hpp" +#include -#include "kapi/memory.hpp" -#include "kapi/system.hpp" +#include +#include #include 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 diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index af5ceab..572dd82 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -1,8 +1,8 @@ -#include "kernel/filesystem/dentry.hpp" +#include -#include "kernel/filesystem/inode.hpp" +#include -#include "kapi/system.hpp" +#include #include diff --git a/kernel/src/filesystem/dentry.tests.cpp b/kernel/src/filesystem/dentry.tests.cpp index a6620d3..f81c260 100644 --- a/kernel/src/filesystem/dentry.tests.cpp +++ b/kernel/src/filesystem/dentry.tests.cpp @@ -1,7 +1,7 @@ -#include "kernel/filesystem/dentry.hpp" +#include -#include "kernel/test_support/cpu.hpp" -#include "kernel/test_support/filesystem/inode.hpp" +#include +#include #include #include diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp index 76b9489..96e40a8 100644 --- a/kernel/src/filesystem/devfs/filesystem.cpp +++ b/kernel/src/filesystem/devfs/filesystem.cpp @@ -1,11 +1,11 @@ -#include "kernel/filesystem/devfs/filesystem.hpp" +#include -#include "kernel/devices/storage/management.hpp" -#include "kernel/filesystem/devfs/inode.hpp" -#include "kernel/filesystem/device_inode.hpp" -#include "kernel/filesystem/inode.hpp" +#include +#include +#include +#include -#include "kapi/devices/device.hpp" +#include #include diff --git a/kernel/src/filesystem/devfs/filesystem.tests.cpp b/kernel/src/filesystem/devfs/filesystem.tests.cpp index f8c4764..2b6c09b 100644 --- a/kernel/src/filesystem/devfs/filesystem.tests.cpp +++ b/kernel/src/filesystem/devfs/filesystem.tests.cpp @@ -1,7 +1,7 @@ -#include "kernel/filesystem/devfs/filesystem.hpp" +#include -#include "kernel/filesystem/filesystem.hpp" -#include "kernel/test_support/filesystem/storage_boot_module_fixture.hpp" +#include +#include #include diff --git a/kernel/src/filesystem/devfs/inode.cpp b/kernel/src/filesystem/devfs/inode.cpp index 52cf6fa..0ed66ad 100644 --- a/kernel/src/filesystem/devfs/inode.cpp +++ b/kernel/src/filesystem/devfs/inode.cpp @@ -1,6 +1,6 @@ -#include "kernel/filesystem/devfs/inode.hpp" +#include -#include "kernel/filesystem/inode.hpp" +#include #include diff --git a/kernel/src/filesystem/devfs/inode.tests.cpp b/kernel/src/filesystem/devfs/inode.tests.cpp index 50e34a7..030d709 100644 --- a/kernel/src/filesystem/devfs/inode.tests.cpp +++ b/kernel/src/filesystem/devfs/inode.tests.cpp @@ -1,4 +1,4 @@ -#include "kernel/filesystem/devfs/inode.hpp" +#include #include #include diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp index 5793bfc..3bafe06 100644 --- a/kernel/src/filesystem/device_inode.cpp +++ b/kernel/src/filesystem/device_inode.cpp @@ -1,10 +1,10 @@ -#include "kernel/filesystem/device_inode.hpp" +#include -#include "kernel/devices/block_device_utils.hpp" -#include "kernel/filesystem/inode.hpp" +#include +#include -#include "kapi/devices/device.hpp" -#include "kapi/system.hpp" +#include +#include #include diff --git a/kernel/src/filesystem/device_inode.tests.cpp b/kernel/src/filesystem/device_inode.tests.cpp index 4e31812..8ac4eff 100644 --- a/kernel/src/filesystem/device_inode.tests.cpp +++ b/kernel/src/filesystem/device_inode.tests.cpp @@ -1,8 +1,8 @@ -#include "kernel/filesystem/device_inode.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/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index c0f97ed..41572ee 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -1,11 +1,11 @@ -#include "kernel/filesystem/ext2/filesystem.hpp" - -#include "kernel/filesystem/ext2/block_group_descriptor.hpp" -#include "kernel/filesystem/ext2/inode.hpp" -#include "kernel/filesystem/ext2/linked_directory_entry.hpp" -#include "kernel/filesystem/ext2/superblock.hpp" -#include "kernel/filesystem/filesystem.hpp" -#include "kernel/filesystem/inode.hpp" +#include + +#include +#include +#include +#include +#include +#include #include #include diff --git a/kernel/src/filesystem/ext2/filesystem.tests.cpp b/kernel/src/filesystem/ext2/filesystem.tests.cpp index a7b8d5b..31c4c29 100644 --- a/kernel/src/filesystem/ext2/filesystem.tests.cpp +++ b/kernel/src/filesystem/ext2/filesystem.tests.cpp @@ -1,12 +1,12 @@ -#include "kernel/filesystem/ext2/filesystem.hpp" - -#include "kernel/devices/storage/management.hpp" -#include "kernel/filesystem/device_inode.hpp" -#include "kernel/filesystem/ext2/inode.hpp" -#include "kernel/filesystem/filesystem.hpp" -#include "kernel/test_support/devices/block_device.hpp" -#include "kernel/test_support/filesystem/ext2.hpp" -#include "kernel/test_support/filesystem/storage_boot_module_fixture.hpp" +#include + +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index 6b42db6..c45c41e 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -1,9 +1,9 @@ -#include "kernel/filesystem/ext2/inode.hpp" +#include -#include "kernel/filesystem/ext2/filesystem.hpp" -#include "kernel/filesystem/inode.hpp" +#include +#include -#include "kapi/system.hpp" +#include #include #include diff --git a/kernel/src/filesystem/ext2/inode.tests.cpp b/kernel/src/filesystem/ext2/inode.tests.cpp index ae66aff..4d61790 100644 --- a/kernel/src/filesystem/ext2/inode.tests.cpp +++ b/kernel/src/filesystem/ext2/inode.tests.cpp @@ -1,13 +1,13 @@ -#include "kernel/filesystem/ext2/inode.hpp" - -#include "kernel/devices/storage/management.hpp" -#include "kernel/filesystem/device_inode.hpp" -#include "kernel/filesystem/ext2/filesystem.hpp" -#include "kernel/filesystem/filesystem.hpp" -#include "kernel/test_support/cpu.hpp" -#include "kernel/test_support/devices/block_device.hpp" -#include "kernel/test_support/filesystem/ext2.hpp" -#include "kernel/test_support/filesystem/storage_boot_module_fixture.hpp" +#include + +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp index 4160429..db7692b 100644 --- a/kernel/src/filesystem/file_descriptor_table.cpp +++ b/kernel/src/filesystem/file_descriptor_table.cpp @@ -1,8 +1,8 @@ -#include "kernel/filesystem/file_descriptor_table.hpp" +#include -#include "kernel/filesystem/open_file_description.hpp" +#include -#include "kapi/system.hpp" +#include #include diff --git a/kernel/src/filesystem/file_descriptor_table.tests.cpp b/kernel/src/filesystem/file_descriptor_table.tests.cpp index 5aeadb2..86ed7bf 100644 --- a/kernel/src/filesystem/file_descriptor_table.tests.cpp +++ b/kernel/src/filesystem/file_descriptor_table.tests.cpp @@ -1,7 +1,7 @@ -#include "kernel/filesystem/file_descriptor_table.hpp" +#include -#include "kernel/filesystem/open_file_description.hpp" -#include "kernel/test_support/filesystem/inode.hpp" +#include +#include #include #include diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index f958660..24d0e22 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -1,9 +1,9 @@ -#include "kernel/filesystem/filesystem.hpp" +#include -#include "kernel/filesystem/ext2/filesystem.hpp" -#include "kernel/filesystem/inode.hpp" +#include +#include -#include "kapi/system.hpp" +#include #include diff --git a/kernel/src/filesystem/inode.cpp b/kernel/src/filesystem/inode.cpp index 1cbead8..2f0764c 100644 --- a/kernel/src/filesystem/inode.cpp +++ b/kernel/src/filesystem/inode.cpp @@ -1,4 +1,4 @@ -#include "kernel/filesystem/inode.hpp" +#include namespace kernel::filesystem { diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index 9c8584b..67450b7 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -1,9 +1,9 @@ -#include "kernel/filesystem/mount.hpp" +#include -#include "kernel/filesystem/dentry.hpp" -#include "kernel/filesystem/filesystem.hpp" +#include +#include -#include "kapi/system.hpp" +#include #include #include diff --git a/kernel/src/filesystem/mount.tests.cpp b/kernel/src/filesystem/mount.tests.cpp index 4c4393a..d630464 100644 --- a/kernel/src/filesystem/mount.tests.cpp +++ b/kernel/src/filesystem/mount.tests.cpp @@ -1,9 +1,9 @@ -#include "kernel/filesystem/mount.hpp" +#include -#include "kernel/filesystem/dentry.hpp" -#include "kernel/test_support/cpu.hpp" -#include "kernel/test_support/filesystem/filesystem.hpp" -#include "kernel/test_support/filesystem/inode.hpp" +#include +#include +#include +#include #include #include diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 3b1dee3..da3c451 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -1,7 +1,7 @@ -#include "kernel/filesystem/mount_table.hpp" +#include -#include "kernel/filesystem/dentry.hpp" -#include "kernel/filesystem/mount.hpp" +#include +#include #include #include diff --git a/kernel/src/filesystem/mount_table.tests.cpp b/kernel/src/filesystem/mount_table.tests.cpp index 439fe97..747ffdf 100644 --- a/kernel/src/filesystem/mount_table.tests.cpp +++ b/kernel/src/filesystem/mount_table.tests.cpp @@ -1,9 +1,9 @@ -#include "kernel/filesystem/mount_table.hpp" +#include -#include "kernel/filesystem/dentry.hpp" -#include "kernel/filesystem/mount.hpp" -#include "kernel/test_support/filesystem/filesystem.hpp" -#include "kernel/test_support/filesystem/inode.hpp" +#include +#include +#include +#include #include #include diff --git a/kernel/src/filesystem/open_file_description.cpp b/kernel/src/filesystem/open_file_description.cpp index f049a34..3033e2b 100644 --- a/kernel/src/filesystem/open_file_description.cpp +++ b/kernel/src/filesystem/open_file_description.cpp @@ -1,6 +1,6 @@ -#include "kernel/filesystem/open_file_description.hpp" +#include -#include "kernel/filesystem/inode.hpp" +#include #include #include diff --git a/kernel/src/filesystem/open_file_description.tests.cpp b/kernel/src/filesystem/open_file_description.tests.cpp index ec35546..ce3c81a 100644 --- a/kernel/src/filesystem/open_file_description.tests.cpp +++ b/kernel/src/filesystem/open_file_description.tests.cpp @@ -1,8 +1,8 @@ -#include "kernel/filesystem/open_file_description.hpp" +#include -#include "kernel/filesystem/vfs.hpp" -#include "kernel/test_support/filesystem/inode.hpp" -#include "kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp" +#include +#include +#include #include #include diff --git a/kernel/src/filesystem/rootfs/filesystem.cpp b/kernel/src/filesystem/rootfs/filesystem.cpp index f718c72..6187c3c 100644 --- a/kernel/src/filesystem/rootfs/filesystem.cpp +++ b/kernel/src/filesystem/rootfs/filesystem.cpp @@ -1,7 +1,7 @@ -#include "kernel/filesystem/rootfs/filesystem.hpp" +#include -#include "kernel/filesystem/inode.hpp" -#include "kernel/filesystem/rootfs/inode.hpp" +#include +#include #include diff --git a/kernel/src/filesystem/rootfs/filesystem.tests.cpp b/kernel/src/filesystem/rootfs/filesystem.tests.cpp index b013f78..81ac9e4 100644 --- a/kernel/src/filesystem/rootfs/filesystem.tests.cpp +++ b/kernel/src/filesystem/rootfs/filesystem.tests.cpp @@ -1,6 +1,6 @@ -#include "kernel/filesystem/rootfs/filesystem.hpp" +#include -#include "kernel/filesystem/filesystem.hpp" +#include #include #include diff --git a/kernel/src/filesystem/rootfs/inode.cpp b/kernel/src/filesystem/rootfs/inode.cpp index 3ca9c02..eeea3fe 100644 --- a/kernel/src/filesystem/rootfs/inode.cpp +++ b/kernel/src/filesystem/rootfs/inode.cpp @@ -1,6 +1,6 @@ -#include "kernel/filesystem/inode.hpp" +#include -#include "kernel/filesystem/rootfs/inode.hpp" +#include #include #include diff --git a/kernel/src/filesystem/rootfs/inode.tests.cpp b/kernel/src/filesystem/rootfs/inode.tests.cpp index a0c5938..879818c 100644 --- a/kernel/src/filesystem/rootfs/inode.tests.cpp +++ b/kernel/src/filesystem/rootfs/inode.tests.cpp @@ -1,4 +1,4 @@ -#include "kernel/filesystem/rootfs/inode.hpp" +#include #include #include diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 23ced4c..5b454f6 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -1,13 +1,13 @@ -#include "kernel/filesystem/vfs.hpp" +#include -#include "kernel/filesystem/dentry.hpp" -#include "kernel/filesystem/devfs/filesystem.hpp" -#include "kernel/filesystem/filesystem.hpp" -#include "kernel/filesystem/mount.hpp" -#include "kernel/filesystem/mount_table.hpp" -#include "kernel/filesystem/rootfs/filesystem.hpp" +#include +#include +#include +#include +#include +#include -#include "kapi/system.hpp" +#include #include diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index eba157d..9cadb4d 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -1,7 +1,7 @@ -#include "kernel/filesystem/vfs.hpp" +#include -#include "kernel/filesystem/open_file_description.hpp" -#include "kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp" +#include +#include #include #include diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 52cbe2e..60b6e6e 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,17 +1,17 @@ -#include "kernel/devices/storage/management.hpp" -#include "kernel/filesystem/device_inode.hpp" -#include "kernel/filesystem/file_descriptor_table.hpp" -#include "kernel/filesystem/open_file_description.hpp" -#include "kernel/filesystem/vfs.hpp" -#include "kernel/memory.hpp" - -#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" +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/kernel/src/memory.cpp b/kernel/src/memory.cpp index b5f65fa..6a85c0e 100644 --- a/kernel/src/memory.cpp +++ b/kernel/src/memory.cpp @@ -1,10 +1,10 @@ -#include "kernel/memory.hpp" +#include -#include "kernel/memory/block_list_allocator.hpp" -#include "kernel/memory/heap_allocator.hpp" +#include +#include -#include "kapi/memory.hpp" -#include "kapi/system.hpp" +#include +#include #include #include diff --git a/kernel/src/memory/bitmap_allocator.cpp b/kernel/src/memory/bitmap_allocator.cpp index caaf5a4..240e2af 100644 --- a/kernel/src/memory/bitmap_allocator.cpp +++ b/kernel/src/memory/bitmap_allocator.cpp @@ -1,6 +1,6 @@ -#include "kernel/memory/bitmap_allocator.hpp" +#include -#include "kapi/memory.hpp" +#include #include #include diff --git a/kernel/src/memory/bitmap_allocator.tests.cpp b/kernel/src/memory/bitmap_allocator.tests.cpp index eff6d85..05d11a3 100644 --- a/kernel/src/memory/bitmap_allocator.tests.cpp +++ b/kernel/src/memory/bitmap_allocator.tests.cpp @@ -1,10 +1,10 @@ -#include "kernel/memory/bitmap_allocator.hpp" +#include -#include "kapi/memory.hpp" +#include -#include "catch2/matchers/catch_matchers.hpp" -#include "catch2/matchers/catch_matchers_range_equals.hpp" #include +#include +#include #include #include diff --git a/kernel/src/memory/block_list_allocator.cpp b/kernel/src/memory/block_list_allocator.cpp index 5c416fa..6e68ada 100644 --- a/kernel/src/memory/block_list_allocator.cpp +++ b/kernel/src/memory/block_list_allocator.cpp @@ -1,9 +1,9 @@ -#include "kernel/memory/block_list_allocator.hpp" +#include -#include "kernel/memory/heap_allocator.hpp" +#include -#include "kapi/memory.hpp" -#include "kapi/system.hpp" +#include +#include #include #include diff --git a/kernel/src/memory/block_list_allocator.tests.cpp b/kernel/src/memory/block_list_allocator.tests.cpp index fccdad5..c5f84c5 100644 --- a/kernel/src/memory/block_list_allocator.tests.cpp +++ b/kernel/src/memory/block_list_allocator.tests.cpp @@ -1,8 +1,8 @@ -#include "kernel/memory/block_list_allocator.hpp" +#include -#include "kernel/test_support/memory.hpp" +#include -#include "kapi/memory.hpp" +#include #include diff --git a/kernel/src/memory/mmio_allocator.cpp b/kernel/src/memory/mmio_allocator.cpp index ddbdfc2..ba23dbd 100644 --- a/kernel/src/memory/mmio_allocator.cpp +++ b/kernel/src/memory/mmio_allocator.cpp @@ -1,7 +1,7 @@ -#include "kernel/memory/mmio_allocator.hpp" +#include -#include "kapi/memory.hpp" -#include "kapi/system.hpp" +#include +#include #include diff --git a/kernel/src/memory/operators.cpp b/kernel/src/memory/operators.cpp index dd3b4fa..5673d68 100644 --- a/kernel/src/memory/operators.cpp +++ b/kernel/src/memory/operators.cpp @@ -1,6 +1,6 @@ -#include "kernel/memory.hpp" +#include -#include "kapi/system.hpp" +#include #include diff --git a/kernel/src/test_support/devices/block_device.cpp b/kernel/src/test_support/devices/block_device.cpp index d1d4101..9a9e544 100644 --- a/kernel/src/test_support/devices/block_device.cpp +++ b/kernel/src/test_support/devices/block_device.cpp @@ -1,6 +1,6 @@ -#include "kernel/test_support/devices/block_device.hpp" +#include -#include "kernel/devices/block_device.hpp" +#include #include #include diff --git a/kernel/src/test_support/devices/character_device.cpp b/kernel/src/test_support/devices/character_device.cpp index 9e9227d..3806654 100644 --- a/kernel/src/test_support/devices/character_device.cpp +++ b/kernel/src/test_support/devices/character_device.cpp @@ -1,7 +1,6 @@ +#include -#include "kernel/test_support/devices/character_device.hpp" - -#include "kapi/devices.hpp" +#include #include diff --git a/kernel/src/test_support/filesystem/ext2.cpp b/kernel/src/test_support/filesystem/ext2.cpp index 3627373..5a27b63 100644 --- a/kernel/src/test_support/filesystem/ext2.cpp +++ b/kernel/src/test_support/filesystem/ext2.cpp @@ -1,10 +1,10 @@ -#include "kernel/test_support/filesystem/ext2.hpp" +#include -#include "kernel/filesystem/ext2/block_group_descriptor.hpp" -#include "kernel/filesystem/ext2/filesystem.hpp" -#include "kernel/filesystem/ext2/inode.hpp" -#include "kernel/filesystem/ext2/superblock.hpp" -#include "kernel/test_support/devices/block_device.hpp" +#include +#include +#include +#include +#include #include #include diff --git a/kernel/src/test_support/filesystem/filesystem.cpp b/kernel/src/test_support/filesystem/filesystem.cpp index 225d096..12d43e0 100644 --- a/kernel/src/test_support/filesystem/filesystem.cpp +++ b/kernel/src/test_support/filesystem/filesystem.cpp @@ -1,7 +1,7 @@ -#include "kernel/test_support/filesystem/filesystem.hpp" +#include -#include "kernel/filesystem/inode.hpp" -#include "kernel/test_support/filesystem/inode.hpp" +#include +#include #include diff --git a/kernel/src/test_support/filesystem/inode.cpp b/kernel/src/test_support/filesystem/inode.cpp index 5df7bcd..54bd7e0 100644 --- a/kernel/src/test_support/filesystem/inode.cpp +++ b/kernel/src/test_support/filesystem/inode.cpp @@ -1,6 +1,6 @@ -#include "kernel/test_support/filesystem/inode.hpp" +#include -#include "kernel/filesystem/inode.hpp" +#include #include diff --git a/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp b/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp index 7fa2cb8..aabaace 100644 --- a/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp +++ b/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp @@ -1,12 +1,12 @@ -#include "kernel/test_support/filesystem/storage_boot_module_fixture.hpp" +#include -#include "kernel/devices/storage/management.hpp" -#include "kernel/test_support/boot_modules.hpp" -#include "kernel/test_support/devices/storage/management.hpp" +#include +#include +#include -#include "kapi/boot_module/boot_module.hpp" -#include "kapi/boot_modules.hpp" -#include "kapi/memory.hpp" +#include +#include +#include #include #include diff --git a/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp b/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp index 1a71b57..02ccfec 100644 --- a/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp +++ b/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp @@ -1,7 +1,7 @@ -#include "kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp" +#include -#include "kernel/filesystem/vfs.hpp" -#include "kernel/test_support/filesystem/vfs.hpp" +#include +#include #include #include diff --git a/kernel/src/test_support/kapi/cio.cpp b/kernel/src/test_support/kapi/cio.cpp index 5cdd462..98bc99d 100644 --- a/kernel/src/test_support/kapi/cio.cpp +++ b/kernel/src/test_support/kapi/cio.cpp @@ -1,6 +1,6 @@ -#include "kernel/test_support/cio.hpp" +#include -#include "kernel/test_support/log_buffer.hpp" +#include #include diff --git a/kernel/src/test_support/kapi/cpu.cpp b/kernel/src/test_support/kapi/cpu.cpp index 671097e..5d95633 100644 --- a/kernel/src/test_support/kapi/cpu.cpp +++ b/kernel/src/test_support/kapi/cpu.cpp @@ -1,4 +1,4 @@ -#include "kernel/test_support/cpu.hpp" +#include #include diff --git a/kernel/src/test_support/kapi/memory.cpp b/kernel/src/test_support/kapi/memory.cpp index 3b4a1bd..7fc95cb 100644 --- a/kernel/src/test_support/kapi/memory.cpp +++ b/kernel/src/test_support/kapi/memory.cpp @@ -1,7 +1,7 @@ -#include "kapi/memory.hpp" +#include -#include "kernel/test_support/bump_frame_allocator.hpp" -#include "kernel/test_support/page_mapper.hpp" +#include +#include #include diff --git a/kernel/src/test_support/log_buffer.cpp b/kernel/src/test_support/log_buffer.cpp index 9cff596..04d875b 100644 --- a/kernel/src/test_support/log_buffer.cpp +++ b/kernel/src/test_support/log_buffer.cpp @@ -1,4 +1,4 @@ -#include "kernel/test_support/log_buffer.hpp" +#include #include #include diff --git a/kernel/src/test_support/output_device.cpp b/kernel/src/test_support/output_device.cpp index 505e385..45fb4bc 100644 --- a/kernel/src/test_support/output_device.cpp +++ b/kernel/src/test_support/output_device.cpp @@ -1,7 +1,7 @@ -#include "kernel/test_support/cio.hpp" -#include "kernel/test_support/log_buffer.hpp" +#include +#include -#include "kapi/cio.hpp" +#include #include #include diff --git a/kernel/src/test_support/page_mapper.cpp b/kernel/src/test_support/page_mapper.cpp index 9236deb..3d50ff1 100644 --- a/kernel/src/test_support/page_mapper.cpp +++ b/kernel/src/test_support/page_mapper.cpp @@ -1,6 +1,6 @@ -#include "kernel/test_support/page_mapper.hpp" +#include -#include "kapi/memory.hpp" +#include #include diff --git a/kernel/src/test_support/simulated_memory.cpp b/kernel/src/test_support/simulated_memory.cpp index 2a4f15b..074e6b1 100644 --- a/kernel/src/test_support/simulated_memory.cpp +++ b/kernel/src/test_support/simulated_memory.cpp @@ -1,6 +1,6 @@ -#include "kernel/test_support/simulated_memory.hpp" +#include -#include "kapi/memory.hpp" +#include #include diff --git a/kernel/src/test_support/state_reset_listener.cpp b/kernel/src/test_support/state_reset_listener.cpp index 1967743..1815110 100644 --- a/kernel/src/test_support/state_reset_listener.cpp +++ b/kernel/src/test_support/state_reset_listener.cpp @@ -1,15 +1,15 @@ -#include "kernel/filesystem/file_descriptor_table.hpp" -#include "kernel/test_support/boot_modules.hpp" -#include "kernel/test_support/cio.hpp" -#include "kernel/test_support/cpu.hpp" -#include "kernel/test_support/devices/storage/management.hpp" -#include "kernel/test_support/filesystem/file_descriptor_table.hpp" -#include "kernel/test_support/filesystem/vfs.hpp" -#include "kernel/test_support/memory.hpp" - -#include "kapi/cio.hpp" -#include "kapi/cpu.hpp" -#include "kapi/memory.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include #include #include -- cgit v1.2.3 From 97afdf08922956627073d929bcb2529306333313 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 25 Apr 2026 23:29:27 +0200 Subject: add demo code --- kernel/src/main.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 60b6e6e..9f4ec1e 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -187,6 +188,64 @@ auto run_test_code() -> void kstd::println("---------------------------------"); } +auto run_demo() -> void +{ + // 1) open a file + auto fd_1 = kapi::filesystem::open("/entrance/tickets.txt"); + if (fd_1 == -1) + { + kstd::os::panic("demo failed"); + } + + // 2) read from the file + kstd::vector buffer_1{10}; + auto bytes_read = kapi::filesystem::read(fd_1, buffer_1.data(), buffer_1.size()); + auto buffer_as_str = std::string_view{reinterpret_cast(buffer_1.data()), static_cast(bytes_read)}; + kstd::println("Read {} bytes from /entrance/tickets.txt: {}", bytes_read, buffer_as_str); + + // 3) show that /entrance/information/info_1.txt is not accessible before mounting + auto fd_before_mount = kapi::filesystem::open("/entrance/information/info_1.txt"); + if (fd_before_mount == -1) + { + kstd::println("/entrance/information/info_1.txt is not accessible before mounting, as expected."); + } + + // 4) mount a new filesystem on top of /entrance + kapi::filesystem::mount("/dev/ram16", "/entrance"); + + // 5) open a file from the new filesystem + auto fd_2 = kapi::filesystem::open("/entrance/information/info_1.txt"); + if (fd_2 == -1) + { + kstd::os::panic("demo failed"); + } + + // 6) read from the new file + kstd::vector buffer_2{10}; + bytes_read = kapi::filesystem::read(fd_2, buffer_2.data(), buffer_2.size()); + buffer_as_str = std::string_view{reinterpret_cast(buffer_2.data()), static_cast(bytes_read)}; + kstd::println("Read {} bytes from /entrance/information/info_1.txt: {}", bytes_read, buffer_as_str); + + // 7) open device as file + auto fd_3 = kapi::filesystem::open("/dev/ram48"); + if (fd_3 == -1) + { + kstd::os::panic("demo failed"); + } + + // 8) read from the device file + kstd::vector buffer_3{2}; + bytes_read = kapi::filesystem::read(fd_3, buffer_3.data(), buffer_3.size()); + kstd::println("Read {} bytes from /dev/ram48: {::#04x}", bytes_read, buffer_3); + + // 9) write to the device file + kstd::vector write_buffer{std::byte{0xAA}, std::byte{0xAA}}; + auto bytes_written = kapi::filesystem::write(fd_3, write_buffer.data(), write_buffer.size()); + kstd::println("Written {} bytes to /dev/ram48: {::#04x}", bytes_written, write_buffer); + + // 10) do memory dump to show that the write to the device file had an effect +} + auto main() -> int { kapi::cio::init(); @@ -221,6 +280,10 @@ auto main() -> int kernel::filesystem::vfs::init(); kstd::println("[OS] Virtual filesystem initialized."); + // TODO BA-FS26 remove demo and test code again? + // run_demo(); + + // TODO BA-FS26 remove demo and test code again? run_test_code(); kstd::println("[TEST] All tests completed."); -- cgit v1.2.3 From 3b82b63aab8dcede2e099b8cbf12e7f3f0407896 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 25 Apr 2026 23:29:54 +0200 Subject: remove unused include --- kernel/include/kernel/filesystem/vfs.hpp | 1 - 1 file changed, 1 deletion(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 5b5c868..881f458 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include -- cgit v1.2.3 From c002a6fe53375d8757d43c48c59ac7f327f412b5 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 25 Apr 2026 23:31:26 +0200 Subject: add documentation, refactoring --- kernel/kapi/filesystem.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index c8d4c6d..741875a 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -42,14 +42,14 @@ namespace kapi::filesystem return -1; } - auto close(int fd) -> int + auto close(int file_descriptor) -> int { - return kernel::filesystem::file_descriptor_table::get().remove_file(fd); + return kernel::filesystem::file_descriptor_table::get().remove_file(file_descriptor); } - auto read(int fd, void * buffer, size_t size) -> ssize_t + auto read(int file_descriptor, void * buffer, size_t size) -> ssize_t { - if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(fd)) + if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(file_descriptor)) { return open_file_description->read(buffer, size); } @@ -57,9 +57,9 @@ namespace kapi::filesystem return -1; } - auto write(int fd, void const * buffer, size_t size) -> ssize_t + auto write(int file_descriptor, void const * buffer, size_t size) -> ssize_t { - if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(fd)) + if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(file_descriptor)) { return open_file_description->write(buffer, size); } -- cgit v1.2.3 From 4e2624b63236fa309c9ecf53a694b6ac9babf4e6 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 26 Apr 2026 10:11:24 +0200 Subject: rename open_file_description to open_file_descriptor --- kernel/CMakeLists.txt | 4 +- .../kernel/filesystem/file_descriptor_table.hpp | 14 +-- .../kernel/filesystem/open_file_description.hpp | 62 ----------- .../kernel/filesystem/open_file_descriptor.hpp | 62 +++++++++++ kernel/kapi/filesystem.cpp | 14 +-- kernel/src/filesystem/file_descriptor_table.cpp | 12 +-- .../src/filesystem/file_descriptor_table.tests.cpp | 62 +++++------ kernel/src/filesystem/open_file_description.cpp | 41 -------- .../src/filesystem/open_file_description.tests.cpp | 115 --------------------- kernel/src/filesystem/open_file_descriptor.cpp | 40 +++++++ .../src/filesystem/open_file_descriptor.tests.cpp | 114 ++++++++++++++++++++ kernel/src/filesystem/vfs.tests.cpp | 8 +- kernel/src/main.cpp | 16 +-- 13 files changed, 281 insertions(+), 283 deletions(-) delete mode 100644 kernel/include/kernel/filesystem/open_file_description.hpp create mode 100644 kernel/include/kernel/filesystem/open_file_descriptor.hpp delete mode 100644 kernel/src/filesystem/open_file_description.cpp delete mode 100644 kernel/src/filesystem/open_file_description.tests.cpp create mode 100644 kernel/src/filesystem/open_file_descriptor.cpp create mode 100644 kernel/src/filesystem/open_file_descriptor.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index d4484cd..cddec97 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -52,7 +52,7 @@ target_sources("kernel_lib" PRIVATE "src/filesystem/inode.cpp" "src/filesystem/mount_table.cpp" "src/filesystem/mount.cpp" - "src/filesystem/open_file_description.cpp" + "src/filesystem/open_file_descriptor.cpp" "src/filesystem/vfs.cpp" # DevFS Filesystem @@ -195,7 +195,7 @@ if(BUILD_TESTING) "src/filesystem/file_descriptor_table.tests.cpp" "src/filesystem/mount_table.tests.cpp" "src/filesystem/mount.tests.cpp" - "src/filesystem/open_file_description.tests.cpp" + "src/filesystem/open_file_descriptor.tests.cpp" "src/filesystem/vfs.tests.cpp" # Storage Subsystem Tests diff --git a/kernel/include/kernel/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/filesystem/file_descriptor_table.hpp index 293dc36..b0e699b 100644 --- a/kernel/include/kernel/filesystem/file_descriptor_table.hpp +++ b/kernel/include/kernel/filesystem/file_descriptor_table.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP #define TEACH_OS_KERNEL_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP -#include +#include #include #include @@ -10,7 +10,7 @@ namespace kernel::filesystem { /** @brief A table for managing file descriptors in the filesystem. This class provides methods for adding, retrieving, - and removing open file descriptions. + and removing open file descriptors. */ struct file_descriptor_table { @@ -35,17 +35,17 @@ namespace kernel::filesystem /** @brief Add a file to the descriptor table. - @param f The file description to add. + @param f The file descriptor to add. @return The file descriptor index assigned to the file, or -1 on failure. */ - auto add_file(kstd::shared_ptr const & f) -> int; + auto add_file(kstd::shared_ptr const & f) -> int; /** @brief Get a file from the descriptor table. @param fd The file descriptor index to retrieve. - @return A pointer to the requested file description, or a null pointer if not found. + @return A pointer to the requested file descriptor, or a null pointer if not found. */ - [[nodiscard]] auto get_file(int fd) const -> kstd::shared_ptr; + [[nodiscard]] auto get_file(int fd) const -> kstd::shared_ptr; /** @brief Remove a file from the descriptor table. @@ -57,7 +57,7 @@ namespace kernel::filesystem private: file_descriptor_table() = default; - kstd::vector> m_open_files{}; + kstd::vector> m_open_files{}; }; } // namespace kernel::filesystem diff --git a/kernel/include/kernel/filesystem/open_file_description.hpp b/kernel/include/kernel/filesystem/open_file_description.hpp deleted file mode 100644 index fad41e4..0000000 --- a/kernel/include/kernel/filesystem/open_file_description.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP - -#include - -#include - -#include - -namespace kernel::filesystem -{ - /** - @brief Represents an open file description in the filesystem. This class encapsulates the state of an open file, - including a reference to the associated inode and the current file offset. - */ - struct open_file_description - { - /** - @brief Constructs an open file description for the given @p inode. - @param inode The inode to associate with the open file description. - */ - explicit open_file_description(kstd::shared_ptr const & inode); - - /** - @brief Destructor for the open file description. - */ - ~open_file_description() = default; - - /** - @brief Reads data from the open file description into a @p buffer, starting at the current file offset and for a - given - @p size. The file offset is advanced by the number of bytes read. - @param buffer The buffer to read data into. - @param size The number of bytes to read. - @return The number of bytes read. - */ - auto read(void * buffer, size_t size) -> size_t; - - /** - @brief Writes data to the open file description from a @p buffer, starting at the current file offset and for a - given - @p size. The file offset is advanced by the number of bytes written. - @param buffer The buffer to write data from. - @param size The number of bytes to write. - @return The number of bytes written. - */ - auto write(void const * buffer, size_t size) -> size_t; - - /** - @brief Returns the current file offset for this open file description. - @return The current file offset in bytes. - */ - [[nodiscard]] auto offset() const -> size_t; - - private: - kstd::shared_ptr m_inode; - size_t m_offset; - }; - -} // namespace kernel::filesystem - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/open_file_descriptor.hpp b/kernel/include/kernel/filesystem/open_file_descriptor.hpp new file mode 100644 index 0000000..036dcf0 --- /dev/null +++ b/kernel/include/kernel/filesystem/open_file_descriptor.hpp @@ -0,0 +1,62 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTOR_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTOR_HPP + +#include + +#include + +#include + +namespace kernel::filesystem +{ + /** + @brief Represents an open file descriptor in the filesystem. This class encapsulates the state of an open file, + including a reference to the associated inode and the current file offset. + */ + struct open_file_descriptor + { + /** + @brief Constructs an open file descriptor for the given @p inode. + @param inode The inode to associate with the open file descriptor. + */ + explicit open_file_descriptor(kstd::shared_ptr const & inode); + + /** + @brief Destructor for the open file descriptor. + */ + ~open_file_descriptor() = default; + + /** + @brief Reads data from the open file descriptor into a @p buffer, starting at the current file offset and for a + given + @p size. The file offset is advanced by the number of bytes read. + @param buffer The buffer to read data into. + @param size The number of bytes to read. + @return The number of bytes read. + */ + auto read(void * buffer, size_t size) -> size_t; + + /** + @brief Writes data to the open file descriptor from a @p buffer, starting at the current file offset and for a + given + @p size. The file offset is advanced by the number of bytes written. + @param buffer The buffer to write data from. + @param size The number of bytes to write. + @return The number of bytes written. + */ + auto write(void const * buffer, size_t size) -> size_t; + + /** + @brief Returns the current file offset for this open file descriptor. + @return The current file offset in bytes. + */ + [[nodiscard]] auto offset() const -> size_t; + + private: + kstd::shared_ptr m_inode; + size_t m_offset; + }; + +} // namespace kernel::filesystem + +#endif \ No newline at end of file diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index 741875a..8481f20 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include #include @@ -35,8 +35,8 @@ namespace kapi::filesystem { if (auto dentry = kernel::filesystem::vfs::get().open(path)) { - auto open_file_description = kstd::make_shared(dentry->get_inode()); - return kernel::filesystem::file_descriptor_table::get().add_file(open_file_description); + auto open_file_descriptor = kstd::make_shared(dentry->get_inode()); + return kernel::filesystem::file_descriptor_table::get().add_file(open_file_descriptor); } return -1; @@ -49,9 +49,9 @@ namespace kapi::filesystem auto read(int file_descriptor, void * buffer, size_t size) -> ssize_t { - if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(file_descriptor)) + if (auto open_file_descriptor = kernel::filesystem::file_descriptor_table::get().get_file(file_descriptor)) { - return open_file_description->read(buffer, size); + return open_file_descriptor->read(buffer, size); } return -1; @@ -59,9 +59,9 @@ namespace kapi::filesystem auto write(int file_descriptor, void const * buffer, size_t size) -> ssize_t { - if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(file_descriptor)) + if (auto open_file_descriptor = kernel::filesystem::file_descriptor_table::get().get_file(file_descriptor)) { - return open_file_description->write(buffer, size); + return open_file_descriptor->write(buffer, size); } return -1; diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp index db7692b..9361f37 100644 --- a/kernel/src/filesystem/file_descriptor_table.cpp +++ b/kernel/src/filesystem/file_descriptor_table.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include @@ -37,9 +37,9 @@ namespace kernel::filesystem return *global_file_descriptor_table; } - auto file_descriptor_table::add_file(kstd::shared_ptr const & file_description) -> int + auto file_descriptor_table::add_file(kstd::shared_ptr const & file_descriptor) -> int { - if (!file_description) + if (!file_descriptor) { return -1; } @@ -47,15 +47,15 @@ namespace kernel::filesystem auto it = std::ranges::find_if(m_open_files, [](auto const & open_file) { return open_file == nullptr; }); if (it != m_open_files.end()) { - *it = file_description; + *it = file_descriptor; return static_cast(it - m_open_files.begin()); } - m_open_files.push_back(file_description); + m_open_files.push_back(file_descriptor); return static_cast(m_open_files.size() - 1); } - auto file_descriptor_table::get_file(int fd) const -> kstd::shared_ptr + auto file_descriptor_table::get_file(int fd) const -> kstd::shared_ptr { if (fd < 0) { diff --git a/kernel/src/filesystem/file_descriptor_table.tests.cpp b/kernel/src/filesystem/file_descriptor_table.tests.cpp index 86ed7bf..dd04e00 100644 --- a/kernel/src/filesystem/file_descriptor_table.tests.cpp +++ b/kernel/src/filesystem/file_descriptor_table.tests.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include @@ -11,18 +11,18 @@ SCENARIO("File descriptor table add/get file", "[filesystem][file_descriptor_table]") { - GIVEN("a file descriptor table and an open file description") + GIVEN("a file descriptor table and an open file descriptor") { auto & table = kernel::filesystem::file_descriptor_table::get(); auto inode = kstd::make_shared(); - auto file_description_1 = kstd::make_shared(inode); - auto file_description_2 = kstd::make_shared(inode); + auto file_descriptor_1 = kstd::make_shared(inode); + auto file_descriptor_2 = kstd::make_shared(inode); - WHEN("adding the open file description to the file descriptor table") + WHEN("adding the open file descriptor to the file descriptor table") { - auto fd_1 = table.add_file(file_description_1); - auto fd_2 = table.add_file(file_description_2); - auto fd_3 = table.add_file(file_description_2); + auto fd_1 = table.add_file(file_descriptor_1); + auto fd_2 = table.add_file(file_descriptor_2); + auto fd_3 = table.add_file(file_descriptor_2); THEN("a valid file descriptor is returned") { @@ -31,67 +31,67 @@ SCENARIO("File descriptor table add/get file", "[filesystem][file_descriptor_tab REQUIRE(fd_3 == 2); } - THEN("the file description can be retrieved using the returned file descriptor") + THEN("the file descriptor can be retrieved using the returned file descriptor") { - auto retrieved_description = table.get_file(fd_1); - REQUIRE(retrieved_description == file_description_1); + auto retrieved_descriptor = table.get_file(fd_1); + REQUIRE(retrieved_descriptor == file_descriptor_1); } } } - GIVEN("a invalid open file description") + GIVEN("a invalid open file descriptor") { auto & table = kernel::filesystem::file_descriptor_table::get(); - THEN("adding a null file description returns an error code") + THEN("adding a null file descriptor returns an error code") { auto fd = table.add_file(nullptr); REQUIRE(fd == -1); } - THEN("retrieving a file description with a negative file descriptor returns a null pointer") + THEN("retrieving a file descriptor with a negative file descriptor returns a null pointer") { - auto retrieved_description = table.get_file(-1); - REQUIRE(retrieved_description == nullptr); + auto retrieved_descriptor = table.get_file(-1); + REQUIRE(retrieved_descriptor == nullptr); } - THEN("retrieving a file description with an out-of-bounds file descriptor returns a null pointer") + THEN("retrieving a file descriptor with an out-of-bounds file descriptor returns a null pointer") { - auto retrieved_description = table.get_file(1000); - REQUIRE(retrieved_description == nullptr); + auto retrieved_descriptor = table.get_file(1000); + REQUIRE(retrieved_descriptor == nullptr); } } } SCENARIO("File descriptor table remove file", "[filesystem][file_descriptor_table]") { - GIVEN("a file descriptor table with an open file description") + GIVEN("a file descriptor table with an open file descriptor") { auto & table = kernel::filesystem::file_descriptor_table::get(); auto inode = kstd::make_shared(); - auto file_description = kstd::make_shared(inode); - auto fd = table.add_file(file_description); + auto file_descriptor = kstd::make_shared(inode); + auto fd = table.add_file(file_descriptor); - WHEN("removing the file description using the file descriptor") + WHEN("removing the file descriptor using the file descriptor") { table.remove_file(fd); - THEN("the file description can no longer be retrieved using the file descriptor") + THEN("the file descriptor can no longer be retrieved using the file descriptor") { - auto retrieved_description = table.get_file(fd); - REQUIRE(retrieved_description == nullptr); + auto retrieved_descriptor = table.get_file(fd); + REQUIRE(retrieved_descriptor == nullptr); } } - WHEN("removing a file description the other file descriptor keep the same index") + WHEN("removing a file descriptor the other file descriptor keep the same index") { - auto fd2 = table.add_file(file_description); + auto fd2 = table.add_file(file_descriptor); table.remove_file(fd); - THEN("the second file description can still be retrieved using its file descriptor") + THEN("the second file descriptor can still be retrieved using its file descriptor") { - auto retrieved_description = table.get_file(fd2); - REQUIRE(retrieved_description == file_description); + auto retrieved_descriptor = table.get_file(fd2); + REQUIRE(retrieved_descriptor == file_descriptor); } } } diff --git a/kernel/src/filesystem/open_file_description.cpp b/kernel/src/filesystem/open_file_description.cpp deleted file mode 100644 index 3033e2b..0000000 --- a/kernel/src/filesystem/open_file_description.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include - -#include - -#include -#include - -#include - -namespace kernel::filesystem -{ - open_file_description::open_file_description(kstd::shared_ptr const & inode) - : m_inode(inode) - , m_offset(0) - { - if (!inode) - { - kstd::os::panic("[FILESYSTEM] open_file_description constructed with null inode."); - } - } - - auto open_file_description::read(void * buffer, size_t size) -> size_t - { - auto read_bytes = m_inode->read(buffer, m_offset, size); - m_offset += read_bytes; - return read_bytes; - } - - auto open_file_description::write(void const * buffer, size_t size) -> size_t - { - auto written_bytes = m_inode->write(buffer, m_offset, size); - m_offset += written_bytes; - return written_bytes; - } - - auto open_file_description::offset() const -> size_t - { - return m_offset; - } - -} // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/open_file_description.tests.cpp b/kernel/src/filesystem/open_file_description.tests.cpp deleted file mode 100644 index ce3c81a..0000000 --- a/kernel/src/filesystem/open_file_description.tests.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include - -SCENARIO("Open file description construction", "[filesystem][open_file_description]") -{ - GIVEN("an inode and an open file description for that inode") - { - auto inode = kstd::make_shared(); - auto file_description = kernel::filesystem::open_file_description{inode}; - - THEN("the initial offset is zero") - { - REQUIRE(file_description.offset() == 0); - } - } -} - -SCENARIO("Open file description read/write offset management", "[filesystem][open_file_description]") -{ - GIVEN("an inode that tracks read/write calls and an open file description for that inode") - { - auto inode = kstd::make_shared(); - auto file_description = kernel::filesystem::open_file_description{inode}; - - THEN("the offset is updated correctly after reads") - { - REQUIRE(file_description.read(nullptr, 100) == 100); - REQUIRE(file_description.offset() == 100); - REQUIRE(file_description.read(nullptr, 50) == 50); - REQUIRE(file_description.offset() == 150); - } - - THEN("the offset is updated correctly after writes") - { - REQUIRE(file_description.write(nullptr, 200) == 200); - REQUIRE(file_description.offset() == 200); - REQUIRE(file_description.write(nullptr, 25) == 25); - REQUIRE(file_description.offset() == 225); - } - - THEN("reads and writes both update the same offset") - { - REQUIRE(file_description.read(nullptr, 10) == 10); - REQUIRE(file_description.offset() == 10); - REQUIRE(file_description.write(nullptr, 20) == 20); - REQUIRE(file_description.offset() == 30); - REQUIRE(file_description.read(nullptr, 5) == 5); - REQUIRE(file_description.offset() == 35); - REQUIRE(file_description.write(nullptr, 15) == 15); - REQUIRE(file_description.offset() == 50); - } - } -} - -SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, - "Open file description read with real image", "[filesystem][open_file_description][img]") -{ - auto const image_path = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_1KB_fs.img"; - - GIVEN("an open file description for a file in a real image") - { - REQUIRE(std::filesystem::exists(image_path)); - REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module"}, {image_path})); - - auto & vfs = kernel::filesystem::vfs::get(); - auto dentry = vfs.open("/information/info_1.txt"); - REQUIRE(dentry != nullptr); - auto ofd = kstd::make_shared(dentry->get_inode()); - - THEN("the file can be read and the offset is updated") - { - kstd::vector buffer(32); - auto bytes_read = ofd->read(buffer.data(), buffer.size()); - REQUIRE(bytes_read == 32); - REQUIRE(ofd->offset() == 32); - - std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(bytes_read)}; - auto const content_end = buffer_as_str.find('\0'); - REQUIRE(buffer_as_str.substr(0, content_end) == "info_1\n"); - - for (auto i = content_end; i < buffer_as_str.size(); ++i) - { - REQUIRE(buffer_as_str[i] == '\0'); - } - } - - THEN("the file can be read multiple times") - { - kstd::vector buffer(4); - auto bytes_read_1 = ofd->read(buffer.data(), buffer.size() / 2); - REQUIRE(bytes_read_1 == buffer.size() / 2); - REQUIRE(ofd->offset() == buffer.size() / 2); - - auto bytes_read_2 = ofd->read(buffer.data() + buffer.size() / 2, buffer.size() / 2); - REQUIRE(bytes_read_2 == buffer.size() / 2); - REQUIRE(ofd->offset() == buffer.size()); - - std::string_view buffer_as_str{reinterpret_cast(buffer.data()), bytes_read_1 + bytes_read_2}; - REQUIRE(buffer_as_str == "info"); - } - } -} diff --git a/kernel/src/filesystem/open_file_descriptor.cpp b/kernel/src/filesystem/open_file_descriptor.cpp new file mode 100644 index 0000000..25bffbd --- /dev/null +++ b/kernel/src/filesystem/open_file_descriptor.cpp @@ -0,0 +1,40 @@ +#include +#include + +#include +#include + +#include + +namespace kernel::filesystem +{ + open_file_descriptor::open_file_descriptor(kstd::shared_ptr const & inode) + : m_inode(inode) + , m_offset(0) + { + if (!inode) + { + kstd::os::panic("[FILESYSTEM] open_file_descriptor constructed with null inode."); + } + } + + auto open_file_descriptor::read(void * buffer, size_t size) -> size_t + { + auto read_bytes = m_inode->read(buffer, m_offset, size); + m_offset += read_bytes; + return read_bytes; + } + + auto open_file_descriptor::write(void const * buffer, size_t size) -> size_t + { + auto written_bytes = m_inode->write(buffer, m_offset, size); + m_offset += written_bytes; + return written_bytes; + } + + auto open_file_descriptor::offset() const -> size_t + { + return m_offset; + } + +} // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/open_file_descriptor.tests.cpp b/kernel/src/filesystem/open_file_descriptor.tests.cpp new file mode 100644 index 0000000..095e203 --- /dev/null +++ b/kernel/src/filesystem/open_file_descriptor.tests.cpp @@ -0,0 +1,114 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +SCENARIO("Open file descriptor construction", "[filesystem][open_file_descriptor]") +{ + GIVEN("an inode and an open file descriptor for that inode") + { + auto inode = kstd::make_shared(); + auto file_descriptor = kernel::filesystem::open_file_descriptor{inode}; + + THEN("the initial offset is zero") + { + REQUIRE(file_descriptor.offset() == 0); + } + } +} + +SCENARIO("Open file descriptor read/write offset management", "[filesystem][open_file_descriptor]") +{ + GIVEN("an inode that tracks read/write calls and an open file descriptor for that inode") + { + auto inode = kstd::make_shared(); + auto file_descriptor = kernel::filesystem::open_file_descriptor{inode}; + + THEN("the offset is updated correctly after reads") + { + REQUIRE(file_descriptor.read(nullptr, 100) == 100); + REQUIRE(file_descriptor.offset() == 100); + REQUIRE(file_descriptor.read(nullptr, 50) == 50); + REQUIRE(file_descriptor.offset() == 150); + } + + THEN("the offset is updated correctly after writes") + { + REQUIRE(file_descriptor.write(nullptr, 200) == 200); + REQUIRE(file_descriptor.offset() == 200); + REQUIRE(file_descriptor.write(nullptr, 25) == 25); + REQUIRE(file_descriptor.offset() == 225); + } + + THEN("reads and writes both update the same offset") + { + REQUIRE(file_descriptor.read(nullptr, 10) == 10); + REQUIRE(file_descriptor.offset() == 10); + REQUIRE(file_descriptor.write(nullptr, 20) == 20); + REQUIRE(file_descriptor.offset() == 30); + REQUIRE(file_descriptor.read(nullptr, 5) == 5); + REQUIRE(file_descriptor.offset() == 35); + REQUIRE(file_descriptor.write(nullptr, 15) == 15); + REQUIRE(file_descriptor.offset() == 50); + } + } +} + +SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Open file descriptor read with real image", + "[filesystem][open_file_descriptor][img]") +{ + auto const image_path = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_1KB_fs.img"; + + GIVEN("an open file descriptor for a file in a real image") + { + REQUIRE(std::filesystem::exists(image_path)); + REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module"}, {image_path})); + + auto & vfs = kernel::filesystem::vfs::get(); + auto dentry = vfs.open("/information/info_1.txt"); + REQUIRE(dentry != nullptr); + auto ofd = kstd::make_shared(dentry->get_inode()); + + THEN("the file can be read and the offset is updated") + { + kstd::vector buffer(32); + auto bytes_read = ofd->read(buffer.data(), buffer.size()); + REQUIRE(bytes_read == 32); + REQUIRE(ofd->offset() == 32); + + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(bytes_read)}; + auto const content_end = buffer_as_str.find('\0'); + REQUIRE(buffer_as_str.substr(0, content_end) == "info_1\n"); + + for (auto i = content_end; i < buffer_as_str.size(); ++i) + { + REQUIRE(buffer_as_str[i] == '\0'); + } + } + + THEN("the file can be read multiple times") + { + kstd::vector buffer(4); + auto bytes_read_1 = ofd->read(buffer.data(), buffer.size() / 2); + REQUIRE(bytes_read_1 == buffer.size() / 2); + REQUIRE(ofd->offset() == buffer.size() / 2); + + auto bytes_read_2 = ofd->read(buffer.data() + buffer.size() / 2, buffer.size() / 2); + REQUIRE(bytes_read_2 == buffer.size() / 2); + REQUIRE(ofd->offset() == buffer.size()); + + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), bytes_read_1 + bytes_read_2}; + REQUIRE(buffer_as_str == "info"); + } + } +} diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 9cadb4d..979ea42 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include @@ -185,7 +185,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto dentry = vfs.open("/information/sheep_1.txt"); REQUIRE(dentry != nullptr); - auto sheep_1_ofd = kstd::make_shared(dentry->get_inode()); + auto sheep_1_ofd = kstd::make_shared(dentry->get_inode()); kstd::vector buffer(7); auto bytes_read = sheep_1_ofd->read(buffer.data(), buffer.size()); @@ -210,8 +210,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(sheep_1 != nullptr); REQUIRE(goat_1 != nullptr); - auto sheep_1_ofd = kstd::make_shared(sheep_1->get_inode()); - auto goat_1_ofd = kstd::make_shared(goat_1->get_inode()); + auto sheep_1_ofd = kstd::make_shared(sheep_1->get_inode()); + auto goat_1_ofd = kstd::make_shared(goat_1->get_inode()); kstd::vector sheep_buffer(7); auto bytes_read = sheep_1_ofd->read(sheep_buffer.data(), sheep_buffer.size()); diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 9f4ec1e..9878d20 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include @@ -36,7 +36,7 @@ auto test_device_names() -> void }); } -auto test_file_description_manually() -> void +auto test_file_descriptor_manually() -> void { // setup auto fd_table = kernel::filesystem::file_descriptor_table::get(); @@ -45,7 +45,7 @@ auto test_file_description_manually() -> void auto dev_node = kstd::make_shared(device); - auto ofd = kstd::make_shared(dev_node); + auto ofd = kstd::make_shared(dev_node); auto fd_index = fd_table.add_file(ofd); // use: read two bytes and write two again @@ -71,7 +71,7 @@ auto test_file_description_manually() -> void fd_table.remove_file(fd_index); // use: read four bytes again -> two old bytes two new bytes - auto ofd1 = kstd::make_shared(dev_node); + auto ofd1 = kstd::make_shared(dev_node); fd_index = fd_table.add_file(ofd1); auto fd1 = fd_table.get_file(fd_index); @@ -96,7 +96,7 @@ auto test_device_with_vfs() -> void } auto fd_table = kernel::filesystem::file_descriptor_table::get(); - auto ofd = kstd::make_shared(dentry->get_inode()); + auto ofd = kstd::make_shared(dentry->get_inode()); auto fd = fd_table.add_file(ofd); kstd::vector buffer{2}; auto file = fd_table.get_file(fd); @@ -122,7 +122,7 @@ auto test_file_lookup() -> void } kstd::vector buffer{32}; - auto ofd = kstd::make_shared(dentry->get_inode()); + auto ofd = kstd::make_shared(dentry->get_inode()); auto number_of_read_bytes = ofd->read(buffer.data(), buffer.size()); kstd::println("read bytes: {}", number_of_read_bytes); kstd::println("buffer: {::#04x}", buffer); @@ -175,8 +175,8 @@ auto run_test_code() -> void test_device_names(); kstd::println("---------------------------------"); - kstd::println("[TEST] file description manually"); - test_file_description_manually(); + kstd::println("[TEST] file descriptor manually"); + test_file_descriptor_manually(); kstd::println("---------------------------------"); kstd::println("[TEST] device with VFS"); -- cgit v1.2.3 From e0854bc0aad9e59d67fbf300cb223b116b127ffc Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 26 Apr 2026 12:36:26 +0200 Subject: rename file_descriptor_table to open_file_table --- kernel/CMakeLists.txt | 4 +- .../kernel/filesystem/file_descriptor_table.hpp | 64 ------------ .../include/kernel/filesystem/open_file_table.hpp | 63 ++++++++++++ .../filesystem/file_descriptor_table.hpp | 10 +- kernel/kapi/filesystem.cpp | 10 +- kernel/src/filesystem/file_descriptor_table.cpp | 98 ------------------ .../src/filesystem/file_descriptor_table.tests.cpp | 113 --------------------- kernel/src/filesystem/open_file_table.cpp | 98 ++++++++++++++++++ kernel/src/filesystem/open_file_table.tests.cpp | 113 +++++++++++++++++++++ kernel/src/main.cpp | 10 +- kernel/src/test_support/state_reset_listener.cpp | 8 +- 11 files changed, 295 insertions(+), 296 deletions(-) delete mode 100644 kernel/include/kernel/filesystem/file_descriptor_table.hpp create mode 100644 kernel/include/kernel/filesystem/open_file_table.hpp delete mode 100644 kernel/src/filesystem/file_descriptor_table.cpp delete mode 100644 kernel/src/filesystem/file_descriptor_table.tests.cpp create mode 100644 kernel/src/filesystem/open_file_table.cpp create mode 100644 kernel/src/filesystem/open_file_table.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index cddec97..909ccf7 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -47,12 +47,12 @@ target_sources("kernel_lib" PRIVATE # Filesystem Subsystem "src/filesystem/dentry.cpp" "src/filesystem/device_inode.cpp" - "src/filesystem/file_descriptor_table.cpp" "src/filesystem/filesystem.cpp" "src/filesystem/inode.cpp" "src/filesystem/mount_table.cpp" "src/filesystem/mount.cpp" "src/filesystem/open_file_descriptor.cpp" + "src/filesystem/open_file_table.cpp" "src/filesystem/vfs.cpp" # DevFS Filesystem @@ -192,10 +192,10 @@ if(BUILD_TESTING) "src/filesystem/rootfs/inode.tests.cpp" "src/filesystem/dentry.tests.cpp" "src/filesystem/device_inode.tests.cpp" - "src/filesystem/file_descriptor_table.tests.cpp" "src/filesystem/mount_table.tests.cpp" "src/filesystem/mount.tests.cpp" "src/filesystem/open_file_descriptor.tests.cpp" + "src/filesystem/open_file_table.tests.cpp" "src/filesystem/vfs.tests.cpp" # Storage Subsystem Tests diff --git a/kernel/include/kernel/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/filesystem/file_descriptor_table.hpp deleted file mode 100644 index b0e699b..0000000 --- a/kernel/include/kernel/filesystem/file_descriptor_table.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP - -#include - -#include -#include - -namespace kernel::filesystem -{ - /** - @brief A table for managing file descriptors in the filesystem. This class provides methods for adding, retrieving, - and removing open file descriptors. - */ - struct file_descriptor_table - { - /** - @brief Initialize the global file descriptor table. This method creates the singleton instance of the file - descriptor table. - @warning Panics if called more than once. - */ - auto static init() -> void; - - /** - @brief Get the global file descriptor table instance. - @return A reference to the global file descriptor table. - @warning Panics if the file descriptor table has not been initialized. - */ - auto static get() -> file_descriptor_table &; - - /** - @brief Destructor for the file descriptor table. - */ - ~file_descriptor_table() = default; - - /** - @brief Add a file to the descriptor table. - @param f The file descriptor to add. - @return The file descriptor index assigned to the file, or -1 on failure. - */ - auto add_file(kstd::shared_ptr const & f) -> int; - - /** - @brief Get a file from the descriptor table. - @param fd The file descriptor index to retrieve. - @return A pointer to the requested file descriptor, or a null pointer if not found. - */ - [[nodiscard]] auto get_file(int fd) const -> kstd::shared_ptr; - - /** - @brief Remove a file from the descriptor table. - @param fd The file descriptor index to remove. - @return 0 on success, or -1 on failure. - */ - auto remove_file(int fd) -> int; - - private: - file_descriptor_table() = default; - - kstd::vector> m_open_files{}; - }; -} // namespace kernel::filesystem - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/filesystem/open_file_table.hpp b/kernel/include/kernel/filesystem/open_file_table.hpp new file mode 100644 index 0000000..2f9a421 --- /dev/null +++ b/kernel/include/kernel/filesystem/open_file_table.hpp @@ -0,0 +1,63 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_TABLE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_TABLE_HPP + +#include + +#include +#include + +namespace kernel::filesystem +{ + /** + @brief A table for managing file descriptors in the filesystem. This class provides methods for adding, retrieving, + and removing open file descriptors. + */ + struct open_file_table + { + /** + @brief Initialize the global open file table. This method creates the singleton instance of the open file table. + @warning Panics if called more than once. + */ + auto static init() -> void; + + /** + @brief Get the global open file table instance. + @return A reference to the global open file table. + @warning Panics if the open file table has not been initialized. + */ + auto static get() -> open_file_table &; + + /** + @brief Destructor for the open file table. + */ + ~open_file_table() = default; + + /** + @brief Add a file to the open file table. + @param f The file descriptor to add. + @return The file descriptor index assigned to the file, or -1 on failure. + */ + auto add_file(kstd::shared_ptr const & f) -> int; + + /** + @brief Get a file from the open file table. + @param fd The file descriptor index to retrieve. + @return A pointer to the requested file descriptor, or a null pointer if not found. + */ + [[nodiscard]] auto get_file(int fd) const -> kstd::shared_ptr; + + /** + @brief Remove a file from the open file table. + @param fd The file descriptor index to remove. + @return 0 on success, or -1 on failure. + */ + auto remove_file(int fd) -> int; + + private: + open_file_table() = default; + + kstd::vector> m_open_files{}; + }; +} // namespace kernel::filesystem + +#endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp index bbc0f4a..46b0334 100644 --- a/kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp +++ b/kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp @@ -1,10 +1,10 @@ -#ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP -#define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_OPEN_FILE_TABLE_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_OPEN_FILE_TABLE_HPP -namespace kernel::tests::filesystem::file_descriptor_table +namespace kernel::tests::filesystem::open_file_table { - //! Deinitialize the file descriptor table singleton. + //! Deinitialize the open file table singleton. auto deinit() -> void; -} // namespace kernel::tests::filesystem::file_descriptor_table +} // namespace kernel::tests::filesystem::open_file_table #endif \ No newline at end of file diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index 8481f20..4c68f28 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -1,7 +1,7 @@ #include -#include #include +#include #include #include @@ -36,7 +36,7 @@ namespace kapi::filesystem if (auto dentry = kernel::filesystem::vfs::get().open(path)) { auto open_file_descriptor = kstd::make_shared(dentry->get_inode()); - return kernel::filesystem::file_descriptor_table::get().add_file(open_file_descriptor); + return kernel::filesystem::open_file_table::get().add_file(open_file_descriptor); } return -1; @@ -44,12 +44,12 @@ namespace kapi::filesystem auto close(int file_descriptor) -> int { - return kernel::filesystem::file_descriptor_table::get().remove_file(file_descriptor); + return kernel::filesystem::open_file_table::get().remove_file(file_descriptor); } auto read(int file_descriptor, void * buffer, size_t size) -> ssize_t { - if (auto open_file_descriptor = kernel::filesystem::file_descriptor_table::get().get_file(file_descriptor)) + if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().get_file(file_descriptor)) { return open_file_descriptor->read(buffer, size); } @@ -59,7 +59,7 @@ namespace kapi::filesystem auto write(int file_descriptor, void const * buffer, size_t size) -> ssize_t { - if (auto open_file_descriptor = kernel::filesystem::file_descriptor_table::get().get_file(file_descriptor)) + if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().get_file(file_descriptor)) { return open_file_descriptor->write(buffer, size); } diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp deleted file mode 100644 index 9361f37..0000000 --- a/kernel/src/filesystem/file_descriptor_table.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include - -#include - -#include - -#include - -#include -#include -#include - -namespace -{ - constinit auto static global_file_descriptor_table = std::optional{}; -} // namespace - -namespace kernel::filesystem -{ - auto file_descriptor_table::init() -> void - { - if (global_file_descriptor_table) - { - kapi::system::panic("[FILESYSTEM] File descriptor table has already been initialized."); - } - - global_file_descriptor_table.emplace(file_descriptor_table{}); - } - - auto file_descriptor_table::get() -> file_descriptor_table & - { - if (!global_file_descriptor_table) - { - kapi::system::panic("[FILESYSTEM] File descriptor table has not been initialized."); - } - - return *global_file_descriptor_table; - } - - auto file_descriptor_table::add_file(kstd::shared_ptr const & file_descriptor) -> int - { - if (!file_descriptor) - { - return -1; - } - - auto it = std::ranges::find_if(m_open_files, [](auto const & open_file) { return open_file == nullptr; }); - if (it != m_open_files.end()) - { - *it = file_descriptor; - return static_cast(it - m_open_files.begin()); - } - - m_open_files.push_back(file_descriptor); - return static_cast(m_open_files.size() - 1); - } - - auto file_descriptor_table::get_file(int fd) const -> kstd::shared_ptr - { - if (fd < 0) - { - return nullptr; - } - - auto const index = static_cast(fd); - if (index >= m_open_files.size()) - { - return nullptr; - } - - return m_open_files.at(index); - } - - auto file_descriptor_table::remove_file(int fd) -> int - { - if (fd < 0) - { - return -1; - } - - auto const index = static_cast(fd); - if (index >= m_open_files.size()) - { - return -1; - } - - m_open_files.at(index) = nullptr; - return 0; - } -} // namespace kernel::filesystem - -namespace kernel::tests::filesystem::file_descriptor_table -{ - auto deinit() -> void - { - global_file_descriptor_table.reset(); - } -} // namespace kernel::tests::filesystem::file_descriptor_table diff --git a/kernel/src/filesystem/file_descriptor_table.tests.cpp b/kernel/src/filesystem/file_descriptor_table.tests.cpp deleted file mode 100644 index dd04e00..0000000 --- a/kernel/src/filesystem/file_descriptor_table.tests.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include - -#include -#include - -#include -#include -#include - -#include - -SCENARIO("File descriptor table add/get file", "[filesystem][file_descriptor_table]") -{ - GIVEN("a file descriptor table and an open file descriptor") - { - auto & table = kernel::filesystem::file_descriptor_table::get(); - auto inode = kstd::make_shared(); - auto file_descriptor_1 = kstd::make_shared(inode); - auto file_descriptor_2 = kstd::make_shared(inode); - - WHEN("adding the open file descriptor to the file descriptor table") - { - auto fd_1 = table.add_file(file_descriptor_1); - auto fd_2 = table.add_file(file_descriptor_2); - auto fd_3 = table.add_file(file_descriptor_2); - - THEN("a valid file descriptor is returned") - { - REQUIRE(fd_1 == 0); - REQUIRE(fd_2 == 1); - REQUIRE(fd_3 == 2); - } - - THEN("the file descriptor can be retrieved using the returned file descriptor") - { - auto retrieved_descriptor = table.get_file(fd_1); - REQUIRE(retrieved_descriptor == file_descriptor_1); - } - } - } - - GIVEN("a invalid open file descriptor") - { - auto & table = kernel::filesystem::file_descriptor_table::get(); - - THEN("adding a null file descriptor returns an error code") - { - auto fd = table.add_file(nullptr); - REQUIRE(fd == -1); - } - - THEN("retrieving a file descriptor with a negative file descriptor returns a null pointer") - { - auto retrieved_descriptor = table.get_file(-1); - REQUIRE(retrieved_descriptor == nullptr); - } - - THEN("retrieving a file descriptor with an out-of-bounds file descriptor returns a null pointer") - { - auto retrieved_descriptor = table.get_file(1000); - REQUIRE(retrieved_descriptor == nullptr); - } - } -} - -SCENARIO("File descriptor table remove file", "[filesystem][file_descriptor_table]") -{ - GIVEN("a file descriptor table with an open file descriptor") - { - auto & table = kernel::filesystem::file_descriptor_table::get(); - auto inode = kstd::make_shared(); - auto file_descriptor = kstd::make_shared(inode); - auto fd = table.add_file(file_descriptor); - - WHEN("removing the file descriptor using the file descriptor") - { - table.remove_file(fd); - - THEN("the file descriptor can no longer be retrieved using the file descriptor") - { - auto retrieved_descriptor = table.get_file(fd); - REQUIRE(retrieved_descriptor == nullptr); - } - } - - WHEN("removing a file descriptor the other file descriptor keep the same index") - { - auto fd2 = table.add_file(file_descriptor); - table.remove_file(fd); - - THEN("the second file descriptor can still be retrieved using its file descriptor") - { - auto retrieved_descriptor = table.get_file(fd2); - REQUIRE(retrieved_descriptor == file_descriptor); - } - } - } - - GIVEN("an invalid file descriptor") - { - auto & table = kernel::filesystem::file_descriptor_table::get(); - - THEN("removing a file with a negative file descriptor does nothing") - { - REQUIRE_NOTHROW(table.remove_file(-1)); - } - - THEN("removing a file with an out-of-bounds file descriptor does nothing") - { - REQUIRE_NOTHROW(table.remove_file(1000)); - } - } -} \ No newline at end of file diff --git a/kernel/src/filesystem/open_file_table.cpp b/kernel/src/filesystem/open_file_table.cpp new file mode 100644 index 0000000..e47d229 --- /dev/null +++ b/kernel/src/filesystem/open_file_table.cpp @@ -0,0 +1,98 @@ +#include + +#include + +#include + +#include + +#include +#include +#include + +namespace +{ + constinit auto static global_open_file_table = std::optional{}; +} // namespace + +namespace kernel::filesystem +{ + auto open_file_table::init() -> void + { + if (global_open_file_table) + { + kapi::system::panic("[FILESYSTEM] Open file table has already been initialized."); + } + + global_open_file_table.emplace(open_file_table{}); + } + + auto open_file_table::get() -> open_file_table & + { + if (!global_open_file_table) + { + kapi::system::panic("[FILESYSTEM] Open file table has not been initialized."); + } + + return *global_open_file_table; + } + + auto open_file_table::add_file(kstd::shared_ptr const & file_descriptor) -> int + { + if (!file_descriptor) + { + return -1; + } + + auto it = std::ranges::find_if(m_open_files, [](auto const & open_file) { return open_file == nullptr; }); + if (it != m_open_files.end()) + { + *it = file_descriptor; + return static_cast(it - m_open_files.begin()); + } + + m_open_files.push_back(file_descriptor); + return static_cast(m_open_files.size() - 1); + } + + auto open_file_table::get_file(int fd) const -> kstd::shared_ptr + { + if (fd < 0) + { + return nullptr; + } + + auto const index = static_cast(fd); + if (index >= m_open_files.size()) + { + return nullptr; + } + + return m_open_files.at(index); + } + + auto open_file_table::remove_file(int fd) -> int + { + if (fd < 0) + { + return -1; + } + + auto const index = static_cast(fd); + if (index >= m_open_files.size()) + { + return -1; + } + + m_open_files.at(index) = nullptr; + return 0; + } +} // namespace kernel::filesystem + +namespace kernel::tests::filesystem::open_file_table +{ + auto deinit() -> void + { + global_open_file_table.reset(); + } +} // namespace kernel::tests::filesystem::open_file_table diff --git a/kernel/src/filesystem/open_file_table.tests.cpp b/kernel/src/filesystem/open_file_table.tests.cpp new file mode 100644 index 0000000..a5c791d --- /dev/null +++ b/kernel/src/filesystem/open_file_table.tests.cpp @@ -0,0 +1,113 @@ +#include + +#include +#include + +#include +#include +#include + +#include + +SCENARIO("Open file table add/get file", "[filesystem][open_file_table]") +{ + GIVEN("a open file table and an open file descriptor") + { + auto & table = kernel::filesystem::open_file_table::get(); + auto inode = kstd::make_shared(); + auto file_descriptor_1 = kstd::make_shared(inode); + auto file_descriptor_2 = kstd::make_shared(inode); + + WHEN("adding the open file descriptor to the open file table") + { + auto fd_1 = table.add_file(file_descriptor_1); + auto fd_2 = table.add_file(file_descriptor_2); + auto fd_3 = table.add_file(file_descriptor_2); + + THEN("a valid file descriptor is returned") + { + REQUIRE(fd_1 == 0); + REQUIRE(fd_2 == 1); + REQUIRE(fd_3 == 2); + } + + THEN("the file descriptor can be retrieved using the returned file descriptor") + { + auto retrieved_descriptor = table.get_file(fd_1); + REQUIRE(retrieved_descriptor == file_descriptor_1); + } + } + } + + GIVEN("a invalid open file descriptor") + { + auto & table = kernel::filesystem::open_file_table::get(); + + THEN("adding a null file descriptor returns an error code") + { + auto fd = table.add_file(nullptr); + REQUIRE(fd == -1); + } + + THEN("retrieving a file descriptor with a negative file descriptor returns a null pointer") + { + auto retrieved_descriptor = table.get_file(-1); + REQUIRE(retrieved_descriptor == nullptr); + } + + THEN("retrieving a file descriptor with an out-of-bounds file descriptor returns a null pointer") + { + auto retrieved_descriptor = table.get_file(1000); + REQUIRE(retrieved_descriptor == nullptr); + } + } +} + +SCENARIO("Open file table remove file", "[filesystem][open_file_table]") +{ + GIVEN("a open file table with an open file descriptor") + { + auto & table = kernel::filesystem::open_file_table::get(); + auto inode = kstd::make_shared(); + auto file_descriptor = kstd::make_shared(inode); + auto fd = table.add_file(file_descriptor); + + WHEN("removing the file descriptor using the file descriptor") + { + table.remove_file(fd); + + THEN("the file descriptor can no longer be retrieved using the file descriptor") + { + auto retrieved_descriptor = table.get_file(fd); + REQUIRE(retrieved_descriptor == nullptr); + } + } + + WHEN("removing a file descriptor the other file descriptor keep the same index") + { + auto fd2 = table.add_file(file_descriptor); + table.remove_file(fd); + + THEN("the second file descriptor can still be retrieved using its file descriptor") + { + auto retrieved_descriptor = table.get_file(fd2); + REQUIRE(retrieved_descriptor == file_descriptor); + } + } + } + + GIVEN("an invalid file descriptor") + { + auto & table = kernel::filesystem::open_file_table::get(); + + THEN("removing a file with a negative file descriptor does nothing") + { + REQUIRE_NOTHROW(table.remove_file(-1)); + } + + THEN("removing a file with an out-of-bounds file descriptor does nothing") + { + REQUIRE_NOTHROW(table.remove_file(1000)); + } + } +} \ No newline at end of file diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 9878d20..ffea979 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,7 +1,7 @@ #include #include -#include #include +#include #include #include @@ -39,7 +39,7 @@ auto test_device_names() -> void auto test_file_descriptor_manually() -> void { // setup - auto fd_table = kernel::filesystem::file_descriptor_table::get(); + auto fd_table = kernel::filesystem::open_file_table::get(); auto storage_mgmt = kernel::devices::storage::management::get(); auto device = storage_mgmt.device_by_major_minor(1, 0); @@ -95,7 +95,7 @@ auto test_device_with_vfs() -> void kstd::os::panic("test code failed"); } - auto fd_table = kernel::filesystem::file_descriptor_table::get(); + auto fd_table = kernel::filesystem::open_file_table::get(); auto ofd = kstd::make_shared(dentry->get_inode()); auto fd = fd_table.add_file(ofd); kstd::vector buffer{2}; @@ -274,8 +274,8 @@ auto main() -> int kernel::devices::storage::management::init(); kstd::println("[OS] Storage management initialized."); - kernel::filesystem::file_descriptor_table::init(); - kstd::println("[OS] Global file descriptor table initialized."); + kernel::filesystem::open_file_table::init(); + kstd::println("[OS] Global open file table initialized."); kernel::filesystem::vfs::init(); kstd::println("[OS] Virtual filesystem initialized."); diff --git a/kernel/src/test_support/state_reset_listener.cpp b/kernel/src/test_support/state_reset_listener.cpp index 1815110..6bb7537 100644 --- a/kernel/src/test_support/state_reset_listener.cpp +++ b/kernel/src/test_support/state_reset_listener.cpp @@ -1,9 +1,9 @@ -#include +#include #include #include #include #include -#include +#include #include #include @@ -22,7 +22,7 @@ struct state_reset_listener : Catch::EventListenerBase void testCaseStarting(Catch::TestCaseInfo const &) override { - kernel::filesystem::file_descriptor_table::init(); + kernel::filesystem::open_file_table::init(); kapi::cio::init(); kapi::cpu::init(); @@ -31,7 +31,7 @@ struct state_reset_listener : Catch::EventListenerBase void testCaseEnded(Catch::TestCaseStats const &) override { - kernel::tests::filesystem::file_descriptor_table::deinit(); + kernel::tests::filesystem::open_file_table::deinit(); kernel::tests::filesystem::vfs::deinit(); kernel::tests::boot_modules::deinit(); kernel::tests::devices::storage::management::deinit(); -- cgit v1.2.3 From d349812c2e1e6a7d62f53d1c959137794e8a648d Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 26 Apr 2026 12:41:43 +0200 Subject: fix bht build --- .../kernel/test_support/filesystem/file_descriptor_table.hpp | 10 ---------- .../include/kernel/test_support/filesystem/open_file_table.hpp | 10 ++++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) delete mode 100644 kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp create mode 100644 kernel/include/kernel/test_support/filesystem/open_file_table.hpp (limited to 'kernel') diff --git a/kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp deleted file mode 100644 index 46b0334..0000000 --- a/kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_OPEN_FILE_TABLE_HPP -#define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_OPEN_FILE_TABLE_HPP - -namespace kernel::tests::filesystem::open_file_table -{ - //! Deinitialize the open file table singleton. - auto deinit() -> void; -} // namespace kernel::tests::filesystem::open_file_table - -#endif \ No newline at end of file diff --git a/kernel/include/kernel/test_support/filesystem/open_file_table.hpp b/kernel/include/kernel/test_support/filesystem/open_file_table.hpp new file mode 100644 index 0000000..46b0334 --- /dev/null +++ b/kernel/include/kernel/test_support/filesystem/open_file_table.hpp @@ -0,0 +1,10 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_OPEN_FILE_TABLE_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_OPEN_FILE_TABLE_HPP + +namespace kernel::tests::filesystem::open_file_table +{ + //! Deinitialize the open file table singleton. + auto deinit() -> void; +} // namespace kernel::tests::filesystem::open_file_table + +#endif \ No newline at end of file -- 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') 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 d3e02e6d9de4751910a8c51079e9489bd15948c7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 30 Apr 2026 18:42:08 +0200 Subject: kernel/acpi: simplify manager constructor --- kernel/src/acpi/manager.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp index 99c8860..bb895fd 100644 --- a/kernel/src/acpi/manager.cpp +++ b/kernel/src/acpi/manager.cpp @@ -20,22 +20,19 @@ namespace kernel::acpi manager::manager(::acpi::rsdp const & sdp) : m_sdp{&sdp} { - if (m_sdp->signature() != "RSD PTR ") + if (!m_sdp->validate()) { kapi::system::panic("[OS:ACPI] Invalid RSDP signature!"); } - if (m_sdp->revision() >= 2) + m_extended = m_sdp->revision() >= 2; + + if (m_extended) { - auto const xsdp = static_cast<::acpi::xsdp const *>(m_sdp); - if (!xsdp->validate()) + if (!static_cast<::acpi::xsdp const *>(m_sdp)->validate()) { kapi::system::panic("[OS:ACPI] Invalid XSDP signature!"); } - auto physical_extended_table_address = kapi::memory::physical_address{xsdp->table_address()}; - auto linear_extended_table_address = kapi::memory::hhdm_to_linear(physical_extended_table_address); - m_rsdt = static_cast<::acpi::xsdt const *>(linear_extended_table_address); - m_extended = true; } else { @@ -43,10 +40,11 @@ namespace kernel::acpi { kapi::system::panic("[OS:ACPI] Invalid RSDP checksum!"); } - auto physical_root_table_address = kapi::memory::physical_address{m_sdp->table_address()}; - auto linear_root_table_address = kapi::memory::hhdm_to_linear(physical_root_table_address); - m_rsdt = static_cast<::acpi::rsdt const *>(linear_root_table_address); } + + auto physical_address = kapi::memory::physical_address{m_sdp->table_address()}; + auto linear_address = kapi::memory::hhdm_to_linear(physical_address); + m_rsdt = static_cast<::acpi::table_header const *>(linear_address); } auto manager::load_tables() -> bool -- cgit v1.2.3 From b3209ac2564f21f3b78ecf5e0c05ca346a4a4276 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 28 Apr 2026 10:49:34 +0200 Subject: refactor inode kind --- kernel/include/kernel/filesystem/devfs/inode.hpp | 10 +++--- kernel/include/kernel/filesystem/device_inode.hpp | 5 +++ kernel/include/kernel/filesystem/ext2/inode.hpp | 21 +++++++++--- kernel/include/kernel/filesystem/inode.hpp | 25 +++------------ .../include/kernel/filesystem/open_file_table.hpp | 4 +-- kernel/include/kernel/filesystem/rootfs/inode.hpp | 10 +++--- .../kernel/test_support/filesystem/inode.hpp | 4 +-- kernel/src/filesystem/devfs/inode.cpp | 11 +++---- kernel/src/filesystem/device_inode.cpp | 9 ++++-- kernel/src/filesystem/ext2/filesystem.cpp | 36 +++------------------ kernel/src/filesystem/ext2/inode.cpp | 21 ++++++++++-- kernel/src/filesystem/ext2/inode.tests.cpp | 37 +++++++++++++++------- kernel/src/filesystem/inode.cpp | 10 ++---- kernel/src/filesystem/rootfs/inode.cpp | 9 +++--- kernel/src/test_support/filesystem/inode.cpp | 9 +++--- 15 files changed, 113 insertions(+), 108 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/devfs/inode.hpp b/kernel/include/kernel/filesystem/devfs/inode.hpp index 0fab280..5589730 100644 --- a/kernel/include/kernel/filesystem/devfs/inode.hpp +++ b/kernel/include/kernel/filesystem/devfs/inode.hpp @@ -13,11 +13,6 @@ namespace kernel::filesystem::devfs */ struct inode : kernel::filesystem::inode { - /** - @brief Create a devfs inode. The inode is initialized with the appropriate kind (directory). - */ - inode(); - /** @brief Reads from the devfs directory inode. @param buffer Destination buffer. @@ -35,6 +30,11 @@ namespace kernel::filesystem::devfs @return Number of bytes written (always 0 because writes are not supported for this inode). */ auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + + /** + // % TODO BA-FS26 + */ + [[nodiscard]] auto is_directory() const -> bool override; }; } // namespace kernel::filesystem::devfs diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index 2f79fca..fb60524 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -50,6 +50,11 @@ namespace kernel::filesystem */ [[nodiscard]] auto device() const -> kstd::shared_ptr const &; + /** + // TODO BA-FS26 + */ + [[nodiscard]] auto is_device() const -> bool override; + private: kstd::shared_ptr m_device; }; diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp index 9291eea..64cdb06 100644 --- a/kernel/include/kernel/filesystem/ext2/inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/inode.hpp @@ -42,8 +42,10 @@ namespace kernel::filesystem::ext2 { /** @brief Create an ext2 inode associated with the given filesystem. + @param fs The ext2 filesystem that this inode belongs to. + @param data The data associated with this inode, read from the disk. */ - explicit inode(filesystem * fs); + explicit inode(filesystem * fs, inode_data const & data); /** @brief Reads from the ext2 inode into a @p buffer, starting at the specified @p offset and for a given @p size. @@ -65,12 +67,23 @@ namespace kernel::filesystem::ext2 auto write(void const * buffer, size_t offset, size_t size) -> size_t override; /** - @brief The raw inode data as read from the disk. - */ - inode_data m_data{}; + // TODO BA-FS26 + */ + [[nodiscard]] auto data() const -> inode_data const &; + + /** + // TODO BA-FS26 + */ + [[nodiscard]] auto is_directory() const -> bool override; + + /** + // TODO BA-FS26 + */ + [[nodiscard]] auto is_regular() const -> bool override; private: filesystem * m_filesystem; + inode_data m_data{}; }; } // namespace kernel::filesystem::ext2 diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp index 5208be2..d071a6b 100644 --- a/kernel/include/kernel/filesystem/inode.hpp +++ b/kernel/include/kernel/filesystem/inode.hpp @@ -11,20 +11,9 @@ namespace kernel::filesystem struct inode { /** - @brief Represents the kind of an inode. + @brief Create an inode. */ - enum class inode_kind - { - regular, - directory, - device - }; - - /** - @brief Create an inode with the given @p kind. - @param kind The kind of the inode. - */ - explicit inode(inode_kind kind); + inode() = default; /** @brief Virtual destructor for the inode. @@ -55,23 +44,19 @@ namespace kernel::filesystem @brief Returns whether the inode is a directory. @return true if the inode is a directory, false otherwise. */ - [[nodiscard]] auto is_directory() const -> bool; + [[nodiscard]] virtual auto is_directory() const -> bool; /** @brief Returns whether the inode is a regular file. @return true if the inode is a regular file, false otherwise. */ - [[nodiscard]] auto is_regular() const -> bool; + [[nodiscard]] virtual auto is_regular() const -> bool; /** @brief Returns whether the inode is a device. @return true if the inode is a device, false otherwise. */ - [[nodiscard]] auto is_device() const -> bool; - - // TODO BA-FS26 avoid public member - public: - inode_kind m_kind{inode_kind::regular}; + [[nodiscard]] virtual auto is_device() const -> bool; }; } // namespace kernel::filesystem diff --git a/kernel/include/kernel/filesystem/open_file_table.hpp b/kernel/include/kernel/filesystem/open_file_table.hpp index 2f9a421..694f3b6 100644 --- a/kernel/include/kernel/filesystem/open_file_table.hpp +++ b/kernel/include/kernel/filesystem/open_file_table.hpp @@ -34,10 +34,10 @@ namespace kernel::filesystem /** @brief Add a file to the open file table. - @param f The file descriptor to add. + @param fd The file descriptor to add. @return The file descriptor index assigned to the file, or -1 on failure. */ - auto add_file(kstd::shared_ptr const & f) -> int; + auto add_file(kstd::shared_ptr const & fd) -> int; /** @brief Get a file from the open file table. diff --git a/kernel/include/kernel/filesystem/rootfs/inode.hpp b/kernel/include/kernel/filesystem/rootfs/inode.hpp index 37d0a30..e7c7eff 100644 --- a/kernel/include/kernel/filesystem/rootfs/inode.hpp +++ b/kernel/include/kernel/filesystem/rootfs/inode.hpp @@ -21,11 +21,6 @@ namespace kernel::filesystem::rootfs */ struct inode : kernel::filesystem::inode { - /** - @brief Create a rootfs inode. The inode is initialized with the appropriate kind (directory). - */ - inode(); - /** @brief Reads from the rootfs directory inode. @param buffer Destination buffer. @@ -57,6 +52,11 @@ namespace kernel::filesystem::rootfs */ auto lookup_child(std::string_view name) -> kstd::shared_ptr; + /** + // TODO BA-FS26 + */ + [[nodiscard]] auto is_directory() const -> bool override; + private: kstd::vector>> m_children; }; diff --git a/kernel/include/kernel/test_support/filesystem/inode.hpp b/kernel/include/kernel/test_support/filesystem/inode.hpp index 9d17917..8a76437 100644 --- a/kernel/include/kernel/test_support/filesystem/inode.hpp +++ b/kernel/include/kernel/test_support/filesystem/inode.hpp @@ -9,10 +9,10 @@ namespace kernel::tests::filesystem { struct inode : kernel::filesystem::inode { - inode(); - auto read(void * buffer, size_t offset, size_t size) const -> size_t override; auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + + [[nodiscard]] auto is_regular() const -> bool override; }; } // namespace kernel::tests::filesystem diff --git a/kernel/src/filesystem/devfs/inode.cpp b/kernel/src/filesystem/devfs/inode.cpp index 0ed66ad..2029a7f 100644 --- a/kernel/src/filesystem/devfs/inode.cpp +++ b/kernel/src/filesystem/devfs/inode.cpp @@ -1,15 +1,9 @@ #include -#include - #include namespace kernel::filesystem::devfs { - inode::inode() - : kernel::filesystem::inode(inode_kind::directory) - {} - auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t { return 0; @@ -19,4 +13,9 @@ namespace kernel::filesystem::devfs { return 0; } + + auto inode::is_directory() const -> bool + { + return true; + } } // namespace kernel::filesystem::devfs \ No newline at end of file diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp index 3bafe06..81a784c 100644 --- a/kernel/src/filesystem/device_inode.cpp +++ b/kernel/src/filesystem/device_inode.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include @@ -13,8 +12,7 @@ namespace kernel::filesystem { device_inode::device_inode(kstd::shared_ptr const & device) - : inode(inode_kind::device) - , m_device(device) + : m_device(device) { if (!device) { @@ -51,4 +49,9 @@ namespace kernel::filesystem return m_device; } + auto device_inode::is_device() const -> bool + { + return true; + } + } // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 41572ee..47e54fe 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -16,19 +16,6 @@ namespace kernel::filesystem::ext2 { - namespace - { - auto S_ISREG(uint16_t mode) -> bool - { - return (mode & constants::mode_mask) == constants::mode_regular; - } - - auto S_ISDIR(uint16_t mode) -> bool - { - return (mode & constants::mode_mask) == constants::mode_directory; - } - } // namespace - auto filesystem::mount(kstd::shared_ptr const & backing_inode) -> operation_result { kernel::filesystem::filesystem::mount(backing_inode); @@ -74,7 +61,7 @@ namespace kernel::filesystem::ext2 } auto const block_size = get_block_size(); - auto const & inode_data = ext2_parent->m_data; + auto const & inode_data = ext2_parent->data(); kstd::vector buffer(block_size); for (uint32_t i = 0; i < get_inode_block_count(inode_data); ++i) @@ -119,25 +106,10 @@ namespace kernel::filesystem::ext2 auto const inode_table_offset = static_cast(inode_table_start_block) * block_size; auto const inode_offset = inode_table_offset + inode_index_within_group * get_inode_size(); - auto new_inode = kstd::make_shared(this); - m_backing_inode->read(&new_inode->m_data, inode_offset, sizeof(inode_data)); - - // TODO BA-FS26 improve inode_kind really needed? or just map it to the mode bits? - if (S_ISREG(new_inode->m_data.mode)) - { - new_inode->m_kind = inode::inode_kind::regular; - } - else if (S_ISDIR(new_inode->m_data.mode)) - { - new_inode->m_kind = inode::inode_kind::directory; - } - else - { - // TODO BA-FS26 really correct?? - return nullptr; - } + auto new_inode_data = inode_data{}; + m_backing_inode->read(&new_inode_data, inode_offset, sizeof(inode_data)); - return new_inode; + return kstd::make_shared(this, new_inode_data); } auto filesystem::map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) -> uint32_t diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index c45c41e..279c84f 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -11,9 +11,9 @@ namespace kernel::filesystem::ext2 { - inode::inode(filesystem * fs) - : kernel::filesystem::inode(inode_kind::regular) - , m_filesystem(fs) + inode::inode(filesystem * fs, inode_data const & data) + : m_filesystem(fs) + , m_data(data) { if (!m_filesystem) { @@ -57,4 +57,19 @@ namespace kernel::filesystem::ext2 kapi::system::panic("[EXT2] inode::write is not implemented yet"); return 0; } + + [[nodiscard]] auto inode::data() const -> inode_data const & + { + return m_data; + } + + auto inode::is_regular() const -> bool + { + return (m_data.mode & constants::mode_mask) == constants::mode_regular; + } + + auto inode::is_directory() const -> bool + { + return (m_data.mode & constants::mode_mask) == constants::mode_directory; + } } // namespace kernel::filesystem::ext2 diff --git a/kernel/src/filesystem/ext2/inode.tests.cpp b/kernel/src/filesystem/ext2/inode.tests.cpp index 4d61790..e68352f 100644 --- a/kernel/src/filesystem/ext2/inode.tests.cpp +++ b/kernel/src/filesystem/ext2/inode.tests.cpp @@ -23,21 +23,34 @@ SCENARIO("Ext2 inode initialization and properties", "[filesystem][ext2][inode]" GIVEN("an ext2 filesystem") { auto fs = kernel::filesystem::ext2::filesystem{}; + auto data = kernel::filesystem::ext2::inode_data{}; - THEN("the inode is initialized and has the kind regular") + THEN("the inode is initialized with regular file mode in data and has the kind regular") { - auto inode = kernel::filesystem::ext2::inode{&fs}; + data.mode = kernel::filesystem::ext2::constants::mode_regular; + auto inode = kernel::filesystem::ext2::inode(&fs, data); + REQUIRE(inode.is_regular()); REQUIRE(!inode.is_directory()); REQUIRE(!inode.is_device()); } + + THEN("the inode is initialized with directory mode in data and has the kind directory") + { + data.mode = kernel::filesystem::ext2::constants::mode_directory; + auto inode = kernel::filesystem::ext2::inode(&fs, data); + + REQUIRE(!inode.is_regular()); + REQUIRE(inode.is_directory()); + REQUIRE(!inode.is_device()); + } } GIVEN("no filesystem (null pointer)") { THEN("constructing an inode with a null filesystem pointer panics") { - REQUIRE_THROWS_AS(kernel::filesystem::ext2::inode{nullptr}, kernel::tests::cpu::halt); + REQUIRE_THROWS_AS(kernel::filesystem::ext2::inode(nullptr, {}), kernel::tests::cpu::halt); } } } @@ -102,9 +115,10 @@ SCENARIO("Ext2 inode read stops when block mapping resolves to zero", "[filesyst auto fs = kernel::filesystem::ext2::filesystem{}; REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); - auto inode = kernel::filesystem::ext2::inode{&fs}; - inode.m_data.blocks = 2; - inode.m_data.block[0] = 0; + auto data = kernel::filesystem::ext2::inode_data{}; + data.blocks = 2; + data.block[0] = 0; + auto inode = kernel::filesystem::ext2::inode{&fs, data}; auto buffer = kstd::vector(32, std::byte{0xAB}); @@ -130,12 +144,13 @@ SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]") auto fs = kernel::filesystem::ext2::filesystem{}; REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); - auto inode = kernel::filesystem::ext2::inode{&fs}; - inode.m_data.blocks = 2; - inode.m_data.block[0] = 20; + auto inode_data = kernel::filesystem::ext2::inode_data{}; + inode_data.blocks = 2; + inode_data.block[0] = 20; kernel::tests::filesystem::ext2::write_bytes(*device, 21 * block_size - 6, "Hello ", 6); - inode.m_data.block[1] = 21; + inode_data.block[1] = 21; kernel::tests::filesystem::ext2::write_bytes(*device, 21 * block_size, "World!", 6); + auto inode = kernel::filesystem::ext2::inode{&fs, inode_data}; auto buffer = kstd::vector(12, std::byte{0x00}); @@ -155,7 +170,7 @@ SCENARIO("Ext2 inode write is not implemented", "[filesystem][ext2][inode]") GIVEN("an ext2 inode") { auto fs = kernel::filesystem::ext2::filesystem{}; - auto inode = kernel::filesystem::ext2::inode{&fs}; + auto inode = kernel::filesystem::ext2::inode{&fs, kernel::filesystem::ext2::inode_data{}}; THEN("writing to the inode panics") { diff --git a/kernel/src/filesystem/inode.cpp b/kernel/src/filesystem/inode.cpp index 2f0764c..f2a7741 100644 --- a/kernel/src/filesystem/inode.cpp +++ b/kernel/src/filesystem/inode.cpp @@ -2,22 +2,18 @@ namespace kernel::filesystem { - inode::inode(inode_kind kind) - : m_kind(kind) - {} - auto inode::is_directory() const -> bool { - return m_kind == inode_kind::directory; + return false; } auto inode::is_regular() const -> bool { - return m_kind == inode_kind::regular; + return false; } auto inode::is_device() const -> bool { - return m_kind == inode_kind::device; + return false; } } // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/rootfs/inode.cpp b/kernel/src/filesystem/rootfs/inode.cpp index eeea3fe..d099676 100644 --- a/kernel/src/filesystem/rootfs/inode.cpp +++ b/kernel/src/filesystem/rootfs/inode.cpp @@ -12,10 +12,6 @@ namespace kernel::filesystem::rootfs { - inode::inode() - : kernel::filesystem::inode(inode_kind::directory) - {} - auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t { return 0; @@ -36,4 +32,9 @@ namespace kernel::filesystem::rootfs auto it = std::ranges::find_if(m_children, [&](auto const & pair) { return pair.first == name; }); return (it != m_children.end()) ? it->second : nullptr; } + + auto inode::is_directory() const -> bool + { + return true; + } } // namespace kernel::filesystem::rootfs diff --git a/kernel/src/test_support/filesystem/inode.cpp b/kernel/src/test_support/filesystem/inode.cpp index 54bd7e0..0c8d956 100644 --- a/kernel/src/test_support/filesystem/inode.cpp +++ b/kernel/src/test_support/filesystem/inode.cpp @@ -6,10 +6,6 @@ namespace kernel::tests::filesystem { - inode::inode() - : kernel::filesystem::inode(inode_kind::regular) - {} - auto inode::read(void *, size_t, size_t size) const -> size_t { return size; @@ -19,4 +15,9 @@ namespace kernel::tests::filesystem { return size; } + + auto inode::is_regular() const -> bool + { + return true; + } } // namespace kernel::tests::filesystem \ No newline at end of file -- cgit v1.2.3 From 6790ab170578594f26e8e84a3e57b80cb6094e21 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 28 Apr 2026 10:55:37 +0200 Subject: add is_symbolic_link method in ext2 inode --- .../include/kernel/filesystem/ext2/filesystem.hpp | 1 + kernel/include/kernel/filesystem/ext2/inode.hpp | 5 +++++ kernel/include/kernel/filesystem/inode.hpp | 6 ++++++ kernel/src/filesystem/ext2/inode.cpp | 5 +++++ kernel/src/filesystem/ext2/inode.tests.cpp | 24 ++++++++++++++++++++++ kernel/src/filesystem/inode.cpp | 5 +++++ 6 files changed, 46 insertions(+) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index 516e71d..d22433f 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -35,6 +35,7 @@ namespace kernel::filesystem::ext2 constexpr uint16_t inline mode_mask = 0xF000; constexpr uint16_t inline mode_regular = 0x8000; constexpr uint16_t inline mode_directory = 0x4000; + constexpr uint16_t inline mode_symbolic_link = 0xA000; } // namespace constants /** diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp index 64cdb06..688a1d8 100644 --- a/kernel/include/kernel/filesystem/ext2/inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/inode.hpp @@ -81,6 +81,11 @@ namespace kernel::filesystem::ext2 */ [[nodiscard]] auto is_regular() const -> bool override; + /** + // TODO BA-FS26 + */ + [[nodiscard]] auto is_symbolic_link() const -> bool override; + private: filesystem * m_filesystem; inode_data m_data{}; diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp index d071a6b..b34b921 100644 --- a/kernel/include/kernel/filesystem/inode.hpp +++ b/kernel/include/kernel/filesystem/inode.hpp @@ -57,6 +57,12 @@ namespace kernel::filesystem @return true if the inode is a device, false otherwise. */ [[nodiscard]] virtual auto is_device() const -> bool; + + /** + @brief Returns whether the inode is a symbolic link. + @return true if the inode is a symbolic link, false otherwise. + */ + [[nodiscard]] virtual auto is_symbolic_link() const -> bool; }; } // namespace kernel::filesystem diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index 279c84f..5b6bcb3 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -72,4 +72,9 @@ namespace kernel::filesystem::ext2 { return (m_data.mode & constants::mode_mask) == constants::mode_directory; } + + auto inode::is_symbolic_link() const -> bool + { + return (m_data.mode & constants::mode_mask) == constants::mode_symbolic_link; + } } // namespace kernel::filesystem::ext2 diff --git a/kernel/src/filesystem/ext2/inode.tests.cpp b/kernel/src/filesystem/ext2/inode.tests.cpp index e68352f..f0f4aaf 100644 --- a/kernel/src/filesystem/ext2/inode.tests.cpp +++ b/kernel/src/filesystem/ext2/inode.tests.cpp @@ -33,6 +33,7 @@ SCENARIO("Ext2 inode initialization and properties", "[filesystem][ext2][inode]" REQUIRE(inode.is_regular()); REQUIRE(!inode.is_directory()); REQUIRE(!inode.is_device()); + REQUIRE(!inode.is_symbolic_link()); } THEN("the inode is initialized with directory mode in data and has the kind directory") @@ -43,6 +44,29 @@ SCENARIO("Ext2 inode initialization and properties", "[filesystem][ext2][inode]" REQUIRE(!inode.is_regular()); REQUIRE(inode.is_directory()); REQUIRE(!inode.is_device()); + REQUIRE(!inode.is_symbolic_link()); + } + + THEN("the inode is initialized with symbolic link mode in data and has the kind symbolic link") + { + data.mode = kernel::filesystem::ext2::constants::mode_symbolic_link; + auto inode = kernel::filesystem::ext2::inode(&fs, data); + + REQUIRE(!inode.is_regular()); + REQUIRE(!inode.is_directory()); + REQUIRE(!inode.is_device()); + REQUIRE(inode.is_symbolic_link()); + } + + THEN("the inode is initialized with zero mode in data and has no specific kind") + { + data.mode = 0; + auto inode = kernel::filesystem::ext2::inode(&fs, data); + + REQUIRE(!inode.is_regular()); + REQUIRE(!inode.is_directory()); + REQUIRE(!inode.is_device()); + REQUIRE(!inode.is_symbolic_link()); } } diff --git a/kernel/src/filesystem/inode.cpp b/kernel/src/filesystem/inode.cpp index f2a7741..c188917 100644 --- a/kernel/src/filesystem/inode.cpp +++ b/kernel/src/filesystem/inode.cpp @@ -16,4 +16,9 @@ namespace kernel::filesystem { return false; } + + auto inode::is_symbolic_link() const -> bool + { + return false; + } } // namespace kernel::filesystem \ No newline at end of file -- cgit v1.2.3 From 62da1b8c8d1c59abc7ca33c144591839f126937e Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 30 Apr 2026 21:32:49 +0200 Subject: resolve todos --- kernel/include/kernel/filesystem/devfs/inode.hpp | 3 ++- kernel/include/kernel/filesystem/device_inode.hpp | 3 ++- kernel/include/kernel/filesystem/ext2/inode.hpp | 12 ++++++++---- kernel/include/kernel/filesystem/rootfs/inode.hpp | 3 ++- 4 files changed, 14 insertions(+), 7 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/devfs/inode.hpp b/kernel/include/kernel/filesystem/devfs/inode.hpp index 5589730..e428891 100644 --- a/kernel/include/kernel/filesystem/devfs/inode.hpp +++ b/kernel/include/kernel/filesystem/devfs/inode.hpp @@ -32,7 +32,8 @@ namespace kernel::filesystem::devfs auto write(void const * buffer, size_t offset, size_t size) -> size_t override; /** - // % TODO BA-FS26 + @brief Check if this inode represents a directory. + @return returns true, since this inode represents the /dev directory in the devfs filesystem. */ [[nodiscard]] auto is_directory() const -> bool override; }; diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index fb60524..f4aa2d1 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -51,7 +51,8 @@ namespace kernel::filesystem [[nodiscard]] auto device() const -> kstd::shared_ptr const &; /** - // TODO BA-FS26 + @brief Check if this inode represents a device. + @return returns true, since this indoe is a device inode and represents a device. */ [[nodiscard]] auto is_device() const -> bool override; diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp index 688a1d8..b4a3cc4 100644 --- a/kernel/include/kernel/filesystem/ext2/inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/inode.hpp @@ -67,22 +67,26 @@ namespace kernel::filesystem::ext2 auto write(void const * buffer, size_t offset, size_t size) -> size_t override; /** - // TODO BA-FS26 + @brief Get the data associated with this inode. + @return A reference to the inode data. */ [[nodiscard]] auto data() const -> inode_data const &; /** - // TODO BA-FS26 + @brief Check if this inode represents a directory. + @return returns true if this inode represents a directory, false otherwise. */ [[nodiscard]] auto is_directory() const -> bool override; /** - // TODO BA-FS26 + @brief Check if this inode represents a regular file. + @return returns true if this inode represents a regular file, false otherwise. */ [[nodiscard]] auto is_regular() const -> bool override; /** - // TODO BA-FS26 + @brief Check if this inode represents a symbolic link. + @return returns true if this inode represents a symbolic link, false otherwise. */ [[nodiscard]] auto is_symbolic_link() const -> bool override; diff --git a/kernel/include/kernel/filesystem/rootfs/inode.hpp b/kernel/include/kernel/filesystem/rootfs/inode.hpp index e7c7eff..58035ea 100644 --- a/kernel/include/kernel/filesystem/rootfs/inode.hpp +++ b/kernel/include/kernel/filesystem/rootfs/inode.hpp @@ -53,7 +53,8 @@ namespace kernel::filesystem::rootfs auto lookup_child(std::string_view name) -> kstd::shared_ptr; /** - // TODO BA-FS26 + @brief Check if this inode represents a directory. + @return returns true, since this inode represents the root directory in the rootfs filesystem. */ [[nodiscard]] auto is_directory() const -> bool override; -- cgit v1.2.3 From 8550b6a1aacc2bfce733dcac7a44065b7e9116a1 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 2 May 2026 14:14:24 +0200 Subject: relative path support --- kernel/include/kernel/filesystem/dentry.hpp | 2 +- kernel/src/filesystem/mount_table.cpp | 4 +- kernel/src/filesystem/vfs.cpp | 115 ++++++++++++++++++++++++---- 3 files changed, 103 insertions(+), 18 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index 94fa39a..45d2ca2 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -24,7 +24,7 @@ namespace kernel::filesystem */ enum class dentry_flags : uint32_t { - dcache_mounted = 1 << 15 + mounted = 1 << 15 }; /** diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index da3c451..e21e497 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -54,7 +54,7 @@ namespace kernel::filesystem m_mounts.push_back(mount); if (auto mount_dentry = mount->get_mount_dentry()) { - mount_dentry->set_flag(dentry::dentry_flags::dcache_mounted); + mount_dentry->set_flag(dentry::dentry_flags::mounted); } } @@ -75,7 +75,7 @@ namespace kernel::filesystem return operation_result::has_child_mounts; } - mount->get_mount_dentry()->unset_flag(dentry::dentry_flags::dcache_mounted); + mount->get_mount_dentry()->unset_flag(dentry::dentry_flags::mounted); m_mounts.erase(std::ranges::find(m_mounts, mount)); return operation_result::removed; } diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 5b454f6..41afad3 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -10,6 +10,8 @@ #include #include +#include +#include #include #include @@ -35,21 +37,38 @@ namespace kernel::filesystem auto vfs::init_internal() -> void { + // Mount rootfs at / as the temporary base auto root_fs = kstd::make_shared(); root_fs->mount(nullptr); - auto root_fs_root_dentry = kstd::make_shared(nullptr, root_fs->root_inode()); - m_mount_table.add_mount(kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, "", nullptr)); + auto root_fs_root_dentry = kstd::make_shared(nullptr, root_fs->root_inode(), "/"); + m_mount_table.add_mount(kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, "/", nullptr)); + // Mount devfs at /dev in rootfs (temporary, will be shadowed) auto device_fs = kstd::make_shared(); device_fs->mount(nullptr); - do_mount_internal("/dev", root_fs_root_dentry, device_fs); + auto dev_mount_point_dentry = resolve_path("/dev"); + if (!dev_mount_point_dentry) + { + kapi::system::panic("[FILESYSTEM] failed to resolve /dev for initial devfs mount."); + } + do_mount_internal("/dev", dev_mount_point_dentry, device_fs); - if (auto boot_device_dentry = resolve_path("/dev/ram0")) // TODO BA-FS26 better boot device detection + // Mount boot filesystem at / (will shadow rootfs) + if (auto boot_device_dentry = resolve_path("/dev/ram0")) { if (auto boot_root_fs = kernel::filesystem::filesystem::probe_and_mount(boot_device_dentry->get_inode())) { do_mount_internal("/", root_fs_root_dentry, boot_root_fs); + + // Resolve / to get the boot root dentry + if (auto boot_root_dentry = resolve_path("/")) + { + auto dev_dentry = kstd::make_shared(boot_root_dentry, device_fs->root_inode(), "dev"); + boot_root_dentry->add_child(dev_dentry); + + do_mount_internal("/dev", dev_dentry, device_fs); + } } } } @@ -117,33 +136,46 @@ namespace kernel::filesystem kstd::shared_ptr const & fs) -> void { auto parent_mount = m_mount_table.find_longest_prefix_mount(path); - auto new_fs_root = kstd::make_shared(mount_point_dentry, fs->root_inode()); + auto new_fs_root = + kstd::make_shared(mount_point_dentry->get_parent(), fs->root_inode(), mount_point_dentry->get_name()); auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, path, parent_mount); m_mount_table.add_mount(new_mount); } auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr { - // TODO BA-FS26 implement full path resolution semantics. // TODO BA-FS26 better path validation // TODO BA-FS26 implement a path parser (maybe in libs?) and use it here and in do_mount - if (path.empty() || path.front() != '/') return nullptr; - // TODO BA-FS26 longest match in mount_table -> jump into final fs directly - // TODO BA-FS26 performance optimization first check mounted_flag O(1) then check mount_table O(n) - - auto best_mount = m_mount_table.find_longest_prefix_mount(path); - if (!best_mount) + auto current_mount = m_mount_table.find_longest_prefix_mount("/"); + if (!current_mount) { kapi::system::panic("[FILESYSTEM] no root mount found."); } - auto current_dentry = best_mount->root_dentry(); - auto current_fs = best_mount->get_filesystem(); + auto current_dentry = current_mount->root_dentry(); + kstd::vector resolved_parts{}; + + // TODO BA-FS26 remove again an get path out of the dentires instead of building it up again here + auto build_resolved_path = [&resolved_parts]() { + kstd::string resolved_path{"/"}; + + for (auto const & resolved_part : resolved_parts) + { + if (resolved_path.size() > 1) + { + resolved_path += '/'; + } + + resolved_path += resolved_part; + } - std::string_view remaining = path.substr(best_mount->get_mount_path().size()); + return resolved_path; + }; + + std::string_view remaining = path.substr(current_mount->get_mount_path().size()); auto path_parts = std::views::split(remaining, '/') | std::views::filter([](auto const & part) { return !part.empty(); }); @@ -152,9 +184,50 @@ namespace kernel::filesystem { std::string_view part_view{part}; + if (part_view == ".") + { + continue; + } + + if (part_view == "..") + { + if (!resolved_parts.empty()) + { + resolved_parts.pop_back(); + } + + auto parent_dentry = current_dentry->get_parent(); + + if (current_dentry == current_mount->root_dentry()) + { + // change the mount point + if (auto parent_mount = current_mount->get_parent_mount()) + { + current_mount = parent_mount; + current_dentry = current_dentry->get_parent(); + + if (!parent_dentry) + { + parent_dentry = current_mount->root_dentry(); + } + } + } + + if (!parent_dentry) + { + return nullptr; + } + + current_dentry = parent_dentry; + continue; + } + + resolved_parts.push_back(part_view); + auto next_dentry = current_dentry->find_child(part_view); if (!next_dentry) { + auto current_fs = current_mount->get_filesystem(); auto found_inode = current_fs->lookup(current_dentry->get_inode(), part_view); if (!found_inode) return nullptr; @@ -162,6 +235,18 @@ namespace kernel::filesystem next_dentry = kstd::make_shared(current_dentry, found_inode, part_view); current_dentry->add_child(next_dentry); } + else if (next_dentry->has_flag(dentry::dentry_flags::mounted)) + { + // change the mount point + // TODO BA-FS26 get resolved path out of the dentry... + current_mount = m_mount_table.find_longest_prefix_mount(build_resolved_path().view()); + if (!current_mount) + { + kapi::system::panic("[FILESYSTEM] mount for dentry with mounted flag not found."); + } + + next_dentry = current_mount->root_dentry(); + } current_dentry = next_dentry; } -- cgit v1.2.3 From a096d84920aa078b5775149a95e5d3f010ae995e Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 2 May 2026 14:14:55 +0200 Subject: fix bht build --- kernel/src/filesystem/dentry.tests.cpp | 16 ++++++++-------- kernel/src/filesystem/mount_table.tests.cpp | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/dentry.tests.cpp b/kernel/src/filesystem/dentry.tests.cpp index f81c260..c42c405 100644 --- a/kernel/src/filesystem/dentry.tests.cpp +++ b/kernel/src/filesystem/dentry.tests.cpp @@ -28,7 +28,7 @@ SCENARIO("Dentry construction", "[filesystem][dentry]") THEN("no flag is set") { - REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); } } @@ -45,7 +45,7 @@ SCENARIO("Dentry construction", "[filesystem][dentry]") THEN("no flag is set") { - REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); } } @@ -62,7 +62,7 @@ SCENARIO("Dentry construction", "[filesystem][dentry]") THEN("no flag is set") { - REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); } } @@ -113,22 +113,22 @@ SCENARIO("Dentry Flag logic", "[filesystem][dentry]") WHEN("setting a flag") { - dentry.set_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted); + dentry.set_flag(kernel::filesystem::dentry::dentry_flags::mounted); THEN("the flag is set") { - REQUIRE(dentry.has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + REQUIRE(dentry.has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); } } WHEN("unsetting a flag") { - dentry.set_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted); - dentry.unset_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted); + dentry.set_flag(kernel::filesystem::dentry::dentry_flags::mounted); + dentry.unset_flag(kernel::filesystem::dentry::dentry_flags::mounted); THEN("the flag is unset") { - REQUIRE_FALSE(dentry.has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + REQUIRE_FALSE(dentry.has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); } } } diff --git a/kernel/src/filesystem/mount_table.tests.cpp b/kernel/src/filesystem/mount_table.tests.cpp index 747ffdf..60b1755 100644 --- a/kernel/src/filesystem/mount_table.tests.cpp +++ b/kernel/src/filesystem/mount_table.tests.cpp @@ -54,8 +54,8 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("dentry flags are set correctly for mounted dentries") { - REQUIRE(root_dentry1->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); - REQUIRE(!root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + REQUIRE(root_dentry1->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE(!root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); } THEN("finding mounts by path returns the correct mount") @@ -70,7 +70,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("removing a mount that has no child mounts succeeds") { REQUIRE(table.remove_mount("/mnt") == kernel::filesystem::mount_table::operation_result::removed); - REQUIRE(!root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + REQUIRE(!root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); REQUIRE(table.find_longest_prefix_mount("/mnt") == mount1); } @@ -109,7 +109,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("removing the topmost mount with the same path succeeds") { REQUIRE(table.remove_mount("/") == kernel::filesystem::mount_table::operation_result::removed); - REQUIRE(!root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + REQUIRE(!root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); REQUIRE(table.find_longest_prefix_mount("/") == mount1); } } @@ -156,7 +156,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("removing a leaf mount succeeds") { REQUIRE(table.remove_mount("/mnt/submnt") == kernel::filesystem::mount_table::operation_result::removed); - REQUIRE(!root_dentry3->has_flag(kernel::filesystem::dentry::dentry_flags::dcache_mounted)); + REQUIRE(!root_dentry3->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); REQUIRE(table.find_longest_prefix_mount("/mnt/submnt") == mount2); } } -- cgit v1.2.3 From 46f3992c10e960d33dbb314dad597650902686da Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 2 May 2026 14:15:26 +0200 Subject: add relative path tests --- kernel/src/filesystem/vfs.tests.cpp | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 979ea42..109ee89 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -168,6 +168,52 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.unmount("/information/nonexistent") == kernel::filesystem::vfs::operation_result::mount_point_not_found); } + + THEN("a file can be access if . in the path") + { + auto info_1 = vfs.open("/information/./info_1.txt"); + REQUIRE(info_1 != nullptr); + } + + THEN("a file can be accessed within the same mount if path contains .. ") + { + auto info_1 = vfs.open("/archiv/../information/info_1.txt"); + REQUIRE(info_1 != nullptr); + + auto img = vfs.open("/archiv/../information/../archiv/2024.img"); + REQUIRE(img != nullptr); + } + + THEN("a file can be accessed over multiple mounts if path contains .. or . ") + { + REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); + + auto img = vfs.open("/information/monkey_house/caretaker/../../../archiv/2024.img"); + REQUIRE(img != nullptr); + + auto dev_32 = vfs.open("/information/monkey_house/caretaker/../../../dev/ram32"); + REQUIRE(dev_32 != nullptr); + + auto water = vfs.open("/information/./monkey_house/infrastructure/water.txt"); + REQUIRE(water != nullptr); + } + + THEN("a file can be accessed over multiple mounts (device and file) if path contains .. ") + { + REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/archiv/2024.img", "/information/monkey_house/infrastructure") == + kernel::filesystem::vfs::operation_result::success); + + auto pig_1 = vfs.open("/information/monkey_house/infrastructure/stable/pig_1.txt"); + REQUIRE(pig_1 != nullptr); + + auto isabelle = + vfs.open("/information/monkey_house/infrastructure/stable/../../../monkey_house/caretaker/isabelle.txt"); + REQUIRE(isabelle != nullptr); + + auto closed = vfs.open("/information/monkey_house/infrastructure/stable/../../../../closed.txt"); + REQUIRE(closed != nullptr); + } } GIVEN("A real image file containing as filesystem formatted files") -- cgit v1.2.3 From d3c8b74020bfeee554394b7e41c58d5ddda6f396 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 2 May 2026 14:23:19 +0200 Subject: refactoring --- kernel/include/kernel/filesystem/dentry.hpp | 6 ++++++ kernel/src/filesystem/dentry.cpp | 17 +++++++++++++++ kernel/src/filesystem/vfs.cpp | 32 ++--------------------------- 3 files changed, 25 insertions(+), 30 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index 45d2ca2..bd62735 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -54,6 +54,12 @@ namespace kernel::filesystem */ [[nodiscard]] auto get_name() const -> std::string_view; + /** + @brief Get the full path of the dentry by traversing up to the root. + @return The full path of the dentry. + */ + [[nodiscard]] auto get_full_path() const -> kstd::string; + /** @brief Add a @p child dentry. @param child The child dentry to add. diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index 572dd82..72500fd 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -38,6 +39,22 @@ namespace kernel::filesystem return m_name.view(); } + // TODO BA-FS26 fix warning (do not use recursion) + auto dentry::get_full_path() const -> kstd::string + { + if (m_parent) + { + auto parent_path = m_parent->get_full_path(); + if (parent_path != "/") + { + parent_path += '/'; + } + return parent_path + m_name.view(); + } + + return m_name.empty() ? "/" : m_name.view(); + } + auto dentry::add_child(kstd::shared_ptr const & child) -> void { m_children.push_back(child); diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 41afad3..9a6625d 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include @@ -156,25 +155,6 @@ namespace kernel::filesystem } auto current_dentry = current_mount->root_dentry(); - kstd::vector resolved_parts{}; - - // TODO BA-FS26 remove again an get path out of the dentires instead of building it up again here - auto build_resolved_path = [&resolved_parts]() { - kstd::string resolved_path{"/"}; - - for (auto const & resolved_part : resolved_parts) - { - if (resolved_path.size() > 1) - { - resolved_path += '/'; - } - - resolved_path += resolved_part; - } - - return resolved_path; - }; - std::string_view remaining = path.substr(current_mount->get_mount_path().size()); auto path_parts = @@ -191,11 +171,6 @@ namespace kernel::filesystem if (part_view == "..") { - if (!resolved_parts.empty()) - { - resolved_parts.pop_back(); - } - auto parent_dentry = current_dentry->get_parent(); if (current_dentry == current_mount->root_dentry()) @@ -222,8 +197,6 @@ namespace kernel::filesystem continue; } - resolved_parts.push_back(part_view); - auto next_dentry = current_dentry->find_child(part_view); if (!next_dentry) { @@ -237,9 +210,8 @@ namespace kernel::filesystem } else if (next_dentry->has_flag(dentry::dentry_flags::mounted)) { - // change the mount point - // TODO BA-FS26 get resolved path out of the dentry... - current_mount = m_mount_table.find_longest_prefix_mount(build_resolved_path().view()); + // TODO BA-FS26 really do it like this? or just call "get" without longes_prefix stuff + current_mount = m_mount_table.find_longest_prefix_mount(next_dentry->get_full_path().view()); if (!current_mount) { kapi::system::panic("[FILESYSTEM] mount for dentry with mounted flag not found."); -- cgit v1.2.3 From e74e56559ae99fd14715371ebceb2545f68008de Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 2 May 2026 14:24:46 +0200 Subject: add todos --- kernel/src/filesystem/vfs.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 9a6625d..a3da258 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -89,6 +89,7 @@ namespace kernel::filesystem auto vfs::do_mount(std::string_view source, std::string_view target) -> operation_result { + // TODO BA-FS26 better path validation if (target.empty() || target.front() != '/' || (target.size() > 1 && target.back() == '/')) { return operation_result::invalid_path; @@ -112,6 +113,7 @@ namespace kernel::filesystem auto vfs::unmount(std::string_view path) -> operation_result { + // TODO BA-FS26 better path validation if (path.empty() || path.front() != '/' || (path.size() > 1 && path.back() == '/')) { return operation_result::invalid_path; -- cgit v1.2.3 From 40fbefab704695b905e3de3e80668447cc64b20e Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 2 May 2026 15:36:19 +0200 Subject: refactoring and extend tests --- kernel/src/filesystem/devfs/filesystem.tests.cpp | 2 +- kernel/src/filesystem/devfs/inode.tests.cpp | 1 + kernel/src/filesystem/device_inode.tests.cpp | 1 + kernel/src/filesystem/ext2/inode.tests.cpp | 26 ++++++++++++------------ kernel/src/filesystem/mount_table.tests.cpp | 8 ++++---- kernel/src/filesystem/rootfs/inode.tests.cpp | 1 + 6 files changed, 21 insertions(+), 18 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/devfs/filesystem.tests.cpp b/kernel/src/filesystem/devfs/filesystem.tests.cpp index 2b6c09b..36cb411 100644 --- a/kernel/src/filesystem/devfs/filesystem.tests.cpp +++ b/kernel/src/filesystem/devfs/filesystem.tests.cpp @@ -47,7 +47,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, { auto non_directory_inode = fs.lookup(fs.root_inode(), "ram0"); REQUIRE(non_directory_inode != nullptr); - REQUIRE(!non_directory_inode->is_directory()); + REQUIRE_FALSE(non_directory_inode->is_directory()); auto result = fs.lookup(non_directory_inode, "anything"); REQUIRE(result == nullptr); diff --git a/kernel/src/filesystem/devfs/inode.tests.cpp b/kernel/src/filesystem/devfs/inode.tests.cpp index 030d709..ae26e74 100644 --- a/kernel/src/filesystem/devfs/inode.tests.cpp +++ b/kernel/src/filesystem/devfs/inode.tests.cpp @@ -19,6 +19,7 @@ SCENARIO("Devfs inode creation", "[filesystem][devfs][inode]") REQUIRE(inode.is_directory()); REQUIRE_FALSE(inode.is_device()); REQUIRE_FALSE(inode.is_regular()); + REQUIRE_FALSE(inode.is_symbolic_link()); } } } diff --git a/kernel/src/filesystem/device_inode.tests.cpp b/kernel/src/filesystem/device_inode.tests.cpp index 8ac4eff..025a22a 100644 --- a/kernel/src/filesystem/device_inode.tests.cpp +++ b/kernel/src/filesystem/device_inode.tests.cpp @@ -33,6 +33,7 @@ SCENARIO("Device inode construction", "[filesystem][device_inode]") REQUIRE(inode.is_device()); REQUIRE_FALSE(inode.is_directory()); REQUIRE_FALSE(inode.is_regular()); + REQUIRE_FALSE(inode.is_symbolic_link()); } } diff --git a/kernel/src/filesystem/ext2/inode.tests.cpp b/kernel/src/filesystem/ext2/inode.tests.cpp index f0f4aaf..49ba21b 100644 --- a/kernel/src/filesystem/ext2/inode.tests.cpp +++ b/kernel/src/filesystem/ext2/inode.tests.cpp @@ -31,9 +31,9 @@ SCENARIO("Ext2 inode initialization and properties", "[filesystem][ext2][inode]" auto inode = kernel::filesystem::ext2::inode(&fs, data); REQUIRE(inode.is_regular()); - REQUIRE(!inode.is_directory()); - REQUIRE(!inode.is_device()); - REQUIRE(!inode.is_symbolic_link()); + REQUIRE_FALSE(inode.is_directory()); + REQUIRE_FALSE(inode.is_device()); + REQUIRE_FALSE(inode.is_symbolic_link()); } THEN("the inode is initialized with directory mode in data and has the kind directory") @@ -41,10 +41,10 @@ SCENARIO("Ext2 inode initialization and properties", "[filesystem][ext2][inode]" data.mode = kernel::filesystem::ext2::constants::mode_directory; auto inode = kernel::filesystem::ext2::inode(&fs, data); - REQUIRE(!inode.is_regular()); + REQUIRE_FALSE(inode.is_regular()); REQUIRE(inode.is_directory()); - REQUIRE(!inode.is_device()); - REQUIRE(!inode.is_symbolic_link()); + REQUIRE_FALSE(inode.is_device()); + REQUIRE_FALSE(inode.is_symbolic_link()); } THEN("the inode is initialized with symbolic link mode in data and has the kind symbolic link") @@ -52,9 +52,9 @@ SCENARIO("Ext2 inode initialization and properties", "[filesystem][ext2][inode]" data.mode = kernel::filesystem::ext2::constants::mode_symbolic_link; auto inode = kernel::filesystem::ext2::inode(&fs, data); - REQUIRE(!inode.is_regular()); - REQUIRE(!inode.is_directory()); - REQUIRE(!inode.is_device()); + REQUIRE_FALSE(inode.is_regular()); + REQUIRE_FALSE(inode.is_directory()); + REQUIRE_FALSE(inode.is_device()); REQUIRE(inode.is_symbolic_link()); } @@ -63,10 +63,10 @@ SCENARIO("Ext2 inode initialization and properties", "[filesystem][ext2][inode]" data.mode = 0; auto inode = kernel::filesystem::ext2::inode(&fs, data); - REQUIRE(!inode.is_regular()); - REQUIRE(!inode.is_directory()); - REQUIRE(!inode.is_device()); - REQUIRE(!inode.is_symbolic_link()); + REQUIRE_FALSE(inode.is_regular()); + REQUIRE_FALSE(inode.is_directory()); + REQUIRE_FALSE(inode.is_device()); + REQUIRE_FALSE(inode.is_symbolic_link()); } } diff --git a/kernel/src/filesystem/mount_table.tests.cpp b/kernel/src/filesystem/mount_table.tests.cpp index 60b1755..e028ac8 100644 --- a/kernel/src/filesystem/mount_table.tests.cpp +++ b/kernel/src/filesystem/mount_table.tests.cpp @@ -55,7 +55,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("dentry flags are set correctly for mounted dentries") { REQUIRE(root_dentry1->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); - REQUIRE(!root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE_FALSE(root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); } THEN("finding mounts by path returns the correct mount") @@ -70,7 +70,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("removing a mount that has no child mounts succeeds") { REQUIRE(table.remove_mount("/mnt") == kernel::filesystem::mount_table::operation_result::removed); - REQUIRE(!root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE_FALSE(root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); REQUIRE(table.find_longest_prefix_mount("/mnt") == mount1); } @@ -109,7 +109,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("removing the topmost mount with the same path succeeds") { REQUIRE(table.remove_mount("/") == kernel::filesystem::mount_table::operation_result::removed); - REQUIRE(!root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE_FALSE(root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); REQUIRE(table.find_longest_prefix_mount("/") == mount1); } } @@ -156,7 +156,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("removing a leaf mount succeeds") { REQUIRE(table.remove_mount("/mnt/submnt") == kernel::filesystem::mount_table::operation_result::removed); - REQUIRE(!root_dentry3->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE_FALSE(root_dentry3->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); REQUIRE(table.find_longest_prefix_mount("/mnt/submnt") == mount2); } } diff --git a/kernel/src/filesystem/rootfs/inode.tests.cpp b/kernel/src/filesystem/rootfs/inode.tests.cpp index 879818c..7cc217f 100644 --- a/kernel/src/filesystem/rootfs/inode.tests.cpp +++ b/kernel/src/filesystem/rootfs/inode.tests.cpp @@ -17,6 +17,7 @@ SCENARIO("Rootfs inode creation", "[filesystem][rootfs][inode]") REQUIRE(inode.is_directory()); REQUIRE_FALSE(inode.is_device()); REQUIRE_FALSE(inode.is_regular()); + REQUIRE_FALSE(inode.is_symbolic_link()); } THEN("the inode has no children") -- cgit v1.2.3 From 1269410c4c733ed38859b3e70713728afb273443 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Sun, 3 May 2026 15:01:49 +0200 Subject: Use iterator in path resolution, start with symlink implementation --- kernel/src/filesystem/vfs.cpp | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index a3da258..ba4f404 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -94,7 +94,7 @@ namespace kernel::filesystem { return operation_result::invalid_path; } - + // TODO BA-FS26 check if target is directory? if (auto mount_point_dentry = resolve_path(target)) { if (auto source_dentry = resolve_path(source)) @@ -162,9 +162,9 @@ namespace kernel::filesystem auto path_parts = std::views::split(remaining, '/') | std::views::filter([](auto const & part) { return !part.empty(); }); - for (auto const & part : path_parts) + for (auto it = path_parts.begin(); it != path_parts.end(); ++it) { - std::string_view part_view{part}; + std::string_view part_view{*it}; if (part_view == ".") { @@ -205,7 +205,9 @@ namespace kernel::filesystem auto current_fs = current_mount->get_filesystem(); auto found_inode = current_fs->lookup(current_dentry->get_inode(), part_view); if (!found_inode) + { return nullptr; + } next_dentry = kstd::make_shared(current_dentry, found_inode, part_view); current_dentry->add_child(next_dentry); @@ -222,6 +224,38 @@ namespace kernel::filesystem next_dentry = current_mount->root_dentry(); } + if (next_dentry->get_inode()->is_symbolic_link()) + { + // TODO BA-FS26 this for loop is ugly --> fix + kstd::string symlink_path = "halo"; + if (symlink_path.size() > 0 && symlink_path.front() == '/') + { + for (auto it2 = std::next(it); it2 != path_parts.end(); ++it2) + { + symlink_path += "/"; + symlink_path.append(std::string_view{*it2}); + } + return resolve_path(symlink_path.view()); + } + else + { + kstd::string combined; + for (auto it3 = path_parts.begin(); it3 != it; ++it3) + { + combined += "/"; + combined.append(std::string_view{*it3}); + } + combined += "/"; + combined += symlink_path; + for (auto it4 = std::next(it); it4 != path_parts.end(); ++it4) + { + combined += "/"; + combined.append(std::string_view{*it4}); + } + return resolve_path(combined.view()); + } + } + current_dentry = next_dentry; } -- cgit v1.2.3 From 72d686961a26789b7659f17fb090511ee28604ec Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 4 May 2026 19:47:15 +0200 Subject: Add helper functions for path validation and splitting --- kernel/include/kernel/filesystem/path.hpp | 56 +++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 kernel/include/kernel/filesystem/path.hpp (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/path.hpp b/kernel/include/kernel/filesystem/path.hpp new file mode 100644 index 0000000..976926f --- /dev/null +++ b/kernel/include/kernel/filesystem/path.hpp @@ -0,0 +1,56 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_PATH_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_PATH_HPP + +#include +#include + +namespace kernel::filesystem::path +{ + /** + @brief Provides utilities for handling filesystem paths, including validation and splitting into components. + */ + + /** + @brief Checks if the given path is a valid absolute path (starts with '/'). + @param path The path to check. + @return true if the path is a valid absolute path, false otherwise. + */ + auto inline is_valid_absolute_path(std::string_view path) -> bool + { + return !path.empty() && path.front() == '/'; + } + + /** + @brief Checks if the given path is a valid relative path (doesn't start with '/'). + @param path The path to check. + @return true if the path is a valid relative path, false otherwise. + */ + auto inline is_valid_relative_path(std::string_view path) -> bool + { + return !path.empty() && path.front() != '/'; + } + + /** + @brief Checks if the given path is a valid path (either absolute or relative). + @param path The path to check. + @return true if the path is a valid path, false otherwise. + */ + auto inline is_valid_path(std::string_view path) -> bool + { + return is_valid_absolute_path(path) || is_valid_relative_path(path); + } + + /** + @brief Splits the given path into its components. + @param path The path to split. + @return A range of string views representing the components of the path. + */ + auto inline split(std::string_view path) + { + return std::views::split(path, '/') | std::views::filter([](auto const & part) { return !part.empty(); }) | + std::views::transform([](auto const & part) { return std::string_view(part.begin(), part.end()); }); + } + +} // namespace kernel::filesystem::path + +#endif // TEACH_OS_KERNEL_FILESYSTEM_PATH_HPP \ No newline at end of file -- cgit v1.2.3 From 7ff97f0fe861bb7382f41ecd4bab26cbb62b1f7d Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 4 May 2026 19:47:57 +0200 Subject: Resolve TODOs concerning path validation --- kernel/src/filesystem/vfs.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index ba4f404..8f48820 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -89,12 +90,11 @@ namespace kernel::filesystem auto vfs::do_mount(std::string_view source, std::string_view target) -> operation_result { - // TODO BA-FS26 better path validation - if (target.empty() || target.front() != '/' || (target.size() > 1 && target.back() == '/')) + if (!kernel::filesystem::path::is_valid_path(source) || !kernel::filesystem::path::is_valid_path(target)) { return operation_result::invalid_path; } - // TODO BA-FS26 check if target is directory? + if (auto mount_point_dentry = resolve_path(target)) { if (auto source_dentry = resolve_path(source)) @@ -113,8 +113,7 @@ namespace kernel::filesystem auto vfs::unmount(std::string_view path) -> operation_result { - // TODO BA-FS26 better path validation - if (path.empty() || path.front() != '/' || (path.size() > 1 && path.back() == '/')) + if (!kernel::filesystem::path::is_valid_path(path)) { return operation_result::invalid_path; } @@ -145,11 +144,12 @@ namespace kernel::filesystem auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr { - // TODO BA-FS26 better path validation - // TODO BA-FS26 implement a path parser (maybe in libs?) and use it here and in do_mount - if (path.empty() || path.front() != '/') + if (!kernel::filesystem::path::is_valid_absolute_path(path)) + { return nullptr; + } + // TODO BA-FS26 refactor (get mount by path, no more prefix matching) auto current_mount = m_mount_table.find_longest_prefix_mount("/"); if (!current_mount) { @@ -157,10 +157,8 @@ namespace kernel::filesystem } auto current_dentry = current_mount->root_dentry(); - std::string_view remaining = path.substr(current_mount->get_mount_path().size()); - auto path_parts = - std::views::split(remaining, '/') | std::views::filter([](auto const & part) { return !part.empty(); }); + auto path_parts = kernel::filesystem::path::split(path); for (auto it = path_parts.begin(); it != path_parts.end(); ++it) { -- cgit v1.2.3 From d90d6bb4b4820df6cb4b0747439293bb85b8cbec Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 4 May 2026 20:17:43 +0200 Subject: Implement symlink read in inode, fix max amount of bytes to read --- kernel/include/kernel/filesystem/ext2/inode.hpp | 2 +- kernel/src/filesystem/ext2/inode.cpp | 16 +++++++++++++++- kernel/src/filesystem/open_file_descriptor.tests.cpp | 13 ++++--------- 3 files changed, 20 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp index b4a3cc4..b8f892a 100644 --- a/kernel/include/kernel/filesystem/ext2/inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/inode.hpp @@ -20,7 +20,7 @@ namespace kernel::filesystem::ext2 { uint16_t mode; uint16_t uid; - uint32_t size; + uint32_t size; // TODO BA-FS26 signed? uint32_t atime; uint32_t ctime; uint32_t mtime; diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index 5b6bcb3..1914c70 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -5,6 +5,8 @@ #include +#include + #include #include #include @@ -23,6 +25,17 @@ namespace kernel::filesystem::ext2 auto inode::read(void * buffer, size_t offset, size_t size) const -> size_t { + // TODO BA-FS26 use revision 1 size + auto const max_readable = static_cast(m_data.size) - offset; + auto const requested_size = std::min(size, max_readable); + + if (is_symbolic_link() && m_data.size <= sizeof(m_data.block)) + { + auto inline_target = reinterpret_cast(m_data.block.data()); + kstd::libc::memcpy(static_cast(buffer), inline_target + offset, requested_size); + return requested_size; + } + auto block_index = offset / m_filesystem->get_block_size(); auto in_block_offset = offset % m_filesystem->get_block_size(); @@ -40,7 +53,8 @@ namespace kernel::filesystem::ext2 auto const block_start_offset = block_number * m_filesystem->get_block_size(); auto const read_offset = block_start_offset + in_block_offset; - auto const bytes_to_read = std::min(size - bytes_read, m_filesystem->get_block_size() - in_block_offset); + auto const bytes_to_read = + std::min(requested_size - bytes_read, m_filesystem->get_block_size() - in_block_offset); bytes_read += m_filesystem->backing_inode()->read(static_cast(buffer) + bytes_read, read_offset, bytes_to_read); diff --git a/kernel/src/filesystem/open_file_descriptor.tests.cpp b/kernel/src/filesystem/open_file_descriptor.tests.cpp index 095e203..53835ba 100644 --- a/kernel/src/filesystem/open_file_descriptor.tests.cpp +++ b/kernel/src/filesystem/open_file_descriptor.tests.cpp @@ -1,4 +1,5 @@ #include + #include #include #include @@ -83,17 +84,11 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope { kstd::vector buffer(32); auto bytes_read = ofd->read(buffer.data(), buffer.size()); - REQUIRE(bytes_read == 32); - REQUIRE(ofd->offset() == 32); + REQUIRE(bytes_read == 7); + REQUIRE(ofd->offset() == 7); std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(bytes_read)}; - auto const content_end = buffer_as_str.find('\0'); - REQUIRE(buffer_as_str.substr(0, content_end) == "info_1\n"); - - for (auto i = content_end; i < buffer_as_str.size(); ++i) - { - REQUIRE(buffer_as_str[i] == '\0'); - } + REQUIRE(buffer_as_str == "info_1\n"); } THEN("the file can be read multiple times") -- cgit v1.2.3 From d1e64340abb960c579651635d580660c12f94e6e Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 4 May 2026 20:31:58 +0200 Subject: Refactor path resolution, use vector and while instead of iterator and for-loop --- kernel/src/filesystem/vfs.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 8f48820..c9939fa 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -12,7 +12,9 @@ #include #include +#include +#include #include #include #include @@ -159,10 +161,13 @@ namespace kernel::filesystem auto current_dentry = current_mount->root_dentry(); auto path_parts = kernel::filesystem::path::split(path); + kstd::vector path_parts_vector(path_parts.begin(), path_parts.end()); + std::ranges::reverse(path_parts_vector); - for (auto it = path_parts.begin(); it != path_parts.end(); ++it) + while (!path_parts_vector.empty()) { - std::string_view part_view{*it}; + std::string_view part_view{path_parts_vector.back()}; + path_parts_vector.pop_back(); if (part_view == ".") { -- cgit v1.2.3 From bddee0f0cb77eb247eceea18005dc575b433bb69 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 4 May 2026 20:51:49 +0200 Subject: Implement symlink non-recursive --- kernel/src/filesystem/vfs.cpp | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index c9939fa..06d36ce 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -229,33 +230,21 @@ namespace kernel::filesystem if (next_dentry->get_inode()->is_symbolic_link()) { - // TODO BA-FS26 this for loop is ugly --> fix - kstd::string symlink_path = "halo"; - if (symlink_path.size() > 0 && symlink_path.front() == '/') - { - for (auto it2 = std::next(it); it2 != path_parts.end(); ++it2) - { - symlink_path += "/"; - symlink_path.append(std::string_view{*it2}); - } - return resolve_path(symlink_path.view()); - } - else + // TODO BA-FS26 max symbolic link depth to prevent infinite loops + kstd::vector buffer(4096); // TODO BA-FS26 max symlink size? + auto const bytes_read = next_dentry->get_inode()->read(buffer.data(), 0, buffer.size()); + auto const symbolic_link_path = std::string_view{reinterpret_cast(buffer.data()), bytes_read}; + + auto symbolic_link_parts = kernel::filesystem::path::split(symbolic_link_path); + kstd::vector symbolic_link_parts_vector(symbolic_link_parts.begin(), symbolic_link_parts.end()); + std::ranges::reverse(symbolic_link_parts_vector); + + path_parts_vector.insert_range(path_parts_vector.end(), symbolic_link_parts_vector); + + if (kernel::filesystem::path::is_valid_absolute_path(symbolic_link_path)) { - kstd::string combined; - for (auto it3 = path_parts.begin(); it3 != it; ++it3) - { - combined += "/"; - combined.append(std::string_view{*it3}); - } - combined += "/"; - combined += symlink_path; - for (auto it4 = std::next(it); it4 != path_parts.end(); ++it4) - { - combined += "/"; - combined.append(std::string_view{*it4}); - } - return resolve_path(combined.view()); + current_mount = m_mount_table.find_longest_prefix_mount("/"); + next_dentry = current_mount->root_dentry(); } } -- cgit v1.2.3 From 9aaabb2cf73f20cc4d4c68588e7bf4592837626f Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 4 May 2026 23:25:16 +0200 Subject: Add simple symlink tests --- kernel/src/filesystem/vfs.tests.cpp | 20 ++++++++++++++++++++ .../filesystem/test_assets/ext2_1KB_fs.img | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 109ee89..829c9d2 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -283,4 +283,24 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(unmounted_sheep_1 == nullptr); } } + + GIVEN("one real image files, containing symbolic links") + { + REQUIRE(std::filesystem::exists(image_path_1)); + REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module_1"}, {image_path_1})); + + THEN("file can be opened through absolute symbolic link") + { + auto & vfs = kernel::filesystem::vfs::get(); + auto info_1 = vfs.open("/symlinks/info_1_absolute"); + REQUIRE(info_1 != nullptr); + } + + THEN("file can be opened through relative symbolic link") + { + auto & vfs = kernel::filesystem::vfs::get(); + auto info_1 = vfs.open("/symlinks/info_1_relative"); + REQUIRE(info_1 != nullptr); + } + } } diff --git a/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img b/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img index 5bbb76d..0312727 100644 --- a/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img +++ b/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c2ef9536a439825520d9e230eedaa9ae327f9763350eddbc0f24bf5b9b5d2bf2 +oid sha256:7cf40c3cf3d8e3be614cadf2da1c76138c492734c3730eadbca645f50ed99a50 size 10485760 -- cgit v1.2.3 From 2ab9d6ffbc4aad8ab3a393bd32191e3c07103c0a Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 5 May 2026 14:37:47 +0200 Subject: fix problem with string_view lifetime --- kernel/include/kernel/filesystem/path.hpp | 5 +++-- kernel/src/filesystem/vfs.cpp | 15 ++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/path.hpp b/kernel/include/kernel/filesystem/path.hpp index 976926f..298ac5f 100644 --- a/kernel/include/kernel/filesystem/path.hpp +++ b/kernel/include/kernel/filesystem/path.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace kernel::filesystem::path { @@ -43,12 +44,12 @@ namespace kernel::filesystem::path /** @brief Splits the given path into its components. @param path The path to split. - @return A range of string views representing the components of the path. + @return A range of strings representing the components of the path. */ auto inline split(std::string_view path) { return std::views::split(path, '/') | std::views::filter([](auto const & part) { return !part.empty(); }) | - std::views::transform([](auto const & part) { return std::string_view(part.begin(), part.end()); }); + std::views::transform([](auto const & part) { return kstd::string(std::string_view(part.begin(), part.end())); }); } } // namespace kernel::filesystem::path diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 06d36ce..03921df 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -167,15 +167,15 @@ namespace kernel::filesystem while (!path_parts_vector.empty()) { - std::string_view part_view{path_parts_vector.back()}; + auto part = path_parts_vector.back(); path_parts_vector.pop_back(); - if (part_view == ".") + if (part == ".") { continue; } - if (part_view == "..") + if (part == "..") { auto parent_dentry = current_dentry->get_parent(); @@ -203,17 +203,17 @@ namespace kernel::filesystem continue; } - auto next_dentry = current_dentry->find_child(part_view); + auto next_dentry = current_dentry->find_child(part.view()); if (!next_dentry) { auto current_fs = current_mount->get_filesystem(); - auto found_inode = current_fs->lookup(current_dentry->get_inode(), part_view); + auto found_inode = current_fs->lookup(current_dentry->get_inode(), part.view()); if (!found_inode) { return nullptr; } - next_dentry = kstd::make_shared(current_dentry, found_inode, part_view); + next_dentry = kstd::make_shared(current_dentry, found_inode, part.view()); current_dentry->add_child(next_dentry); } else if (next_dentry->has_flag(dentry::dentry_flags::mounted)) @@ -244,8 +244,9 @@ namespace kernel::filesystem if (kernel::filesystem::path::is_valid_absolute_path(symbolic_link_path)) { current_mount = m_mount_table.find_longest_prefix_mount("/"); - next_dentry = current_mount->root_dentry(); + current_dentry = current_mount->root_dentry(); } + continue; } current_dentry = next_dentry; -- cgit v1.2.3 From 88ebc124ed0e703e02dfe96006d0d490e83de4fe Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Tue, 5 May 2026 14:46:21 +0200 Subject: Fix vfs tests --- kernel/src/filesystem/vfs.tests.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 829c9d2..cbd67be 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -140,8 +140,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("mount with invalid path fails") { REQUIRE(vfs.do_mount("/dev/ram16", "") == kernel::filesystem::vfs::operation_result::invalid_path); - REQUIRE(vfs.do_mount("/dev/ram16", "information") == kernel::filesystem::vfs::operation_result::invalid_path); - REQUIRE(vfs.do_mount("/dev/ram16", "/information/") == kernel::filesystem::vfs::operation_result::invalid_path); + REQUIRE(vfs.do_mount("/dev/ram16", "information") == + kernel::filesystem::vfs::operation_result::mount_point_not_found); } THEN("mount with non-existent source path fails") @@ -159,8 +159,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("unmount with invalid path fails") { REQUIRE(vfs.unmount("") == kernel::filesystem::vfs::operation_result::invalid_path); - REQUIRE(vfs.unmount("information") == kernel::filesystem::vfs::operation_result::invalid_path); - REQUIRE(vfs.unmount("/information/") == kernel::filesystem::vfs::operation_result::invalid_path); + REQUIRE(vfs.unmount("information") == kernel::filesystem::vfs::operation_result::mount_point_not_found); } THEN("unmounting non-existent mount point returns expected error code") -- cgit v1.2.3 From 156925495d7bc8bd684a346e2ab9eea12f8187cc Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Tue, 5 May 2026 15:59:08 +0200 Subject: Add constants --- kernel/include/kernel/filesystem/constants.hpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 kernel/include/kernel/filesystem/constants.hpp (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/constants.hpp b/kernel/include/kernel/filesystem/constants.hpp new file mode 100644 index 0000000..aff512a --- /dev/null +++ b/kernel/include/kernel/filesystem/constants.hpp @@ -0,0 +1,13 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_CONSTANTS_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_CONSTANTS_HPP + +#include +namespace kernel::filesystem::constants +{ + constexpr size_t inline max_path_length = 4096; + + constexpr size_t inline symlink_max_path_length = 4096; + constexpr size_t inline symloop_max = 40; +} // namespace kernel::filesystem::constants + +#endif \ No newline at end of file -- cgit v1.2.3 From 9f6353679f4052b2f685ad74994bfb6d54678d44 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Tue, 5 May 2026 16:00:11 +0200 Subject: Add check for valid path length --- kernel/include/kernel/filesystem/path.hpp | 32 ++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/path.hpp b/kernel/include/kernel/filesystem/path.hpp index 298ac5f..4845bf1 100644 --- a/kernel/include/kernel/filesystem/path.hpp +++ b/kernel/include/kernel/filesystem/path.hpp @@ -1,41 +1,54 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_PATH_HPP #define TEACH_OS_KERNEL_FILESYSTEM_PATH_HPP +#include + +#include + #include #include -#include namespace kernel::filesystem::path { /** @brief Provides utilities for handling filesystem paths, including validation and splitting into components. - */ + */ + + /** + @brief Checks if the given path is within the maximum allowed length. + @param path The path to check. + @return true if the path length is valid, false otherwise. + */ + auto inline is_valid_path_length(std::string_view path) -> bool + { + return path.length() < kernel::filesystem::constants::max_path_length; + } /** @brief Checks if the given path is a valid absolute path (starts with '/'). @param path The path to check. @return true if the path is a valid absolute path, false otherwise. - */ + */ auto inline is_valid_absolute_path(std::string_view path) -> bool { - return !path.empty() && path.front() == '/'; + return !path.empty() && path.front() == '/' && is_valid_path_length(path); } /** @brief Checks if the given path is a valid relative path (doesn't start with '/'). @param path The path to check. @return true if the path is a valid relative path, false otherwise. - */ + */ auto inline is_valid_relative_path(std::string_view path) -> bool { - return !path.empty() && path.front() != '/'; + return !path.empty() && path.front() != '/' && is_valid_path_length(path); } /** @brief Checks if the given path is a valid path (either absolute or relative). @param path The path to check. @return true if the path is a valid path, false otherwise. - */ + */ auto inline is_valid_path(std::string_view path) -> bool { return is_valid_absolute_path(path) || is_valid_relative_path(path); @@ -45,11 +58,12 @@ namespace kernel::filesystem::path @brief Splits the given path into its components. @param path The path to split. @return A range of strings representing the components of the path. - */ + */ auto inline split(std::string_view path) { return std::views::split(path, '/') | std::views::filter([](auto const & part) { return !part.empty(); }) | - std::views::transform([](auto const & part) { return kstd::string(std::string_view(part.begin(), part.end())); }); + std::views::transform( + [](auto const & part) { return kstd::string(std::string_view(part.begin(), part.end())); }); } } // namespace kernel::filesystem::path -- cgit v1.2.3 From b6cc02c3bac002ebac8e6ba734b00f0e60b24778 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Tue, 5 May 2026 16:05:48 +0200 Subject: Add check for max symlink count --- kernel/src/filesystem/vfs.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 03921df..e6d9241 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -93,7 +94,7 @@ namespace kernel::filesystem auto vfs::do_mount(std::string_view source, std::string_view target) -> operation_result { - if (!kernel::filesystem::path::is_valid_path(source) || !kernel::filesystem::path::is_valid_path(target)) + if (!path::is_valid_path(source) || !path::is_valid_path(target)) { return operation_result::invalid_path; } @@ -116,7 +117,7 @@ namespace kernel::filesystem auto vfs::unmount(std::string_view path) -> operation_result { - if (!kernel::filesystem::path::is_valid_path(path)) + if (!path::is_valid_path(path)) { return operation_result::invalid_path; } @@ -147,7 +148,7 @@ namespace kernel::filesystem auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr { - if (!kernel::filesystem::path::is_valid_absolute_path(path)) + if (!path::is_valid_absolute_path(path)) { return nullptr; } @@ -161,10 +162,12 @@ namespace kernel::filesystem auto current_dentry = current_mount->root_dentry(); - auto path_parts = kernel::filesystem::path::split(path); + auto path_parts = path::split(path); kstd::vector path_parts_vector(path_parts.begin(), path_parts.end()); std::ranges::reverse(path_parts_vector); + auto symlink_counter = 0uz; + while (!path_parts_vector.empty()) { auto part = path_parts_vector.back(); @@ -230,18 +233,22 @@ namespace kernel::filesystem if (next_dentry->get_inode()->is_symbolic_link()) { - // TODO BA-FS26 max symbolic link depth to prevent infinite loops - kstd::vector buffer(4096); // TODO BA-FS26 max symlink size? + if (symlink_counter++ > constants::symloop_max) + { + return nullptr; + } + + kstd::vector buffer(constants::symlink_max_path_length); auto const bytes_read = next_dentry->get_inode()->read(buffer.data(), 0, buffer.size()); auto const symbolic_link_path = std::string_view{reinterpret_cast(buffer.data()), bytes_read}; - auto symbolic_link_parts = kernel::filesystem::path::split(symbolic_link_path); + auto symbolic_link_parts = path::split(symbolic_link_path); kstd::vector symbolic_link_parts_vector(symbolic_link_parts.begin(), symbolic_link_parts.end()); std::ranges::reverse(symbolic_link_parts_vector); path_parts_vector.insert_range(path_parts_vector.end(), symbolic_link_parts_vector); - if (kernel::filesystem::path::is_valid_absolute_path(symbolic_link_path)) + if (path::is_valid_absolute_path(symbolic_link_path)) { current_mount = m_mount_table.find_longest_prefix_mount("/"); current_dentry = current_mount->root_dentry(); -- cgit v1.2.3 From 94232ac15ce987cf6792be0c4d5b0141d7cac0b1 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Tue, 5 May 2026 16:18:54 +0200 Subject: Add tests for path utility --- kernel/CMakeLists.txt | 1 + kernel/src/filesystem/path.tests.cpp | 69 ++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 kernel/src/filesystem/path.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 909ccf7..860e28b 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -188,6 +188,7 @@ if(BUILD_TESTING) "src/filesystem/devfs/inode.tests.cpp" "src/filesystem/ext2/filesystem.tests.cpp" "src/filesystem/ext2/inode.tests.cpp" + "src/filesystem/path.tests.cpp" "src/filesystem/rootfs/filesystem.tests.cpp" "src/filesystem/rootfs/inode.tests.cpp" "src/filesystem/dentry.tests.cpp" diff --git a/kernel/src/filesystem/path.tests.cpp b/kernel/src/filesystem/path.tests.cpp new file mode 100644 index 0000000..3c18b5c --- /dev/null +++ b/kernel/src/filesystem/path.tests.cpp @@ -0,0 +1,69 @@ +#include + +#include + +#include +#include +#include +#include + +SCENARIO("path utilities", "[filesystem][path]") +{ + GIVEN("valid and invalid paths") + { + THEN("valid absolute paths are recognized as valid") + { + REQUIRE(kernel::filesystem::path::is_valid_path("/valid/absolute/path")); + REQUIRE(kernel::filesystem::path::is_valid_path("/")); + } + + THEN("valid relative paths are recognized as valid") + { + REQUIRE(kernel::filesystem::path::is_valid_path("valid/../relative/.././path")); + REQUIRE(kernel::filesystem::path::is_valid_path("valid/relative/path")); + REQUIRE(kernel::filesystem::path::is_valid_path("file.txt")); + } + + THEN("invalid paths are recognized as invalid") + { + REQUIRE_FALSE(kernel::filesystem::path::is_valid_path("")); + REQUIRE_FALSE(kernel::filesystem::path::is_valid_path(std::string(4096, 'a'))); + } + + THEN("valid absolute paths are recognized as absolute") + { + REQUIRE(kernel::filesystem::path::is_valid_absolute_path("/valid/absolute/path")); + REQUIRE_FALSE(kernel::filesystem::path::is_valid_absolute_path("valid/relative/path")); + } + + THEN("invalid paths are not recognized as absolute") + { + REQUIRE_FALSE(kernel::filesystem::path::is_valid_absolute_path("")); + REQUIRE_FALSE(kernel::filesystem::path::is_valid_absolute_path(std::string(4096, 'a'))); + REQUIRE_FALSE(kernel::filesystem::path::is_valid_absolute_path("invalid/absolute/path")); + } + + THEN("valid relative paths are recognized as relative") + { + REQUIRE(kernel::filesystem::path::is_valid_relative_path("valid/relative/path")); + REQUIRE_FALSE(kernel::filesystem::path::is_valid_relative_path("/valid/absolute/path")); + } + + THEN("invalid paths are not recognized as relative") + { + REQUIRE_FALSE(kernel::filesystem::path::is_valid_relative_path("")); + REQUIRE_FALSE(kernel::filesystem::path::is_valid_relative_path(std::string(4096, 'a'))); + REQUIRE_FALSE(kernel::filesystem::path::is_valid_relative_path("/invalid/absolute/path")); + } + } + + GIVEN("a valid path") + { + THEN("it can be split into components") + { + auto components = kernel::filesystem::path::split("/a/b///c/d.txt"); + std::vector expected = {"a", "b", "c", "d.txt"}; + REQUIRE(std::ranges::equal(components, expected)); + } + } +} \ No newline at end of file -- cgit v1.2.3 From c60f2e345231e03176e0882a88f8675c1814e456 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Tue, 5 May 2026 16:22:23 +0200 Subject: Remove manual tests --- kernel/src/main.cpp | 168 +--------------------------------------------------- 1 file changed, 1 insertion(+), 167 deletions(-) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index ffea979..bfb731a 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -21,173 +21,11 @@ #include #include -#include #include #include using namespace kstd::units_literals; -auto test_device_names() -> void -{ - auto storage_mgmt = kernel::devices::storage::management::get(); - std::ranges::for_each(storage_mgmt.all_controllers(), [](auto const & controller) { - std::ranges::for_each(controller->all_devices(), - [](auto const & device) { kstd::println("{}", device->name().view()); }); - }); -} - -auto test_file_descriptor_manually() -> void -{ - // setup - auto fd_table = kernel::filesystem::open_file_table::get(); - auto storage_mgmt = kernel::devices::storage::management::get(); - auto device = storage_mgmt.device_by_major_minor(1, 0); - - auto dev_node = kstd::make_shared(device); - - auto ofd = kstd::make_shared(dev_node); - auto fd_index = fd_table.add_file(ofd); - - // use: read two bytes and write two again - auto fd = fd_table.get_file(fd_index); - if (!fd) - { - kstd::os::panic("test code failed"); - } - - kstd::vector buffer{2}; - auto number_of_read_bytes = fd->read(buffer.data(), buffer.size()); - kstd::println("read bytes: {}", number_of_read_bytes); - kstd::println("buffer: {::#04x}", buffer); - - // write half of the file new - auto const value1 = std::byte{0xAA}; - auto const value2 = std::byte{0xBB}; - kstd::vector write_buffer{value1, value2}; - auto written_bytes = fd->write(write_buffer.data(), write_buffer.size()); - - kstd::println("written bytes: {}", written_bytes); - - fd_table.remove_file(fd_index); - - // use: read four bytes again -> two old bytes two new bytes - auto ofd1 = kstd::make_shared(dev_node); - fd_index = fd_table.add_file(ofd1); - auto fd1 = fd_table.get_file(fd_index); - - if (!fd1) - { - kstd::os::panic("test code failed"); - } - - kstd::vector buffer1{4}; - number_of_read_bytes = fd1->read(buffer1.data(), buffer1.size()); - kstd::println("read bytes: {}", number_of_read_bytes); - kstd::println("buffer: {::#04x}", buffer1); -} - -auto test_device_with_vfs() -> void -{ - auto vfs = kernel::filesystem::vfs::get(); - auto dentry = vfs.open("/dev/ram0"); - if (!dentry) - { - kstd::os::panic("test code failed"); - } - - auto fd_table = kernel::filesystem::open_file_table::get(); - auto ofd = kstd::make_shared(dentry->get_inode()); - auto fd = fd_table.add_file(ofd); - kstd::vector buffer{2}; - auto file = fd_table.get_file(fd); - if (!file) - { - kstd::os::panic("test code failed"); - } - - auto number_of_read_bytes = file->read(buffer.data(), buffer.size()); - kstd::println("read bytes: {}", number_of_read_bytes); - kstd::println("buffer: {::#04x}", buffer); -} - -auto test_file_lookup() -> void -{ - auto vfs = kernel::filesystem::vfs::get(); - auto read_and_write_file = [&vfs](std::string_view path) { - kstd::println("[TEST] Reading and writing file at path: {}", path); - auto dentry = vfs.open(path); - if (!dentry) - { - kstd::os::panic("test code failed"); - } - - kstd::vector buffer{32}; - auto ofd = kstd::make_shared(dentry->get_inode()); - auto number_of_read_bytes = ofd->read(buffer.data(), buffer.size()); - kstd::println("read bytes: {}", number_of_read_bytes); - kstd::println("buffer: {::#04x}", buffer); - - std::string_view buffer_as_str{reinterpret_cast(buffer.data()), number_of_read_bytes}; - kstd::println("buffer_as_str: {}", buffer_as_str); - }; - - read_and_write_file("/info.txt"); - read_and_write_file("/enclosures/info.txt"); - read_and_write_file("/enclosures/aquarium/tank_1/fish_4.txt"); - read_and_write_file("/enclosures/elephant_house/elephant_1.txt"); - read_and_write_file( - "/enclosures/aquarium/tank_2/" - "this_is_a_very_very_long_fish_filename_that_keeps_going_and_going_until_it_almost_breaks_linux_filesystem_" - "limits_for_testing_purposes_and_we_add_more_characters_to_make_it_even_longer_30.txt"); - - vfs.do_mount("/dev/ram16", "/enclosures/aquarium"); - read_and_write_file("/enclosures/aquarium/closed.txt"); - read_and_write_file("/enclosures/aquarium/information/info_2.txt"); - - vfs.unmount("/enclosures/aquarium"); - read_and_write_file("/enclosures/aquarium/tank_1/fish_4.txt"); - - vfs.do_mount("/dev/ram32", "/enclosures/elephant_house"); - read_and_write_file("/enclosures/elephant_house/monkey_house/infrastructure/info.txt"); - - vfs.do_mount("/dev/ram16", "/enclosures/elephant_house/monkey_house"); - read_and_write_file("/enclosures/elephant_house/monkey_house/information/info_2.txt"); - - auto result = vfs.unmount("/enclosures/elephant_house"); - if (result == kernel::filesystem::vfs::operation_result::unmount_failed) - { - kstd::println("[TEST] Unmount failed as expected due to active child mount."); - } - - vfs.unmount("/enclosures/elephant_house/monkey_house"); - result = vfs.unmount("/enclosures/elephant_house"); - if (result == kernel::filesystem::vfs::operation_result::success) - { - kstd::println("[TEST] Unmount succeeded after unmounting child mount."); - } -} - -auto run_test_code() -> void -{ - kstd::println("[TEST] Running test code..."); - - kstd::println("[TEST] device names"); - test_device_names(); - kstd::println("---------------------------------"); - - kstd::println("[TEST] file descriptor manually"); - test_file_descriptor_manually(); - kstd::println("---------------------------------"); - - kstd::println("[TEST] device with VFS"); - test_device_with_vfs(); - kstd::println("---------------------------------"); - - kstd::println("[TEST] file lookup"); - test_file_lookup(); - kstd::println("---------------------------------"); -} - auto run_demo() -> void { // 1) open a file @@ -280,12 +118,8 @@ auto main() -> int kernel::filesystem::vfs::init(); kstd::println("[OS] Virtual filesystem initialized."); - // TODO BA-FS26 remove demo and test code again? + // TODO BA-FS26 remove demo code? // run_demo(); - // TODO BA-FS26 remove demo and test code again? - run_test_code(); - kstd::println("[TEST] All tests completed."); - kapi::system::panic("Returning from kernel main!"); } -- cgit v1.2.3 From 9f729ef76de79c8dabace2b4a6255f006385f6df Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Tue, 5 May 2026 16:29:50 +0200 Subject: Disable recursion-warning --- kernel/src/filesystem/dentry.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index 72500fd..1cf8730 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -39,7 +39,7 @@ namespace kernel::filesystem return m_name.view(); } - // TODO BA-FS26 fix warning (do not use recursion) + // NOLINTNEXTLINE(misc-no-recursion) auto dentry::get_full_path() const -> kstd::string { if (m_parent) @@ -52,7 +52,7 @@ namespace kernel::filesystem return parent_path + m_name.view(); } - return m_name.empty() ? "/" : m_name.view(); + return m_name.view(); } auto dentry::add_child(kstd::shared_ptr const & child) -> void -- cgit v1.2.3 From 2c24321681974e1aa8b1240155420f49a16f3c2e Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Tue, 5 May 2026 17:15:09 +0200 Subject: Add testing symlinks to filesystem images --- kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img | 2 +- kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img | 2 +- kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img b/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img index 0312727..a5202ca 100644 --- a/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img +++ b/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7cf40c3cf3d8e3be614cadf2da1c76138c492734c3730eadbca645f50ed99a50 +oid sha256:98ac3c1be872806e25fb14eea168ca79a91959f4e6a5ac3d00c5d8224c1f73a3 size 10485760 diff --git a/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img b/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img index 1880911..8327022 100644 --- a/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img +++ b/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a13da5abb9c65c737105b1da0d4344c7cd7604c7952c762c4f4e3d3f96fd42d +oid sha256:a1d102f2e40083613060d43b2b32d31031137bbef99761a2d1bf4d38e155adb7 size 5242880 diff --git a/kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img b/kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img index 3aaceb8..2cd452f 100644 --- a/kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img +++ b/kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ce6a1aea277906e1af6de223c017ff900b96569f076b4d99fc04eaa1ee986f4 +oid sha256:62e1fa40f95e0cb037c43e3f55d0094ab6cb4d68e00914f555a90faf7cc00c31 size 10485760 -- cgit v1.2.3 From 491d7cb23f48b995e954b7cbb836ab3efb47ea88 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Tue, 5 May 2026 17:22:27 +0200 Subject: Update readme for images, add symlink to readme into test_assets folder --- kernel/src/test_support/filesystem/test_assets/README.md | 1 + 1 file changed, 1 insertion(+) create mode 120000 kernel/src/test_support/filesystem/test_assets/README.md (limited to 'kernel') diff --git a/kernel/src/test_support/filesystem/test_assets/README.md b/kernel/src/test_support/filesystem/test_assets/README.md new file mode 120000 index 0000000..718a227 --- /dev/null +++ b/kernel/src/test_support/filesystem/test_assets/README.md @@ -0,0 +1 @@ +/arch/x86_64/support/modules/README.md \ No newline at end of file -- cgit v1.2.3 From 265ac82029665921bd95d74411682968ee0d4ada Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 5 May 2026 19:41:50 +0200 Subject: refactoring do_mount_internal (retrieve path from dentry), handle .. correctly in relative path --- kernel/include/kernel/filesystem/vfs.hpp | 4 ++-- kernel/src/filesystem/vfs.cpp | 29 +++++++++++++++-------------- 2 files changed, 17 insertions(+), 16 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 881f458..7e66fb7 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -77,8 +77,8 @@ namespace kernel::filesystem auto init_internal() -> void; [[nodiscard]] auto resolve_path(std::string_view path) -> kstd::shared_ptr; - auto do_mount_internal(std::string_view path, kstd::shared_ptr const & mount_point_dentry, - kstd::shared_ptr const & fs) -> void; + auto do_mount_internal(kstd::shared_ptr const & mount_point_dentry, kstd::shared_ptr const & fs) + -> void; mount_table m_mount_table; }; diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index e6d9241..4defc81 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -56,14 +56,14 @@ namespace kernel::filesystem { kapi::system::panic("[FILESYSTEM] failed to resolve /dev for initial devfs mount."); } - do_mount_internal("/dev", dev_mount_point_dentry, device_fs); + do_mount_internal(dev_mount_point_dentry, device_fs); // Mount boot filesystem at / (will shadow rootfs) if (auto boot_device_dentry = resolve_path("/dev/ram0")) { if (auto boot_root_fs = kernel::filesystem::filesystem::probe_and_mount(boot_device_dentry->get_inode())) { - do_mount_internal("/", root_fs_root_dentry, boot_root_fs); + do_mount_internal(root_fs_root_dentry, boot_root_fs); // Resolve / to get the boot root dentry if (auto boot_root_dentry = resolve_path("/")) @@ -71,7 +71,7 @@ namespace kernel::filesystem auto dev_dentry = kstd::make_shared(boot_root_dentry, device_fs->root_inode(), "dev"); boot_root_dentry->add_child(dev_dentry); - do_mount_internal("/dev", dev_dentry, device_fs); + do_mount_internal(dev_dentry, device_fs); } } } @@ -105,7 +105,7 @@ namespace kernel::filesystem { if (auto fs = kernel::filesystem::filesystem::probe_and_mount(source_dentry->get_inode())) { - do_mount_internal(target, mount_point_dentry, fs); + do_mount_internal(mount_point_dentry, fs); return operation_result::success; } return operation_result::invalid_filesystem; @@ -136,13 +136,15 @@ namespace kernel::filesystem return operation_result::mount_point_not_found; } - auto vfs::do_mount_internal(std::string_view path, kstd::shared_ptr const & mount_point_dentry, + auto vfs::do_mount_internal(kstd::shared_ptr const & mount_point_dentry, kstd::shared_ptr const & fs) -> void { - auto parent_mount = m_mount_table.find_longest_prefix_mount(path); + auto mount_path = mount_point_dentry->get_full_path(); + + auto parent_mount = m_mount_table.find_longest_prefix_mount(mount_path.view()); auto new_fs_root = kstd::make_shared(mount_point_dentry->get_parent(), fs->root_inode(), mount_point_dentry->get_name()); - auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, path, parent_mount); + auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, mount_path.view(), parent_mount); m_mount_table.add_mount(new_mount); } @@ -188,16 +190,15 @@ namespace kernel::filesystem if (auto parent_mount = current_mount->get_parent_mount()) { current_mount = parent_mount; - current_dentry = current_dentry->get_parent(); + current_dentry = parent_dentry; + } - if (!parent_dentry) - { - parent_dentry = current_mount->root_dentry(); - } + if (!parent_dentry) + { + parent_dentry = current_mount->root_dentry(); } } - - if (!parent_dentry) + else if (!parent_dentry) { return nullptr; } -- cgit v1.2.3 From b7fba373341dd44b53642d7233396efbef4526b2 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 5 May 2026 20:07:37 +0200 Subject: avoid to traverse back over the root --- kernel/src/filesystem/vfs.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 4defc81..7f21a5c 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -186,22 +186,17 @@ namespace kernel::filesystem if (current_dentry == current_mount->root_dentry()) { - // change the mount point - if (auto parent_mount = current_mount->get_parent_mount()) + if (current_mount->get_mount_path() == "/") { - current_mount = parent_mount; - current_dentry = parent_dentry; + continue; } - if (!parent_dentry) + if (auto parent_mount = current_mount->get_parent_mount()) { - parent_dentry = current_mount->root_dentry(); + current_mount = parent_mount; + current_dentry = parent_dentry; } } - else if (!parent_dentry) - { - return nullptr; - } current_dentry = parent_dentry; continue; -- cgit v1.2.3 From a0f1c6f2199f55d2faaa5d9eafa9f763b2b299e4 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 5 May 2026 20:08:00 +0200 Subject: add symbolic link tests --- kernel/src/filesystem/vfs.tests.cpp | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index cbd67be..5160d15 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -301,5 +301,47 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto info_1 = vfs.open("/symlinks/info_1_relative"); REQUIRE(info_1 != nullptr); } + + THEN("file can be opened through symbolic link pointing absolute to the directory containing the file") + { + auto & vfs = kernel::filesystem::vfs::get(); + auto info_1 = vfs.open("/symlinks/information_directory_absolute/info_1.txt"); + REQUIRE(info_1 != nullptr); + } + + THEN("file can be opened through symbolic link pointing relative to the directory containing the file") + { + auto & vfs = kernel::filesystem::vfs::get(); + auto info_1 = vfs.open("/symlinks/information_directory_relative/info_1.txt"); + REQUIRE(info_1 != nullptr); + } + + THEN("symbolic link with path traversing back to the root") + { + auto & vfs = kernel::filesystem::vfs::get(); + auto info_1 = vfs.open("/symlinks/traverse_back_5_times/information/info_1.txt"); + REQUIRE(info_1 != nullptr); + } + + THEN("symbolic link containing an invalid absolute path is handled correctly") + { + auto & vfs = kernel::filesystem::vfs::get(); + auto invalid_symlink = vfs.open("/symlinks/invalid_absolute"); + REQUIRE(invalid_symlink == nullptr); + } + + THEN("symbolic link containing an invalid relative path is handled correctly") + { + auto & vfs = kernel::filesystem::vfs::get(); + auto invalid_symlink = vfs.open("/symlinks/invalid_relative"); + REQUIRE(invalid_symlink == nullptr); + } + + THEN("circular symbolic links are detected and handled correctly") + { + auto & vfs = kernel::filesystem::vfs::get(); + auto circular_symlink = vfs.open("/symlinks/symloop_a"); + REQUIRE(circular_symlink == nullptr); + } } } -- cgit v1.2.3 From 7414148b662a33cf6c69f89b7b0c3162f6880d6c Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 5 May 2026 20:33:28 +0200 Subject: refactoring mount_table lookup --- kernel/include/kernel/filesystem/mount_table.hpp | 10 ++++++++-- kernel/src/filesystem/mount_table.cpp | 8 ++++++++ kernel/src/filesystem/vfs.cpp | 10 ++++------ 3 files changed, 20 insertions(+), 8 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount_table.hpp b/kernel/include/kernel/filesystem/mount_table.hpp index 00277ea..8e57d9e 100644 --- a/kernel/include/kernel/filesystem/mount_table.hpp +++ b/kernel/include/kernel/filesystem/mount_table.hpp @@ -39,13 +39,19 @@ namespace kernel::filesystem [[nodiscard]] auto remove_mount(std::string_view path) -> operation_result; /** - @brief Finds the mount with the longest prefix matching the given @p path. This method is used to determine which - mounted filesystem should handle a given path lookup. + @brief Finds the mount with the longest prefix matching the given @p path. @param path The path to match against the mount paths in the table. @return A pointer to the mount with the longest matching prefix, or a null pointer if no mount matches the path. */ [[nodiscard]] auto find_longest_prefix_mount(std::string_view path) const -> kstd::shared_ptr; + /** + @brief Finds the mount with the exact mount path matching the given @p path. + @param path The path to match against the mount paths in the table. + @return A pointer to the mount with the exact matching path, or a null pointer if no mount matches the path. + */ + [[nodiscard]] auto find_exact_mount(std::string_view path) const -> kstd::shared_ptr; + private: [[nodiscard]] auto has_child_mounts(kstd::shared_ptr const & parent_mount) const -> bool; diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index e21e497..965e83b 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -102,4 +102,12 @@ namespace kernel::filesystem return mount_with_longest_prefix; } + + auto mount_table::find_exact_mount(std::string_view path) const -> kstd::shared_ptr + { + auto reversed_mounts = std::ranges::reverse_view(m_mounts); + auto mount_it = + std::ranges::find_if(reversed_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }); + return (mount_it != reversed_mounts.end()) ? *mount_it : nullptr; + } } // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 7f21a5c..19f5f48 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -41,7 +41,6 @@ namespace kernel::filesystem auto vfs::init_internal() -> void { - // Mount rootfs at / as the temporary base auto root_fs = kstd::make_shared(); root_fs->mount(nullptr); @@ -140,8 +139,8 @@ namespace kernel::filesystem kstd::shared_ptr const & fs) -> void { auto mount_path = mount_point_dentry->get_full_path(); - auto parent_mount = m_mount_table.find_longest_prefix_mount(mount_path.view()); + auto new_fs_root = kstd::make_shared(mount_point_dentry->get_parent(), fs->root_inode(), mount_point_dentry->get_name()); auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, mount_path.view(), parent_mount); @@ -156,7 +155,7 @@ namespace kernel::filesystem } // TODO BA-FS26 refactor (get mount by path, no more prefix matching) - auto current_mount = m_mount_table.find_longest_prefix_mount("/"); + auto current_mount = m_mount_table.find_exact_mount("/"); if (!current_mount) { kapi::system::panic("[FILESYSTEM] no root mount found."); @@ -217,8 +216,7 @@ namespace kernel::filesystem } else if (next_dentry->has_flag(dentry::dentry_flags::mounted)) { - // TODO BA-FS26 really do it like this? or just call "get" without longes_prefix stuff - current_mount = m_mount_table.find_longest_prefix_mount(next_dentry->get_full_path().view()); + current_mount = m_mount_table.find_exact_mount(next_dentry->get_full_path().view()); if (!current_mount) { kapi::system::panic("[FILESYSTEM] mount for dentry with mounted flag not found."); @@ -246,7 +244,7 @@ namespace kernel::filesystem if (path::is_valid_absolute_path(symbolic_link_path)) { - current_mount = m_mount_table.find_longest_prefix_mount("/"); + current_mount = m_mount_table.find_exact_mount("/"); current_dentry = current_mount->root_dentry(); } continue; -- cgit v1.2.3 From 8739d65ea50f13dbbb5bd1a27f461c367deb5b99 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 5 May 2026 20:59:52 +0200 Subject: add symlink chain to image --- kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img b/kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img index 2cd452f..c3f6daf 100644 --- a/kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img +++ b/kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62e1fa40f95e0cb037c43e3f55d0094ab6cb4d68e00914f555a90faf7cc00c31 +oid sha256:026ca30269dbd80beb2dd74677c94676d1d4a7f6b5fe406c4ddb82836ba2dc00 size 10485760 -- cgit v1.2.3 From 9d1fc7cbe7d3851541f1986dc4bc66a2bc944c89 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 5 May 2026 21:00:17 +0200 Subject: add vfs symlink tests --- kernel/src/filesystem/vfs.tests.cpp | 63 ++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 5160d15..2eec572 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -283,7 +283,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS } } - GIVEN("one real image files, containing symbolic links") + GIVEN("A real image files, containing symbolic links") { REQUIRE(std::filesystem::exists(image_path_1)); REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module_1"}, {image_path_1})); @@ -344,4 +344,65 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(circular_symlink == nullptr); } } + + GIVEN("A real image file containing as filesystem formatted files and this filesystem contains a symbolic link") + { + REQUIRE(std::filesystem::exists(image_path_1)); + REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module_1"}, {image_path_1})); + + auto & vfs = kernel::filesystem::vfs::get(); + vfs.do_mount("/archiv/2024.img", "/information"); + + THEN("file can be opened through symbolic link pointing to the parent filesystem") + { + auto closed_file = vfs.open("/information/symlinks/traverse_back_twice/closed.txt"); + REQUIRE(closed_file != nullptr); + } + } + + GIVEN("Two real images, one containing a symbolic link leaving and reentering filesystem again") + { + REQUIRE(std::filesystem::exists(image_path_1)); + REQUIRE(std::filesystem::exists(image_path_2)); + REQUIRE_NOTHROW( + setup_modules_from_img_and_init_vfs({"test_img_module_1", "test_img_module_2"}, {image_path_1, image_path_2})); + + auto & vfs = kernel::filesystem::vfs::get(); + vfs.do_mount("/dev/ram16", "/information"); + + THEN("file can be opened through symbolic link pointing to the parent filesystem and back into the mounted " + "filesystem again") + { + auto monkey_1 = vfs.open("/information/symlinks/leave_and_reenter_mount/monkey_1.txt"); + REQUIRE(monkey_1 != nullptr); + } + } + + GIVEN("One real image containing a very long symbolic link") + { + REQUIRE(std::filesystem::exists(image_path_3)); + REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module_3"}, {image_path_3})); + + auto & vfs = kernel::filesystem::vfs::get(); + + THEN("file can be opened through symbolic link with a long path") + { + auto fish_30 = vfs.open("/symlinks/very_long_symlink"); + REQUIRE(fish_30 != nullptr); + } + } + + GIVEN("One real image containing a valid symbolic link chain") + { + REQUIRE(std::filesystem::exists(image_path_3)); + REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module_3"}, {image_path_3})); + + auto & vfs = kernel::filesystem::vfs::get(); + + THEN("file can be opened through symbolic link chain") + { + auto map = vfs.open("/symlinks/symlink_chain_1/map.txt"); + REQUIRE(map != nullptr); + } + } } -- cgit v1.2.3 From a2dff6812af354f282b731bc138e98a18bf7f35c Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 5 May 2026 21:13:45 +0200 Subject: add filesystem interface tests --- kernel/kapi/filesystem.tests.cpp | 49 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/kapi/filesystem.tests.cpp b/kernel/kapi/filesystem.tests.cpp index baa8613..8a532bb 100644 --- a/kernel/kapi/filesystem.tests.cpp +++ b/kernel/kapi/filesystem.tests.cpp @@ -16,7 +16,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap auto const image_path_1 = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_1KB_fs.img"; auto const image_path_2 = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_2KB_fs.img"; - GIVEN("a real image file") + GIVEN("Two real image files") { REQUIRE(std::filesystem::exists(image_path_1)); REQUIRE(std::filesystem::exists(image_path_2)); @@ -38,6 +38,53 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap REQUIRE(kapi::filesystem::close(fd) == 0); } + THEN("files can be opened through absolute symbolic link, read and closed again") + { + auto fd = kapi::filesystem::open("/symlinks/information_directory_absolute/info_1.txt"); + REQUIRE(fd >= 0); + + auto buffer = std::vector(6); + auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size()); + REQUIRE(bytes_read >= 0); + + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(bytes_read)}; + REQUIRE(buffer_as_str == "info_1"); + + REQUIRE(kapi::filesystem::close(fd) == 0); + } + + THEN("files can be opened through relative symbolic link, read and closed again") + { + auto fd = kapi::filesystem::open("/symlinks/information_directory_relative/info_1.txt"); + REQUIRE(fd >= 0); + + auto buffer = std::vector(6); + auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size()); + REQUIRE(bytes_read >= 0); + + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(bytes_read)}; + REQUIRE(buffer_as_str == "info_1"); + + REQUIRE(kapi::filesystem::close(fd) == 0); + } + + THEN("files can be opened through relative symbolic link over multiple mount points, read and closed again") + { + kapi::filesystem::mount("/archiv/2024.img", "/information"); + + auto fd = kapi::filesystem::open("/information/symlinks/traverse_back_twice/information/sheep_1.txt"); + REQUIRE(fd >= 0); + + auto buffer = std::vector(7); + auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size()); + REQUIRE(bytes_read >= 0); + + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(bytes_read)}; + REQUIRE(buffer_as_str == "sheep_1"); + + REQUIRE(kapi::filesystem::close(fd) == 0); + } + THEN("a filesystem can be mounted, files can be opened, read and closed again and unmounted") { REQUIRE(kapi::filesystem::mount("/dev/ram16", "/information") == 0); -- cgit v1.2.3 From 7ccfa26a3dde4d4266f8c59f4e3de8bd6f760059 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 5 May 2026 21:17:23 +0200 Subject: small refactoring, add todo --- kernel/kapi/filesystem.tests.cpp | 6 ++++-- kernel/src/filesystem/vfs.cpp | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/filesystem.tests.cpp b/kernel/kapi/filesystem.tests.cpp index 8a532bb..1d1f8ee 100644 --- a/kernel/kapi/filesystem.tests.cpp +++ b/kernel/kapi/filesystem.tests.cpp @@ -161,14 +161,16 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap THEN("not opened files cannot be read from") { std::vector buffer(10); - auto bytes_read = kapi::filesystem::read(999, buffer.data(), buffer.size()); + auto const invalid_fd = 999uz; + auto bytes_read = kapi::filesystem::read(invalid_fd, buffer.data(), buffer.size()); REQUIRE(bytes_read < 0); } THEN("not opened files cannot be written to") { std::vector buffer(10); - auto bytes_written = kapi::filesystem::write(999, buffer.data(), buffer.size()); + auto const invalid_fd = 999uz; + auto bytes_written = kapi::filesystem::write(invalid_fd, buffer.data(), buffer.size()); REQUIRE(bytes_written < 0); } } diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 19f5f48..b84f690 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -139,6 +139,7 @@ namespace kernel::filesystem kstd::shared_ptr const & fs) -> void { auto mount_path = mount_point_dentry->get_full_path(); + // TODO BA-FS26 refactoring, implement dentry lookup to get the parent mount... auto parent_mount = m_mount_table.find_longest_prefix_mount(mount_path.view()); auto new_fs_root = -- cgit v1.2.3 From 870039d48d28f479eea88c7548b8d2b2a28c09bc Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 5 May 2026 21:18:48 +0200 Subject: add mount table find_exact_mount tests, remove todo --- kernel/src/filesystem/mount_table.tests.cpp | 21 +++++++++++++++++++-- kernel/src/filesystem/vfs.cpp | 1 - 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/mount_table.tests.cpp b/kernel/src/filesystem/mount_table.tests.cpp index e028ac8..efacdfe 100644 --- a/kernel/src/filesystem/mount_table.tests.cpp +++ b/kernel/src/filesystem/mount_table.tests.cpp @@ -58,7 +58,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] REQUIRE_FALSE(root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); } - THEN("finding mounts by path returns the correct mount") + THEN("finding mounts by longest prefix returns the correct mount") { REQUIRE(table.find_longest_prefix_mount("/") == mount1); REQUIRE(table.find_longest_prefix_mount("/file") == mount1); @@ -67,6 +67,18 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] REQUIRE(table.find_longest_prefix_mount("/other") == mount1); } + THEN("finding mounts by exact valid path returns the correct mount") + { + REQUIRE(table.find_exact_mount("/") == mount1); + REQUIRE(table.find_exact_mount("/mnt") == mount2); + } + + THEN("finding mounts by exact invalid path returns null") + { + REQUIRE(table.find_exact_mount("/nonexistent") == nullptr); + REQUIRE(table.find_exact_mount("/mnt/file") == nullptr); + } + THEN("removing a mount that has no child mounts succeeds") { REQUIRE(table.remove_mount("/mnt") == kernel::filesystem::mount_table::operation_result::removed); @@ -97,7 +109,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] table.add_mount(mount1); table.add_mount(mount2); - THEN("finding mounts by path returns the correct mount based on longest prefix") + THEN("finding mounts by longest prefix returns the correct mount") { REQUIRE(table.find_longest_prefix_mount("/") == mount2); REQUIRE(table.find_longest_prefix_mount("/file") == mount2); @@ -106,6 +118,11 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] REQUIRE(table.find_longest_prefix_mount("/other") == mount2); } + THEN("finding mounts by exact valid path returns the correct mount") + { + REQUIRE(table.find_exact_mount("/") == mount2); + } + THEN("removing the topmost mount with the same path succeeds") { REQUIRE(table.remove_mount("/") == kernel::filesystem::mount_table::operation_result::removed); diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index b84f690..519550b 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -155,7 +155,6 @@ namespace kernel::filesystem return nullptr; } - // TODO BA-FS26 refactor (get mount by path, no more prefix matching) auto current_mount = m_mount_table.find_exact_mount("/"); if (!current_mount) { -- cgit v1.2.3 From 4522374b902ee9a30c83c2ec23880522e80febea Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 5 May 2026 21:37:12 +0200 Subject: .. int the root directory remains in the root --- kernel/src/filesystem/vfs.tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 2eec572..8e4cb70 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -187,7 +187,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS { REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); - auto img = vfs.open("/information/monkey_house/caretaker/../../../archiv/2024.img"); + auto img = vfs.open("/information/monkey_house/caretaker/../../../../../../archiv/2024.img"); REQUIRE(img != nullptr); auto dev_32 = vfs.open("/information/monkey_house/caretaker/../../../dev/ram32"); -- cgit v1.2.3 From 8a11512eb8030de09ed806d8b40b7f54c2f204ab Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 11 May 2026 14:48:46 +0200 Subject: Refactor get_full_path remove recursion --- kernel/src/filesystem/dentry.cpp | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index 1cf8730..a3bd7f4 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -39,20 +40,35 @@ namespace kernel::filesystem return m_name.view(); } - // NOLINTNEXTLINE(misc-no-recursion) auto dentry::get_full_path() const -> kstd::string { - if (m_parent) + if (m_name == "/") { - auto parent_path = m_parent->get_full_path(); - if (parent_path != "/") - { - parent_path += '/'; - } - return parent_path + m_name.view(); + return "/"; } - return m_name.view(); + kstd::vector components; + components.push_back(m_name.view()); + components.push_back("/"); + + auto parent = m_parent; + + while (parent && parent->m_name != "/") + { + components.push_back(parent->m_name.view()); + components.push_back("/"); + parent = parent->get_parent(); + } + + std::ranges::reverse(components); + + kstd::string full_path = ""; + for (auto const & view : components) + { + full_path += view; + } + + return full_path; } auto dentry::add_child(kstd::shared_ptr const & child) -> void -- cgit v1.2.3 From 7ea0aa798e3062dea20a317e2b19d7cf879611ca Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 11 May 2026 18:46:10 +0200 Subject: Refactor dentry --- kernel/include/kernel/filesystem/dentry.hpp | 2 +- kernel/src/filesystem/dentry.cpp | 40 +++++++++++++---------------- kernel/src/filesystem/dentry.tests.cpp | 15 +++-------- 3 files changed, 22 insertions(+), 35 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index bd62735..1366206 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -34,7 +34,7 @@ namespace kernel::filesystem @param inode The associated inode for this dentry. @param name The name of the dentry (optional). */ - dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & inode, std::string_view name = {}); + dentry(kstd::shared_ptr const & parent, kstd::shared_ptr const & inode, std::string_view name); /** @brief Get the associated inode. diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index a3bd7f4..7617b28 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -23,6 +23,10 @@ namespace kernel::filesystem { kapi::system::panic("[FILESYSTEM] dentry constructed with null inode."); } + if (m_name.empty()) + { + kapi::system::panic("[FILESYSTEM] dentry constructed with empty name."); + } } auto dentry::get_inode() const -> kstd::shared_ptr const & @@ -42,33 +46,25 @@ namespace kernel::filesystem auto dentry::get_full_path() const -> kstd::string { - if (m_name == "/") - { - return "/"; - } - - kstd::vector components; - components.push_back(m_name.view()); - components.push_back("/"); + kstd::string path = m_name; auto parent = m_parent; - - while (parent && parent->m_name != "/") - { - components.push_back(parent->m_name.view()); - components.push_back("/"); - parent = parent->get_parent(); - } - - std::ranges::reverse(components); - - kstd::string full_path = ""; - for (auto const & view : components) + while (parent) { - full_path += view; + auto parent_name = parent->m_name; + if (parent_name == "/") + { + path = "/" + path; + } + else + { + path = parent_name + "/" + path; + } + + parent = parent->m_parent; } - return full_path; + return path; } auto dentry::add_child(kstd::shared_ptr const & child) -> void diff --git a/kernel/src/filesystem/dentry.tests.cpp b/kernel/src/filesystem/dentry.tests.cpp index c42c405..200262a 100644 --- a/kernel/src/filesystem/dentry.tests.cpp +++ b/kernel/src/filesystem/dentry.tests.cpp @@ -13,7 +13,7 @@ SCENARIO("Dentry construction", "[filesystem][dentry]") GIVEN("A parent dentry and inode") { auto inode = kstd::make_shared(); - auto parent_dentry = kstd::make_shared(nullptr, inode); + auto parent_dentry = kstd::make_shared(nullptr, inode, "parent"); WHEN("constructing a dentry") { @@ -34,18 +34,9 @@ SCENARIO("Dentry construction", "[filesystem][dentry]") WHEN("constructing a dentry with an empty name") { - auto child_dentry = kernel::filesystem::dentry{parent_dentry, inode}; - THEN("the dentry has the correct parent and inode, and an empty name") { - REQUIRE(child_dentry.get_parent() == parent_dentry); - REQUIRE(child_dentry.get_inode() == inode); - REQUIRE(child_dentry.get_name().empty()); - } - - THEN("no flag is set") - { - REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE_THROWS_AS((kernel::filesystem::dentry{parent_dentry, inode, ""}), kernel::tests::cpu::halt); } } @@ -81,7 +72,7 @@ SCENARIO("Dentry child logic", "[filesystem][dentry]") GIVEN("A parent dentry and inode") { auto inode = kstd::make_shared(); - auto parent_dentry = kstd::make_shared(nullptr, inode); + auto parent_dentry = kstd::make_shared(nullptr, inode, "parent"); WHEN("adding child dentries") { -- cgit v1.2.3 From 7683d52861f05566a3b82e24484e367fcdc63ea8 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 11 May 2026 18:52:59 +0200 Subject: Add test for dentry get_full_path --- kernel/src/filesystem/dentry.tests.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'kernel') diff --git a/kernel/src/filesystem/dentry.tests.cpp b/kernel/src/filesystem/dentry.tests.cpp index 200262a..1a5a784 100644 --- a/kernel/src/filesystem/dentry.tests.cpp +++ b/kernel/src/filesystem/dentry.tests.cpp @@ -124,3 +124,27 @@ SCENARIO("Dentry Flag logic", "[filesystem][dentry]") } } } + +SCENARIO("Dentry path resolution", "[filesystem][dentry]") +{ + GIVEN("A dentry with a parent hierarchy") + { + auto root_inode = kstd::make_shared(); + auto root_dentry = kstd::make_shared(nullptr, root_inode, "/"); + + auto home_inode = kstd::make_shared(); + auto home_dentry = kstd::make_shared(root_dentry, home_inode, "home"); + root_dentry->add_child(home_dentry); + + auto user_inode = kstd::make_shared(); + auto user_dentry = kstd::make_shared(home_dentry, user_inode, "user"); + home_dentry->add_child(user_dentry); + + THEN("the full path is constructed correctly") + { + REQUIRE(root_dentry->get_full_path() == "/"); + REQUIRE(home_dentry->get_full_path() == "/home"); + REQUIRE(user_dentry->get_full_path() == "/home/user"); + } + } +} \ No newline at end of file -- cgit v1.2.3 From a4c9b9bdb768ce20c9f9eac353a34598e4a422a9 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 11 May 2026 18:54:27 +0200 Subject: Rename get_full_path to get_absolute_path --- kernel/include/kernel/filesystem/dentry.hpp | 2 +- kernel/src/filesystem/dentry.cpp | 2 +- kernel/src/filesystem/dentry.tests.cpp | 6 +++--- kernel/src/filesystem/vfs.cpp | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index 1366206..226f2b9 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -58,7 +58,7 @@ namespace kernel::filesystem @brief Get the full path of the dentry by traversing up to the root. @return The full path of the dentry. */ - [[nodiscard]] auto get_full_path() const -> kstd::string; + [[nodiscard]] auto get_absolute_path() const -> kstd::string; /** @brief Add a @p child dentry. diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index 7617b28..59fd89e 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -44,7 +44,7 @@ namespace kernel::filesystem return m_name.view(); } - auto dentry::get_full_path() const -> kstd::string + auto dentry::get_absolute_path() const -> kstd::string { kstd::string path = m_name; diff --git a/kernel/src/filesystem/dentry.tests.cpp b/kernel/src/filesystem/dentry.tests.cpp index 1a5a784..dd01394 100644 --- a/kernel/src/filesystem/dentry.tests.cpp +++ b/kernel/src/filesystem/dentry.tests.cpp @@ -142,9 +142,9 @@ SCENARIO("Dentry path resolution", "[filesystem][dentry]") THEN("the full path is constructed correctly") { - REQUIRE(root_dentry->get_full_path() == "/"); - REQUIRE(home_dentry->get_full_path() == "/home"); - REQUIRE(user_dentry->get_full_path() == "/home/user"); + REQUIRE(root_dentry->get_absolute_path() == "/"); + REQUIRE(home_dentry->get_absolute_path() == "/home"); + REQUIRE(user_dentry->get_absolute_path() == "/home/user"); } } } \ No newline at end of file diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 519550b..1410b2a 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -138,7 +138,7 @@ namespace kernel::filesystem auto vfs::do_mount_internal(kstd::shared_ptr const & mount_point_dentry, kstd::shared_ptr const & fs) -> void { - auto mount_path = mount_point_dentry->get_full_path(); + auto mount_path = mount_point_dentry->get_absolute_path(); // TODO BA-FS26 refactoring, implement dentry lookup to get the parent mount... auto parent_mount = m_mount_table.find_longest_prefix_mount(mount_path.view()); @@ -216,7 +216,7 @@ namespace kernel::filesystem } else if (next_dentry->has_flag(dentry::dentry_flags::mounted)) { - current_mount = m_mount_table.find_exact_mount(next_dentry->get_full_path().view()); + current_mount = m_mount_table.find_exact_mount(next_dentry->get_absolute_path().view()); if (!current_mount) { kapi::system::panic("[FILESYSTEM] mount for dentry with mounted flag not found."); -- cgit v1.2.3 From c958b72922b89fff35c0b8e0bbf21ad42a667022 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 11 May 2026 20:27:01 +0200 Subject: Remove unused include --- kernel/src/filesystem/dentry.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index 59fd89e..a77ce23 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include -- cgit v1.2.3 From df549fb7a3ed3ff9d675da6a90595c78bed7a1f8 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 10 May 2026 13:20:47 +0200 Subject: return const boot_module_registry reference --- kernel/kapi/boot_modules.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/kapi/boot_modules.cpp b/kernel/kapi/boot_modules.cpp index 1ad541b..5629b77 100644 --- a/kernel/kapi/boot_modules.cpp +++ b/kernel/kapi/boot_modules.cpp @@ -21,7 +21,7 @@ namespace kapi::boot_modules registry = new_registry; } - auto get_boot_module_registry() -> boot_module_registry & + auto get_boot_module_registry() -> boot_module_registry const & { if (!registry) { -- 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') 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 00aa2c8695b81944798010d81d600038e1f1ef3d Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 10 May 2026 19:08:07 +0200 Subject: remove mount_path from mount struct (retrieve path from m_mount_dentry) --- kernel/include/kernel/filesystem/mount.hpp | 8 +--- kernel/src/filesystem/mount.cpp | 14 ++++--- kernel/src/filesystem/mount.tests.cpp | 4 +- kernel/src/filesystem/mount_table.cpp | 7 +++- kernel/src/filesystem/mount_table.tests.cpp | 60 ++++++++++++++++++----------- kernel/src/filesystem/vfs.cpp | 7 +++- 6 files changed, 59 insertions(+), 41 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index 72855a0..102f660 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -7,8 +7,6 @@ #include #include -#include - namespace kernel::filesystem { /** @@ -27,8 +25,7 @@ namespace kernel::filesystem @param parent_mount The parent mount that this mount is attached beneath. */ mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & root_dentry, - kstd::shared_ptr const & fs, std::string_view mount_path, - kstd::shared_ptr const & parent_mount); + kstd::shared_ptr const & fs, kstd::shared_ptr const & parent_mount); /** @brief Get the dentry where the filesystem is mounted. @@ -48,7 +45,7 @@ namespace kernel::filesystem /** @brief Get the path at which the filesystem is mounted. */ - [[nodiscard]] auto get_mount_path() const -> std::string_view; + [[nodiscard]] auto get_mount_path() const -> kstd::string; /** @brief Get the parent mount that this mount was attached beneath. @@ -56,7 +53,6 @@ namespace kernel::filesystem [[nodiscard]] auto get_parent_mount() const -> kstd::shared_ptr const &; private: - kstd::string m_mount_path; kstd::shared_ptr m_mount_dentry; kstd::shared_ptr m_root_dentry; kstd::shared_ptr m_filesystem{}; diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index 67450b7..c474c8e 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -13,10 +13,8 @@ namespace kernel::filesystem { mount::mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & root_dentry, - kstd::shared_ptr const & fs, std::string_view mount_path, - kstd::shared_ptr const & parent_mount) - : m_mount_path(mount_path) - , m_mount_dentry(mount_dentry) + kstd::shared_ptr const & fs, kstd::shared_ptr const & parent_mount) + : m_mount_dentry(mount_dentry) , m_root_dentry(root_dentry) , m_filesystem(fs) , m_parent_mount(parent_mount) @@ -42,9 +40,13 @@ namespace kernel::filesystem return m_root_dentry; } - auto mount::get_mount_path() const -> std::string_view + auto mount::get_mount_path() const -> kstd::string { - return m_mount_path.view(); + if (m_mount_dentry) + { + return m_mount_dentry->get_full_path(); + } + return "/"; } auto mount::get_parent_mount() const -> kstd::shared_ptr const & diff --git a/kernel/src/filesystem/mount.tests.cpp b/kernel/src/filesystem/mount.tests.cpp index d630464..4b44983 100644 --- a/kernel/src/filesystem/mount.tests.cpp +++ b/kernel/src/filesystem/mount.tests.cpp @@ -21,7 +21,7 @@ SCENARIO("Mount construction", "[filesystem][mount]") WHEN("constructing a mount with the filesystem and root dentry") { - auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, "/", nullptr}; + auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr}; THEN("the mount has the correct filesystem, root dentry, mount dentry, and mount path") { @@ -41,7 +41,7 @@ SCENARIO("Mount construction", "[filesystem][mount]") { THEN("the constructor panics") { - REQUIRE_THROWS_AS((kernel::filesystem::mount{root_dentry, root_dentry, nullptr, "/", nullptr}), + REQUIRE_THROWS_AS((kernel::filesystem::mount{root_dentry, root_dentry, nullptr, nullptr}), kernel::tests::cpu::halt); } } diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 965e83b..b67e05c 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -37,7 +37,9 @@ namespace kernel::filesystem kstd::vector> const & mounts) -> bool { return std::ranges::none_of(mounts, [&](auto const & other) { - return other != candidate && is_strict_prefix(other->get_mount_path(), candidate->get_mount_path()) && + // TODO BA-FS26 really correct? + return other != candidate && + is_strict_prefix(other->get_mount_path().view(), candidate->get_mount_path().view()) && !is_descendant_of(candidate, other); }); } @@ -80,6 +82,7 @@ namespace kernel::filesystem return operation_result::removed; } + // TODO BA-FS26 remove? auto mount_table::find_longest_prefix_mount(std::string_view path) const -> kstd::shared_ptr { kstd::shared_ptr mount_with_longest_prefix = nullptr; @@ -90,7 +93,7 @@ namespace kernel::filesystem auto mp = mount->get_mount_path(); // /a/b/c should match /a/b but not /a/bb or /a/b/c/d, / should match everything - bool is_prefix = path.starts_with(mp) && (mp == "/" || path.size() == mp.size() || path[mp.size()] == '/'); + bool is_prefix = path.starts_with(mp.view()) && (mp == "/" || path.size() == mp.size() || path[mp.size()] == '/'); bool visible = is_visible_mount(mount, m_mounts); if (is_prefix && visible && mp.size() >= best_len) diff --git a/kernel/src/filesystem/mount_table.tests.cpp b/kernel/src/filesystem/mount_table.tests.cpp index efacdfe..732d32f 100644 --- a/kernel/src/filesystem/mount_table.tests.cpp +++ b/kernel/src/filesystem/mount_table.tests.cpp @@ -40,22 +40,26 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] kernel::filesystem::mount_table table; auto fs1 = kstd::make_shared(); - auto root_inode1 = kstd::make_shared(); - auto root_dentry1 = kstd::make_shared(nullptr, root_inode1, "/"); - auto mount1 = kstd::make_shared(root_dentry1, root_dentry1, fs1, "/", nullptr); + auto root_dentry1 = kstd::make_shared( + nullptr, kstd::make_shared(), "/"); + auto mount_dentry1 = kstd::make_shared( + nullptr, kstd::make_shared(), "/"); + auto mount1 = kstd::make_shared(mount_dentry1, root_dentry1, fs1, nullptr); auto fs2 = kstd::make_shared(); - auto root_inode2 = kstd::make_shared(); - auto root_dentry2 = kstd::make_shared(nullptr, root_inode2, "/"); - auto mount2 = kstd::make_shared(root_dentry1, root_dentry2, fs2, "/mnt", nullptr); + auto root_dentry2 = kstd::make_shared( + nullptr, kstd::make_shared(), "/"); + auto mount_dentry2 = kstd::make_shared( + nullptr, kstd::make_shared(), "/mnt"); + auto mount2 = kstd::make_shared(mount_dentry2, root_dentry2, fs2, nullptr); table.add_mount(mount1); table.add_mount(mount2); THEN("dentry flags are set correctly for mounted dentries") { - REQUIRE(root_dentry1->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); - REQUIRE_FALSE(root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE(mount_dentry1->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE(mount_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); } THEN("finding mounts by longest prefix returns the correct mount") @@ -97,14 +101,18 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] kernel::filesystem::mount_table table; auto fs1 = kstd::make_shared(); - auto root_inode1 = kstd::make_shared(); - auto root_dentry1 = kstd::make_shared(nullptr, root_inode1, "/"); - auto mount1 = kstd::make_shared(root_dentry1, root_dentry1, fs1, "/", nullptr); + auto root_dentry1 = kstd::make_shared( + nullptr, kstd::make_shared(), "/"); + auto mount_dentry1 = kstd::make_shared( + nullptr, kstd::make_shared(), "/"); + auto mount1 = kstd::make_shared(mount_dentry1, root_dentry1, fs1, nullptr); auto fs2 = kstd::make_shared(); - auto root_inode2 = kstd::make_shared(); - auto root_dentry2 = kstd::make_shared(nullptr, root_inode2, "/"); - auto mount2 = kstd::make_shared(root_dentry1, root_dentry2, fs2, "/", mount1); + auto root_dentry2 = kstd::make_shared( + nullptr, kstd::make_shared(), "/"); + auto mount_dentry2 = kstd::make_shared( + nullptr, kstd::make_shared(), "/"); + auto mount2 = kstd::make_shared(mount_dentry2, root_dentry2, fs2, nullptr); table.add_mount(mount1); table.add_mount(mount2); @@ -136,19 +144,25 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] kernel::filesystem::mount_table table; auto fs1 = kstd::make_shared(); - auto root_inode1 = kstd::make_shared(); - auto root_dentry1 = kstd::make_shared(nullptr, root_inode1, "/"); - auto mount1 = kstd::make_shared(root_dentry1, root_dentry1, fs1, "/", nullptr); + auto root_dentry1 = kstd::make_shared( + nullptr, kstd::make_shared(), "/"); + auto mount_dentry1 = kstd::make_shared( + nullptr, kstd::make_shared(), "/"); + auto mount1 = kstd::make_shared(mount_dentry1, root_dentry1, fs1, nullptr); auto fs2 = kstd::make_shared(); - auto root_inode2 = kstd::make_shared(); - auto root_dentry2 = kstd::make_shared(nullptr, root_inode2, "/"); - auto mount2 = kstd::make_shared(root_dentry1, root_dentry2, fs2, "/mnt", mount1); + auto root_dentry2 = kstd::make_shared( + nullptr, kstd::make_shared(), "/"); + auto mount_dentry2 = kstd::make_shared( + mount_dentry1, kstd::make_shared(), "mnt"); + auto mount2 = kstd::make_shared(mount_dentry2, root_dentry2, fs2, mount1); auto fs3 = kstd::make_shared(); - auto root_inode3 = kstd::make_shared(); - auto root_dentry3 = kstd::make_shared(nullptr, root_inode3, "/"); - auto mount3 = kstd::make_shared(root_dentry2, root_dentry3, fs3, "/mnt/submnt", mount2); + auto root_dentry3 = kstd::make_shared( + nullptr, kstd::make_shared(), "/"); + auto mount_dentry3 = kstd::make_shared( + mount_dentry2, kstd::make_shared(), "submnt"); + auto mount3 = kstd::make_shared(mount_dentry3, root_dentry3, fs3, mount2); table.add_mount(mount1); table.add_mount(mount2); diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 1410b2a..ea060a9 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -45,7 +45,7 @@ namespace kernel::filesystem root_fs->mount(nullptr); auto root_fs_root_dentry = kstd::make_shared(nullptr, root_fs->root_inode(), "/"); - m_mount_table.add_mount(kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, "/", nullptr)); + m_mount_table.add_mount(kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, nullptr)); // Mount devfs at /dev in rootfs (temporary, will be shadowed) auto device_fs = kstd::make_shared(); @@ -142,9 +142,12 @@ namespace kernel::filesystem // TODO BA-FS26 refactoring, implement dentry lookup to get the parent mount... auto parent_mount = m_mount_table.find_longest_prefix_mount(mount_path.view()); + // auto parent_mount_dentry = mount_point_dentry->get_parent_mounted_dentry(); + // auto parent_mount = m_mount_table.find_exact_mount(parent_mount_dentry->get_full_path()); + auto new_fs_root = kstd::make_shared(mount_point_dentry->get_parent(), fs->root_inode(), mount_point_dentry->get_name()); - auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, mount_path.view(), parent_mount); + auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, parent_mount); m_mount_table.add_mount(new_mount); } -- cgit v1.2.3 From feab4cd81f2bbc89e55353a54df2575b9c21b514 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Sun, 10 May 2026 20:07:51 +0200 Subject: Add method that returns the next ancestor with mount flag set --- kernel/include/kernel/filesystem/dentry.hpp | 6 ++++++ kernel/src/filesystem/dentry.cpp | 10 ++++++++++ 2 files changed, 16 insertions(+) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index 226f2b9..1d99a25 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -60,6 +60,12 @@ namespace kernel::filesystem */ [[nodiscard]] auto get_absolute_path() const -> kstd::string; + /** + @brief traverse parent dentries until dentry with mount flag is found. + @return The found dentry. + */ + [[nodiscard]] auto get_ancestor_with_mount_flag() const -> kstd::shared_ptr; + /** @brief Add a @p child dentry. @param child The child dentry to add. diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index a77ce23..6945a27 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -66,6 +66,16 @@ namespace kernel::filesystem return path; } + auto dentry::get_ancestor_with_mount_flag() const -> kstd::shared_ptr + { + auto parent = m_parent; + while (parent && !parent->has_flag(dentry_flags::mounted)) + { + parent = parent->get_parent(); + } + return parent; + } + auto dentry::add_child(kstd::shared_ptr const & child) -> void { m_children.push_back(child); -- cgit v1.2.3 From 85fd2e3b4da7d84a9357b35bde740b780fe0cb72 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Sun, 10 May 2026 21:49:20 +0200 Subject: Rename root_dentry() to get_root_dentry() --- kernel/include/kernel/filesystem/mount.hpp | 2 +- kernel/src/filesystem/mount.cpp | 2 +- kernel/src/filesystem/mount.tests.cpp | 2 +- kernel/src/filesystem/vfs.cpp | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index 102f660..af5d08b 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -35,7 +35,7 @@ namespace kernel::filesystem /** @brief Get the root dentry of the mounted filesystem. */ - [[nodiscard]] auto root_dentry() const -> kstd::shared_ptr const &; + [[nodiscard]] auto get_root_dentry() const -> kstd::shared_ptr const &; /** @brief Get the filesystem instance being mounted. diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index c474c8e..ebacf32 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -35,7 +35,7 @@ namespace kernel::filesystem return m_filesystem; } - auto mount::root_dentry() const -> kstd::shared_ptr const & + auto mount::get_root_dentry() const -> kstd::shared_ptr const & { return m_root_dentry; } diff --git a/kernel/src/filesystem/mount.tests.cpp b/kernel/src/filesystem/mount.tests.cpp index 4b44983..58e9bab 100644 --- a/kernel/src/filesystem/mount.tests.cpp +++ b/kernel/src/filesystem/mount.tests.cpp @@ -26,7 +26,7 @@ SCENARIO("Mount construction", "[filesystem][mount]") THEN("the mount has the correct filesystem, root dentry, mount dentry, and mount path") { REQUIRE(mount.get_filesystem() == fs); - REQUIRE(mount.root_dentry() == root_dentry); + REQUIRE(mount.get_root_dentry() == root_dentry); REQUIRE(mount.get_mount_dentry() == root_dentry); REQUIRE(mount.get_mount_path() == "/"); } diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index ea060a9..2b8c3bd 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -164,7 +164,7 @@ namespace kernel::filesystem kapi::system::panic("[FILESYSTEM] no root mount found."); } - auto current_dentry = current_mount->root_dentry(); + auto current_dentry = current_mount->get_root_dentry(); auto path_parts = path::split(path); kstd::vector path_parts_vector(path_parts.begin(), path_parts.end()); @@ -186,7 +186,7 @@ namespace kernel::filesystem { auto parent_dentry = current_dentry->get_parent(); - if (current_dentry == current_mount->root_dentry()) + if (current_dentry == current_mount->get_root_dentry()) { if (current_mount->get_mount_path() == "/") { @@ -225,7 +225,7 @@ namespace kernel::filesystem kapi::system::panic("[FILESYSTEM] mount for dentry with mounted flag not found."); } - next_dentry = current_mount->root_dentry(); + next_dentry = current_mount->get_root_dentry(); } if (next_dentry->get_inode()->is_symbolic_link()) @@ -248,7 +248,7 @@ namespace kernel::filesystem if (path::is_valid_absolute_path(symbolic_link_path)) { current_mount = m_mount_table.find_exact_mount("/"); - current_dentry = current_mount->root_dentry(); + current_dentry = current_mount->get_root_dentry(); } continue; } -- cgit v1.2.3 From 636551d03ac725e015dd88631d531c02067ed3de Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Sun, 10 May 2026 21:51:11 +0200 Subject: Create first draft of get_parent_mount without find_longest_prefix_mount --- kernel/src/filesystem/vfs.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 2b8c3bd..e7f9015 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -138,13 +138,13 @@ namespace kernel::filesystem auto vfs::do_mount_internal(kstd::shared_ptr const & mount_point_dentry, kstd::shared_ptr const & fs) -> void { - auto mount_path = mount_point_dentry->get_absolute_path(); - // TODO BA-FS26 refactoring, implement dentry lookup to get the parent mount... - auto parent_mount = m_mount_table.find_longest_prefix_mount(mount_path.view()); - - // auto parent_mount_dentry = mount_point_dentry->get_parent_mounted_dentry(); - // auto parent_mount = m_mount_table.find_exact_mount(parent_mount_dentry->get_full_path()); - + auto parent_mount_dentry = mount_point_dentry->get_ancestor_with_mount_flag(); + kstd::shared_ptr parent_mount = nullptr; + if (parent_mount_dentry) + { + parent_mount = m_mount_table.find_exact_mount(parent_mount_dentry->get_absolute_path().view()); + } + auto new_fs_root = kstd::make_shared(mount_point_dentry->get_parent(), fs->root_inode(), mount_point_dentry->get_name()); auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, parent_mount); -- cgit v1.2.3 From 763227e31adf924a5dfe3139db158e26162294a0 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Sun, 10 May 2026 21:58:54 +0200 Subject: Remove find_longest_prefix_mount --- kernel/include/kernel/filesystem/mount_table.hpp | 7 ----- kernel/src/filesystem/mount_table.cpp | 24 --------------- kernel/src/filesystem/mount_table.tests.cpp | 37 ------------------------ 3 files changed, 68 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount_table.hpp b/kernel/include/kernel/filesystem/mount_table.hpp index 8e57d9e..59b9503 100644 --- a/kernel/include/kernel/filesystem/mount_table.hpp +++ b/kernel/include/kernel/filesystem/mount_table.hpp @@ -38,13 +38,6 @@ namespace kernel::filesystem */ [[nodiscard]] auto remove_mount(std::string_view path) -> operation_result; - /** - @brief Finds the mount with the longest prefix matching the given @p path. - @param path The path to match against the mount paths in the table. - @return A pointer to the mount with the longest matching prefix, or a null pointer if no mount matches the path. - */ - [[nodiscard]] auto find_longest_prefix_mount(std::string_view path) const -> kstd::shared_ptr; - /** @brief Finds the mount with the exact mount path matching the given @p path. @param path The path to match against the mount paths in the table. diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index b67e05c..30a94f4 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -82,30 +82,6 @@ namespace kernel::filesystem return operation_result::removed; } - // TODO BA-FS26 remove? - auto mount_table::find_longest_prefix_mount(std::string_view path) const -> kstd::shared_ptr - { - kstd::shared_ptr mount_with_longest_prefix = nullptr; - std::size_t best_len = 0; - - for (auto const & mount : m_mounts) - { - auto mp = mount->get_mount_path(); - - // /a/b/c should match /a/b but not /a/bb or /a/b/c/d, / should match everything - bool is_prefix = path.starts_with(mp.view()) && (mp == "/" || path.size() == mp.size() || path[mp.size()] == '/'); - bool visible = is_visible_mount(mount, m_mounts); - - if (is_prefix && visible && mp.size() >= best_len) - { - mount_with_longest_prefix = mount; - best_len = mp.size(); - } - } - - return mount_with_longest_prefix; - } - auto mount_table::find_exact_mount(std::string_view path) const -> kstd::shared_ptr { auto reversed_mounts = std::ranges::reverse_view(m_mounts); diff --git a/kernel/src/filesystem/mount_table.tests.cpp b/kernel/src/filesystem/mount_table.tests.cpp index 732d32f..80772ca 100644 --- a/kernel/src/filesystem/mount_table.tests.cpp +++ b/kernel/src/filesystem/mount_table.tests.cpp @@ -19,12 +19,6 @@ SCENARIO("Mount table construction", "[filesystem][mount_table]") { kernel::filesystem::mount_table table; - THEN("finding any mount returns null") - { - REQUIRE(table.find_longest_prefix_mount("/") == nullptr); - REQUIRE(table.find_longest_prefix_mount("/any/path") == nullptr); - } - THEN("removing any mount returns mount_not_found") { REQUIRE(table.remove_mount("/") == kernel::filesystem::mount_table::operation_result::mount_not_found); @@ -62,15 +56,6 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] REQUIRE(mount_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); } - THEN("finding mounts by longest prefix returns the correct mount") - { - REQUIRE(table.find_longest_prefix_mount("/") == mount1); - REQUIRE(table.find_longest_prefix_mount("/file") == mount1); - REQUIRE(table.find_longest_prefix_mount("/mnt") == mount2); - REQUIRE(table.find_longest_prefix_mount("/mnt/file") == mount2); - REQUIRE(table.find_longest_prefix_mount("/other") == mount1); - } - THEN("finding mounts by exact valid path returns the correct mount") { REQUIRE(table.find_exact_mount("/") == mount1); @@ -87,7 +72,6 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] { REQUIRE(table.remove_mount("/mnt") == kernel::filesystem::mount_table::operation_result::removed); REQUIRE_FALSE(root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); - REQUIRE(table.find_longest_prefix_mount("/mnt") == mount1); } THEN("removing a mount that does not exist returns mount_not_found") @@ -117,15 +101,6 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] table.add_mount(mount1); table.add_mount(mount2); - THEN("finding mounts by longest prefix returns the correct mount") - { - REQUIRE(table.find_longest_prefix_mount("/") == mount2); - REQUIRE(table.find_longest_prefix_mount("/file") == mount2); - REQUIRE(table.find_longest_prefix_mount("/mnt") == mount2); - REQUIRE(table.find_longest_prefix_mount("/mnt/file") == mount2); - REQUIRE(table.find_longest_prefix_mount("/other") == mount2); - } - THEN("finding mounts by exact valid path returns the correct mount") { REQUIRE(table.find_exact_mount("/") == mount2); @@ -135,7 +110,6 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] { REQUIRE(table.remove_mount("/") == kernel::filesystem::mount_table::operation_result::removed); REQUIRE_FALSE(root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); - REQUIRE(table.find_longest_prefix_mount("/") == mount1); } } @@ -168,16 +142,6 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] table.add_mount(mount2); table.add_mount(mount3); - THEN("finding mounts by path returns the correct mount based on longest prefix") - { - REQUIRE(table.find_longest_prefix_mount("/") == mount1); - REQUIRE(table.find_longest_prefix_mount("/file") == mount1); - REQUIRE(table.find_longest_prefix_mount("/mnt") == mount2); - REQUIRE(table.find_longest_prefix_mount("/mnt/file") == mount2); - REQUIRE(table.find_longest_prefix_mount("/mnt/submnt") == mount3); - REQUIRE(table.find_longest_prefix_mount("/other") == mount1); - } - THEN("removing a mount with child mounts returns has_child_mounts") { REQUIRE(table.remove_mount("/") == kernel::filesystem::mount_table::operation_result::has_child_mounts); @@ -188,7 +152,6 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] { REQUIRE(table.remove_mount("/mnt/submnt") == kernel::filesystem::mount_table::operation_result::removed); REQUIRE_FALSE(root_dentry3->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); - REQUIRE(table.find_longest_prefix_mount("/mnt/submnt") == mount2); } } } -- cgit v1.2.3 From 5d72c256d4e2b8a9d2fd70e5a27e883a0f733e50 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 11 May 2026 20:48:03 +0200 Subject: Add is_mount_root flag to dentry and use in find_mount_root_dentry --- kernel/include/kernel/filesystem/dentry.hpp | 7 ++++--- kernel/src/filesystem/dentry.cpp | 4 ++-- kernel/src/filesystem/dentry.tests.cpp | 14 +++++++------- kernel/src/filesystem/mount_table.cpp | 9 ++++++--- kernel/src/filesystem/mount_table.tests.cpp | 10 +++++----- kernel/src/filesystem/vfs.cpp | 4 ++-- 6 files changed, 26 insertions(+), 22 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index 1d99a25..7eef693 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -24,7 +24,8 @@ namespace kernel::filesystem */ enum class dentry_flags : uint32_t { - mounted = 1 << 15 + is_mount_point = 1 << 0, + is_mount_root = 1 << 1, }; /** @@ -61,10 +62,10 @@ namespace kernel::filesystem [[nodiscard]] auto get_absolute_path() const -> kstd::string; /** - @brief traverse parent dentries until dentry with mount flag is found. + @brief traverse parent dentries until dentry with is_mount_root flag is found. @return The found dentry. */ - [[nodiscard]] auto get_ancestor_with_mount_flag() const -> kstd::shared_ptr; + [[nodiscard]] auto find_mount_root_dentry() const -> kstd::shared_ptr; /** @brief Add a @p child dentry. diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index 6945a27..c21771b 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -66,10 +66,10 @@ namespace kernel::filesystem return path; } - auto dentry::get_ancestor_with_mount_flag() const -> kstd::shared_ptr + auto dentry::find_mount_root_dentry() const -> kstd::shared_ptr { auto parent = m_parent; - while (parent && !parent->has_flag(dentry_flags::mounted)) + while (parent && !parent->has_flag(dentry_flags::is_mount_root)) { parent = parent->get_parent(); } diff --git a/kernel/src/filesystem/dentry.tests.cpp b/kernel/src/filesystem/dentry.tests.cpp index dd01394..e9ecbc8 100644 --- a/kernel/src/filesystem/dentry.tests.cpp +++ b/kernel/src/filesystem/dentry.tests.cpp @@ -28,7 +28,7 @@ SCENARIO("Dentry construction", "[filesystem][dentry]") THEN("no flag is set") { - REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::is_mount_point)); } } @@ -53,7 +53,7 @@ SCENARIO("Dentry construction", "[filesystem][dentry]") THEN("no flag is set") { - REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE_FALSE(child_dentry.has_flag(kernel::filesystem::dentry::dentry_flags::is_mount_point)); } } @@ -104,22 +104,22 @@ SCENARIO("Dentry Flag logic", "[filesystem][dentry]") WHEN("setting a flag") { - dentry.set_flag(kernel::filesystem::dentry::dentry_flags::mounted); + dentry.set_flag(kernel::filesystem::dentry::dentry_flags::is_mount_point); THEN("the flag is set") { - REQUIRE(dentry.has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE(dentry.has_flag(kernel::filesystem::dentry::dentry_flags::is_mount_point)); } } WHEN("unsetting a flag") { - dentry.set_flag(kernel::filesystem::dentry::dentry_flags::mounted); - dentry.unset_flag(kernel::filesystem::dentry::dentry_flags::mounted); + dentry.set_flag(kernel::filesystem::dentry::dentry_flags::is_mount_point); + dentry.unset_flag(kernel::filesystem::dentry::dentry_flags::is_mount_point); THEN("the flag is unset") { - REQUIRE_FALSE(dentry.has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE_FALSE(dentry.has_flag(kernel::filesystem::dentry::dentry_flags::is_mount_point)); } } } diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 30a94f4..74c18ca 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include @@ -56,7 +55,11 @@ namespace kernel::filesystem m_mounts.push_back(mount); if (auto mount_dentry = mount->get_mount_dentry()) { - mount_dentry->set_flag(dentry::dentry_flags::mounted); + mount_dentry->set_flag(dentry::dentry_flags::is_mount_point); + } + if (auto root_dentry = mount->get_root_dentry()) + { + root_dentry->set_flag(dentry::dentry_flags::is_mount_root); } } @@ -77,7 +80,7 @@ namespace kernel::filesystem return operation_result::has_child_mounts; } - mount->get_mount_dentry()->unset_flag(dentry::dentry_flags::mounted); + mount->get_mount_dentry()->unset_flag(dentry::dentry_flags::is_mount_point); m_mounts.erase(std::ranges::find(m_mounts, mount)); return operation_result::removed; } diff --git a/kernel/src/filesystem/mount_table.tests.cpp b/kernel/src/filesystem/mount_table.tests.cpp index 80772ca..4ae8711 100644 --- a/kernel/src/filesystem/mount_table.tests.cpp +++ b/kernel/src/filesystem/mount_table.tests.cpp @@ -52,8 +52,8 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("dentry flags are set correctly for mounted dentries") { - REQUIRE(mount_dentry1->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); - REQUIRE(mount_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE(mount_dentry1->has_flag(kernel::filesystem::dentry::dentry_flags::is_mount_point)); + REQUIRE(mount_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::is_mount_point)); } THEN("finding mounts by exact valid path returns the correct mount") @@ -71,7 +71,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("removing a mount that has no child mounts succeeds") { REQUIRE(table.remove_mount("/mnt") == kernel::filesystem::mount_table::operation_result::removed); - REQUIRE_FALSE(root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE_FALSE(root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::is_mount_point)); } THEN("removing a mount that does not exist returns mount_not_found") @@ -109,7 +109,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("removing the topmost mount with the same path succeeds") { REQUIRE(table.remove_mount("/") == kernel::filesystem::mount_table::operation_result::removed); - REQUIRE_FALSE(root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE_FALSE(root_dentry2->has_flag(kernel::filesystem::dentry::dentry_flags::is_mount_point)); } } @@ -151,7 +151,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("removing a leaf mount succeeds") { REQUIRE(table.remove_mount("/mnt/submnt") == kernel::filesystem::mount_table::operation_result::removed); - REQUIRE_FALSE(root_dentry3->has_flag(kernel::filesystem::dentry::dentry_flags::mounted)); + REQUIRE_FALSE(root_dentry3->has_flag(kernel::filesystem::dentry::dentry_flags::is_mount_point)); } } } diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index e7f9015..ee7c262 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -138,7 +138,7 @@ namespace kernel::filesystem auto vfs::do_mount_internal(kstd::shared_ptr const & mount_point_dentry, kstd::shared_ptr const & fs) -> void { - auto parent_mount_dentry = mount_point_dentry->get_ancestor_with_mount_flag(); + auto parent_mount_dentry = mount_point_dentry->find_mount_root_dentry(); kstd::shared_ptr parent_mount = nullptr; if (parent_mount_dentry) { @@ -217,7 +217,7 @@ namespace kernel::filesystem next_dentry = kstd::make_shared(current_dentry, found_inode, part.view()); current_dentry->add_child(next_dentry); } - else if (next_dentry->has_flag(dentry::dentry_flags::mounted)) + else if (next_dentry->has_flag(dentry::dentry_flags::is_mount_point)) { current_mount = m_mount_table.find_exact_mount(next_dentry->get_absolute_path().view()); if (!current_mount) -- cgit v1.2.3 From 5bac7cc7cc37d137b633afd3910f251a22818b80 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 11 May 2026 22:49:22 +0200 Subject: fix build after rebase --- kernel/src/filesystem/mount.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index ebacf32..749c86a 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -44,7 +44,7 @@ namespace kernel::filesystem { if (m_mount_dentry) { - return m_mount_dentry->get_full_path(); + return m_mount_dentry->get_absolute_path(); } return "/"; } -- cgit v1.2.3 From cb86b1fdb4656d37937a27343a4971ee5896bd3a Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 12 May 2026 08:51:17 +0200 Subject: remove unused include --- kernel/src/main.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index bfb731a..22d2b1e 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,6 +1,4 @@ #include -#include -#include #include #include #include @@ -15,7 +13,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3 From ac5213633721fcf0e72da814d7ef70c51090c3f9 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 12 May 2026 08:51:49 +0200 Subject: refactoring, simplify code --- kernel/src/filesystem/mount_table.cpp | 51 +++++++---------------------------- 1 file changed, 10 insertions(+), 41 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 74c18ca..daef93e 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -12,38 +12,6 @@ namespace kernel::filesystem { - namespace - { - auto is_descendant_of(kstd::shared_ptr const & candidate, kstd::shared_ptr const & ancestor) -> bool - { - for (auto current = candidate; current; current = current->get_parent_mount()) - { - if (current == ancestor) - { - return true; - } - } - - return false; - } - - auto is_strict_prefix(std::string_view prefix, std::string_view path) -> bool - { - return prefix != "/" && path.starts_with(prefix) && path.size() > prefix.size() && path[prefix.size()] == '/'; - } - - auto is_visible_mount(kstd::shared_ptr const & candidate, - kstd::vector> const & mounts) -> bool - { - return std::ranges::none_of(mounts, [&](auto const & other) { - // TODO BA-FS26 really correct? - return other != candidate && - is_strict_prefix(other->get_mount_path().view(), candidate->get_mount_path().view()) && - !is_descendant_of(candidate, other); - }); - } - } // namespace - auto mount_table::has_child_mounts(kstd::shared_ptr const & parent_mount) const -> bool { return std::ranges::any_of( @@ -53,6 +21,7 @@ namespace kernel::filesystem void mount_table::add_mount(kstd::shared_ptr const & mount) { m_mounts.push_back(mount); + if (auto mount_dentry = mount->get_mount_dentry()) { mount_dentry->set_flag(dentry::dentry_flags::is_mount_point); @@ -65,11 +34,11 @@ namespace kernel::filesystem auto mount_table::remove_mount(std::string_view path) -> operation_result { - auto mount_it = std::ranges::find_if(std::ranges::reverse_view(m_mounts), [&](auto const & mount) { - return mount->get_mount_path() == path && is_visible_mount(mount, m_mounts); - }); + auto mount_range = + std::ranges::find_last_if(m_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }); + auto mount_it = mount_range.begin(); - if (mount_it == std::ranges::reverse_view(m_mounts).end()) + if (mount_it == m_mounts.end()) { return operation_result::mount_not_found; } @@ -81,15 +50,15 @@ namespace kernel::filesystem } mount->get_mount_dentry()->unset_flag(dentry::dentry_flags::is_mount_point); - m_mounts.erase(std::ranges::find(m_mounts, mount)); + m_mounts.erase(mount_it); return operation_result::removed; } auto mount_table::find_exact_mount(std::string_view path) const -> kstd::shared_ptr { - auto reversed_mounts = std::ranges::reverse_view(m_mounts); - auto mount_it = - std::ranges::find_if(reversed_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }); - return (mount_it != reversed_mounts.end()) ? *mount_it : nullptr; + auto mount_range = + std::ranges::find_last_if(m_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }); + auto mount_it = mount_range.begin(); + return (mount_it != m_mounts.end()) ? *mount_it : nullptr; } } // namespace kernel::filesystem \ No newline at end of file -- cgit v1.2.3 From 91821da0110e05724640903434c3d85fc3d02466 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Tue, 12 May 2026 12:00:40 +0200 Subject: if the boot_root_fs contains a /dev directory, vfs mounts the devfs onto the existing directory --- kernel/include/kernel/filesystem/vfs.hpp | 3 ++ kernel/src/filesystem/vfs.cpp | 40 +++++++++++++++------- kernel/src/filesystem/vfs.tests.cpp | 17 +++++++++ .../filesystem/test_assets/ext2_2KB_fs.img | 2 +- 4 files changed, 48 insertions(+), 14 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 7e66fb7..b5053a2 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -1,6 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP #define TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP +#include "kernel/filesystem/devfs/filesystem.hpp" #include #include #include @@ -80,6 +81,8 @@ namespace kernel::filesystem auto do_mount_internal(kstd::shared_ptr const & mount_point_dentry, kstd::shared_ptr const & fs) -> void; + auto graft_persistent_device_fs(kstd::shared_ptr const & device_fs) -> void; + mount_table m_mount_table; }; } // namespace kernel::filesystem diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index ee7c262..535f898 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -41,36 +41,35 @@ namespace kernel::filesystem auto vfs::init_internal() -> void { + // mount rootfs at / auto root_fs = kstd::make_shared(); root_fs->mount(nullptr); auto root_fs_root_dentry = kstd::make_shared(nullptr, root_fs->root_inode(), "/"); m_mount_table.add_mount(kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, nullptr)); - // Mount devfs at /dev in rootfs (temporary, will be shadowed) + // mount devfs at /dev (inside rootfs, temporary, will be shadowed) auto device_fs = kstd::make_shared(); device_fs->mount(nullptr); - auto dev_mount_point_dentry = resolve_path("/dev"); - if (!dev_mount_point_dentry) + + if (auto dev_mount_point_dentry = resolve_path("/dev")) + { + do_mount_internal(dev_mount_point_dentry, device_fs); + } + else { kapi::system::panic("[FILESYSTEM] failed to resolve /dev for initial devfs mount."); } - do_mount_internal(dev_mount_point_dentry, device_fs); - // Mount boot filesystem at / (will shadow rootfs) + // mount boot fs at / (shadows rootfs), re-graft devfs if (auto boot_device_dentry = resolve_path("/dev/ram0")) { if (auto boot_root_fs = kernel::filesystem::filesystem::probe_and_mount(boot_device_dentry->get_inode())) { - do_mount_internal(root_fs_root_dentry, boot_root_fs); - - // Resolve / to get the boot root dentry - if (auto boot_root_dentry = resolve_path("/")) + if (auto root_dentry = resolve_path("/")) { - auto dev_dentry = kstd::make_shared(boot_root_dentry, device_fs->root_inode(), "dev"); - boot_root_dentry->add_child(dev_dentry); - - do_mount_internal(dev_dentry, device_fs); + do_mount_internal(root_dentry, boot_root_fs); + graft_persistent_device_fs(device_fs); } } } @@ -151,6 +150,21 @@ namespace kernel::filesystem m_mount_table.add_mount(new_mount); } + auto vfs::graft_persistent_device_fs(kstd::shared_ptr const & device_fs) -> void + { + if (auto new_root_dentry = resolve_path("/")) + { + auto dev_dentry = new_root_dentry->find_child("dev"); + if (!dev_dentry) + { + dev_dentry = kstd::make_shared(new_root_dentry, device_fs->root_inode(), "dev"); + new_root_dentry->add_child(dev_dentry); + } + + do_mount_internal(dev_dentry, device_fs); + } + } + auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr { if (!path::is_valid_absolute_path(path)) diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 8e4cb70..add96aa 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -62,6 +62,23 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS } } + GIVEN("a real image file containing a /dev directory") + { + REQUIRE(std::filesystem::exists(image_path_2)); + REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module_2"}, {image_path_2})); + + THEN("vfs hides the image's /dev behind the devfs mount") + { + auto & vfs = kernel::filesystem::vfs::get(); + + auto image_1 = vfs.open("/dev/image_1.txt"); + REQUIRE(image_1 == nullptr); + + auto dev = vfs.open("/dev/ram0"); + REQUIRE(dev != nullptr); + } + } + GIVEN("three real image files") { REQUIRE(std::filesystem::exists(image_path_1)); diff --git a/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img b/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img index 8327022..7f297f0 100644 --- a/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img +++ b/kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a1d102f2e40083613060d43b2b32d31031137bbef99761a2d1bf4d38e155adb7 +oid sha256:6d9e872916e7d9107b321cc007e151899d5f19400a694666c0b24d482aef61ca size 5242880 -- cgit v1.2.3 From 988977b80cd118749b6b813e0909f4607a4f27fe Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Tue, 12 May 2026 13:50:56 +0200 Subject: Determine ext2 inode size depending on revision level, add const to several methods --- .../include/kernel/filesystem/ext2/filesystem.hpp | 22 ++++++++++++++++------ kernel/include/kernel/filesystem/ext2/inode.hpp | 12 +++++++++--- kernel/src/filesystem/ext2/filesystem.cpp | 20 +++++++++++++------- kernel/src/filesystem/ext2/inode.cpp | 20 ++++++++++++++++---- 4 files changed, 54 insertions(+), 20 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index d22433f..18ef372 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -25,6 +25,9 @@ namespace kernel::filesystem::ext2 constexpr size_t inline superblock_offset = base_block_size; constexpr uint16_t inline magic_number = 0xEF53; + constexpr uint32_t inline good_old_revision = 0; + constexpr uint32_t inline dynamic_revision = 1; + constexpr uint32_t inline root_inode_number = 2; constexpr size_t inline direct_block_count = 12; @@ -64,7 +67,13 @@ namespace kernel::filesystem::ext2 @brief Gets the size of a block in the filesystem. @return The size of a block in bytes. */ - auto get_block_size() -> size_t; + [[nodiscard]] auto get_block_size() const -> size_t; + + /** + @brief Gets the revision level of the filesystem. + @return The revision level. + */ + [[nodiscard]] auto get_revision_level() const -> size_t; /** @brief Maps an inode block index to a global block number. @@ -72,14 +81,15 @@ namespace kernel::filesystem::ext2 @param data The inode data. @return The global block number. */ - auto map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) -> uint32_t; + [[nodiscard]] auto map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) const + -> uint32_t; private: - auto read_inode(uint32_t inode_number) -> kstd::shared_ptr; - auto read_block_number_at_index(uint32_t block_number, uint32_t index) -> uint32_t; + [[nodiscard]] auto read_inode(uint32_t inode_number) const -> kstd::shared_ptr; + [[nodiscard]] auto read_block_number_at_index(uint32_t block_number, uint32_t index) const -> uint32_t; - auto get_inode_size() -> size_t; - auto get_inode_block_count(inode_data const & data) -> uint32_t; + [[nodiscard]] auto get_inode_size() const -> size_t; + [[nodiscard]] auto get_inode_block_count(inode_data const & data) const -> uint32_t; superblock m_superblock{}; kstd::vector m_block_group_descriptors; diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp index b8f892a..000a5d8 100644 --- a/kernel/include/kernel/filesystem/ext2/inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/inode.hpp @@ -20,7 +20,7 @@ namespace kernel::filesystem::ext2 { uint16_t mode; uint16_t uid; - uint32_t size; // TODO BA-FS26 signed? + uint32_t size; uint32_t atime; uint32_t ctime; uint32_t mtime; @@ -45,7 +45,7 @@ namespace kernel::filesystem::ext2 @param fs The ext2 filesystem that this inode belongs to. @param data The data associated with this inode, read from the disk. */ - explicit inode(filesystem * fs, inode_data const & data); + explicit inode(filesystem const * fs, inode_data const & data); /** @brief Reads from the ext2 inode into a @p buffer, starting at the specified @p offset and for a given @p size. @@ -90,8 +90,14 @@ namespace kernel::filesystem::ext2 */ [[nodiscard]] auto is_symbolic_link() const -> bool override; + /** + @brief Get the size of the file represented by this inode. + @return The size of the file in bytes. + */ + [[nodiscard]] auto get_size() const -> size_t; + private: - filesystem * m_filesystem; + filesystem const * m_filesystem; inode_data m_data{}; }; } // namespace kernel::filesystem::ext2 diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 47e54fe..aaa50c7 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -89,7 +89,7 @@ namespace kernel::filesystem::ext2 return nullptr; } - auto filesystem::read_inode(uint32_t inode_number) -> kstd::shared_ptr + auto filesystem::read_inode(uint32_t inode_number) const -> kstd::shared_ptr { auto const block_size = get_block_size(); auto const inodes_per_group = m_superblock.inodes_per_group; @@ -112,7 +112,8 @@ namespace kernel::filesystem::ext2 return kstd::make_shared(this, new_inode_data); } - auto filesystem::map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) -> uint32_t + auto filesystem::map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) const + -> uint32_t { if (inode_block_index < constants::direct_block_count) { @@ -170,7 +171,7 @@ namespace kernel::filesystem::ext2 return 0; // TODO BA-FS26 really correct?? } - auto filesystem::read_block_number_at_index(uint32_t block_number, uint32_t index) -> uint32_t + auto filesystem::read_block_number_at_index(uint32_t block_number, uint32_t index) const -> uint32_t { uint32_t block_number_buffer = 0; @@ -181,17 +182,22 @@ namespace kernel::filesystem::ext2 return block_number_buffer; } - auto filesystem::get_block_size() -> size_t + auto filesystem::get_block_size() const -> size_t { return constants::base_block_size << m_superblock.log_block_size; } - auto filesystem::get_inode_size() -> size_t + auto filesystem::get_revision_level() const -> size_t { - return m_superblock.rev_level == 0 ? 128 : m_superblock.inode_size; + return m_superblock.rev_level; } - auto filesystem::get_inode_block_count(inode_data const & data) -> uint32_t + auto filesystem::get_inode_size() const -> size_t + { + return get_revision_level() == constants::good_old_revision ? 128 : m_superblock.inode_size; + } + + auto filesystem::get_inode_block_count(inode_data const & data) const -> uint32_t { return data.blocks / (2 << m_superblock.log_block_size); } diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index 1914c70..303838e 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -13,7 +13,7 @@ namespace kernel::filesystem::ext2 { - inode::inode(filesystem * fs, inode_data const & data) + inode::inode(filesystem const * fs, inode_data const & data) : m_filesystem(fs) , m_data(data) { @@ -25,11 +25,10 @@ namespace kernel::filesystem::ext2 auto inode::read(void * buffer, size_t offset, size_t size) const -> size_t { - // TODO BA-FS26 use revision 1 size - auto const max_readable = static_cast(m_data.size) - offset; + auto const max_readable = get_size() - offset; auto const requested_size = std::min(size, max_readable); - if (is_symbolic_link() && m_data.size <= sizeof(m_data.block)) + if (is_symbolic_link() && get_size() <= sizeof(m_data.block)) { auto inline_target = reinterpret_cast(m_data.block.data()); kstd::libc::memcpy(static_cast(buffer), inline_target + offset, requested_size); @@ -91,4 +90,17 @@ namespace kernel::filesystem::ext2 { return (m_data.mode & constants::mode_mask) == constants::mode_symbolic_link; } + + auto inode::get_size() const -> size_t + { + uint64_t size = m_data.size; + + if (m_filesystem->get_revision_level() > constants::good_old_revision && is_regular()) + { + size |= static_cast(m_data.dir_acl) << 32; + } + + return size; + } + } // namespace kernel::filesystem::ext2 -- cgit v1.2.3 From 7b1e578480f2f522fe39a742e688012a7f5ea4ed Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Tue, 12 May 2026 14:46:02 +0200 Subject: Add tests for ext2 inode get_size() --- .../kernel/test_support/filesystem/ext2.hpp | 4 + kernel/src/filesystem/ext2/inode.tests.cpp | 90 +++++++++++++++++++++- kernel/src/test_support/filesystem/ext2.cpp | 6 ++ 3 files changed, 98 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/test_support/filesystem/ext2.hpp b/kernel/include/kernel/test_support/filesystem/ext2.hpp index 107e5a4..18cef1c 100644 --- a/kernel/include/kernel/test_support/filesystem/ext2.hpp +++ b/kernel/include/kernel/test_support/filesystem/ext2.hpp @@ -1,6 +1,7 @@ #ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_EXT2_HPP #define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_EXT2_HPP +#include #include #include @@ -12,6 +13,9 @@ namespace kernel::tests::filesystem::ext2 -> void; auto write_u32(kernel::tests::devices::block_device & device, size_t offset, uint32_t value) -> void; auto setup_mock_ext2_layout(kernel::tests::devices::block_device & device) -> void; + auto setup_mock_ext2_layout(kernel::tests::devices::block_device & device, + kernel::filesystem::ext2::superblock const & superblock) -> void; + } // namespace kernel::tests::filesystem::ext2 #endif \ No newline at end of file diff --git a/kernel/src/filesystem/ext2/inode.tests.cpp b/kernel/src/filesystem/ext2/inode.tests.cpp index 49ba21b..783d930 100644 --- a/kernel/src/filesystem/ext2/inode.tests.cpp +++ b/kernel/src/filesystem/ext2/inode.tests.cpp @@ -1,5 +1,6 @@ #include +#include "kernel/filesystem/ext2/superblock.hpp" #include #include #include @@ -127,7 +128,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in SCENARIO("Ext2 inode read stops when block mapping resolves to zero", "[filesystem][ext2][inode]") { - auto const block_size = 1024; + auto const block_size = 1024uz; GIVEN("an ext2 inode without mapped data blocks") { auto device = kstd::make_shared(0, 0, "mock", block_size, 64 * block_size); @@ -156,7 +157,7 @@ SCENARIO("Ext2 inode read stops when block mapping resolves to zero", "[filesyst SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]") { - auto const block_size = 1024; + auto const block_size = 1024uz; GIVEN("an ext2 inode with two direct blocks and a block size of 1024 bytes") { auto device = kstd::make_shared(0, 0, "mock", block_size, 64 * block_size); @@ -203,3 +204,88 @@ SCENARIO("Ext2 inode write is not implemented", "[filesystem][ext2][inode]") } } } + +SCENARIO("Ext2 inode get_size() correctly returns size depending on revision level", "[filesystem][ext2][inode]") +{ + auto const block_size = 1024uz; + + auto superblock = kernel::filesystem::ext2::superblock{}; + superblock.magic = kernel::filesystem::ext2::constants::magic_number; + superblock.log_block_size = 0; + superblock.blocks_count = 64; + superblock.blocks_per_group = 64; + superblock.inodes_per_group = 32; + superblock.inode_size = 128; + + GIVEN("an ext2 inode with good old revision and inode_data.size = 256, inode_data.dir_acl = 32") + { + superblock.rev_level = 0; + + auto device = kstd::make_shared(0, 0, "mock", block_size, 64 * block_size); + REQUIRE(device != nullptr); + kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device, superblock); + + auto dev_inode = kstd::make_shared(device); + + auto fs = kernel::filesystem::ext2::filesystem{}; + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); + + auto data = kernel::filesystem::ext2::inode_data{}; + data.size = 256; + data.dir_acl = 32; + + THEN("the inode size is 256 if mode = regular") + { + data.mode = kernel::filesystem::ext2::constants::mode_regular; + + auto inode = kernel::filesystem::ext2::inode{&fs, data}; + + REQUIRE(inode.get_size() == 256); + } + + THEN("the inode size is 256 if mode = directory") + { + data.mode = kernel::filesystem::ext2::constants::mode_directory; + + auto inode = kernel::filesystem::ext2::inode{&fs, data}; + + REQUIRE(inode.get_size() == 256); + } + } + + GIVEN("an ext2 inode with good dynamic revision and inode_data.size = 256, inode_data.dir_acl = 32") + { + superblock.rev_level = 1; + + auto device = kstd::make_shared(0, 0, "mock", block_size, 64 * block_size); + REQUIRE(device != nullptr); + kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device, superblock); + + auto dev_inode = kstd::make_shared(device); + + auto fs = kernel::filesystem::ext2::filesystem{}; + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); + + auto data = kernel::filesystem::ext2::inode_data{}; + data.size = 256; + data.dir_acl = 32; + + THEN("the inode size is 256 if mode = regular") + { + data.mode = kernel::filesystem::ext2::constants::mode_regular; + + auto inode = kernel::filesystem::ext2::inode{&fs, data}; + + REQUIRE(inode.get_size() == 0x0000'0020'0000'0100); + } + + THEN("the inode size is 256 if mode = directory") + { + data.mode = kernel::filesystem::ext2::constants::mode_directory; + + auto inode = kernel::filesystem::ext2::inode{&fs, data}; + + REQUIRE(inode.get_size() == 256); + } + } +} \ No newline at end of file diff --git a/kernel/src/test_support/filesystem/ext2.cpp b/kernel/src/test_support/filesystem/ext2.cpp index 5a27b63..52b6efe 100644 --- a/kernel/src/test_support/filesystem/ext2.cpp +++ b/kernel/src/test_support/filesystem/ext2.cpp @@ -43,6 +43,12 @@ namespace kernel::tests::filesystem::ext2 superblock.inodes_per_group = 32; superblock.rev_level = 1; superblock.inode_size = 128; + setup_mock_ext2_layout(device, superblock); + } + + auto setup_mock_ext2_layout(kernel::tests::devices::block_device & device, + kernel::filesystem::ext2::superblock const & superblock) -> void + { write_bytes(device, kernel::filesystem::ext2::constants::superblock_offset, &superblock, sizeof(superblock)); auto group_descriptor = kernel::filesystem::ext2::block_group_descriptor{}; -- cgit v1.2.3 From d061f31f33feccb4203979c6e8d9bbaeabecb453 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 13 May 2026 10:13:13 +0200 Subject: refactor ext2 map_inode_block_index_to_global_block_number --- .../include/kernel/filesystem/ext2/filesystem.hpp | 14 +++- kernel/src/filesystem/ext2/filesystem.cpp | 86 +++++++++++++++------- kernel/src/filesystem/ext2/filesystem.tests.cpp | 2 +- kernel/src/filesystem/vfs.cpp | 2 +- 4 files changed, 76 insertions(+), 28 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index 18ef372..32d9baf 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace kernel::filesystem::ext2 { @@ -82,14 +83,25 @@ namespace kernel::filesystem::ext2 @return The global block number. */ [[nodiscard]] auto map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) const - -> uint32_t; + -> ssize_t; private: [[nodiscard]] auto read_inode(uint32_t inode_number) const -> kstd::shared_ptr; [[nodiscard]] auto read_block_number_at_index(uint32_t block_number, uint32_t index) const -> uint32_t; + [[nodiscard]] auto read_singly_indirect_block_number(uint32_t singly_indirect_block_number, + uint32_t block_index_in_singly_indirect_block) const + -> uint32_t; + [[nodiscard]] auto read_doubly_indirect_block_number(uint32_t doubly_indirect_block_number, + uint32_t block_index_in_doubly_indirect_block) const + -> uint32_t; + [[nodiscard]] auto read_triply_indirect_block_number(uint32_t triply_indirect_block_number, + uint32_t block_index_in_triply_indirect_block) const + -> uint32_t; + [[nodiscard]] auto get_inode_size() const -> size_t; [[nodiscard]] auto get_inode_block_count(inode_data const & data) const -> uint32_t; + [[nodiscard]] auto block_numbers_per_block() const -> uint32_t; superblock m_superblock{}; kstd::vector m_block_group_descriptors; diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index aaa50c7..0f34cfe 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace kernel::filesystem::ext2 { @@ -113,7 +114,7 @@ namespace kernel::filesystem::ext2 } auto filesystem::map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) const - -> uint32_t + -> ssize_t { if (inode_block_index < constants::direct_block_count) { @@ -121,9 +122,7 @@ namespace kernel::filesystem::ext2 } inode_block_index -= constants::direct_block_count; - auto const block_size = get_block_size(); - auto const numbers_per_block = block_size / sizeof(uint32_t); - + auto const numbers_per_block = block_numbers_per_block(); auto const block_numbers_per_singly_indirect_block = numbers_per_block; auto const block_numbers_per_doubly_indirect_block = numbers_per_block * block_numbers_per_singly_indirect_block; auto const block_numbers_per_triply_indirect_block = numbers_per_block * block_numbers_per_doubly_indirect_block; @@ -131,44 +130,76 @@ namespace kernel::filesystem::ext2 if (inode_block_index < block_numbers_per_singly_indirect_block) { auto const singly_indirect_block_number = data.block.at(constants::singly_indirect_block_index); - return read_block_number_at_index(singly_indirect_block_number, inode_block_index); + return read_singly_indirect_block_number(singly_indirect_block_number, inode_block_index); } inode_block_index -= block_numbers_per_singly_indirect_block; if (inode_block_index < block_numbers_per_doubly_indirect_block) { auto const doubly_indirect_block_number = data.block.at(constants::doubly_indirect_block_index); - auto const singly_indirect_block_index_in_doubly_indirect_block = - inode_block_index / block_numbers_per_singly_indirect_block; - auto const singly_indirect_block_number = read_block_number_at_index( - doubly_indirect_block_number, singly_indirect_block_index_in_doubly_indirect_block); - - auto const block_index_in_singly_indirect_block = inode_block_index % block_numbers_per_singly_indirect_block; - return read_block_number_at_index(singly_indirect_block_number, block_index_in_singly_indirect_block); + return read_doubly_indirect_block_number(doubly_indirect_block_number, inode_block_index); } inode_block_index -= block_numbers_per_doubly_indirect_block; if (inode_block_index < block_numbers_per_triply_indirect_block) { auto const triply_indirect_block_number = data.block.at(constants::triply_indirect_block_index); - auto const doubly_indirect_block_index_in_triply_indirect_block = - inode_block_index / block_numbers_per_doubly_indirect_block; - auto const doubly_indirect_block_number = read_block_number_at_index( - triply_indirect_block_number, doubly_indirect_block_index_in_triply_indirect_block); + return read_triply_indirect_block_number(triply_indirect_block_number, inode_block_index); + } + + return -1; + } + + auto filesystem::read_singly_indirect_block_number(uint32_t singly_indirect_block_number, + uint32_t block_index_in_singly_indirect_block) const -> uint32_t + { + if (singly_indirect_block_number == 0) + { + return 0; + } + return read_block_number_at_index(singly_indirect_block_number, block_index_in_singly_indirect_block); + } + + auto filesystem::read_doubly_indirect_block_number(uint32_t doubly_indirect_block_number, + uint32_t block_index_in_doubly_indirect_block) const -> uint32_t + { + auto const block_numbers_per_singly_indirect_block = block_numbers_per_block(); - auto const remaining_block_numbers = inode_block_index % block_numbers_per_doubly_indirect_block; + if (doubly_indirect_block_number == 0) + { + return 0; + } + + auto const singly_indirect_block_index_in_doubly_indirect_block = + block_index_in_doubly_indirect_block / block_numbers_per_singly_indirect_block; + auto const block_index_in_singly_indirect_block = + block_index_in_doubly_indirect_block % block_numbers_per_singly_indirect_block; + + auto const singly_indirect_block_number = + read_block_number_at_index(doubly_indirect_block_number, singly_indirect_block_index_in_doubly_indirect_block); - auto const singly_indirect_block_index_in_doubly_indirect_block = - remaining_block_numbers / block_numbers_per_singly_indirect_block; - auto const singly_indirect_block_number = read_block_number_at_index( - doubly_indirect_block_number, singly_indirect_block_index_in_doubly_indirect_block); + return read_singly_indirect_block_number(singly_indirect_block_number, block_index_in_singly_indirect_block); + } + + auto filesystem::read_triply_indirect_block_number(uint32_t triply_indirect_block_number, + uint32_t block_index_in_triply_indirect_block) const -> uint32_t + { + auto const block_numbers_per_doubly_indirect_block = block_numbers_per_block() * block_numbers_per_block(); - auto const block_index_in_singly_indirect_block = - remaining_block_numbers % block_numbers_per_singly_indirect_block; - return read_block_number_at_index(singly_indirect_block_number, block_index_in_singly_indirect_block); + if (triply_indirect_block_number == 0) + { + return 0; } - return 0; // TODO BA-FS26 really correct?? + auto const doubly_indirect_block_index_in_triply_indirect_block = + block_index_in_triply_indirect_block / block_numbers_per_doubly_indirect_block; + auto const block_index_in_doubly_indirect_block = + block_index_in_triply_indirect_block % block_numbers_per_doubly_indirect_block; + + auto const doubly_indirect_block_number = + read_block_number_at_index(triply_indirect_block_number, doubly_indirect_block_index_in_triply_indirect_block); + + return read_doubly_indirect_block_number(doubly_indirect_block_number, block_index_in_doubly_indirect_block); } auto filesystem::read_block_number_at_index(uint32_t block_number, uint32_t index) const -> uint32_t @@ -182,6 +213,11 @@ namespace kernel::filesystem::ext2 return block_number_buffer; } + auto filesystem::block_numbers_per_block() const -> uint32_t + { + return get_block_size() / sizeof(uint32_t); + } + auto filesystem::get_block_size() const -> size_t { return constants::base_block_size << m_superblock.log_block_size; diff --git a/kernel/src/filesystem/ext2/filesystem.tests.cpp b/kernel/src/filesystem/ext2/filesystem.tests.cpp index 31c4c29..8341070 100644 --- a/kernel/src/filesystem/ext2/filesystem.tests.cpp +++ b/kernel/src/filesystem/ext2/filesystem.tests.cpp @@ -133,7 +133,7 @@ SCENARIO("Ext2 block mapping includes direct and all indirect levels", "[filesys THEN("mapping returns zero for out-of-range indexes") { auto const beyond_triply = triply_start + numbers_per_block * numbers_per_block * numbers_per_block; - REQUIRE(fs.map_inode_block_index_to_global_block_number(beyond_triply, inode_data) == 0); + REQUIRE(fs.map_inode_block_index_to_global_block_number(beyond_triply, inode_data) == -1); } } } diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 535f898..f5d57be 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -143,7 +143,7 @@ namespace kernel::filesystem { parent_mount = m_mount_table.find_exact_mount(parent_mount_dentry->get_absolute_path().view()); } - + auto new_fs_root = kstd::make_shared(mount_point_dentry->get_parent(), fs->root_inode(), mount_point_dentry->get_name()); auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, parent_mount); -- cgit v1.2.3 From de0ef46e7bab75d0ab94f02d569df62e2b4281f2 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 13 May 2026 10:14:21 +0200 Subject: implement sparse files, fix bug with reading more than inode size --- kernel/src/filesystem/ext2/inode.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index 303838e..cfe0a35 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -40,23 +40,29 @@ namespace kernel::filesystem::ext2 auto bytes_read = 0uz; - while (bytes_read < size) + while (bytes_read < requested_size) { auto const block_number = m_filesystem->map_inode_block_index_to_global_block_number(block_index, m_data); - // TODO BA-FS26 really correct? sparse files -> 0 means a full block with zeros --> function - // map_inode_block_index_to_global_block_number should return 0 if not possible to find an block - if (block_number == 0) + if (block_number == -1) { break; } - auto const block_start_offset = block_number * m_filesystem->get_block_size(); - auto const read_offset = block_start_offset + in_block_offset; auto const bytes_to_read = std::min(requested_size - bytes_read, m_filesystem->get_block_size() - in_block_offset); + if (block_number == 0) + { + kstd::libc::memset(static_cast(buffer) + bytes_read, 0, bytes_to_read); + bytes_read += bytes_to_read; + } + else + { + auto const block_start_offset = block_number * m_filesystem->get_block_size(); + auto const read_offset = block_start_offset + in_block_offset; - bytes_read += - m_filesystem->backing_inode()->read(static_cast(buffer) + bytes_read, read_offset, bytes_to_read); + bytes_read += m_filesystem->backing_inode()->read(static_cast(buffer) + bytes_read, read_offset, + bytes_to_read); + } block_index++; in_block_offset = 0; // After the first block, we always start at the beginning of the block -- cgit v1.2.3 From 06b4c8bebbcd8aa845a845817cdeceeb86fbfc13 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 13 May 2026 10:15:09 +0200 Subject: add todos --- kernel/include/kernel/filesystem/mount.hpp | 3 +++ kernel/src/filesystem/mount_table.cpp | 1 + 2 files changed, 4 insertions(+) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index af5d08b..f920891 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -7,6 +7,8 @@ #include #include +#include + namespace kernel::filesystem { /** @@ -57,6 +59,7 @@ namespace kernel::filesystem kstd::shared_ptr m_root_dentry; kstd::shared_ptr m_filesystem{}; kstd::shared_ptr m_parent_mount{}; + std::atomic_uint32_t m_ref_count{0}; // TODO BA-FS26 }; } // namespace kernel::filesystem diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index daef93e..5a49e7a 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -34,6 +34,7 @@ namespace kernel::filesystem auto mount_table::remove_mount(std::string_view path) -> operation_result { + // TODO BA-FS26 check wheter something is open in this mount auto mount_range = std::ranges::find_last_if(m_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }); auto mount_it = mount_range.begin(); -- cgit v1.2.3 From f0715177763e1154668a656fbd7abfb8bb2c3261 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 13 May 2026 11:04:47 +0200 Subject: add inode sparse files tests --- kernel/src/filesystem/ext2/inode.tests.cpp | 101 ++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 8 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/ext2/inode.tests.cpp b/kernel/src/filesystem/ext2/inode.tests.cpp index 783d930..8381ee0 100644 --- a/kernel/src/filesystem/ext2/inode.tests.cpp +++ b/kernel/src/filesystem/ext2/inode.tests.cpp @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -126,10 +127,10 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in } } -SCENARIO("Ext2 inode read stops when block mapping resolves to zero", "[filesystem][ext2][inode]") +SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesystem][ext2][inode]") { auto const block_size = 1024uz; - GIVEN("an ext2 inode without mapped data blocks") + GIVEN("an ext2 inode with only direct mapped data blocks") { auto device = kstd::make_shared(0, 0, "mock", block_size, 64 * block_size); REQUIRE(device != nullptr); @@ -141,16 +142,100 @@ SCENARIO("Ext2 inode read stops when block mapping resolves to zero", "[filesyst REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); auto data = kernel::filesystem::ext2::inode_data{}; - data.blocks = 2; - data.block[0] = 0; + data.block[0] = 30; + data.block[1] = 0; + data.block[2] = 31; + data.size = block_size * 3; + + kernel::tests::filesystem::ext2::write_bytes(*device, 30 * block_size, "Hello", 5); + kernel::tests::filesystem::ext2::write_bytes(*device, 31 * block_size, "World!", 6); + + auto inode = kernel::filesystem::ext2::inode{&fs, data}; + + auto buffer = kstd::vector(data.size, std::byte{0xAB}); + + THEN("correct number of bytes are read and holes are returned as zeros") + { + auto const bytes_read = inode.read(buffer.data(), 0, buffer.size()); + REQUIRE(bytes_read == data.size); + + auto const text = std::string_view{reinterpret_cast(buffer.data()), bytes_read}; + REQUIRE(text.substr(0, 5) == "Hello"); + REQUIRE(std::ranges::all_of(text.substr(5, block_size - 5), [](char c) { return c == '\0'; })); + REQUIRE(text.substr(2 * block_size, 6) == "World!"); + REQUIRE(std::ranges::all_of(text.substr(2 * block_size + 6, 3 * block_size), [](char c) { return c == '\0'; })); + } + } + + GIVEN("an ext2 indode with file holes in singly indirect blocks") + { + auto device = kstd::make_shared(0, 0, "mock", block_size, 64 * block_size); + REQUIRE(device != nullptr); + kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device); + + auto dev_inode = kstd::make_shared(device); + + auto fs = kernel::filesystem::ext2::filesystem{}; + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); + + auto data = kernel::filesystem::ext2::inode_data{}; + data.block[0] = 30; + data.block[12] = 31; + data.size = block_size * 15; + + kernel::tests::filesystem::ext2::write_u32(*device, 31 * block_size, 50); + kernel::tests::filesystem::ext2::write_u32(*device, 31 * block_size + 4, 0); + kernel::tests::filesystem::ext2::write_u32(*device, 31 * block_size + 8, 51); + + kernel::tests::filesystem::ext2::write_bytes(*device, 30 * block_size, "Hello", 5); + kernel::tests::filesystem::ext2::write_bytes(*device, 50 * block_size, "Blub", 4); + kernel::tests::filesystem::ext2::write_bytes(*device, 51 * block_size, "World!", 6); + + auto inode = kernel::filesystem::ext2::inode{&fs, data}; + + auto buffer = kstd::vector(data.size, std::byte{0xAB}); + + THEN("correct number of bytes are read and holes are returned as zeros") + { + auto const bytes_read = inode.read(buffer.data(), 0, buffer.size()); + REQUIRE(bytes_read == data.size); + + auto const text = std::string_view{reinterpret_cast(buffer.data()), bytes_read}; + REQUIRE(text.substr(0, 5) == "Hello"); + REQUIRE(std::ranges::all_of(text.substr(5, 12 * block_size - 5), [](char c) { return c == '\0'; })); + REQUIRE(text.substr(12 * block_size, 4) == "Blub"); + REQUIRE( + std::ranges::all_of(text.substr(12 * block_size + 4, 2 * block_size - 4), [](char c) { return c == '\0'; })); + REQUIRE(text.substr(14 * block_size, 6) == "World!"); + REQUIRE( + std::ranges::all_of(text.substr(14 * block_size + 6, 1 * block_size - 6), [](char c) { return c == '\0'; })); + } + } + + GIVEN("an ext2 inode with zero singly indirect block pointer") + { + auto device = kstd::make_shared(0, 0, "mock", block_size, 64 * block_size); + REQUIRE(device != nullptr); + kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device); + + auto dev_inode = kstd::make_shared(device); + + auto fs = kernel::filesystem::ext2::filesystem{}; + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); + + auto data = kernel::filesystem::ext2::inode_data{}; + data.block[12] = 0; + data.size = block_size * 15; + auto inode = kernel::filesystem::ext2::inode{&fs, data}; - auto buffer = kstd::vector(32, std::byte{0xAB}); + auto buffer = kstd::vector(block_size * 3, std::byte{0xAB}); - THEN("no bytes are read") + THEN("all direct blocks are zero when singly indirect block pointer is zero") { auto const bytes_read = inode.read(buffer.data(), 0, buffer.size()); - REQUIRE(bytes_read == 0); + REQUIRE(bytes_read == buffer.size()); + REQUIRE(std::ranges::all_of(buffer, [](std::byte c) { return c == std::byte{0x00}; })); } } } @@ -170,7 +255,7 @@ SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]") REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); auto inode_data = kernel::filesystem::ext2::inode_data{}; - inode_data.blocks = 2; + inode_data.size = block_size * 2; inode_data.block[0] = 20; kernel::tests::filesystem::ext2::write_bytes(*device, 21 * block_size - 6, "Hello ", 6); inode_data.block[1] = 21; -- cgit v1.2.3 From 117b16cc5e3506da637a806a25bb22b82a02ef9e Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 13 May 2026 11:11:22 +0200 Subject: refactoring --- .../include/kernel/filesystem/ext2/filesystem.hpp | 4 +++ kernel/src/filesystem/ext2/filesystem.cpp | 42 ++++++++++++---------- 2 files changed, 28 insertions(+), 18 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index 32d9baf..46be32f 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -101,7 +101,11 @@ namespace kernel::filesystem::ext2 [[nodiscard]] auto get_inode_size() const -> size_t; [[nodiscard]] auto get_inode_block_count(inode_data const & data) const -> uint32_t; + [[nodiscard]] auto block_numbers_per_block() const -> uint32_t; + [[nodiscard]] auto block_numbers_per_singly_indirect_block() const -> uint32_t; + [[nodiscard]] auto block_numbers_per_doubly_indirect_block() const -> uint32_t; + [[nodiscard]] auto block_numbers_per_triply_indirect_block() const -> uint32_t; superblock m_superblock{}; kstd::vector m_block_group_descriptors; diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 0f34cfe..893cc38 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -122,26 +122,21 @@ namespace kernel::filesystem::ext2 } inode_block_index -= constants::direct_block_count; - auto const numbers_per_block = block_numbers_per_block(); - auto const block_numbers_per_singly_indirect_block = numbers_per_block; - auto const block_numbers_per_doubly_indirect_block = numbers_per_block * block_numbers_per_singly_indirect_block; - auto const block_numbers_per_triply_indirect_block = numbers_per_block * block_numbers_per_doubly_indirect_block; - - if (inode_block_index < block_numbers_per_singly_indirect_block) + if (inode_block_index < block_numbers_per_singly_indirect_block()) { auto const singly_indirect_block_number = data.block.at(constants::singly_indirect_block_index); return read_singly_indirect_block_number(singly_indirect_block_number, inode_block_index); } - inode_block_index -= block_numbers_per_singly_indirect_block; + inode_block_index -= block_numbers_per_singly_indirect_block(); - if (inode_block_index < block_numbers_per_doubly_indirect_block) + if (inode_block_index < block_numbers_per_doubly_indirect_block()) { auto const doubly_indirect_block_number = data.block.at(constants::doubly_indirect_block_index); return read_doubly_indirect_block_number(doubly_indirect_block_number, inode_block_index); } - inode_block_index -= block_numbers_per_doubly_indirect_block; + inode_block_index -= block_numbers_per_doubly_indirect_block(); - if (inode_block_index < block_numbers_per_triply_indirect_block) + if (inode_block_index < block_numbers_per_triply_indirect_block()) { auto const triply_indirect_block_number = data.block.at(constants::triply_indirect_block_index); return read_triply_indirect_block_number(triply_indirect_block_number, inode_block_index); @@ -163,17 +158,15 @@ namespace kernel::filesystem::ext2 auto filesystem::read_doubly_indirect_block_number(uint32_t doubly_indirect_block_number, uint32_t block_index_in_doubly_indirect_block) const -> uint32_t { - auto const block_numbers_per_singly_indirect_block = block_numbers_per_block(); - if (doubly_indirect_block_number == 0) { return 0; } auto const singly_indirect_block_index_in_doubly_indirect_block = - block_index_in_doubly_indirect_block / block_numbers_per_singly_indirect_block; + block_index_in_doubly_indirect_block / block_numbers_per_singly_indirect_block(); auto const block_index_in_singly_indirect_block = - block_index_in_doubly_indirect_block % block_numbers_per_singly_indirect_block; + block_index_in_doubly_indirect_block % block_numbers_per_singly_indirect_block(); auto const singly_indirect_block_number = read_block_number_at_index(doubly_indirect_block_number, singly_indirect_block_index_in_doubly_indirect_block); @@ -184,17 +177,15 @@ namespace kernel::filesystem::ext2 auto filesystem::read_triply_indirect_block_number(uint32_t triply_indirect_block_number, uint32_t block_index_in_triply_indirect_block) const -> uint32_t { - auto const block_numbers_per_doubly_indirect_block = block_numbers_per_block() * block_numbers_per_block(); - if (triply_indirect_block_number == 0) { return 0; } auto const doubly_indirect_block_index_in_triply_indirect_block = - block_index_in_triply_indirect_block / block_numbers_per_doubly_indirect_block; + block_index_in_triply_indirect_block / block_numbers_per_doubly_indirect_block(); auto const block_index_in_doubly_indirect_block = - block_index_in_triply_indirect_block % block_numbers_per_doubly_indirect_block; + block_index_in_triply_indirect_block % block_numbers_per_doubly_indirect_block(); auto const doubly_indirect_block_number = read_block_number_at_index(triply_indirect_block_number, doubly_indirect_block_index_in_triply_indirect_block); @@ -218,6 +209,21 @@ namespace kernel::filesystem::ext2 return get_block_size() / sizeof(uint32_t); } + auto filesystem::block_numbers_per_singly_indirect_block() const -> uint32_t + { + return block_numbers_per_block(); + } + + auto filesystem::block_numbers_per_doubly_indirect_block() const -> uint32_t + { + return block_numbers_per_singly_indirect_block() * block_numbers_per_block(); + } + + auto filesystem::block_numbers_per_triply_indirect_block() const -> uint32_t + { + return block_numbers_per_doubly_indirect_block() * block_numbers_per_block(); + } + auto filesystem::get_block_size() const -> size_t { return constants::base_block_size << m_superblock.log_block_size; -- cgit v1.2.3 From 15afa6a030ee6e1fc6c255f9567b54d78c530d25 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 13 May 2026 11:23:33 +0200 Subject: increase buffer size to really test the singly indirect block pointer --- kernel/src/filesystem/ext2/inode.tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/ext2/inode.tests.cpp b/kernel/src/filesystem/ext2/inode.tests.cpp index 8381ee0..45bea51 100644 --- a/kernel/src/filesystem/ext2/inode.tests.cpp +++ b/kernel/src/filesystem/ext2/inode.tests.cpp @@ -229,7 +229,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste auto inode = kernel::filesystem::ext2::inode{&fs, data}; - auto buffer = kstd::vector(block_size * 3, std::byte{0xAB}); + auto buffer = kstd::vector(block_size * 15, std::byte{0xAB}); THEN("all direct blocks are zero when singly indirect block pointer is zero") { -- cgit v1.2.3 From a5e65a09667cbaad0259ebf7315d09401651bbc2 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Wed, 13 May 2026 13:37:15 +0200 Subject: add tests for mount and unmount boot root filesystem --- kernel/src/filesystem/vfs.tests.cpp | 63 +++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index add96aa..0f1d6d5 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -148,6 +148,69 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(mounted_monkey != nullptr); } + THEN("image can be mounted on / file opened and unmounted again") + { + auto info_1 = vfs.open("/information/info_1.txt"); + REQUIRE(info_1 != nullptr); + + REQUIRE(vfs.do_mount("/dev/ram16", "/") == kernel::filesystem::vfs::operation_result::success); + + info_1 = vfs.open("/information/info_1.txt"); + REQUIRE(info_1 == nullptr); + + auto water = vfs.open("/monkey_house/infrastructure/water.txt"); + REQUIRE(water != nullptr); + + REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success); + + info_1 = vfs.open("/information/info_1.txt"); + REQUIRE(info_1 != nullptr); + } + + THEN("image can be mounted on / just the boot root has /dev") + { + auto info_1 = vfs.open("/information/info_1.txt"); + REQUIRE(info_1 != nullptr); + + REQUIRE(vfs.do_mount("/dev/ram16", "/") == kernel::filesystem::vfs::operation_result::success); + + info_1 = vfs.open("/information/info_1.txt"); + REQUIRE(info_1 == nullptr); + + auto water = vfs.open("/monkey_house/infrastructure/water.txt"); + REQUIRE(water != nullptr); + + auto dev_ram_16 = vfs.open("/dev/ram16"); + REQUIRE(dev_ram_16 == nullptr); + + REQUIRE(vfs.do_mount("/dev/ram32", "/") == kernel::filesystem::vfs::operation_result::non_existent_path); + + REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success); + + auto dev_ram_32 = vfs.open("/dev/ram32"); + REQUIRE(dev_ram_32 != nullptr); + } + + THEN("boot root can be unmounted and remounted again but /dev is not re-grafted") + { + auto info_1 = vfs.open("/information/info_1.txt"); + REQUIRE(info_1 != nullptr); + + REQUIRE(vfs.unmount("/dev") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success); + + info_1 = vfs.open("/information/info_1.txt"); + REQUIRE(info_1 == nullptr); + + REQUIRE(vfs.do_mount("/dev/ram0", "/") == kernel::filesystem::vfs::operation_result::success); + + info_1 = vfs.open("/information/info_1.txt"); + REQUIRE(info_1 != nullptr); + + auto dev_ram_0 = vfs.open("/dev/ram0"); + REQUIRE(dev_ram_0 == nullptr); + } + THEN("mount with null file system fails") { REQUIRE(vfs.do_mount("/closed.txt", "/information") == -- cgit v1.2.3 From 2833fa2a2d2bf1f98f627503e52531615d1c1496 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 14 May 2026 15:41:21 +0200 Subject: small refactoring --- kernel/include/kernel/filesystem/dentry.hpp | 2 +- kernel/src/filesystem/dentry.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index 7eef693..3813f61 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -104,7 +104,7 @@ namespace kernel::filesystem kstd::shared_ptr m_parent; kstd::vector> m_children; kstd::shared_ptr m_inode; - uint32_t m_flags{0}; + uint32_t m_flags; }; } // namespace kernel::filesystem diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index c21771b..7603e11 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -17,6 +17,7 @@ namespace kernel::filesystem : m_name(name) , m_parent(parent) , m_inode(inode) + , m_flags(0) { if (!m_inode) { -- cgit v1.2.3 From 13f41e3816bd0be96c9bf728b534a58e6d4e5c28 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Thu, 14 May 2026 15:41:54 +0200 Subject: add todo --- kernel/src/filesystem/mount_table.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'kernel') diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 5a49e7a..e0cf140 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -35,6 +35,7 @@ namespace kernel::filesystem auto mount_table::remove_mount(std::string_view path) -> operation_result { // TODO BA-FS26 check wheter something is open in this mount + // TODO BA-FS26 nearly the same code is in find_exact_mount -> refactor to avoid code duplication auto mount_range = std::ranges::find_last_if(m_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }); auto mount_it = mount_range.begin(); -- cgit v1.2.3 From 245f47af9362e83235a28f993c89f844886e65c3 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Thu, 14 May 2026 16:25:15 +0200 Subject: Unify header inclusion syntax --- kernel/include/kernel/filesystem/vfs.hpp | 2 +- kernel/src/filesystem/ext2/inode.tests.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index b5053a2..4b6de53 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -1,8 +1,8 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP #define TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP -#include "kernel/filesystem/devfs/filesystem.hpp" #include +#include #include #include diff --git a/kernel/src/filesystem/ext2/inode.tests.cpp b/kernel/src/filesystem/ext2/inode.tests.cpp index 45bea51..efc0660 100644 --- a/kernel/src/filesystem/ext2/inode.tests.cpp +++ b/kernel/src/filesystem/ext2/inode.tests.cpp @@ -1,9 +1,9 @@ #include -#include "kernel/filesystem/ext2/superblock.hpp" #include #include #include +#include #include #include #include -- cgit v1.2.3 From c6953852b9e10823830688bdfb269650b080f1bb Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Thu, 14 May 2026 16:29:29 +0200 Subject: Track dentry instead of inode in open_file_descriptor --- kernel/include/kernel/filesystem/open_file_descriptor.hpp | 12 ++++++------ kernel/kapi/filesystem.cpp | 2 +- kernel/src/filesystem/open_file_descriptor.cpp | 15 ++++++++------- kernel/src/filesystem/open_file_descriptor.tests.cpp | 14 +++++++++----- kernel/src/filesystem/open_file_table.tests.cpp | 10 +++++++--- kernel/src/filesystem/vfs.tests.cpp | 6 +++--- 6 files changed, 34 insertions(+), 25 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/open_file_descriptor.hpp b/kernel/include/kernel/filesystem/open_file_descriptor.hpp index 036dcf0..823fe13 100644 --- a/kernel/include/kernel/filesystem/open_file_descriptor.hpp +++ b/kernel/include/kernel/filesystem/open_file_descriptor.hpp @@ -1,7 +1,7 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTOR_HPP #define TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTOR_HPP -#include +#include #include @@ -11,15 +11,15 @@ namespace kernel::filesystem { /** @brief Represents an open file descriptor in the filesystem. This class encapsulates the state of an open file, - including a reference to the associated inode and the current file offset. + including a reference to the associated dentry and the current file offset. */ struct open_file_descriptor { /** - @brief Constructs an open file descriptor for the given @p inode. - @param inode The inode to associate with the open file descriptor. + @brief Constructs an open file descriptor for the given @p dentry. + @param dentry The dentry to associate with the open file descriptor. */ - explicit open_file_descriptor(kstd::shared_ptr const & inode); + explicit open_file_descriptor(kstd::shared_ptr const & dentry); /** @brief Destructor for the open file descriptor. @@ -53,7 +53,7 @@ namespace kernel::filesystem [[nodiscard]] auto offset() const -> size_t; private: - kstd::shared_ptr m_inode; + kstd::shared_ptr m_dentry; size_t m_offset; }; diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index 4c68f28..77d7eb0 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -35,7 +35,7 @@ namespace kapi::filesystem { if (auto dentry = kernel::filesystem::vfs::get().open(path)) { - auto open_file_descriptor = kstd::make_shared(dentry->get_inode()); + auto open_file_descriptor = kstd::make_shared(dentry); return kernel::filesystem::open_file_table::get().add_file(open_file_descriptor); } diff --git a/kernel/src/filesystem/open_file_descriptor.cpp b/kernel/src/filesystem/open_file_descriptor.cpp index 25bffbd..27e6449 100644 --- a/kernel/src/filesystem/open_file_descriptor.cpp +++ b/kernel/src/filesystem/open_file_descriptor.cpp @@ -1,6 +1,7 @@ -#include #include +#include + #include #include @@ -8,26 +9,26 @@ namespace kernel::filesystem { - open_file_descriptor::open_file_descriptor(kstd::shared_ptr const & inode) - : m_inode(inode) + open_file_descriptor::open_file_descriptor(kstd::shared_ptr const & dentry) + : m_dentry(dentry) , m_offset(0) { - if (!inode) + if (!dentry) { - kstd::os::panic("[FILESYSTEM] open_file_descriptor constructed with null inode."); + kstd::os::panic("[FILESYSTEM] open_file_descriptor constructed with null dentry."); } } auto open_file_descriptor::read(void * buffer, size_t size) -> size_t { - auto read_bytes = m_inode->read(buffer, m_offset, size); + auto read_bytes = m_dentry->get_inode()->read(buffer, m_offset, size); m_offset += read_bytes; return read_bytes; } auto open_file_descriptor::write(void const * buffer, size_t size) -> size_t { - auto written_bytes = m_inode->write(buffer, m_offset, size); + auto written_bytes = m_dentry->get_inode()->write(buffer, m_offset, size); m_offset += written_bytes; return written_bytes; } diff --git a/kernel/src/filesystem/open_file_descriptor.tests.cpp b/kernel/src/filesystem/open_file_descriptor.tests.cpp index 53835ba..8c24cf0 100644 --- a/kernel/src/filesystem/open_file_descriptor.tests.cpp +++ b/kernel/src/filesystem/open_file_descriptor.tests.cpp @@ -1,5 +1,7 @@ #include +#include +#include #include #include #include @@ -16,10 +18,11 @@ SCENARIO("Open file descriptor construction", "[filesystem][open_file_descriptor]") { - GIVEN("an inode and an open file descriptor for that inode") + GIVEN("a dentry and an open file descriptor for that dentry") { auto inode = kstd::make_shared(); - auto file_descriptor = kernel::filesystem::open_file_descriptor{inode}; + auto dentry = kstd::make_shared(nullptr, inode, "test_dentry"); + auto file_descriptor = kernel::filesystem::open_file_descriptor{dentry}; THEN("the initial offset is zero") { @@ -30,10 +33,11 @@ SCENARIO("Open file descriptor construction", "[filesystem][open_file_descriptor SCENARIO("Open file descriptor read/write offset management", "[filesystem][open_file_descriptor]") { - GIVEN("an inode that tracks read/write calls and an open file descriptor for that inode") + GIVEN("a dentry that tracks read/write calls and an open file descriptor for that dentry") { auto inode = kstd::make_shared(); - auto file_descriptor = kernel::filesystem::open_file_descriptor{inode}; + auto dentry = kstd::make_shared(nullptr, inode, "test_dentry"); + auto file_descriptor = kernel::filesystem::open_file_descriptor{dentry}; THEN("the offset is updated correctly after reads") { @@ -78,7 +82,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope auto & vfs = kernel::filesystem::vfs::get(); auto dentry = vfs.open("/information/info_1.txt"); REQUIRE(dentry != nullptr); - auto ofd = kstd::make_shared(dentry->get_inode()); + auto ofd = kstd::make_shared(dentry); THEN("the file can be read and the offset is updated") { diff --git a/kernel/src/filesystem/open_file_table.tests.cpp b/kernel/src/filesystem/open_file_table.tests.cpp index a5c791d..456d6b7 100644 --- a/kernel/src/filesystem/open_file_table.tests.cpp +++ b/kernel/src/filesystem/open_file_table.tests.cpp @@ -1,5 +1,6 @@ #include +#include #include #include @@ -15,8 +16,10 @@ SCENARIO("Open file table add/get file", "[filesystem][open_file_table]") { auto & table = kernel::filesystem::open_file_table::get(); auto inode = kstd::make_shared(); - auto file_descriptor_1 = kstd::make_shared(inode); - auto file_descriptor_2 = kstd::make_shared(inode); + auto dentry = kstd::make_shared(nullptr, inode, "test_dentry"); + + auto file_descriptor_1 = kstd::make_shared(dentry); + auto file_descriptor_2 = kstd::make_shared(dentry); WHEN("adding the open file descriptor to the open file table") { @@ -69,7 +72,8 @@ SCENARIO("Open file table remove file", "[filesystem][open_file_table]") { auto & table = kernel::filesystem::open_file_table::get(); auto inode = kstd::make_shared(); - auto file_descriptor = kstd::make_shared(inode); + auto dentry = kstd::make_shared(nullptr, inode, "test_dentry"); + auto file_descriptor = kstd::make_shared(dentry); auto fd = table.add_file(file_descriptor); WHEN("removing the file descriptor using the file descriptor") diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 0f1d6d5..eaffbc9 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -310,7 +310,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto dentry = vfs.open("/information/sheep_1.txt"); REQUIRE(dentry != nullptr); - auto sheep_1_ofd = kstd::make_shared(dentry->get_inode()); + auto sheep_1_ofd = kstd::make_shared(dentry); kstd::vector buffer(7); auto bytes_read = sheep_1_ofd->read(buffer.data(), buffer.size()); @@ -335,8 +335,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(sheep_1 != nullptr); REQUIRE(goat_1 != nullptr); - auto sheep_1_ofd = kstd::make_shared(sheep_1->get_inode()); - auto goat_1_ofd = kstd::make_shared(goat_1->get_inode()); + auto sheep_1_ofd = kstd::make_shared(sheep_1); + auto goat_1_ofd = kstd::make_shared(goat_1); kstd::vector sheep_buffer(7); auto bytes_read = sheep_1_ofd->read(sheep_buffer.data(), sheep_buffer.size()); -- cgit v1.2.3 From 216ec44cf2fdc914ce38e3ab56eb3a8d82b54c77 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Thu, 14 May 2026 16:59:56 +0200 Subject: Refactor resolve_path --- kernel/include/kernel/filesystem/vfs.hpp | 6 ++++++ kernel/src/filesystem/vfs.cpp | 21 ++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 4b6de53..2aa1dd7 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -4,11 +4,13 @@ #include #include #include +#include #include #include #include +#include namespace kernel::filesystem { @@ -77,7 +79,11 @@ namespace kernel::filesystem vfs() = default; auto init_internal() -> void; + [[nodiscard]] auto resolve_path_internal(std::string_view path) + -> std::pair, kstd::shared_ptr>; [[nodiscard]] auto resolve_path(std::string_view path) -> kstd::shared_ptr; + [[nodiscard]] auto find_mount(std::string_view path) -> kstd::shared_ptr; + auto do_mount_internal(kstd::shared_ptr const & mount_point_dentry, kstd::shared_ptr const & fs) -> void; diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index f5d57be..52ffcc8 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace { @@ -165,11 +166,11 @@ namespace kernel::filesystem } } - auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr + auto vfs::resolve_path_internal(std::string_view path) -> std::pair, kstd::shared_ptr> { if (!path::is_valid_absolute_path(path)) { - return nullptr; + return {nullptr, nullptr}; } auto current_mount = m_mount_table.find_exact_mount("/"); @@ -225,7 +226,7 @@ namespace kernel::filesystem auto found_inode = current_fs->lookup(current_dentry->get_inode(), part.view()); if (!found_inode) { - return nullptr; + return {nullptr, nullptr}; } next_dentry = kstd::make_shared(current_dentry, found_inode, part.view()); @@ -246,7 +247,7 @@ namespace kernel::filesystem { if (symlink_counter++ > constants::symloop_max) { - return nullptr; + return {nullptr, nullptr}; } kstd::vector buffer(constants::symlink_max_path_length); @@ -269,9 +270,19 @@ namespace kernel::filesystem current_dentry = next_dentry; } + return {current_dentry, current_mount}; + } + + auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr + { + return resolve_path_internal(path).first; + } - return current_dentry; + auto vfs::find_mount(std::string_view path) -> kstd::shared_ptr + { + return resolve_path_internal(path).second; } + } // namespace kernel::filesystem namespace kernel::tests::filesystem::vfs -- cgit v1.2.3 From f2b46c2d9cd9b1bf4b5ec5f35593ae60b3740d0c Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Thu, 14 May 2026 17:24:49 +0200 Subject: Document design rationale for resolve_path return type --- kernel/include/kernel/filesystem/vfs.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 2aa1dd7..7a6ebf9 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -79,6 +79,16 @@ namespace kernel::filesystem vfs() = default; auto init_internal() -> void; + /** + * Note: Resolving a dentry requires traversing mount points; since the + * associated 'mount' object is discovered as a byproduct of this + * traversal, we return it alongside the dentry to avoid redundant + * lookups in callers that require mount context. + * + * If only one component is needed, the convenience wrappers can be used: + * - resolve_path() for the dentry only. + * - find_mount() for the mount context only. + */ [[nodiscard]] auto resolve_path_internal(std::string_view path) -> std::pair, kstd::shared_ptr>; [[nodiscard]] auto resolve_path(std::string_view path) -> kstd::shared_ptr; -- cgit v1.2.3 From 146c40b22b834e4bf8d5e1d7256d3071f11d4bf9 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Thu, 14 May 2026 17:33:14 +0200 Subject: Rename mount_point_dentry to target_dentry --- kernel/include/kernel/filesystem/vfs.hpp | 2 +- kernel/src/filesystem/vfs.cpp | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 7a6ebf9..dfb8f0e 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -94,7 +94,7 @@ namespace kernel::filesystem [[nodiscard]] auto resolve_path(std::string_view path) -> kstd::shared_ptr; [[nodiscard]] auto find_mount(std::string_view path) -> kstd::shared_ptr; - auto do_mount_internal(kstd::shared_ptr const & mount_point_dentry, kstd::shared_ptr const & fs) + auto do_mount_internal(kstd::shared_ptr const & target_dentry, kstd::shared_ptr const & fs) -> void; auto graft_persistent_device_fs(kstd::shared_ptr const & device_fs) -> void; diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 52ffcc8..31ffa42 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -53,9 +53,9 @@ namespace kernel::filesystem auto device_fs = kstd::make_shared(); device_fs->mount(nullptr); - if (auto dev_mount_point_dentry = resolve_path("/dev")) + if (auto dev_target_dentry = resolve_path("/dev")) { - do_mount_internal(dev_mount_point_dentry, device_fs); + do_mount_internal(dev_target_dentry, device_fs); } else { @@ -98,13 +98,13 @@ namespace kernel::filesystem return operation_result::invalid_path; } - if (auto mount_point_dentry = resolve_path(target)) + if (auto target_dentry = resolve_path(target)) { if (auto source_dentry = resolve_path(source)) { if (auto fs = kernel::filesystem::filesystem::probe_and_mount(source_dentry->get_inode())) { - do_mount_internal(mount_point_dentry, fs); + do_mount_internal(target_dentry, fs); return operation_result::success; } return operation_result::invalid_filesystem; @@ -135,10 +135,10 @@ namespace kernel::filesystem return operation_result::mount_point_not_found; } - auto vfs::do_mount_internal(kstd::shared_ptr const & mount_point_dentry, - kstd::shared_ptr const & fs) -> void + auto vfs::do_mount_internal(kstd::shared_ptr const & target_dentry, kstd::shared_ptr const & fs) + -> void { - auto parent_mount_dentry = mount_point_dentry->find_mount_root_dentry(); + auto parent_mount_dentry = target_dentry->find_mount_root_dentry(); kstd::shared_ptr parent_mount = nullptr; if (parent_mount_dentry) { @@ -146,8 +146,8 @@ namespace kernel::filesystem } auto new_fs_root = - kstd::make_shared(mount_point_dentry->get_parent(), fs->root_inode(), mount_point_dentry->get_name()); - auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, parent_mount); + kstd::make_shared(target_dentry->get_parent(), fs->root_inode(), target_dentry->get_name()); + auto new_mount = kstd::make_shared(target_dentry, new_fs_root, fs, parent_mount); m_mount_table.add_mount(new_mount); } -- cgit v1.2.3 From 4cc120e7dba5c858a3a0f68b63e91e8d7b831701 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Thu, 14 May 2026 18:03:44 +0200 Subject: Refactor do_mount_internal to use target_mount as parameter --- kernel/include/kernel/filesystem/vfs.hpp | 4 ++-- kernel/src/filesystem/vfs.cpp | 30 ++++++++++++++---------------- 2 files changed, 16 insertions(+), 18 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index dfb8f0e..8515af0 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -94,8 +94,8 @@ namespace kernel::filesystem [[nodiscard]] auto resolve_path(std::string_view path) -> kstd::shared_ptr; [[nodiscard]] auto find_mount(std::string_view path) -> kstd::shared_ptr; - auto do_mount_internal(kstd::shared_ptr const & target_dentry, kstd::shared_ptr const & fs) - -> void; + auto do_mount_internal(kstd::shared_ptr const & target_dentry, kstd::shared_ptr const & target_mount, + kstd::shared_ptr const & fs) -> void; auto graft_persistent_device_fs(kstd::shared_ptr const & device_fs) -> void; diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 31ffa42..c395e74 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -47,7 +47,8 @@ namespace kernel::filesystem root_fs->mount(nullptr); auto root_fs_root_dentry = kstd::make_shared(nullptr, root_fs->root_inode(), "/"); - m_mount_table.add_mount(kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, nullptr)); + auto root_mount = kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, nullptr); + m_mount_table.add_mount(root_mount); // mount devfs at /dev (inside rootfs, temporary, will be shadowed) auto device_fs = kstd::make_shared(); @@ -55,7 +56,7 @@ namespace kernel::filesystem if (auto dev_target_dentry = resolve_path("/dev")) { - do_mount_internal(dev_target_dentry, device_fs); + do_mount_internal(dev_target_dentry, root_mount, device_fs); } else { @@ -69,7 +70,7 @@ namespace kernel::filesystem { if (auto root_dentry = resolve_path("/")) { - do_mount_internal(root_dentry, boot_root_fs); + do_mount_internal(root_dentry, root_mount, boot_root_fs); graft_persistent_device_fs(device_fs); } } @@ -98,13 +99,15 @@ namespace kernel::filesystem return operation_result::invalid_path; } - if (auto target_dentry = resolve_path(target)) + auto [target_dentry, target_mount] = resolve_path_internal(target); + + if (target_dentry && target_mount) { if (auto source_dentry = resolve_path(source)) { if (auto fs = kernel::filesystem::filesystem::probe_and_mount(source_dentry->get_inode())) { - do_mount_internal(target_dentry, fs); + do_mount_internal(target_dentry, target_mount, fs); return operation_result::success; } return operation_result::invalid_filesystem; @@ -135,25 +138,20 @@ namespace kernel::filesystem return operation_result::mount_point_not_found; } - auto vfs::do_mount_internal(kstd::shared_ptr const & target_dentry, kstd::shared_ptr const & fs) + auto vfs::do_mount_internal(kstd::shared_ptr const & target_dentry, + kstd::shared_ptr const & target_mount, kstd::shared_ptr const & fs) -> void { - auto parent_mount_dentry = target_dentry->find_mount_root_dentry(); - kstd::shared_ptr parent_mount = nullptr; - if (parent_mount_dentry) - { - parent_mount = m_mount_table.find_exact_mount(parent_mount_dentry->get_absolute_path().view()); - } - auto new_fs_root = kstd::make_shared(target_dentry->get_parent(), fs->root_inode(), target_dentry->get_name()); - auto new_mount = kstd::make_shared(target_dentry, new_fs_root, fs, parent_mount); + auto new_mount = kstd::make_shared(target_dentry, new_fs_root, fs, target_mount); m_mount_table.add_mount(new_mount); } auto vfs::graft_persistent_device_fs(kstd::shared_ptr const & device_fs) -> void { - if (auto new_root_dentry = resolve_path("/")) + auto [new_root_dentry, root_mount] = resolve_path_internal("/"); + if (new_root_dentry && root_mount) { auto dev_dentry = new_root_dentry->find_child("dev"); if (!dev_dentry) @@ -162,7 +160,7 @@ namespace kernel::filesystem new_root_dentry->add_child(dev_dentry); } - do_mount_internal(dev_dentry, device_fs); + do_mount_internal(dev_dentry, root_mount, device_fs); } } -- cgit v1.2.3 From 5b97abfc9ce1032a0e42be213906b1abd51355dd Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Thu, 14 May 2026 18:09:17 +0200 Subject: Remove unneeded functionality --- kernel/include/kernel/filesystem/dentry.hpp | 9 +-------- kernel/src/filesystem/dentry.cpp | 10 ---------- 2 files changed, 1 insertion(+), 18 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index 3813f61..925768a 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -24,8 +24,7 @@ namespace kernel::filesystem */ enum class dentry_flags : uint32_t { - is_mount_point = 1 << 0, - is_mount_root = 1 << 1, + is_mount_point = 1 << 0 }; /** @@ -61,12 +60,6 @@ namespace kernel::filesystem */ [[nodiscard]] auto get_absolute_path() const -> kstd::string; - /** - @brief traverse parent dentries until dentry with is_mount_root flag is found. - @return The found dentry. - */ - [[nodiscard]] auto find_mount_root_dentry() const -> kstd::shared_ptr; - /** @brief Add a @p child dentry. @param child The child dentry to add. diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index 7603e11..d963ed7 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -67,16 +67,6 @@ namespace kernel::filesystem return path; } - auto dentry::find_mount_root_dentry() const -> kstd::shared_ptr - { - auto parent = m_parent; - while (parent && !parent->has_flag(dentry_flags::is_mount_root)) - { - parent = parent->get_parent(); - } - return parent; - } - auto dentry::add_child(kstd::shared_ptr const & child) -> void { m_children.push_back(child); -- cgit v1.2.3 From fe0b38db0f8848da8cf28bb883e01bbbb889dd0a Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Thu, 14 May 2026 21:02:25 +0200 Subject: Remove unneeded functionality part 2 --- kernel/src/filesystem/mount_table.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index e0cf140..4b61fb0 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -26,10 +26,6 @@ namespace kernel::filesystem { mount_dentry->set_flag(dentry::dentry_flags::is_mount_point); } - if (auto root_dentry = mount->get_root_dentry()) - { - root_dentry->set_flag(dentry::dentry_flags::is_mount_root); - } } auto mount_table::remove_mount(std::string_view path) -> operation_result -- cgit v1.2.3 From 963c926c68aac4606d80743aca8e7b052eee7efe Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Fri, 15 May 2026 11:42:33 +0200 Subject: Rename mount_table method from find_exact_mount to find_mount --- kernel/include/kernel/filesystem/mount_table.hpp | 2 +- kernel/src/filesystem/mount_table.cpp | 4 ++-- kernel/src/filesystem/mount_table.tests.cpp | 10 +++++----- kernel/src/filesystem/vfs.cpp | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount_table.hpp b/kernel/include/kernel/filesystem/mount_table.hpp index 59b9503..8bebfe2 100644 --- a/kernel/include/kernel/filesystem/mount_table.hpp +++ b/kernel/include/kernel/filesystem/mount_table.hpp @@ -43,7 +43,7 @@ namespace kernel::filesystem @param path The path to match against the mount paths in the table. @return A pointer to the mount with the exact matching path, or a null pointer if no mount matches the path. */ - [[nodiscard]] auto find_exact_mount(std::string_view path) const -> kstd::shared_ptr; + [[nodiscard]] auto find_mount(std::string_view path) const -> kstd::shared_ptr; private: [[nodiscard]] auto has_child_mounts(kstd::shared_ptr const & parent_mount) const -> bool; diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 4b61fb0..78ac727 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -31,7 +31,7 @@ namespace kernel::filesystem auto mount_table::remove_mount(std::string_view path) -> operation_result { // TODO BA-FS26 check wheter something is open in this mount - // TODO BA-FS26 nearly the same code is in find_exact_mount -> refactor to avoid code duplication + // TODO BA-FS26 nearly the same code is in find_mount -> refactor to avoid code duplication auto mount_range = std::ranges::find_last_if(m_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }); auto mount_it = mount_range.begin(); @@ -52,7 +52,7 @@ namespace kernel::filesystem return operation_result::removed; } - auto mount_table::find_exact_mount(std::string_view path) const -> kstd::shared_ptr + auto mount_table::find_mount(std::string_view path) const -> kstd::shared_ptr { auto mount_range = std::ranges::find_last_if(m_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }); diff --git a/kernel/src/filesystem/mount_table.tests.cpp b/kernel/src/filesystem/mount_table.tests.cpp index 4ae8711..f22b25e 100644 --- a/kernel/src/filesystem/mount_table.tests.cpp +++ b/kernel/src/filesystem/mount_table.tests.cpp @@ -58,14 +58,14 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("finding mounts by exact valid path returns the correct mount") { - REQUIRE(table.find_exact_mount("/") == mount1); - REQUIRE(table.find_exact_mount("/mnt") == mount2); + REQUIRE(table.find_mount("/") == mount1); + REQUIRE(table.find_mount("/mnt") == mount2); } THEN("finding mounts by exact invalid path returns null") { - REQUIRE(table.find_exact_mount("/nonexistent") == nullptr); - REQUIRE(table.find_exact_mount("/mnt/file") == nullptr); + REQUIRE(table.find_mount("/nonexistent") == nullptr); + REQUIRE(table.find_mount("/mnt/file") == nullptr); } THEN("removing a mount that has no child mounts succeeds") @@ -103,7 +103,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("finding mounts by exact valid path returns the correct mount") { - REQUIRE(table.find_exact_mount("/") == mount2); + REQUIRE(table.find_mount("/") == mount2); } THEN("removing the topmost mount with the same path succeeds") diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index c395e74..9b0440d 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -171,7 +171,7 @@ namespace kernel::filesystem return {nullptr, nullptr}; } - auto current_mount = m_mount_table.find_exact_mount("/"); + auto current_mount = m_mount_table.find_mount("/"); if (!current_mount) { kapi::system::panic("[FILESYSTEM] no root mount found."); @@ -232,7 +232,7 @@ namespace kernel::filesystem } else if (next_dentry->has_flag(dentry::dentry_flags::is_mount_point)) { - current_mount = m_mount_table.find_exact_mount(next_dentry->get_absolute_path().view()); + current_mount = m_mount_table.find_mount(next_dentry->get_absolute_path().view()); if (!current_mount) { kapi::system::panic("[FILESYSTEM] mount for dentry with mounted flag not found."); @@ -260,7 +260,7 @@ namespace kernel::filesystem if (path::is_valid_absolute_path(symbolic_link_path)) { - current_mount = m_mount_table.find_exact_mount("/"); + current_mount = m_mount_table.find_mount("/"); current_dentry = current_mount->get_root_dentry(); } continue; -- cgit v1.2.3 From 66d0e68376c9ad3e2b13f6ff8d999a0c85bda1a4 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 15 May 2026 15:47:06 +0200 Subject: renaming --- kernel/include/kernel/filesystem/vfs.hpp | 5 +++-- kernel/src/filesystem/vfs.cpp | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 16 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 8515af0..7e2eae7 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -94,8 +94,9 @@ namespace kernel::filesystem [[nodiscard]] auto resolve_path(std::string_view path) -> kstd::shared_ptr; [[nodiscard]] auto find_mount(std::string_view path) -> kstd::shared_ptr; - auto do_mount_internal(kstd::shared_ptr const & target_dentry, kstd::shared_ptr const & target_mount, - kstd::shared_ptr const & fs) -> void; + auto do_mount_internal(kstd::shared_ptr const & mount_point_dentry, + kstd::shared_ptr const & parent_mount, kstd::shared_ptr const & fs) + -> void; auto graft_persistent_device_fs(kstd::shared_ptr const & device_fs) -> void; diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 9b0440d..77ae015 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -54,9 +54,9 @@ namespace kernel::filesystem auto device_fs = kstd::make_shared(); device_fs->mount(nullptr); - if (auto dev_target_dentry = resolve_path("/dev")) + if (auto dev_mount_point_dentry = resolve_path("/dev")) { - do_mount_internal(dev_target_dentry, root_mount, device_fs); + do_mount_internal(dev_mount_point_dentry, root_mount, device_fs); } else { @@ -99,15 +99,15 @@ namespace kernel::filesystem return operation_result::invalid_path; } - auto [target_dentry, target_mount] = resolve_path_internal(target); + auto [mount_point_dentry, mount_context] = resolve_path_internal(target); - if (target_dentry && target_mount) + if (mount_point_dentry && mount_context) { if (auto source_dentry = resolve_path(source)) { if (auto fs = kernel::filesystem::filesystem::probe_and_mount(source_dentry->get_inode())) { - do_mount_internal(target_dentry, target_mount, fs); + do_mount_internal(mount_point_dentry, mount_context, fs); return operation_result::success; } return operation_result::invalid_filesystem; @@ -138,26 +138,26 @@ namespace kernel::filesystem return operation_result::mount_point_not_found; } - auto vfs::do_mount_internal(kstd::shared_ptr const & target_dentry, - kstd::shared_ptr const & target_mount, kstd::shared_ptr const & fs) + auto vfs::do_mount_internal(kstd::shared_ptr const & mount_point_dentry, + kstd::shared_ptr const & parent_mount, kstd::shared_ptr const & fs) -> void { auto new_fs_root = - kstd::make_shared(target_dentry->get_parent(), fs->root_inode(), target_dentry->get_name()); - auto new_mount = kstd::make_shared(target_dentry, new_fs_root, fs, target_mount); + kstd::make_shared(mount_point_dentry->get_parent(), fs->root_inode(), mount_point_dentry->get_name()); + auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, parent_mount); m_mount_table.add_mount(new_mount); } auto vfs::graft_persistent_device_fs(kstd::shared_ptr const & device_fs) -> void { - auto [new_root_dentry, root_mount] = resolve_path_internal("/"); - if (new_root_dentry && root_mount) + auto [root_mount_point_dentry, root_mount] = resolve_path_internal("/"); + if (root_mount_point_dentry && root_mount) { - auto dev_dentry = new_root_dentry->find_child("dev"); + auto dev_dentry = root_mount_point_dentry->find_child("dev"); if (!dev_dentry) { - dev_dentry = kstd::make_shared(new_root_dentry, device_fs->root_inode(), "dev"); - new_root_dentry->add_child(dev_dentry); + dev_dentry = kstd::make_shared(root_mount_point_dentry, device_fs->root_inode(), "dev"); + root_mount_point_dentry->add_child(dev_dentry); } do_mount_internal(dev_dentry, root_mount, device_fs); -- cgit v1.2.3 From 95ff59017db74a6988f791ca9f122254dd743541 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 15 May 2026 16:17:50 +0200 Subject: refactor find_mount_iterator to avoid code duplication --- kernel/include/kernel/filesystem/mount_table.hpp | 2 ++ kernel/src/filesystem/mount_table.cpp | 17 +++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount_table.hpp b/kernel/include/kernel/filesystem/mount_table.hpp index 8bebfe2..742c928 100644 --- a/kernel/include/kernel/filesystem/mount_table.hpp +++ b/kernel/include/kernel/filesystem/mount_table.hpp @@ -47,6 +47,8 @@ namespace kernel::filesystem private: [[nodiscard]] auto has_child_mounts(kstd::shared_ptr const & parent_mount) const -> bool; + [[nodiscard]] auto find_mount_iterator(std::string_view path) const + -> kstd::vector>::const_iterator; kstd::vector> m_mounts; }; diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 78ac727..b582fd9 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -31,11 +31,7 @@ namespace kernel::filesystem auto mount_table::remove_mount(std::string_view path) -> operation_result { // TODO BA-FS26 check wheter something is open in this mount - // TODO BA-FS26 nearly the same code is in find_mount -> refactor to avoid code duplication - auto mount_range = - std::ranges::find_last_if(m_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }); - auto mount_it = mount_range.begin(); - + auto mount_it = find_mount_iterator(path); if (mount_it == m_mounts.end()) { return operation_result::mount_not_found; @@ -54,9 +50,14 @@ namespace kernel::filesystem auto mount_table::find_mount(std::string_view path) const -> kstd::shared_ptr { - auto mount_range = - std::ranges::find_last_if(m_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }); - auto mount_it = mount_range.begin(); + auto mount_it = find_mount_iterator(path); return (mount_it != m_mounts.end()) ? *mount_it : nullptr; } + + auto mount_table::find_mount_iterator(std::string_view path) const + -> kstd::vector>::const_iterator + { + return std::ranges::find_last_if(m_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }) + .begin(); + } } // namespace kernel::filesystem \ No newline at end of file -- cgit v1.2.3 From 1d647adb1ba20121eeb5c8e4470f48b2e972b3d4 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 15 May 2026 16:50:55 +0200 Subject: Mount can only be unmounted if no references are present, increment references on open file and decrement on close file --- kernel/include/kernel/filesystem/mount.hpp | 19 ++++++++++++++++- kernel/include/kernel/filesystem/mount_table.hpp | 3 ++- .../kernel/filesystem/open_file_descriptor.hpp | 8 +++++++- kernel/include/kernel/filesystem/vfs.hpp | 8 ++++++++ kernel/kapi/filesystem.cpp | 10 ++++++++- kernel/src/filesystem/mount.cpp | 22 ++++++++++++++++++++ kernel/src/filesystem/mount_table.cpp | 5 ++++- kernel/src/filesystem/open_file_descriptor.cpp | 7 ++++++- .../src/filesystem/open_file_descriptor.tests.cpp | 24 +++++++++++----------- kernel/src/filesystem/vfs.cpp | 17 ++++++++++++++- 10 files changed, 104 insertions(+), 19 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index f920891..fb5a627 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -54,12 +54,29 @@ namespace kernel::filesystem */ [[nodiscard]] auto get_parent_mount() const -> kstd::shared_ptr const &; + /** + @brief Increment the reference count for this mount. + */ + auto increment_ref_count() -> void; + + /** + @brief Decrement the reference count for this mount. + @return True if the reference count reached zero, false otherwise. + */ + auto decrement_ref_count() -> bool; + + /** + @brief Check if the mount is ready to be unmounted. + @return True if the mount is ready to be unmounted, false otherwise. + */ + [[nodiscard]] auto is_ready_to_unmount() const -> bool; + private: kstd::shared_ptr m_mount_dentry; kstd::shared_ptr m_root_dentry; kstd::shared_ptr m_filesystem{}; kstd::shared_ptr m_parent_mount{}; - std::atomic_uint32_t m_ref_count{0}; // TODO BA-FS26 + std::atomic_size_t m_ref_count; }; } // namespace kernel::filesystem diff --git a/kernel/include/kernel/filesystem/mount_table.hpp b/kernel/include/kernel/filesystem/mount_table.hpp index 742c928..4f2d1b7 100644 --- a/kernel/include/kernel/filesystem/mount_table.hpp +++ b/kernel/include/kernel/filesystem/mount_table.hpp @@ -22,7 +22,8 @@ namespace kernel::filesystem { removed = 0, has_child_mounts = -1, - mount_not_found = -2 + mount_not_found = -2, + cannot_be_unmounted = -3 }; /** diff --git a/kernel/include/kernel/filesystem/open_file_descriptor.hpp b/kernel/include/kernel/filesystem/open_file_descriptor.hpp index 823fe13..7ca7350 100644 --- a/kernel/include/kernel/filesystem/open_file_descriptor.hpp +++ b/kernel/include/kernel/filesystem/open_file_descriptor.hpp @@ -50,7 +50,13 @@ namespace kernel::filesystem @brief Returns the current file offset for this open file descriptor. @return The current file offset in bytes. */ - [[nodiscard]] auto offset() const -> size_t; + [[nodiscard]] auto get_offset() const -> size_t; + + /** + @brief Return a reference to the dentry associated with this open file descriptor. + @return A reference to the associated dentry. + */ + [[nodiscard]] auto get_dentry() const -> kstd::shared_ptr const &; private: kstd::shared_ptr m_dentry; diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 7e2eae7..48b99b2 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -33,6 +33,7 @@ namespace kernel::filesystem mount_point_not_found = -3, unmount_failed = -4, invalid_filesystem = -5, + close_failed = -6 }; /** @@ -60,6 +61,13 @@ namespace kernel::filesystem */ auto open(std::string_view path) -> kstd::shared_ptr; + /** + @brief Close a file by its associated @p dentry. + @param dentry The dentry of the file to close. + @return The result of the close operation. + */ + auto close(kstd::shared_ptr const & dentry) -> operation_result; + /** @brief Mount a @p source path to a specific @p target path. @param source The source of the filesystem to mount. diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index 77d7eb0..1782da5 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -44,7 +44,15 @@ namespace kapi::filesystem auto close(int file_descriptor) -> int { - return kernel::filesystem::open_file_table::get().remove_file(file_descriptor); + if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().get_file(file_descriptor)) + { + if (kernel::filesystem::vfs::get().close(open_file_descriptor->get_dentry()) == + kernel::filesystem::vfs::operation_result::success) + { + return kernel::filesystem::open_file_table::get().remove_file(file_descriptor); + } + } + return -1; } auto read(int file_descriptor, void * buffer, size_t size) -> ssize_t diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index 749c86a..3016509 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -18,6 +18,7 @@ namespace kernel::filesystem , m_root_dentry(root_dentry) , m_filesystem(fs) , m_parent_mount(parent_mount) + , m_ref_count(0) { if (!m_filesystem) { @@ -53,4 +54,25 @@ namespace kernel::filesystem { return m_parent_mount; } + + auto mount::increment_ref_count() -> void + { + m_ref_count += 1; + } + + auto mount::decrement_ref_count() -> bool + { + if (m_ref_count == 0) + { + return false; + } + + m_ref_count -= 1; + return true; + } + + auto mount::is_ready_to_unmount() const -> bool + { + return m_ref_count == 0; + } } // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index b582fd9..9951590 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -30,7 +30,6 @@ namespace kernel::filesystem auto mount_table::remove_mount(std::string_view path) -> operation_result { - // TODO BA-FS26 check wheter something is open in this mount auto mount_it = find_mount_iterator(path); if (mount_it == m_mounts.end()) { @@ -38,6 +37,10 @@ namespace kernel::filesystem } auto const & mount = *mount_it; + if (!mount->is_ready_to_unmount()) + { + return operation_result::cannot_be_unmounted; + } if (has_child_mounts(mount)) { return operation_result::has_child_mounts; diff --git a/kernel/src/filesystem/open_file_descriptor.cpp b/kernel/src/filesystem/open_file_descriptor.cpp index 27e6449..ebaabef 100644 --- a/kernel/src/filesystem/open_file_descriptor.cpp +++ b/kernel/src/filesystem/open_file_descriptor.cpp @@ -33,9 +33,14 @@ namespace kernel::filesystem return written_bytes; } - auto open_file_descriptor::offset() const -> size_t + auto open_file_descriptor::get_offset() const -> size_t { return m_offset; } + auto open_file_descriptor::get_dentry() const -> kstd::shared_ptr const & + { + return m_dentry; + } + } // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/open_file_descriptor.tests.cpp b/kernel/src/filesystem/open_file_descriptor.tests.cpp index 8c24cf0..1910b8b 100644 --- a/kernel/src/filesystem/open_file_descriptor.tests.cpp +++ b/kernel/src/filesystem/open_file_descriptor.tests.cpp @@ -26,7 +26,7 @@ SCENARIO("Open file descriptor construction", "[filesystem][open_file_descriptor THEN("the initial offset is zero") { - REQUIRE(file_descriptor.offset() == 0); + REQUIRE(file_descriptor.get_offset() == 0); } } } @@ -42,29 +42,29 @@ SCENARIO("Open file descriptor read/write offset management", "[filesystem][open THEN("the offset is updated correctly after reads") { REQUIRE(file_descriptor.read(nullptr, 100) == 100); - REQUIRE(file_descriptor.offset() == 100); + REQUIRE(file_descriptor.get_offset() == 100); REQUIRE(file_descriptor.read(nullptr, 50) == 50); - REQUIRE(file_descriptor.offset() == 150); + REQUIRE(file_descriptor.get_offset() == 150); } THEN("the offset is updated correctly after writes") { REQUIRE(file_descriptor.write(nullptr, 200) == 200); - REQUIRE(file_descriptor.offset() == 200); + REQUIRE(file_descriptor.get_offset() == 200); REQUIRE(file_descriptor.write(nullptr, 25) == 25); - REQUIRE(file_descriptor.offset() == 225); + REQUIRE(file_descriptor.get_offset() == 225); } THEN("reads and writes both update the same offset") { REQUIRE(file_descriptor.read(nullptr, 10) == 10); - REQUIRE(file_descriptor.offset() == 10); + REQUIRE(file_descriptor.get_offset() == 10); REQUIRE(file_descriptor.write(nullptr, 20) == 20); - REQUIRE(file_descriptor.offset() == 30); + REQUIRE(file_descriptor.get_offset() == 30); REQUIRE(file_descriptor.read(nullptr, 5) == 5); - REQUIRE(file_descriptor.offset() == 35); + REQUIRE(file_descriptor.get_offset() == 35); REQUIRE(file_descriptor.write(nullptr, 15) == 15); - REQUIRE(file_descriptor.offset() == 50); + REQUIRE(file_descriptor.get_offset() == 50); } } } @@ -89,7 +89,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope kstd::vector buffer(32); auto bytes_read = ofd->read(buffer.data(), buffer.size()); REQUIRE(bytes_read == 7); - REQUIRE(ofd->offset() == 7); + REQUIRE(ofd->get_offset() == 7); std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(bytes_read)}; REQUIRE(buffer_as_str == "info_1\n"); @@ -100,11 +100,11 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope kstd::vector buffer(4); auto bytes_read_1 = ofd->read(buffer.data(), buffer.size() / 2); REQUIRE(bytes_read_1 == buffer.size() / 2); - REQUIRE(ofd->offset() == buffer.size() / 2); + REQUIRE(ofd->get_offset() == buffer.size() / 2); auto bytes_read_2 = ofd->read(buffer.data() + buffer.size() / 2, buffer.size() / 2); REQUIRE(bytes_read_2 == buffer.size() / 2); - REQUIRE(ofd->offset() == buffer.size()); + REQUIRE(ofd->get_offset() == buffer.size()); std::string_view buffer_as_str{reinterpret_cast(buffer.data()), bytes_read_1 + bytes_read_2}; REQUIRE(buffer_as_str == "info"); diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 77ae015..3b3d6ff 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -89,7 +89,22 @@ namespace kernel::filesystem auto vfs::open(std::string_view path) -> kstd::shared_ptr { - return resolve_path(path); + auto [dentry, mount] = resolve_path_internal(path); + mount->increment_ref_count(); + return dentry; + } + + auto vfs::close(kstd::shared_ptr const & dentry) -> operation_result + { + if (auto mount = find_mount(dentry->get_absolute_path().view())) + { + if (mount->decrement_ref_count()) + { + return operation_result::success; + } + return operation_result::close_failed; + } + return operation_result::invalid_path; } auto vfs::do_mount(std::string_view source, std::string_view target) -> operation_result -- cgit v1.2.3 From 0e279db4e1b799c4db0cc7c714d57686e3de7089 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 15 May 2026 22:36:05 +0200 Subject: refactoring rootfs, no separate child management needed --- .../kernel/filesystem/rootfs/filesystem.hpp | 2 +- kernel/include/kernel/filesystem/rootfs/inode.hpp | 30 +------------- kernel/src/filesystem/rootfs/filesystem.cpp | 9 +---- kernel/src/filesystem/rootfs/filesystem.tests.cpp | 7 ---- kernel/src/filesystem/rootfs/inode.cpp | 19 --------- kernel/src/filesystem/rootfs/inode.tests.cpp | 47 ---------------------- kernel/src/filesystem/vfs.cpp | 10 +---- 7 files changed, 5 insertions(+), 119 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp index cc778d8..f99440b 100644 --- a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp @@ -31,7 +31,7 @@ namespace kernel::filesystem::rootfs @brief Looks up an inode by @p name within a @p parent directory. @param parent The parent directory inode. @param name The name of the inode to look up. - @return A pointer to the found inode, or a null pointer if not found. + @return Always returns nullptr. */ auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr override; diff --git a/kernel/include/kernel/filesystem/rootfs/inode.hpp b/kernel/include/kernel/filesystem/rootfs/inode.hpp index 58035ea..442dc8a 100644 --- a/kernel/include/kernel/filesystem/rootfs/inode.hpp +++ b/kernel/include/kernel/filesystem/rootfs/inode.hpp @@ -8,16 +8,10 @@ #include #include -#include -#include - namespace kernel::filesystem::rootfs { /** - @brief Represents an inode in the rootfs filesystem. This inode represents a directory in the root filesystem and - maintains a list of child inodes corresponding to files and subdirectories within the root directory. The rootfs inode - provides methods for reading and writing data (which are no-ops for the root directory), as well as adding and looking - up child inodes by name. + @brief Represents an inode in the rootfs filesystem. */ struct inode : kernel::filesystem::inode { @@ -38,28 +32,6 @@ namespace kernel::filesystem::rootfs @return Number of bytes written (always 0 because writes are not supported for this inode). */ auto write(void const * buffer, size_t offset, size_t size) -> size_t override; - - /** - @brief Adds a child inode to the rootfs directory inode with the specified @p name. - @param name The name of the child inode. - */ - auto add_child(std::string_view name) -> void; - - /** - @brief Looks up a child inode by @p name. - @param name The name of the child inode to look up. - @return A pointer to the found child inode, or a null pointer if not found. - */ - auto lookup_child(std::string_view name) -> kstd::shared_ptr; - - /** - @brief Check if this inode represents a directory. - @return returns true, since this inode represents the root directory in the rootfs filesystem. - */ - [[nodiscard]] auto is_directory() const -> bool override; - - private: - kstd::vector>> m_children; }; } // namespace kernel::filesystem::rootfs diff --git a/kernel/src/filesystem/rootfs/filesystem.cpp b/kernel/src/filesystem/rootfs/filesystem.cpp index 6187c3c..d49e237 100644 --- a/kernel/src/filesystem/rootfs/filesystem.cpp +++ b/kernel/src/filesystem/rootfs/filesystem.cpp @@ -11,18 +11,13 @@ namespace kernel::filesystem::rootfs { auto filesystem::mount(kstd::shared_ptr const &) -> operation_result { - auto rfs_inode = kstd::make_shared(); - rfs_inode->add_child("dev"); - m_root_inode = rfs_inode; - + m_root_inode = kstd::make_shared(); return operation_result::success; } - auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) + auto filesystem::lookup(kstd::shared_ptr const &, std::string_view) -> kstd::shared_ptr { - if (auto * rfs_inode = static_cast(parent.get())) - return rfs_inode->lookup_child(name); return nullptr; } } // namespace kernel::filesystem::rootfs diff --git a/kernel/src/filesystem/rootfs/filesystem.tests.cpp b/kernel/src/filesystem/rootfs/filesystem.tests.cpp index 81ac9e4..ae320e9 100644 --- a/kernel/src/filesystem/rootfs/filesystem.tests.cpp +++ b/kernel/src/filesystem/rootfs/filesystem.tests.cpp @@ -21,13 +21,6 @@ SCENARIO("Rootfs filesystem mount and lookup", "[filesystem][rootfs][filesystem] REQUIRE(fs.root_inode() != nullptr); } - THEN("looking up the 'dev' directory returns a valid inode") - { - auto dev_inode = fs.lookup(fs.root_inode(), "dev"); - REQUIRE(dev_inode != nullptr); - REQUIRE(dev_inode->is_directory()); - } - THEN("looking up a non-existent directory returns null") { auto non_existent_inode_1 = fs.lookup(fs.root_inode(), ""); diff --git a/kernel/src/filesystem/rootfs/inode.cpp b/kernel/src/filesystem/rootfs/inode.cpp index d099676..2ad4815 100644 --- a/kernel/src/filesystem/rootfs/inode.cpp +++ b/kernel/src/filesystem/rootfs/inode.cpp @@ -5,10 +5,7 @@ #include #include -#include #include -#include -#include namespace kernel::filesystem::rootfs { @@ -21,20 +18,4 @@ namespace kernel::filesystem::rootfs { return 0; } - - auto inode::add_child(std::string_view name) -> void - { - m_children.push_back(std::make_pair(kstd::string{name}, kstd::make_shared())); - } - - auto inode::lookup_child(std::string_view name) -> kstd::shared_ptr - { - auto it = std::ranges::find_if(m_children, [&](auto const & pair) { return pair.first == name; }); - return (it != m_children.end()) ? it->second : nullptr; - } - - auto inode::is_directory() const -> bool - { - return true; - } } // namespace kernel::filesystem::rootfs diff --git a/kernel/src/filesystem/rootfs/inode.tests.cpp b/kernel/src/filesystem/rootfs/inode.tests.cpp index 7cc217f..f4b634f 100644 --- a/kernel/src/filesystem/rootfs/inode.tests.cpp +++ b/kernel/src/filesystem/rootfs/inode.tests.cpp @@ -6,53 +6,6 @@ #include -SCENARIO("Rootfs inode creation", "[filesystem][rootfs][inode]") -{ - GIVEN("a rootfs inode") - { - auto inode = kernel::filesystem::rootfs::inode{}; - - THEN("the inode has the correct kind") - { - REQUIRE(inode.is_directory()); - REQUIRE_FALSE(inode.is_device()); - REQUIRE_FALSE(inode.is_regular()); - REQUIRE_FALSE(inode.is_symbolic_link()); - } - - THEN("the inode has no children") - { - REQUIRE(inode.lookup_child("child") == nullptr); - } - } -} - -SCENARIO("Rootfs inode child management", "[filesystem][rootfs][inode]") -{ - GIVEN("a rootfs inode") - { - auto inode = kernel::filesystem::rootfs::inode{}; - - WHEN("adding a child inode") - { - inode.add_child("child"); - inode.add_child("another child"); - - THEN("the child can be looked up by name") - { - auto child_inode = inode.lookup_child("child"); - REQUIRE(child_inode != nullptr); - REQUIRE(child_inode->is_directory()); - } - - THEN("looking up a non-existent child returns null") - { - REQUIRE(inode.lookup_child("nonexistent") == nullptr); - } - } - } -} - SCENARIO("Rootfs inode read/write", "[filesystem][rootfs][inode]") { GIVEN("a rootfs inode") diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 3b3d6ff..67671e2 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -53,15 +53,7 @@ namespace kernel::filesystem // mount devfs at /dev (inside rootfs, temporary, will be shadowed) auto device_fs = kstd::make_shared(); device_fs->mount(nullptr); - - if (auto dev_mount_point_dentry = resolve_path("/dev")) - { - do_mount_internal(dev_mount_point_dentry, root_mount, device_fs); - } - else - { - kapi::system::panic("[FILESYSTEM] failed to resolve /dev for initial devfs mount."); - } + graft_persistent_device_fs(device_fs); // mount boot fs at / (shadows rootfs), re-graft devfs if (auto boot_device_dentry = resolve_path("/dev/ram0")) -- cgit v1.2.3 From 1f9fe3cf18b561749cfbdb2db8ab7572ddc40c03 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 15 May 2026 22:38:24 +0200 Subject: uniform interface for open and close --- kernel/include/kernel/filesystem/vfs.hpp | 6 +++--- kernel/kapi/filesystem.cpp | 2 +- kernel/src/filesystem/vfs.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 48b99b2..0058d04 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -62,11 +62,11 @@ namespace kernel::filesystem auto open(std::string_view path) -> kstd::shared_ptr; /** - @brief Close a file by its associated @p dentry. - @param dentry The dentry of the file to close. + @brief Close a file by its associated @p path. + @param path The path to the file to close. @return The result of the close operation. */ - auto close(kstd::shared_ptr const & dentry) -> operation_result; + auto close(std::string_view path) -> operation_result; /** @brief Mount a @p source path to a specific @p target path. diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index 1782da5..53a71be 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -46,7 +46,7 @@ namespace kapi::filesystem { if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().get_file(file_descriptor)) { - if (kernel::filesystem::vfs::get().close(open_file_descriptor->get_dentry()) == + if (kernel::filesystem::vfs::get().close(open_file_descriptor->get_dentry()->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success) { return kernel::filesystem::open_file_table::get().remove_file(file_descriptor); diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 67671e2..de19d38 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -86,9 +86,9 @@ namespace kernel::filesystem return dentry; } - auto vfs::close(kstd::shared_ptr const & dentry) -> operation_result + auto vfs::close(std::string_view path) -> operation_result { - if (auto mount = find_mount(dentry->get_absolute_path().view())) + if (auto mount = find_mount(path)) { if (mount->decrement_ref_count()) { -- cgit v1.2.3 From 2396fe6174ec875ba12dc135ab18f84550c07e9a Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 15 May 2026 22:40:52 +0200 Subject: avoid nullptr access --- kernel/src/filesystem/vfs.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index de19d38..f6eae25 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -82,6 +82,10 @@ namespace kernel::filesystem auto vfs::open(std::string_view path) -> kstd::shared_ptr { auto [dentry, mount] = resolve_path_internal(path); + if (!dentry || !mount) + { + return nullptr; + } mount->increment_ref_count(); return dentry; } -- cgit v1.2.3 From 16ccdee935d3b14edf93eea5a135e413b2fd47b5 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Fri, 15 May 2026 22:59:23 +0200 Subject: rootfs inode is a directory inode --- kernel/include/kernel/filesystem/rootfs/inode.hpp | 6 ++++++ kernel/src/filesystem/rootfs/inode.cpp | 5 +++++ 2 files changed, 11 insertions(+) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/rootfs/inode.hpp b/kernel/include/kernel/filesystem/rootfs/inode.hpp index 442dc8a..2671207 100644 --- a/kernel/include/kernel/filesystem/rootfs/inode.hpp +++ b/kernel/include/kernel/filesystem/rootfs/inode.hpp @@ -32,6 +32,12 @@ namespace kernel::filesystem::rootfs @return Number of bytes written (always 0 because writes are not supported for this inode). */ auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + + /** + @brief Check if this inode represents a directory. + @return returns true, since this inode represents the / directory in the rootfs filesystem. + */ + [[nodiscard]] auto is_directory() const -> bool override; }; } // namespace kernel::filesystem::rootfs diff --git a/kernel/src/filesystem/rootfs/inode.cpp b/kernel/src/filesystem/rootfs/inode.cpp index 2ad4815..dbe7948 100644 --- a/kernel/src/filesystem/rootfs/inode.cpp +++ b/kernel/src/filesystem/rootfs/inode.cpp @@ -18,4 +18,9 @@ namespace kernel::filesystem::rootfs { return 0; } + + auto inode::is_directory() const -> bool + { + return true; + } } // namespace kernel::filesystem::rootfs -- cgit v1.2.3 From ba2f62972823df320e05dea7080adf658c2977b3 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 16 May 2026 13:43:38 +0200 Subject: fix tests, all files must be closed before unmounting --- kernel/src/filesystem/vfs.tests.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index eaffbc9..28782ec 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -105,6 +105,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); REQUIRE(mounted_monkey_1 != nullptr); + REQUIRE(vfs.close(mounted_monkey_1->get_absolute_path().view()) == + kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); auto unmounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); @@ -126,6 +128,11 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(mounted_monkey_1 != nullptr); REQUIRE(mounted_fish1 != nullptr); + REQUIRE(vfs.close(mounted_monkey_1->get_absolute_path().view()) == + kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_fish1->get_absolute_path().view()) == + kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); REQUIRE(vfs.unmount("/information/monkey_house/infrastructure") == kernel::filesystem::vfs::operation_result::success); @@ -140,6 +147,9 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto mounted_tickets = vfs.open("/information/entrance/tickets.txt"); REQUIRE(mounted_tickets != nullptr); + REQUIRE(vfs.close(mounted_tickets->get_absolute_path().view()) == + kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); mounted_tickets = vfs.open("/information/entrance/tickets.txt"); REQUIRE(mounted_tickets == nullptr); @@ -161,6 +171,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto water = vfs.open("/monkey_house/infrastructure/water.txt"); REQUIRE(water != nullptr); + REQUIRE(vfs.close(water->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success); info_1 = vfs.open("/information/info_1.txt"); @@ -180,6 +192,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto water = vfs.open("/monkey_house/infrastructure/water.txt"); REQUIRE(water != nullptr); + REQUIRE(vfs.close(water->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + auto dev_ram_16 = vfs.open("/dev/ram16"); REQUIRE(dev_ram_16 == nullptr); @@ -196,6 +210,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1 != nullptr); + REQUIRE(vfs.close(info_1->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/dev") == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success); @@ -317,6 +333,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS std::string_view buffer_as_str{reinterpret_cast(buffer.data()), bytes_read}; REQUIRE(buffer_as_str == "sheep_1"); + REQUIRE(vfs.close(dentry->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); REQUIRE(unmounted_sheep_1 == nullptr); @@ -348,6 +366,9 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS buffer_as_str = std::string_view{reinterpret_cast(goat_buffer.data()), bytes_read}; REQUIRE(buffer_as_str == "goat_1"); + REQUIRE(vfs.close(sheep_1->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(goat_1->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); REQUIRE(vfs.unmount("/information/stable") == kernel::filesystem::vfs::operation_result::success); @@ -357,6 +378,9 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto still_mounted_sheep_1 = vfs.open("/information/sheep_1.txt"); REQUIRE(still_mounted_sheep_1 != nullptr); + REQUIRE(vfs.close(still_mounted_sheep_1->get_absolute_path().view()) == + kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); REQUIRE(unmounted_sheep_1 == nullptr); -- cgit v1.2.3 From 7ecf092ca7ff91dd59e81eda7ef2b05fe837844d Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 16 May 2026 13:53:34 +0200 Subject: add mount tests --- kernel/include/kernel/filesystem/mount.hpp | 7 +++++ kernel/src/filesystem/mount.cpp | 6 +++++ kernel/src/filesystem/mount.tests.cpp | 42 ++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index fb5a627..5d8ea69 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -8,6 +8,7 @@ #include #include +#include namespace kernel::filesystem { @@ -71,6 +72,12 @@ namespace kernel::filesystem */ [[nodiscard]] auto is_ready_to_unmount() const -> bool; + /** + @brief Get the current reference count for this mount. + @return The current reference count. + */ + [[nodiscard]] auto get_ref_count() const -> size_t; + private: kstd::shared_ptr m_mount_dentry; kstd::shared_ptr m_root_dentry; diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index 3016509..1e04083 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -8,6 +8,7 @@ #include #include +#include #include namespace kernel::filesystem @@ -75,4 +76,9 @@ namespace kernel::filesystem { return m_ref_count == 0; } + + auto mount::get_ref_count() const -> size_t + { + return m_ref_count; + } } // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/mount.tests.cpp b/kernel/src/filesystem/mount.tests.cpp index 58e9bab..e7dd709 100644 --- a/kernel/src/filesystem/mount.tests.cpp +++ b/kernel/src/filesystem/mount.tests.cpp @@ -29,6 +29,7 @@ SCENARIO("Mount construction", "[filesystem][mount]") REQUIRE(mount.get_root_dentry() == root_dentry); REQUIRE(mount.get_mount_dentry() == root_dentry); REQUIRE(mount.get_mount_path() == "/"); + REQUIRE(mount.is_ready_to_unmount()); } THEN("the mount has no parent mount") @@ -47,3 +48,44 @@ SCENARIO("Mount construction", "[filesystem][mount]") } } } + +SCENARIO("Mount reference counting", "[filesystem][mount]") +{ + GIVEN("a filesystem and a root dentry") + { + auto fs = kstd::make_shared(); + auto root_inode = kstd::make_shared(); + auto root_dentry = kstd::make_shared(nullptr, root_inode, "/"); + + THEN("reference count can be incremented and decremented, the mount is ready to unmount when the reference " + "count == 0") + { + auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr}; + + mount.increment_ref_count(); + REQUIRE(mount.get_ref_count() == 1); + REQUIRE_FALSE(mount.is_ready_to_unmount()); + + mount.increment_ref_count(); + REQUIRE(mount.get_ref_count() == 2); + REQUIRE_FALSE(mount.is_ready_to_unmount()); + + REQUIRE(mount.decrement_ref_count()); + REQUIRE(mount.get_ref_count() == 1); + REQUIRE_FALSE(mount.is_ready_to_unmount()); + + REQUIRE(mount.decrement_ref_count()); + REQUIRE(mount.get_ref_count() == 0); + REQUIRE(mount.is_ready_to_unmount()); + } + + THEN("decrementing reference count when it is already zero does not decrement it below zero") + { + auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr}; + + REQUIRE_FALSE(mount.decrement_ref_count()); + REQUIRE(mount.get_ref_count() == 0); + REQUIRE(mount.is_ready_to_unmount()); + } + } +} \ No newline at end of file -- cgit v1.2.3 From efc7ba748b977a792188724c461852f01c111957 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 16 May 2026 14:05:49 +0200 Subject: add vfs tests --- kernel/src/filesystem/vfs.cpp | 7 +++---- kernel/src/filesystem/vfs.tests.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index f6eae25..8636d0f 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -140,13 +140,12 @@ namespace kernel::filesystem { return operation_result::success; } - - if (remove_result == mount_table::operation_result::has_child_mounts) + else if (remove_result == mount_table::operation_result::mount_not_found) { - return operation_result::unmount_failed; + return operation_result::mount_point_not_found; } - return operation_result::mount_point_not_found; + return operation_result::unmount_failed; } auto vfs::do_mount_internal(kstd::shared_ptr const & mount_point_dentry, diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 28782ec..648ebb8 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -139,6 +139,36 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); } + THEN("image can be mounted, unmount only if no files are open") + { + REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); + + auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); + REQUIRE(mounted_monkey_1 != nullptr); + + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); + + REQUIRE(vfs.close(mounted_monkey_1->get_absolute_path().view()) == + kernel::filesystem::vfs::operation_result::success); + + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); + } + + THEN("file with invalid path or not opened file cannot be closed") + { + REQUIRE(vfs.close("invalid_path") == kernel::filesystem::vfs::operation_result::invalid_path); + REQUIRE(vfs.close("/information/info_1.txt") == kernel::filesystem::vfs::operation_result::close_failed); + } + + THEN("file cannot be closed twice") + { + auto info_1 = vfs.open("/information/info_1.txt"); + REQUIRE(info_1 != nullptr); + + REQUIRE(vfs.close(info_1->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(info_1->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::close_failed); + } + THEN("images can be stacked mounted and correct file system is unmounted again") { REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); -- cgit v1.2.3 From 5b40e4a28307eed814adb46188c3f6783651d286 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 16 May 2026 14:11:49 +0200 Subject: add kapi::filesystem tests --- kernel/kapi/filesystem.tests.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'kernel') diff --git a/kernel/kapi/filesystem.tests.cpp b/kernel/kapi/filesystem.tests.cpp index 1d1f8ee..d241afa 100644 --- a/kernel/kapi/filesystem.tests.cpp +++ b/kernel/kapi/filesystem.tests.cpp @@ -103,6 +103,19 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap REQUIRE(kapi::filesystem::umount("/information") == 0); } + THEN("a filesystem cannot be unmounted if files are still open and can be unmounted after files are closed") + { + REQUIRE(kapi::filesystem::mount("/dev/ram16", "/information") == 0); + + auto fd = kapi::filesystem::open("/information/monkey_house/monkey_1.txt"); + REQUIRE(fd >= 0); + + REQUIRE(kapi::filesystem::umount("/information") < 0); + + REQUIRE(kapi::filesystem::close(fd) == 0); + REQUIRE(kapi::filesystem::umount("/information") == 0); + } + THEN("device can be opened as file and read from") { auto fd = kapi::filesystem::open("/dev/ram0"); @@ -158,6 +171,15 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap REQUIRE(kapi::filesystem::close(999) < 0); } + THEN("same file cannot be closed twice") + { + auto fd = kapi::filesystem::open("/information/info_1.txt"); + REQUIRE(fd >= 0); + + REQUIRE(kapi::filesystem::close(fd) == 0); + REQUIRE(kapi::filesystem::close(fd) < 0); + } + THEN("not opened files cannot be read from") { std::vector buffer(10); -- 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/include/kernel/filesystem/constants.hpp | 1 + kernel/include/kernel/filesystem/dentry.hpp | 6 +- .../include/kernel/filesystem/devfs/filesystem.hpp | 2 +- .../include/kernel/filesystem/ext2/filesystem.hpp | 48 +++++++-------- kernel/include/kernel/filesystem/ext2/inode.hpp | 2 +- kernel/include/kernel/filesystem/filesystem.hpp | 3 +- kernel/include/kernel/filesystem/mount.hpp | 12 ++-- .../kernel/filesystem/open_file_descriptor.hpp | 2 +- .../include/kernel/filesystem/open_file_table.hpp | 9 ++- .../kernel/filesystem/rootfs/filesystem.hpp | 2 +- kernel/include/kernel/filesystem/rootfs/inode.hpp | 1 + kernel/include/kernel/filesystem/vfs.hpp | 6 +- .../kernel/test_support/filesystem/filesystem.hpp | 2 +- kernel/kapi/filesystem.cpp | 20 +++---- kernel/src/devices/block_device_utils.cpp | 2 + kernel/src/filesystem/dentry.cpp | 6 +- kernel/src/filesystem/dentry.tests.cpp | 14 ++--- kernel/src/filesystem/devfs/filesystem.cpp | 10 ++-- kernel/src/filesystem/devfs/inode.cpp | 4 +- kernel/src/filesystem/ext2/filesystem.cpp | 70 +++++++++++----------- kernel/src/filesystem/ext2/inode.cpp | 19 +++--- kernel/src/filesystem/ext2/inode.tests.cpp | 8 +-- kernel/src/filesystem/mount.cpp | 12 ++-- kernel/src/filesystem/mount.tests.cpp | 18 +++--- kernel/src/filesystem/mount_table.cpp | 11 ++-- kernel/src/filesystem/open_file_descriptor.cpp | 2 +- .../src/filesystem/open_file_descriptor.tests.cpp | 24 ++++---- kernel/src/filesystem/open_file_table.cpp | 31 ++++------ kernel/src/filesystem/open_file_table.tests.cpp | 19 ++---- kernel/src/filesystem/rootfs/filesystem.cpp | 3 +- kernel/src/filesystem/rootfs/inode.cpp | 7 +-- kernel/src/filesystem/vfs.cpp | 25 ++++---- kernel/src/filesystem/vfs.tests.cpp | 30 +++++----- kernel/src/test_support/filesystem/filesystem.cpp | 2 +- 34 files changed, 208 insertions(+), 225 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/constants.hpp b/kernel/include/kernel/filesystem/constants.hpp index aff512a..8388d05 100644 --- a/kernel/include/kernel/filesystem/constants.hpp +++ b/kernel/include/kernel/filesystem/constants.hpp @@ -2,6 +2,7 @@ #define TEACH_OS_KERNEL_FILESYSTEM_CONSTANTS_HPP #include + namespace kernel::filesystem::constants { constexpr size_t inline max_path_length = 4096; diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp index 925768a..478596a 100644 --- a/kernel/include/kernel/filesystem/dentry.hpp +++ b/kernel/include/kernel/filesystem/dentry.hpp @@ -46,19 +46,19 @@ namespace kernel::filesystem @brief Get the parent dentry. @return A reference to the parent dentry. */ - [[nodiscard]] auto get_parent() const -> kstd::shared_ptr const &; + [[nodiscard]] auto parent() const -> kstd::shared_ptr const &; /** @brief Get the name of the dentry. @return The name of the dentry. */ - [[nodiscard]] auto get_name() const -> std::string_view; + [[nodiscard]] auto name() const -> std::string_view; /** @brief Get the full path of the dentry by traversing up to the root. @return The full path of the dentry. */ - [[nodiscard]] auto get_absolute_path() const -> kstd::string; + [[nodiscard]] auto absolute_path() const -> kstd::string; /** @brief Add a @p child dentry. diff --git a/kernel/include/kernel/filesystem/devfs/filesystem.hpp b/kernel/include/kernel/filesystem/devfs/filesystem.hpp index 8d96555..dbaa387 100644 --- a/kernel/include/kernel/filesystem/devfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/devfs/filesystem.hpp @@ -33,7 +33,7 @@ namespace kernel::filesystem::devfs @param name The name of the inode to look up. @return A pointer to the found inode, or a null pointer if not found. */ - auto lookup(kstd::shared_ptr const & parent, std::string_view name) + [[nodiscard]] auto lookup(kstd::shared_ptr const & parent, std::string_view name) const -> kstd::shared_ptr override; private: diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index 46be32f..a408c64 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -15,6 +15,8 @@ #include #include +#include + namespace kernel::filesystem::ext2 { /** @@ -61,20 +63,20 @@ namespace kernel::filesystem::ext2 @param name The name of the inode to look up. @return A pointer to the found inode, or a null pointer if not found. */ - auto lookup(kstd::shared_ptr const & parent, std::string_view name) + [[nodiscard]] auto lookup(kstd::shared_ptr const & parent, std::string_view name) const -> kstd::shared_ptr override; /** @brief Gets the size of a block in the filesystem. @return The size of a block in bytes. */ - [[nodiscard]] auto get_block_size() const -> size_t; + [[nodiscard]] auto block_size() const -> size_t; /** @brief Gets the revision level of the filesystem. @return The revision level. */ - [[nodiscard]] auto get_revision_level() const -> size_t; + [[nodiscard]] auto revision_level() const -> size_t; /** @brief Maps an inode block index to a global block number. @@ -82,30 +84,28 @@ namespace kernel::filesystem::ext2 @param data The inode data. @return The global block number. */ - [[nodiscard]] auto map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) const + [[nodiscard]] auto map_inode_block_index_to_global_block_number(size_t inode_block_index, inode_data data) const -> ssize_t; private: - [[nodiscard]] auto read_inode(uint32_t inode_number) const -> kstd::shared_ptr; - [[nodiscard]] auto read_block_number_at_index(uint32_t block_number, uint32_t index) const -> uint32_t; - - [[nodiscard]] auto read_singly_indirect_block_number(uint32_t singly_indirect_block_number, - uint32_t block_index_in_singly_indirect_block) const - -> uint32_t; - [[nodiscard]] auto read_doubly_indirect_block_number(uint32_t doubly_indirect_block_number, - uint32_t block_index_in_doubly_indirect_block) const - -> uint32_t; - [[nodiscard]] auto read_triply_indirect_block_number(uint32_t triply_indirect_block_number, - uint32_t block_index_in_triply_indirect_block) const - -> uint32_t; - - [[nodiscard]] auto get_inode_size() const -> size_t; - [[nodiscard]] auto get_inode_block_count(inode_data const & data) const -> uint32_t; - - [[nodiscard]] auto block_numbers_per_block() const -> uint32_t; - [[nodiscard]] auto block_numbers_per_singly_indirect_block() const -> uint32_t; - [[nodiscard]] auto block_numbers_per_doubly_indirect_block() const -> uint32_t; - [[nodiscard]] auto block_numbers_per_triply_indirect_block() const -> uint32_t; + [[nodiscard]] auto read_inode(size_t inode_number) const -> kstd::shared_ptr; + [[nodiscard]] auto read_block_number_at_index(size_t block_number, size_t index) const -> size_t; + + [[nodiscard]] auto read_singly_indirect_block_number(size_t singly_indirect_block_number, + size_t block_index_in_singly_indirect_block) const -> size_t; + [[nodiscard]] auto read_doubly_indirect_block_number(size_t doubly_indirect_block_number, + size_t block_index_in_doubly_indirect_block) const -> size_t; + [[nodiscard]] auto read_triply_indirect_block_number(size_t triply_indirect_block_number, + size_t block_index_in_triply_indirect_block) const -> size_t; + + [[nodiscard]] auto inode_size() const -> size_t; + [[nodiscard]] auto inode_block_count(inode_data const & data) const -> size_t; + [[nodiscard]] auto block_group_descriptor_table_offset() const -> size_t; + + [[nodiscard]] auto block_numbers_per_block() const -> size_t; + [[nodiscard]] auto block_numbers_per_singly_indirect_block() const -> size_t; + [[nodiscard]] auto block_numbers_per_doubly_indirect_block() const -> size_t; + [[nodiscard]] auto block_numbers_per_triply_indirect_block() const -> size_t; superblock m_superblock{}; kstd::vector m_block_group_descriptors; diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp index 000a5d8..5609319 100644 --- a/kernel/include/kernel/filesystem/ext2/inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/inode.hpp @@ -94,7 +94,7 @@ namespace kernel::filesystem::ext2 @brief Get the size of the file represented by this inode. @return The size of the file in bytes. */ - [[nodiscard]] auto get_size() const -> size_t; + [[nodiscard]] auto size() const -> size_t; private: filesystem const * m_filesystem; diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp index 2fdc0ed..bec1b16 100644 --- a/kernel/include/kernel/filesystem/filesystem.hpp +++ b/kernel/include/kernel/filesystem/filesystem.hpp @@ -56,7 +56,8 @@ namespace kernel::filesystem @param name The name of the child inode to look up. @return A pointer to the requested child inode, or a null pointer if not found. */ - virtual auto lookup(kstd::shared_ptr const & parent, std::string_view name) -> kstd::shared_ptr = 0; + [[nodiscard]] virtual auto lookup(kstd::shared_ptr const & parent, std::string_view name) const + -> kstd::shared_ptr = 0; /** @brief Returns a reference to the root inode of the filesystem. diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index 5d8ea69..4ce374f 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -33,12 +33,12 @@ namespace kernel::filesystem /** @brief Get the dentry where the filesystem is mounted. */ - [[nodiscard]] auto get_mount_dentry() const -> kstd::shared_ptr const &; + [[nodiscard]] auto mount_dentry() const -> kstd::shared_ptr const &; /** @brief Get the root dentry of the mounted filesystem. */ - [[nodiscard]] auto get_root_dentry() const -> kstd::shared_ptr const &; + [[nodiscard]] auto root_dentry() const -> kstd::shared_ptr const &; /** @brief Get the filesystem instance being mounted. @@ -48,12 +48,12 @@ namespace kernel::filesystem /** @brief Get the path at which the filesystem is mounted. */ - [[nodiscard]] auto get_mount_path() const -> kstd::string; + [[nodiscard]] auto mount_path() const -> kstd::string; /** @brief Get the parent mount that this mount was attached beneath. */ - [[nodiscard]] auto get_parent_mount() const -> kstd::shared_ptr const &; + [[nodiscard]] auto parent_mount() const -> kstd::shared_ptr const &; /** @brief Increment the reference count for this mount. @@ -64,7 +64,7 @@ namespace kernel::filesystem @brief Decrement the reference count for this mount. @return True if the reference count reached zero, false otherwise. */ - auto decrement_ref_count() -> bool; + [[nodiscard]] auto decrement_ref_count() -> bool; /** @brief Check if the mount is ready to be unmounted. @@ -76,7 +76,7 @@ namespace kernel::filesystem @brief Get the current reference count for this mount. @return The current reference count. */ - [[nodiscard]] auto get_ref_count() const -> size_t; + [[nodiscard]] auto ref_count() const -> size_t; private: kstd::shared_ptr m_mount_dentry; diff --git a/kernel/include/kernel/filesystem/open_file_descriptor.hpp b/kernel/include/kernel/filesystem/open_file_descriptor.hpp index 7ca7350..fd10e64 100644 --- a/kernel/include/kernel/filesystem/open_file_descriptor.hpp +++ b/kernel/include/kernel/filesystem/open_file_descriptor.hpp @@ -50,7 +50,7 @@ namespace kernel::filesystem @brief Returns the current file offset for this open file descriptor. @return The current file offset in bytes. */ - [[nodiscard]] auto get_offset() const -> size_t; + [[nodiscard]] auto offset() const -> size_t; /** @brief Return a reference to the dentry associated with this open file descriptor. diff --git a/kernel/include/kernel/filesystem/open_file_table.hpp b/kernel/include/kernel/filesystem/open_file_table.hpp index 694f3b6..5794e4c 100644 --- a/kernel/include/kernel/filesystem/open_file_table.hpp +++ b/kernel/include/kernel/filesystem/open_file_table.hpp @@ -6,6 +6,9 @@ #include #include +#include +#include + namespace kernel::filesystem { /** @@ -37,21 +40,21 @@ namespace kernel::filesystem @param fd The file descriptor to add. @return The file descriptor index assigned to the file, or -1 on failure. */ - auto add_file(kstd::shared_ptr const & fd) -> int; + auto add_file(kstd::shared_ptr const & fd) -> ssize_t; /** @brief Get a file from the open file table. @param fd The file descriptor index to retrieve. @return A pointer to the requested file descriptor, or a null pointer if not found. */ - [[nodiscard]] auto get_file(int fd) const -> kstd::shared_ptr; + [[nodiscard]] auto file(size_t fd) const -> kstd::shared_ptr; /** @brief Remove a file from the open file table. @param fd The file descriptor index to remove. @return 0 on success, or -1 on failure. */ - auto remove_file(int fd) -> int; + auto remove_file(size_t fd) -> ssize_t; private: open_file_table() = default; diff --git a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp index f99440b..3c2dcb1 100644 --- a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp +++ b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp @@ -33,7 +33,7 @@ namespace kernel::filesystem::rootfs @param name The name of the inode to look up. @return Always returns nullptr. */ - auto lookup(kstd::shared_ptr const & parent, std::string_view name) + [[nodiscard]] auto lookup(kstd::shared_ptr const & parent, std::string_view name) const -> kstd::shared_ptr override; }; } // namespace kernel::filesystem::rootfs diff --git a/kernel/include/kernel/filesystem/rootfs/inode.hpp b/kernel/include/kernel/filesystem/rootfs/inode.hpp index 2671207..0f21eaa 100644 --- a/kernel/include/kernel/filesystem/rootfs/inode.hpp +++ b/kernel/include/kernel/filesystem/rootfs/inode.hpp @@ -8,6 +8,7 @@ #include #include + namespace kernel::filesystem::rootfs { /** diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 0058d04..aec8bfe 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -97,10 +97,10 @@ namespace kernel::filesystem * - resolve_path() for the dentry only. * - find_mount() for the mount context only. */ - [[nodiscard]] auto resolve_path_internal(std::string_view path) + [[nodiscard]] auto resolve_path_internal(std::string_view path) const -> std::pair, kstd::shared_ptr>; - [[nodiscard]] auto resolve_path(std::string_view path) -> kstd::shared_ptr; - [[nodiscard]] auto find_mount(std::string_view path) -> kstd::shared_ptr; + [[nodiscard]] auto resolve_path(std::string_view path) const -> kstd::shared_ptr; + [[nodiscard]] auto find_mount(std::string_view path) const -> kstd::shared_ptr; auto do_mount_internal(kstd::shared_ptr const & mount_point_dentry, kstd::shared_ptr const & parent_mount, kstd::shared_ptr const & fs) diff --git a/kernel/include/kernel/test_support/filesystem/filesystem.hpp b/kernel/include/kernel/test_support/filesystem/filesystem.hpp index dab0892..5f26022 100644 --- a/kernel/include/kernel/test_support/filesystem/filesystem.hpp +++ b/kernel/include/kernel/test_support/filesystem/filesystem.hpp @@ -14,7 +14,7 @@ namespace kernel::tests::filesystem { filesystem() = default; - auto lookup(kstd::shared_ptr const & parent, std::string_view name) + [[nodiscard]] auto lookup(kstd::shared_ptr const & parent, std::string_view name) const -> kstd::shared_ptr override; }; } // namespace kernel::tests::filesystem diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index 53a71be..db61c34 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -13,7 +13,7 @@ namespace kapi::filesystem { - auto mount(std::string_view source, std::string_view target) -> int + auto mount(std::string_view source, std::string_view target) -> ssize_t { if (kernel::filesystem::vfs::get().do_mount(source, target) == kernel::filesystem::vfs::operation_result::success) { @@ -22,7 +22,7 @@ namespace kapi::filesystem return -1; } - auto umount(std::string_view target) -> int + auto umount(std::string_view target) -> ssize_t { if (kernel::filesystem::vfs::get().unmount(target) == kernel::filesystem::vfs::operation_result::success) { @@ -31,7 +31,7 @@ namespace kapi::filesystem return -1; } - auto open(std::string_view path) -> int + auto open(std::string_view path) -> ssize_t { if (auto dentry = kernel::filesystem::vfs::get().open(path)) { @@ -42,11 +42,11 @@ namespace kapi::filesystem return -1; } - auto close(int file_descriptor) -> int + auto close(size_t file_descriptor) -> ssize_t { - if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().get_file(file_descriptor)) + if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().file(file_descriptor)) { - if (kernel::filesystem::vfs::get().close(open_file_descriptor->get_dentry()->get_absolute_path().view()) == + if (kernel::filesystem::vfs::get().close(open_file_descriptor->get_dentry()->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success) { return kernel::filesystem::open_file_table::get().remove_file(file_descriptor); @@ -55,9 +55,9 @@ namespace kapi::filesystem return -1; } - auto read(int file_descriptor, void * buffer, size_t size) -> ssize_t + auto read(size_t file_descriptor, void * buffer, size_t size) -> ssize_t { - if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().get_file(file_descriptor)) + if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().file(file_descriptor)) { return open_file_descriptor->read(buffer, size); } @@ -65,9 +65,9 @@ namespace kapi::filesystem return -1; } - auto write(int file_descriptor, void const * buffer, size_t size) -> ssize_t + auto write(size_t file_descriptor, void const * buffer, size_t size) -> ssize_t { - if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().get_file(file_descriptor)) + if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().file(file_descriptor)) { return open_file_descriptor->write(buffer, size); } 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}; diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index d963ed7..14de875 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -34,17 +34,17 @@ namespace kernel::filesystem return m_inode; } - auto dentry::get_parent() const -> kstd::shared_ptr const & + auto dentry::parent() const -> kstd::shared_ptr const & { return m_parent; } - auto dentry::get_name() const -> std::string_view + auto dentry::name() const -> std::string_view { return m_name.view(); } - auto dentry::get_absolute_path() const -> kstd::string + auto dentry::absolute_path() const -> kstd::string { kstd::string path = m_name; diff --git a/kernel/src/filesystem/dentry.tests.cpp b/kernel/src/filesystem/dentry.tests.cpp index e9ecbc8..b7690f5 100644 --- a/kernel/src/filesystem/dentry.tests.cpp +++ b/kernel/src/filesystem/dentry.tests.cpp @@ -21,9 +21,9 @@ SCENARIO("Dentry construction", "[filesystem][dentry]") THEN("the dentry has the correct parent, inode, and name") { - REQUIRE(child_dentry.get_parent() == parent_dentry); + REQUIRE(child_dentry.parent() == parent_dentry); REQUIRE(child_dentry.get_inode() == inode); - REQUIRE(child_dentry.get_name() == "child"); + REQUIRE(child_dentry.name() == "child"); } THEN("no flag is set") @@ -46,9 +46,9 @@ SCENARIO("Dentry construction", "[filesystem][dentry]") THEN("the dentry has a null parent, the correct inode, and the correct name") { - REQUIRE(child_dentry.get_parent() == nullptr); + REQUIRE(child_dentry.parent() == nullptr); REQUIRE(child_dentry.get_inode() == inode); - REQUIRE(child_dentry.get_name() == "child"); + REQUIRE(child_dentry.name() == "child"); } THEN("no flag is set") @@ -142,9 +142,9 @@ SCENARIO("Dentry path resolution", "[filesystem][dentry]") THEN("the full path is constructed correctly") { - REQUIRE(root_dentry->get_absolute_path() == "/"); - REQUIRE(home_dentry->get_absolute_path() == "/home"); - REQUIRE(user_dentry->get_absolute_path() == "/home/user"); + REQUIRE(root_dentry->absolute_path() == "/"); + REQUIRE(home_dentry->absolute_path() == "/home"); + REQUIRE(user_dentry->absolute_path() == "/home/user"); } } } \ No newline at end of file diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp index 96e40a8..f0d8bf7 100644 --- a/kernel/src/filesystem/devfs/filesystem.cpp +++ b/kernel/src/filesystem/devfs/filesystem.cpp @@ -1,5 +1,6 @@ #include +#include "kernel/filesystem/filesystem.hpp" #include #include #include @@ -22,7 +23,7 @@ namespace kernel::filesystem::devfs return operation_result::success; } - auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) + auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) const -> kstd::shared_ptr { if (!parent || !parent->is_directory()) @@ -36,12 +37,11 @@ namespace kernel::filesystem::devfs } auto it = std::ranges::find_if(m_inodes, [&](auto const & dev_node) { - auto device_inode_ptr = static_cast(dev_node.get()); - if (!device_inode_ptr) + if (auto device_inode_ptr = static_cast(dev_node.get())) { - return false; + return device_inode_ptr->device()->name() == name; } - return device_inode_ptr->device()->name() == name; + return false; }); return (it != m_inodes.end()) ? *it : nullptr; } diff --git a/kernel/src/filesystem/devfs/inode.cpp b/kernel/src/filesystem/devfs/inode.cpp index 2029a7f..7bbfbbe 100644 --- a/kernel/src/filesystem/devfs/inode.cpp +++ b/kernel/src/filesystem/devfs/inode.cpp @@ -4,12 +4,12 @@ namespace kernel::filesystem::devfs { - auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t + auto inode::read(void *, size_t, size_t) const -> size_t { return 0; } - auto inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t + auto inode::write(void const *, size_t, size_t) -> size_t { return 0; } diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 893cc38..7633972 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -28,14 +28,12 @@ namespace kernel::filesystem::ext2 return operation_result::invalid_magic_number; } - auto const block_size = get_block_size(); auto const blocks_per_group = m_superblock.blocks_per_group; auto const num_block_groups = (m_superblock.blocks_count + blocks_per_group - 1) / blocks_per_group; m_block_group_descriptors = kstd::vector(num_block_groups); - auto const block_group_descriptor_table_offset = block_size == 1024 ? 2 * block_size : block_size; - m_backing_inode->read(m_block_group_descriptors.data(), block_group_descriptor_table_offset, + m_backing_inode->read(m_block_group_descriptors.data(), block_group_descriptor_table_offset(), num_block_groups * sizeof(block_group_descriptor)); m_root_inode = read_inode(constants::root_inode_number); @@ -47,7 +45,7 @@ namespace kernel::filesystem::ext2 return operation_result::success; } - auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) + auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) const -> kstd::shared_ptr { if (!parent || !parent->is_directory()) @@ -61,20 +59,19 @@ namespace kernel::filesystem::ext2 return nullptr; } - auto const block_size = get_block_size(); auto const & inode_data = ext2_parent->data(); - kstd::vector buffer(block_size); + kstd::vector buffer(block_size()); - for (uint32_t i = 0; i < get_inode_block_count(inode_data); ++i) + for (auto i = 0uz; i < inode_block_count(inode_data); ++i) { auto const global_block_number = map_inode_block_index_to_global_block_number(i, inode_data); - auto const block_offset = global_block_number * block_size; - m_backing_inode->read(buffer.data(), block_offset, block_size); + auto const block_offset = global_block_number * block_size(); + m_backing_inode->read(buffer.data(), block_offset, block_size()); auto const * entry = reinterpret_cast(buffer.data()); auto bytes_read = 0uz; - while (bytes_read < block_size && entry->inode != 0) + while (bytes_read < block_size() && entry->inode != 0) { auto const entry_name = std::string_view{entry->name.data(), entry->name_len}; if (entry_name == name) @@ -90,9 +87,8 @@ namespace kernel::filesystem::ext2 return nullptr; } - auto filesystem::read_inode(uint32_t inode_number) const -> kstd::shared_ptr + auto filesystem::read_inode(size_t inode_number) const -> kstd::shared_ptr { - auto const block_size = get_block_size(); auto const inodes_per_group = m_superblock.inodes_per_group; auto const block_group_index = (inode_number - 1) / inodes_per_group; auto const inode_index_within_group = (inode_number - 1) % inodes_per_group; @@ -104,8 +100,8 @@ namespace kernel::filesystem::ext2 auto const & block_group_descriptor = m_block_group_descriptors.at(block_group_index); auto const inode_table_start_block = block_group_descriptor.inode_table; - auto const inode_table_offset = static_cast(inode_table_start_block) * block_size; - auto const inode_offset = inode_table_offset + inode_index_within_group * get_inode_size(); + auto const inode_table_offset = static_cast(inode_table_start_block) * block_size(); + auto const inode_offset = inode_table_offset + inode_index_within_group * inode_size(); auto new_inode_data = inode_data{}; m_backing_inode->read(&new_inode_data, inode_offset, sizeof(inode_data)); @@ -113,7 +109,7 @@ namespace kernel::filesystem::ext2 return kstd::make_shared(this, new_inode_data); } - auto filesystem::map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) const + auto filesystem::map_inode_block_index_to_global_block_number(size_t inode_block_index, inode_data data) const -> ssize_t { if (inode_block_index < constants::direct_block_count) @@ -145,18 +141,19 @@ namespace kernel::filesystem::ext2 return -1; } - auto filesystem::read_singly_indirect_block_number(uint32_t singly_indirect_block_number, - uint32_t block_index_in_singly_indirect_block) const -> uint32_t + auto filesystem::read_singly_indirect_block_number(size_t singly_indirect_block_number, + size_t block_index_in_singly_indirect_block) const -> size_t { if (singly_indirect_block_number == 0) { return 0; } + return read_block_number_at_index(singly_indirect_block_number, block_index_in_singly_indirect_block); } - auto filesystem::read_doubly_indirect_block_number(uint32_t doubly_indirect_block_number, - uint32_t block_index_in_doubly_indirect_block) const -> uint32_t + auto filesystem::read_doubly_indirect_block_number(size_t doubly_indirect_block_number, + size_t block_index_in_doubly_indirect_block) const -> size_t { if (doubly_indirect_block_number == 0) { @@ -174,8 +171,8 @@ namespace kernel::filesystem::ext2 return read_singly_indirect_block_number(singly_indirect_block_number, block_index_in_singly_indirect_block); } - auto filesystem::read_triply_indirect_block_number(uint32_t triply_indirect_block_number, - uint32_t block_index_in_triply_indirect_block) const -> uint32_t + auto filesystem::read_triply_indirect_block_number(size_t triply_indirect_block_number, + size_t block_index_in_triply_indirect_block) const -> size_t { if (triply_indirect_block_number == 0) { @@ -193,54 +190,59 @@ namespace kernel::filesystem::ext2 return read_doubly_indirect_block_number(doubly_indirect_block_number, block_index_in_doubly_indirect_block); } - auto filesystem::read_block_number_at_index(uint32_t block_number, uint32_t index) const -> uint32_t + auto filesystem::read_block_number_at_index(size_t block_number, size_t index) const -> size_t { - uint32_t block_number_buffer = 0; + auto block_number_buffer = 0uz; - auto const block_start_offset = block_number * get_block_size(); + auto const block_start_offset = block_number * block_size(); auto const number_start_address = block_start_offset + index * sizeof(uint32_t); m_backing_inode->read(&block_number_buffer, number_start_address, sizeof(uint32_t)); return block_number_buffer; } - auto filesystem::block_numbers_per_block() const -> uint32_t + auto filesystem::block_numbers_per_block() const -> size_t { - return get_block_size() / sizeof(uint32_t); + return block_size() / sizeof(uint32_t); } - auto filesystem::block_numbers_per_singly_indirect_block() const -> uint32_t + auto filesystem::block_numbers_per_singly_indirect_block() const -> size_t { return block_numbers_per_block(); } - auto filesystem::block_numbers_per_doubly_indirect_block() const -> uint32_t + auto filesystem::block_numbers_per_doubly_indirect_block() const -> size_t { return block_numbers_per_singly_indirect_block() * block_numbers_per_block(); } - auto filesystem::block_numbers_per_triply_indirect_block() const -> uint32_t + auto filesystem::block_numbers_per_triply_indirect_block() const -> size_t { return block_numbers_per_doubly_indirect_block() * block_numbers_per_block(); } - auto filesystem::get_block_size() const -> size_t + auto filesystem::block_size() const -> size_t { return constants::base_block_size << m_superblock.log_block_size; } - auto filesystem::get_revision_level() const -> size_t + auto filesystem::revision_level() const -> size_t { return m_superblock.rev_level; } - auto filesystem::get_inode_size() const -> size_t + auto filesystem::inode_size() const -> size_t { - return get_revision_level() == constants::good_old_revision ? 128 : m_superblock.inode_size; + return revision_level() == constants::good_old_revision ? 128 : m_superblock.inode_size; } - auto filesystem::get_inode_block_count(inode_data const & data) const -> uint32_t + auto filesystem::inode_block_count(inode_data const & data) const -> size_t { return data.blocks / (2 << m_superblock.log_block_size); } + + auto filesystem::block_group_descriptor_table_offset() const -> size_t + { + return block_size() == 1024 ? 2 * block_size() : block_size(); + } } // namespace kernel::filesystem::ext2 diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index cfe0a35..f8c818c 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -25,18 +25,18 @@ namespace kernel::filesystem::ext2 auto inode::read(void * buffer, size_t offset, size_t size) const -> size_t { - auto const max_readable = get_size() - offset; + auto const max_readable = this->size() - offset; auto const requested_size = std::min(size, max_readable); - if (is_symbolic_link() && get_size() <= sizeof(m_data.block)) + if (is_symbolic_link() && this->size() <= sizeof(m_data.block)) { auto inline_target = reinterpret_cast(m_data.block.data()); kstd::libc::memcpy(static_cast(buffer), inline_target + offset, requested_size); return requested_size; } - auto block_index = offset / m_filesystem->get_block_size(); - auto in_block_offset = offset % m_filesystem->get_block_size(); + auto block_index = offset / m_filesystem->block_size(); + auto in_block_offset = offset % m_filesystem->block_size(); auto bytes_read = 0uz; @@ -48,8 +48,7 @@ namespace kernel::filesystem::ext2 break; } - auto const bytes_to_read = - std::min(requested_size - bytes_read, m_filesystem->get_block_size() - in_block_offset); + auto const bytes_to_read = std::min(requested_size - bytes_read, m_filesystem->block_size() - in_block_offset); if (block_number == 0) { kstd::libc::memset(static_cast(buffer) + bytes_read, 0, bytes_to_read); @@ -57,7 +56,7 @@ namespace kernel::filesystem::ext2 } else { - auto const block_start_offset = block_number * m_filesystem->get_block_size(); + auto const block_start_offset = block_number * m_filesystem->block_size(); auto const read_offset = block_start_offset + in_block_offset; bytes_read += m_filesystem->backing_inode()->read(static_cast(buffer) + bytes_read, read_offset, @@ -71,7 +70,7 @@ namespace kernel::filesystem::ext2 return bytes_read; } - auto inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t + auto inode::write(void const *, size_t, size_t) -> size_t { kapi::system::panic("[EXT2] inode::write is not implemented yet"); return 0; @@ -97,11 +96,11 @@ namespace kernel::filesystem::ext2 return (m_data.mode & constants::mode_mask) == constants::mode_symbolic_link; } - auto inode::get_size() const -> size_t + auto inode::size() const -> size_t { uint64_t size = m_data.size; - if (m_filesystem->get_revision_level() > constants::good_old_revision && is_regular()) + if (m_filesystem->revision_level() > constants::good_old_revision && is_regular()) { size |= static_cast(m_data.dir_acl) << 32; } diff --git a/kernel/src/filesystem/ext2/inode.tests.cpp b/kernel/src/filesystem/ext2/inode.tests.cpp index efc0660..4aecc04 100644 --- a/kernel/src/filesystem/ext2/inode.tests.cpp +++ b/kernel/src/filesystem/ext2/inode.tests.cpp @@ -325,7 +325,7 @@ SCENARIO("Ext2 inode get_size() correctly returns size depending on revision lev auto inode = kernel::filesystem::ext2::inode{&fs, data}; - REQUIRE(inode.get_size() == 256); + REQUIRE(inode.size() == 256); } THEN("the inode size is 256 if mode = directory") @@ -334,7 +334,7 @@ SCENARIO("Ext2 inode get_size() correctly returns size depending on revision lev auto inode = kernel::filesystem::ext2::inode{&fs, data}; - REQUIRE(inode.get_size() == 256); + REQUIRE(inode.size() == 256); } } @@ -361,7 +361,7 @@ SCENARIO("Ext2 inode get_size() correctly returns size depending on revision lev auto inode = kernel::filesystem::ext2::inode{&fs, data}; - REQUIRE(inode.get_size() == 0x0000'0020'0000'0100); + REQUIRE(inode.size() == 0x0000'0020'0000'0100); } THEN("the inode size is 256 if mode = directory") @@ -370,7 +370,7 @@ SCENARIO("Ext2 inode get_size() correctly returns size depending on revision lev auto inode = kernel::filesystem::ext2::inode{&fs, data}; - REQUIRE(inode.get_size() == 256); + REQUIRE(inode.size() == 256); } } } \ No newline at end of file diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index 1e04083..b64c370 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -27,7 +27,7 @@ namespace kernel::filesystem } } - auto mount::get_mount_dentry() const -> kstd::shared_ptr const & + auto mount::mount_dentry() const -> kstd::shared_ptr const & { return m_mount_dentry; } @@ -37,21 +37,21 @@ namespace kernel::filesystem return m_filesystem; } - auto mount::get_root_dentry() const -> kstd::shared_ptr const & + auto mount::root_dentry() const -> kstd::shared_ptr const & { return m_root_dentry; } - auto mount::get_mount_path() const -> kstd::string + auto mount::mount_path() const -> kstd::string { if (m_mount_dentry) { - return m_mount_dentry->get_absolute_path(); + return m_mount_dentry->absolute_path(); } return "/"; } - auto mount::get_parent_mount() const -> kstd::shared_ptr const & + auto mount::parent_mount() const -> kstd::shared_ptr const & { return m_parent_mount; } @@ -77,7 +77,7 @@ namespace kernel::filesystem return m_ref_count == 0; } - auto mount::get_ref_count() const -> size_t + auto mount::ref_count() const -> size_t { return m_ref_count; } diff --git a/kernel/src/filesystem/mount.tests.cpp b/kernel/src/filesystem/mount.tests.cpp index e7dd709..6b66571 100644 --- a/kernel/src/filesystem/mount.tests.cpp +++ b/kernel/src/filesystem/mount.tests.cpp @@ -26,15 +26,15 @@ SCENARIO("Mount construction", "[filesystem][mount]") THEN("the mount has the correct filesystem, root dentry, mount dentry, and mount path") { REQUIRE(mount.get_filesystem() == fs); - REQUIRE(mount.get_root_dentry() == root_dentry); - REQUIRE(mount.get_mount_dentry() == root_dentry); - REQUIRE(mount.get_mount_path() == "/"); + REQUIRE(mount.root_dentry() == root_dentry); + REQUIRE(mount.mount_dentry() == root_dentry); + REQUIRE(mount.mount_path() == "/"); REQUIRE(mount.is_ready_to_unmount()); } THEN("the mount has no parent mount") { - REQUIRE(mount.get_parent_mount() == nullptr); + REQUIRE(mount.parent_mount() == nullptr); } } @@ -63,19 +63,19 @@ SCENARIO("Mount reference counting", "[filesystem][mount]") auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr}; mount.increment_ref_count(); - REQUIRE(mount.get_ref_count() == 1); + REQUIRE(mount.ref_count() == 1); REQUIRE_FALSE(mount.is_ready_to_unmount()); mount.increment_ref_count(); - REQUIRE(mount.get_ref_count() == 2); + REQUIRE(mount.ref_count() == 2); REQUIRE_FALSE(mount.is_ready_to_unmount()); REQUIRE(mount.decrement_ref_count()); - REQUIRE(mount.get_ref_count() == 1); + REQUIRE(mount.ref_count() == 1); REQUIRE_FALSE(mount.is_ready_to_unmount()); REQUIRE(mount.decrement_ref_count()); - REQUIRE(mount.get_ref_count() == 0); + REQUIRE(mount.ref_count() == 0); REQUIRE(mount.is_ready_to_unmount()); } @@ -84,7 +84,7 @@ SCENARIO("Mount reference counting", "[filesystem][mount]") auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr}; REQUIRE_FALSE(mount.decrement_ref_count()); - REQUIRE(mount.get_ref_count() == 0); + REQUIRE(mount.ref_count() == 0); REQUIRE(mount.is_ready_to_unmount()); } } diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 9951590..26828b4 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -14,15 +14,15 @@ namespace kernel::filesystem { auto mount_table::has_child_mounts(kstd::shared_ptr const & parent_mount) const -> bool { - return std::ranges::any_of( - m_mounts, [&parent_mount](auto const & mount) { return mount->get_parent_mount() == parent_mount; }); + return std::ranges::any_of(m_mounts, + [&parent_mount](auto const & mount) { return mount->parent_mount() == parent_mount; }); } void mount_table::add_mount(kstd::shared_ptr const & mount) { m_mounts.push_back(mount); - if (auto mount_dentry = mount->get_mount_dentry()) + if (auto mount_dentry = mount->mount_dentry()) { mount_dentry->set_flag(dentry::dentry_flags::is_mount_point); } @@ -46,7 +46,7 @@ namespace kernel::filesystem return operation_result::has_child_mounts; } - mount->get_mount_dentry()->unset_flag(dentry::dentry_flags::is_mount_point); + mount->mount_dentry()->unset_flag(dentry::dentry_flags::is_mount_point); m_mounts.erase(mount_it); return operation_result::removed; } @@ -60,7 +60,6 @@ namespace kernel::filesystem auto mount_table::find_mount_iterator(std::string_view path) const -> kstd::vector>::const_iterator { - return std::ranges::find_last_if(m_mounts, [&](auto const & mount) { return mount->get_mount_path() == path; }) - .begin(); + return std::ranges::find_last_if(m_mounts, [&](auto const & mount) { return mount->mount_path() == path; }).begin(); } } // namespace kernel::filesystem \ No newline at end of file diff --git a/kernel/src/filesystem/open_file_descriptor.cpp b/kernel/src/filesystem/open_file_descriptor.cpp index ebaabef..a5567bf 100644 --- a/kernel/src/filesystem/open_file_descriptor.cpp +++ b/kernel/src/filesystem/open_file_descriptor.cpp @@ -33,7 +33,7 @@ namespace kernel::filesystem return written_bytes; } - auto open_file_descriptor::get_offset() const -> size_t + auto open_file_descriptor::offset() const -> size_t { return m_offset; } diff --git a/kernel/src/filesystem/open_file_descriptor.tests.cpp b/kernel/src/filesystem/open_file_descriptor.tests.cpp index 1910b8b..8c24cf0 100644 --- a/kernel/src/filesystem/open_file_descriptor.tests.cpp +++ b/kernel/src/filesystem/open_file_descriptor.tests.cpp @@ -26,7 +26,7 @@ SCENARIO("Open file descriptor construction", "[filesystem][open_file_descriptor THEN("the initial offset is zero") { - REQUIRE(file_descriptor.get_offset() == 0); + REQUIRE(file_descriptor.offset() == 0); } } } @@ -42,29 +42,29 @@ SCENARIO("Open file descriptor read/write offset management", "[filesystem][open THEN("the offset is updated correctly after reads") { REQUIRE(file_descriptor.read(nullptr, 100) == 100); - REQUIRE(file_descriptor.get_offset() == 100); + REQUIRE(file_descriptor.offset() == 100); REQUIRE(file_descriptor.read(nullptr, 50) == 50); - REQUIRE(file_descriptor.get_offset() == 150); + REQUIRE(file_descriptor.offset() == 150); } THEN("the offset is updated correctly after writes") { REQUIRE(file_descriptor.write(nullptr, 200) == 200); - REQUIRE(file_descriptor.get_offset() == 200); + REQUIRE(file_descriptor.offset() == 200); REQUIRE(file_descriptor.write(nullptr, 25) == 25); - REQUIRE(file_descriptor.get_offset() == 225); + REQUIRE(file_descriptor.offset() == 225); } THEN("reads and writes both update the same offset") { REQUIRE(file_descriptor.read(nullptr, 10) == 10); - REQUIRE(file_descriptor.get_offset() == 10); + REQUIRE(file_descriptor.offset() == 10); REQUIRE(file_descriptor.write(nullptr, 20) == 20); - REQUIRE(file_descriptor.get_offset() == 30); + REQUIRE(file_descriptor.offset() == 30); REQUIRE(file_descriptor.read(nullptr, 5) == 5); - REQUIRE(file_descriptor.get_offset() == 35); + REQUIRE(file_descriptor.offset() == 35); REQUIRE(file_descriptor.write(nullptr, 15) == 15); - REQUIRE(file_descriptor.get_offset() == 50); + REQUIRE(file_descriptor.offset() == 50); } } } @@ -89,7 +89,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope kstd::vector buffer(32); auto bytes_read = ofd->read(buffer.data(), buffer.size()); REQUIRE(bytes_read == 7); - REQUIRE(ofd->get_offset() == 7); + REQUIRE(ofd->offset() == 7); std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(bytes_read)}; REQUIRE(buffer_as_str == "info_1\n"); @@ -100,11 +100,11 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope kstd::vector buffer(4); auto bytes_read_1 = ofd->read(buffer.data(), buffer.size() / 2); REQUIRE(bytes_read_1 == buffer.size() / 2); - REQUIRE(ofd->get_offset() == buffer.size() / 2); + REQUIRE(ofd->offset() == buffer.size() / 2); auto bytes_read_2 = ofd->read(buffer.data() + buffer.size() / 2, buffer.size() / 2); REQUIRE(bytes_read_2 == buffer.size() / 2); - REQUIRE(ofd->get_offset() == buffer.size()); + REQUIRE(ofd->offset() == buffer.size()); std::string_view buffer_as_str{reinterpret_cast(buffer.data()), bytes_read_1 + bytes_read_2}; REQUIRE(buffer_as_str == "info"); diff --git a/kernel/src/filesystem/open_file_table.cpp b/kernel/src/filesystem/open_file_table.cpp index e47d229..4d52d36 100644 --- a/kernel/src/filesystem/open_file_table.cpp +++ b/kernel/src/filesystem/open_file_table.cpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace { @@ -37,7 +38,7 @@ namespace kernel::filesystem return *global_open_file_table; } - auto open_file_table::add_file(kstd::shared_ptr const & file_descriptor) -> int + auto open_file_table::add_file(kstd::shared_ptr const & file_descriptor) -> ssize_t { if (!file_descriptor) { @@ -48,43 +49,31 @@ namespace kernel::filesystem if (it != m_open_files.end()) { *it = file_descriptor; - return static_cast(it - m_open_files.begin()); + return it - m_open_files.begin(); } m_open_files.push_back(file_descriptor); - return static_cast(m_open_files.size() - 1); + return m_open_files.size() - 1; } - auto open_file_table::get_file(int fd) const -> kstd::shared_ptr + auto open_file_table::file(size_t fd) const -> kstd::shared_ptr { - if (fd < 0) + if (fd >= m_open_files.size()) { return nullptr; } - auto const index = static_cast(fd); - if (index >= m_open_files.size()) - { - return nullptr; - } - - return m_open_files.at(index); + return m_open_files.at(fd); } - auto open_file_table::remove_file(int fd) -> int + auto open_file_table::remove_file(size_t fd) -> ssize_t { - if (fd < 0) - { - return -1; - } - - auto const index = static_cast(fd); - if (index >= m_open_files.size()) + if (fd >= m_open_files.size()) { return -1; } - m_open_files.at(index) = nullptr; + m_open_files.at(fd) = nullptr; return 0; } } // namespace kernel::filesystem diff --git a/kernel/src/filesystem/open_file_table.tests.cpp b/kernel/src/filesystem/open_file_table.tests.cpp index 456d6b7..3e91111 100644 --- a/kernel/src/filesystem/open_file_table.tests.cpp +++ b/kernel/src/filesystem/open_file_table.tests.cpp @@ -36,7 +36,7 @@ SCENARIO("Open file table add/get file", "[filesystem][open_file_table]") THEN("the file descriptor can be retrieved using the returned file descriptor") { - auto retrieved_descriptor = table.get_file(fd_1); + auto retrieved_descriptor = table.file(fd_1); REQUIRE(retrieved_descriptor == file_descriptor_1); } } @@ -52,15 +52,9 @@ SCENARIO("Open file table add/get file", "[filesystem][open_file_table]") REQUIRE(fd == -1); } - THEN("retrieving a file descriptor with a negative file descriptor returns a null pointer") - { - auto retrieved_descriptor = table.get_file(-1); - REQUIRE(retrieved_descriptor == nullptr); - } - THEN("retrieving a file descriptor with an out-of-bounds file descriptor returns a null pointer") { - auto retrieved_descriptor = table.get_file(1000); + auto retrieved_descriptor = table.file(1000); REQUIRE(retrieved_descriptor == nullptr); } } @@ -82,7 +76,7 @@ SCENARIO("Open file table remove file", "[filesystem][open_file_table]") THEN("the file descriptor can no longer be retrieved using the file descriptor") { - auto retrieved_descriptor = table.get_file(fd); + auto retrieved_descriptor = table.file(fd); REQUIRE(retrieved_descriptor == nullptr); } } @@ -94,7 +88,7 @@ SCENARIO("Open file table remove file", "[filesystem][open_file_table]") THEN("the second file descriptor can still be retrieved using its file descriptor") { - auto retrieved_descriptor = table.get_file(fd2); + auto retrieved_descriptor = table.file(fd2); REQUIRE(retrieved_descriptor == file_descriptor); } } @@ -104,11 +98,6 @@ SCENARIO("Open file table remove file", "[filesystem][open_file_table]") { auto & table = kernel::filesystem::open_file_table::get(); - THEN("removing a file with a negative file descriptor does nothing") - { - REQUIRE_NOTHROW(table.remove_file(-1)); - } - THEN("removing a file with an out-of-bounds file descriptor does nothing") { REQUIRE_NOTHROW(table.remove_file(1000)); diff --git a/kernel/src/filesystem/rootfs/filesystem.cpp b/kernel/src/filesystem/rootfs/filesystem.cpp index d49e237..0ba2936 100644 --- a/kernel/src/filesystem/rootfs/filesystem.cpp +++ b/kernel/src/filesystem/rootfs/filesystem.cpp @@ -1,5 +1,6 @@ #include +#include "kernel/filesystem/filesystem.hpp" #include #include @@ -15,7 +16,7 @@ namespace kernel::filesystem::rootfs return operation_result::success; } - auto filesystem::lookup(kstd::shared_ptr const &, std::string_view) + auto filesystem::lookup(kstd::shared_ptr const &, std::string_view) const -> kstd::shared_ptr { return nullptr; diff --git a/kernel/src/filesystem/rootfs/inode.cpp b/kernel/src/filesystem/rootfs/inode.cpp index dbe7948..f64fb87 100644 --- a/kernel/src/filesystem/rootfs/inode.cpp +++ b/kernel/src/filesystem/rootfs/inode.cpp @@ -2,19 +2,16 @@ #include -#include -#include - #include namespace kernel::filesystem::rootfs { - auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t + auto inode::read(void *, size_t, size_t) const -> size_t { return 0; } - auto inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t + auto inode::write(void const *, size_t, size_t) -> size_t { return 0; } diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 8636d0f..bf9a77d 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -153,7 +153,7 @@ namespace kernel::filesystem -> void { auto new_fs_root = - kstd::make_shared(mount_point_dentry->get_parent(), fs->root_inode(), mount_point_dentry->get_name()); + kstd::make_shared(mount_point_dentry->parent(), fs->root_inode(), mount_point_dentry->name()); auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, parent_mount); m_mount_table.add_mount(new_mount); } @@ -174,7 +174,8 @@ namespace kernel::filesystem } } - auto vfs::resolve_path_internal(std::string_view path) -> std::pair, kstd::shared_ptr> + auto vfs::resolve_path_internal(std::string_view path) const + -> std::pair, kstd::shared_ptr> { if (!path::is_valid_absolute_path(path)) { @@ -187,7 +188,7 @@ namespace kernel::filesystem kapi::system::panic("[FILESYSTEM] no root mount found."); } - auto current_dentry = current_mount->get_root_dentry(); + auto current_dentry = current_mount->root_dentry(); auto path_parts = path::split(path); kstd::vector path_parts_vector(path_parts.begin(), path_parts.end()); @@ -207,16 +208,16 @@ namespace kernel::filesystem if (part == "..") { - auto parent_dentry = current_dentry->get_parent(); + auto parent_dentry = current_dentry->parent(); - if (current_dentry == current_mount->get_root_dentry()) + if (current_dentry == current_mount->root_dentry()) { - if (current_mount->get_mount_path() == "/") + if (current_mount->mount_path() == "/") { continue; } - if (auto parent_mount = current_mount->get_parent_mount()) + if (auto parent_mount = current_mount->parent_mount()) { current_mount = parent_mount; current_dentry = parent_dentry; @@ -242,13 +243,13 @@ namespace kernel::filesystem } else if (next_dentry->has_flag(dentry::dentry_flags::is_mount_point)) { - current_mount = m_mount_table.find_mount(next_dentry->get_absolute_path().view()); + current_mount = m_mount_table.find_mount(next_dentry->absolute_path().view()); if (!current_mount) { kapi::system::panic("[FILESYSTEM] mount for dentry with mounted flag not found."); } - next_dentry = current_mount->get_root_dentry(); + next_dentry = current_mount->root_dentry(); } if (next_dentry->get_inode()->is_symbolic_link()) @@ -271,7 +272,7 @@ namespace kernel::filesystem if (path::is_valid_absolute_path(symbolic_link_path)) { current_mount = m_mount_table.find_mount("/"); - current_dentry = current_mount->get_root_dentry(); + current_dentry = current_mount->root_dentry(); } continue; } @@ -281,12 +282,12 @@ namespace kernel::filesystem return {current_dentry, current_mount}; } - auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr + auto vfs::resolve_path(std::string_view path) const -> kstd::shared_ptr { return resolve_path_internal(path).first; } - auto vfs::find_mount(std::string_view path) -> kstd::shared_ptr + auto vfs::find_mount(std::string_view path) const -> kstd::shared_ptr { return resolve_path_internal(path).second; } diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 648ebb8..6fcc84e 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -105,7 +105,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); REQUIRE(mounted_monkey_1 != nullptr); - REQUIRE(vfs.close(mounted_monkey_1->get_absolute_path().view()) == + REQUIRE(vfs.close(mounted_monkey_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); @@ -128,10 +128,9 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(mounted_monkey_1 != nullptr); REQUIRE(mounted_fish1 != nullptr); - REQUIRE(vfs.close(mounted_monkey_1->get_absolute_path().view()) == - kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.close(mounted_fish1->get_absolute_path().view()) == + REQUIRE(vfs.close(mounted_monkey_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_fish1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); REQUIRE(vfs.unmount("/information/monkey_house/infrastructure") == @@ -148,7 +147,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); - REQUIRE(vfs.close(mounted_monkey_1->get_absolute_path().view()) == + REQUIRE(vfs.close(mounted_monkey_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); @@ -165,8 +164,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1 != nullptr); - REQUIRE(vfs.close(info_1->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.close(info_1->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::close_failed); + REQUIRE(vfs.close(info_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(info_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::close_failed); } THEN("images can be stacked mounted and correct file system is unmounted again") @@ -177,8 +176,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto mounted_tickets = vfs.open("/information/entrance/tickets.txt"); REQUIRE(mounted_tickets != nullptr); - REQUIRE(vfs.close(mounted_tickets->get_absolute_path().view()) == - kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_tickets->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); mounted_tickets = vfs.open("/information/entrance/tickets.txt"); @@ -201,7 +199,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto water = vfs.open("/monkey_house/infrastructure/water.txt"); REQUIRE(water != nullptr); - REQUIRE(vfs.close(water->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(water->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success); @@ -222,7 +220,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto water = vfs.open("/monkey_house/infrastructure/water.txt"); REQUIRE(water != nullptr); - REQUIRE(vfs.close(water->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(water->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); auto dev_ram_16 = vfs.open("/dev/ram16"); REQUIRE(dev_ram_16 == nullptr); @@ -240,7 +238,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1 != nullptr); - REQUIRE(vfs.close(info_1->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(info_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/dev") == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success); @@ -363,7 +361,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS std::string_view buffer_as_str{reinterpret_cast(buffer.data()), bytes_read}; REQUIRE(buffer_as_str == "sheep_1"); - REQUIRE(vfs.close(dentry->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(dentry->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); @@ -396,8 +394,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS buffer_as_str = std::string_view{reinterpret_cast(goat_buffer.data()), bytes_read}; REQUIRE(buffer_as_str == "goat_1"); - REQUIRE(vfs.close(sheep_1->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.close(goat_1->get_absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(sheep_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(goat_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); @@ -408,7 +406,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto still_mounted_sheep_1 = vfs.open("/information/sheep_1.txt"); REQUIRE(still_mounted_sheep_1 != nullptr); - REQUIRE(vfs.close(still_mounted_sheep_1->get_absolute_path().view()) == + REQUIRE(vfs.close(still_mounted_sheep_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); diff --git a/kernel/src/test_support/filesystem/filesystem.cpp b/kernel/src/test_support/filesystem/filesystem.cpp index 12d43e0..ec70607 100644 --- a/kernel/src/test_support/filesystem/filesystem.cpp +++ b/kernel/src/test_support/filesystem/filesystem.cpp @@ -9,7 +9,7 @@ namespace kernel::tests::filesystem { - auto filesystem::lookup(kstd::shared_ptr const &, std::string_view) + auto filesystem::lookup(kstd::shared_ptr const &, std::string_view) const -> kstd::shared_ptr { return kstd::make_shared(); -- cgit v1.2.3 From 3d8ea5b1b833f39b77f0591fb2a301842ed5eb1c Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Sat, 16 May 2026 17:00:10 +0200 Subject: Refactor data types in ext2 --- kernel/include/kernel/filesystem/ext2/filesystem.hpp | 16 ++++++++-------- kernel/include/kernel/filesystem/ext2/inode.hpp | 2 +- kernel/src/filesystem/ext2/filesystem.cpp | 20 ++++++++++---------- kernel/src/filesystem/ext2/inode.cpp | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index a408c64..45cd6a1 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -76,7 +76,7 @@ namespace kernel::filesystem::ext2 @brief Gets the revision level of the filesystem. @return The revision level. */ - [[nodiscard]] auto revision_level() const -> size_t; + [[nodiscard]] auto revision_level() const -> uint32_t; /** @brief Maps an inode block index to a global block number. @@ -88,18 +88,18 @@ namespace kernel::filesystem::ext2 -> ssize_t; private: - [[nodiscard]] auto read_inode(size_t inode_number) const -> kstd::shared_ptr; - [[nodiscard]] auto read_block_number_at_index(size_t block_number, size_t index) const -> size_t; + [[nodiscard]] auto read_inode(uint32_t inode_number) const -> kstd::shared_ptr; + [[nodiscard]] auto read_block_number_at_index(uint32_t block_number, size_t index) const -> uint32_t; - [[nodiscard]] auto read_singly_indirect_block_number(size_t singly_indirect_block_number, + [[nodiscard]] auto read_singly_indirect_block_number(uint32_t singly_indirect_block_number, size_t block_index_in_singly_indirect_block) const -> size_t; - [[nodiscard]] auto read_doubly_indirect_block_number(size_t doubly_indirect_block_number, + [[nodiscard]] auto read_doubly_indirect_block_number(uint32_t doubly_indirect_block_number, size_t block_index_in_doubly_indirect_block) const -> size_t; - [[nodiscard]] auto read_triply_indirect_block_number(size_t triply_indirect_block_number, + [[nodiscard]] auto read_triply_indirect_block_number(uint32_t triply_indirect_block_number, size_t block_index_in_triply_indirect_block) const -> size_t; - [[nodiscard]] auto inode_size() const -> size_t; - [[nodiscard]] auto inode_block_count(inode_data const & data) const -> size_t; + [[nodiscard]] auto inode_size() const -> uint16_t; + [[nodiscard]] auto inode_block_count(inode_data const & data) const -> uint32_t; [[nodiscard]] auto block_group_descriptor_table_offset() const -> size_t; [[nodiscard]] auto block_numbers_per_block() const -> size_t; diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp index 5609319..f2496f0 100644 --- a/kernel/include/kernel/filesystem/ext2/inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/inode.hpp @@ -94,7 +94,7 @@ namespace kernel::filesystem::ext2 @brief Get the size of the file represented by this inode. @return The size of the file in bytes. */ - [[nodiscard]] auto size() const -> size_t; + [[nodiscard]] auto size() const -> uint64_t; private: filesystem const * m_filesystem; diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 7633972..df5b4c4 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -62,7 +62,7 @@ namespace kernel::filesystem::ext2 auto const & inode_data = ext2_parent->data(); kstd::vector buffer(block_size()); - for (auto i = 0uz; i < inode_block_count(inode_data); ++i) + for (uint32_t i = 0; i < inode_block_count(inode_data); ++i) { auto const global_block_number = map_inode_block_index_to_global_block_number(i, inode_data); auto const block_offset = global_block_number * block_size(); @@ -87,7 +87,7 @@ namespace kernel::filesystem::ext2 return nullptr; } - auto filesystem::read_inode(size_t inode_number) const -> kstd::shared_ptr + auto filesystem::read_inode(uint32_t inode_number) const -> kstd::shared_ptr { auto const inodes_per_group = m_superblock.inodes_per_group; auto const block_group_index = (inode_number - 1) / inodes_per_group; @@ -141,7 +141,7 @@ namespace kernel::filesystem::ext2 return -1; } - auto filesystem::read_singly_indirect_block_number(size_t singly_indirect_block_number, + auto filesystem::read_singly_indirect_block_number(uint32_t singly_indirect_block_number, size_t block_index_in_singly_indirect_block) const -> size_t { if (singly_indirect_block_number == 0) @@ -152,7 +152,7 @@ namespace kernel::filesystem::ext2 return read_block_number_at_index(singly_indirect_block_number, block_index_in_singly_indirect_block); } - auto filesystem::read_doubly_indirect_block_number(size_t doubly_indirect_block_number, + auto filesystem::read_doubly_indirect_block_number(uint32_t doubly_indirect_block_number, size_t block_index_in_doubly_indirect_block) const -> size_t { if (doubly_indirect_block_number == 0) @@ -171,7 +171,7 @@ namespace kernel::filesystem::ext2 return read_singly_indirect_block_number(singly_indirect_block_number, block_index_in_singly_indirect_block); } - auto filesystem::read_triply_indirect_block_number(size_t triply_indirect_block_number, + auto filesystem::read_triply_indirect_block_number(uint32_t triply_indirect_block_number, size_t block_index_in_triply_indirect_block) const -> size_t { if (triply_indirect_block_number == 0) @@ -190,9 +190,9 @@ namespace kernel::filesystem::ext2 return read_doubly_indirect_block_number(doubly_indirect_block_number, block_index_in_doubly_indirect_block); } - auto filesystem::read_block_number_at_index(size_t block_number, size_t index) const -> size_t + auto filesystem::read_block_number_at_index(uint32_t block_number, size_t index) const -> uint32_t { - auto block_number_buffer = 0uz; + uint32_t block_number_buffer = 0; auto const block_start_offset = block_number * block_size(); auto const number_start_address = block_start_offset + index * sizeof(uint32_t); @@ -226,17 +226,17 @@ namespace kernel::filesystem::ext2 return constants::base_block_size << m_superblock.log_block_size; } - auto filesystem::revision_level() const -> size_t + auto filesystem::revision_level() const -> uint32_t { return m_superblock.rev_level; } - auto filesystem::inode_size() const -> size_t + auto filesystem::inode_size() const -> uint16_t { return revision_level() == constants::good_old_revision ? 128 : m_superblock.inode_size; } - auto filesystem::inode_block_count(inode_data const & data) const -> size_t + auto filesystem::inode_block_count(inode_data const & data) const -> uint32_t { return data.blocks / (2 << m_superblock.log_block_size); } diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index f8c818c..35a32ee 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -96,7 +96,7 @@ namespace kernel::filesystem::ext2 return (m_data.mode & constants::mode_mask) == constants::mode_symbolic_link; } - auto inode::size() const -> size_t + auto inode::size() const -> uint64_t { uint64_t size = m_data.size; -- cgit v1.2.3 From a50d6cfcea67b11f6689ec825afc2e2b33252714 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 18 May 2026 15:21:39 +0200 Subject: ci: enable jUnit style test reports --- kernel/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 860e28b..2ce9621 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -220,5 +220,5 @@ if(BUILD_TESTING) ) enable_coverage("kernel_tests") - catch_discover_tests("kernel_tests") + catch_discover_tests("kernel_tests" ${CATCH_TEST_ARGS}) endif() -- cgit v1.2.3 From 033ecf6714089d2ce331152f5e120567f8d546cf Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 19 May 2026 12:48:08 +0200 Subject: build: clean up dependencies --- kernel/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 2ce9621..cbc7fa5 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -137,6 +137,9 @@ endif() #]============================================================================] if(BUILD_TESTING) + find_package("Catch2") + include("Catch") + enable_coverage("kernel_lib") add_executable("kernel_tests") -- cgit v1.2.3 From 2063d3e165a1b92a46c73badf56927228ed4d5e8 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 25 May 2026 10:15:21 +0200 Subject: Refactor ssize_t --- kernel/include/kernel/filesystem/ext2/filesystem.hpp | 6 ++---- kernel/include/kernel/filesystem/open_file_table.hpp | 6 +++--- kernel/kapi/filesystem.cpp | 15 +++++++-------- kernel/src/filesystem/ext2/filesystem.cpp | 4 ++-- kernel/src/filesystem/open_file_table.cpp | 6 +++--- 5 files changed, 17 insertions(+), 20 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index 45cd6a1..d5e5b8b 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -8,14 +8,12 @@ #include #include +#include #include #include #include #include -#include - -#include namespace kernel::filesystem::ext2 { @@ -85,7 +83,7 @@ namespace kernel::filesystem::ext2 @return The global block number. */ [[nodiscard]] auto map_inode_block_index_to_global_block_number(size_t inode_block_index, inode_data data) const - -> ssize_t; + -> kstd::ssize_t; private: [[nodiscard]] auto read_inode(uint32_t inode_number) const -> kstd::shared_ptr; diff --git a/kernel/include/kernel/filesystem/open_file_table.hpp b/kernel/include/kernel/filesystem/open_file_table.hpp index 5794e4c..7e754ac 100644 --- a/kernel/include/kernel/filesystem/open_file_table.hpp +++ b/kernel/include/kernel/filesystem/open_file_table.hpp @@ -4,10 +4,10 @@ #include #include +#include #include #include -#include namespace kernel::filesystem { @@ -40,7 +40,7 @@ namespace kernel::filesystem @param fd The file descriptor to add. @return The file descriptor index assigned to the file, or -1 on failure. */ - auto add_file(kstd::shared_ptr const & fd) -> ssize_t; + auto add_file(kstd::shared_ptr const & fd) -> kstd::ssize_t; /** @brief Get a file from the open file table. @@ -54,7 +54,7 @@ namespace kernel::filesystem @param fd The file descriptor index to remove. @return 0 on success, or -1 on failure. */ - auto remove_file(size_t fd) -> ssize_t; + auto remove_file(size_t fd) -> kstd::ssize_t; private: open_file_table() = default; diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index db61c34..838d2cb 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -5,15 +5,14 @@ #include #include +#include #include #include -#include - namespace kapi::filesystem { - auto mount(std::string_view source, std::string_view target) -> ssize_t + auto mount(std::string_view source, std::string_view target) -> kstd::ssize_t { if (kernel::filesystem::vfs::get().do_mount(source, target) == kernel::filesystem::vfs::operation_result::success) { @@ -22,7 +21,7 @@ namespace kapi::filesystem return -1; } - auto umount(std::string_view target) -> ssize_t + auto umount(std::string_view target) -> kstd::ssize_t { if (kernel::filesystem::vfs::get().unmount(target) == kernel::filesystem::vfs::operation_result::success) { @@ -31,7 +30,7 @@ namespace kapi::filesystem return -1; } - auto open(std::string_view path) -> ssize_t + auto open(std::string_view path) -> kstd::ssize_t { if (auto dentry = kernel::filesystem::vfs::get().open(path)) { @@ -42,7 +41,7 @@ namespace kapi::filesystem return -1; } - auto close(size_t file_descriptor) -> ssize_t + auto close(size_t file_descriptor) -> kstd::ssize_t { if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().file(file_descriptor)) { @@ -55,7 +54,7 @@ namespace kapi::filesystem return -1; } - auto read(size_t file_descriptor, void * buffer, size_t size) -> ssize_t + auto read(size_t file_descriptor, void * buffer, size_t size) -> kstd::ssize_t { if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().file(file_descriptor)) { @@ -65,7 +64,7 @@ namespace kapi::filesystem return -1; } - auto write(size_t file_descriptor, void const * buffer, size_t size) -> ssize_t + auto write(size_t file_descriptor, void const * buffer, size_t size) -> kstd::ssize_t { if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().file(file_descriptor)) { diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index df5b4c4..a30149e 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -8,12 +8,12 @@ #include #include +#include #include #include #include #include -#include namespace kernel::filesystem::ext2 { @@ -110,7 +110,7 @@ namespace kernel::filesystem::ext2 } auto filesystem::map_inode_block_index_to_global_block_number(size_t inode_block_index, inode_data data) const - -> ssize_t + -> kstd::ssize_t { if (inode_block_index < constants::direct_block_count) { diff --git a/kernel/src/filesystem/open_file_table.cpp b/kernel/src/filesystem/open_file_table.cpp index 4d52d36..2afe3aa 100644 --- a/kernel/src/filesystem/open_file_table.cpp +++ b/kernel/src/filesystem/open_file_table.cpp @@ -5,11 +5,11 @@ #include #include +#include #include #include #include -#include namespace { @@ -38,7 +38,7 @@ namespace kernel::filesystem return *global_open_file_table; } - auto open_file_table::add_file(kstd::shared_ptr const & file_descriptor) -> ssize_t + auto open_file_table::add_file(kstd::shared_ptr const & file_descriptor) -> kstd::ssize_t { if (!file_descriptor) { @@ -66,7 +66,7 @@ namespace kernel::filesystem return m_open_files.at(fd); } - auto open_file_table::remove_file(size_t fd) -> ssize_t + auto open_file_table::remove_file(size_t fd) -> kstd::ssize_t { if (fd >= m_open_files.size()) { -- cgit v1.2.3 From 61d29a288334960cd9f43df91e4fd632a7f6ad66 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 25 May 2026 11:13:18 +0200 Subject: Increase reference count of source_mount when one of its files is mounted somewhere --- kernel/include/kernel/filesystem/mount.hpp | 13 ++++++++++--- kernel/include/kernel/filesystem/vfs.hpp | 7 +++---- kernel/src/filesystem/mount.cpp | 14 ++++++++++---- kernel/src/filesystem/mount.tests.cpp | 16 +++++++++------- kernel/src/filesystem/mount_table.cpp | 16 +++++++++++++++- kernel/src/filesystem/mount_table.tests.cpp | 14 +++++++------- kernel/src/filesystem/vfs.cpp | 26 ++++++++++++-------------- kernel/src/filesystem/vfs.tests.cpp | 5 +++-- 8 files changed, 69 insertions(+), 42 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index 4ce374f..6c0c5b9 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -28,7 +28,8 @@ namespace kernel::filesystem @param parent_mount The parent mount that this mount is attached beneath. */ mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & root_dentry, - kstd::shared_ptr const & fs, kstd::shared_ptr const & parent_mount); + kstd::shared_ptr const & fs, kstd::shared_ptr const & parent_mount, + kstd::shared_ptr const & source_mount); /** @brief Get the dentry where the filesystem is mounted. @@ -55,6 +56,11 @@ namespace kernel::filesystem */ [[nodiscard]] auto parent_mount() const -> kstd::shared_ptr const &; + /** + @brief Get the source mount where this mount originates from. + */ + [[nodiscard]] auto source_mount() const -> kstd::shared_ptr; + /** @brief Increment the reference count for this mount. */ @@ -62,9 +68,9 @@ namespace kernel::filesystem /** @brief Decrement the reference count for this mount. - @return True if the reference count reached zero, false otherwise. + @warning Throws if ref_count is zero. */ - [[nodiscard]] auto decrement_ref_count() -> bool; + auto decrement_ref_count() -> void; /** @brief Check if the mount is ready to be unmounted. @@ -83,6 +89,7 @@ namespace kernel::filesystem kstd::shared_ptr m_root_dentry; kstd::shared_ptr m_filesystem{}; kstd::shared_ptr m_parent_mount{}; + kstd::weak_ptr m_source_mount{}; std::atomic_size_t m_ref_count; }; } // namespace kernel::filesystem diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index aec8bfe..e6f2327 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -32,8 +32,7 @@ namespace kernel::filesystem non_existent_path = -2, mount_point_not_found = -3, unmount_failed = -4, - invalid_filesystem = -5, - close_failed = -6 + invalid_filesystem = -5 }; /** @@ -103,8 +102,8 @@ namespace kernel::filesystem [[nodiscard]] auto find_mount(std::string_view path) const -> kstd::shared_ptr; auto do_mount_internal(kstd::shared_ptr const & mount_point_dentry, - kstd::shared_ptr const & parent_mount, kstd::shared_ptr const & fs) - -> void; + kstd::shared_ptr const & parent_mount, kstd::shared_ptr const & fs, + kstd::shared_ptr const & source_mount = nullptr) -> void; auto graft_persistent_device_fs(kstd::shared_ptr const & device_fs) -> void; diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index b64c370..ead7479 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -14,11 +14,13 @@ namespace kernel::filesystem { mount::mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & root_dentry, - kstd::shared_ptr const & fs, kstd::shared_ptr const & parent_mount) + kstd::shared_ptr const & fs, kstd::shared_ptr const & parent_mount, + kstd::shared_ptr const & source_mount) : m_mount_dentry(mount_dentry) , m_root_dentry(root_dentry) , m_filesystem(fs) , m_parent_mount(parent_mount) + , m_source_mount(source_mount) , m_ref_count(0) { if (!m_filesystem) @@ -56,20 +58,24 @@ namespace kernel::filesystem return m_parent_mount; } + auto mount::source_mount() const -> kstd::shared_ptr + { + return m_source_mount.lock(); + } + auto mount::increment_ref_count() -> void { m_ref_count += 1; } - auto mount::decrement_ref_count() -> bool + auto mount::decrement_ref_count() -> void { if (m_ref_count == 0) { - return false; + kapi::system::panic("[FILESYSTEM] decrement_ref_count() was called but ref_count is 0"); } m_ref_count -= 1; - return true; } auto mount::is_ready_to_unmount() const -> bool diff --git a/kernel/src/filesystem/mount.tests.cpp b/kernel/src/filesystem/mount.tests.cpp index 6b66571..40b7cbb 100644 --- a/kernel/src/filesystem/mount.tests.cpp +++ b/kernel/src/filesystem/mount.tests.cpp @@ -11,6 +11,8 @@ #include +#include + SCENARIO("Mount construction", "[filesystem][mount]") { GIVEN("a filesystem and a root dentry") @@ -21,7 +23,7 @@ SCENARIO("Mount construction", "[filesystem][mount]") WHEN("constructing a mount with the filesystem and root dentry") { - auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr}; + auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr, nullptr}; THEN("the mount has the correct filesystem, root dentry, mount dentry, and mount path") { @@ -42,7 +44,7 @@ SCENARIO("Mount construction", "[filesystem][mount]") { THEN("the constructor panics") { - REQUIRE_THROWS_AS((kernel::filesystem::mount{root_dentry, root_dentry, nullptr, nullptr}), + REQUIRE_THROWS_AS((kernel::filesystem::mount{root_dentry, root_dentry, nullptr, nullptr, nullptr}), kernel::tests::cpu::halt); } } @@ -60,7 +62,7 @@ SCENARIO("Mount reference counting", "[filesystem][mount]") THEN("reference count can be incremented and decremented, the mount is ready to unmount when the reference " "count == 0") { - auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr}; + auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr, nullptr}; mount.increment_ref_count(); REQUIRE(mount.ref_count() == 1); @@ -70,20 +72,20 @@ SCENARIO("Mount reference counting", "[filesystem][mount]") REQUIRE(mount.ref_count() == 2); REQUIRE_FALSE(mount.is_ready_to_unmount()); - REQUIRE(mount.decrement_ref_count()); + mount.decrement_ref_count(); REQUIRE(mount.ref_count() == 1); REQUIRE_FALSE(mount.is_ready_to_unmount()); - REQUIRE(mount.decrement_ref_count()); + mount.decrement_ref_count(); REQUIRE(mount.ref_count() == 0); REQUIRE(mount.is_ready_to_unmount()); } THEN("decrementing reference count when it is already zero does not decrement it below zero") { - auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr}; + auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr, nullptr}; - REQUIRE_FALSE(mount.decrement_ref_count()); + REQUIRE_THROWS_AS(mount.decrement_ref_count(), std::runtime_error); REQUIRE(mount.ref_count() == 0); REQUIRE(mount.is_ready_to_unmount()); } diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index 26828b4..af8434b 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -22,6 +22,11 @@ namespace kernel::filesystem { m_mounts.push_back(mount); + if (auto source_mount = mount->source_mount()) + { + source_mount->increment_ref_count(); + } + if (auto mount_dentry = mount->mount_dentry()) { mount_dentry->set_flag(dentry::dentry_flags::is_mount_point); @@ -46,7 +51,16 @@ namespace kernel::filesystem return operation_result::has_child_mounts; } - mount->mount_dentry()->unset_flag(dentry::dentry_flags::is_mount_point); + if (auto source_mount = mount->source_mount()) + { + source_mount->decrement_ref_count(); + } + + if (auto mount_dentry = mount->mount_dentry()) + { + mount_dentry->unset_flag(dentry::dentry_flags::is_mount_point); + } + m_mounts.erase(mount_it); return operation_result::removed; } diff --git a/kernel/src/filesystem/mount_table.tests.cpp b/kernel/src/filesystem/mount_table.tests.cpp index f22b25e..8118e19 100644 --- a/kernel/src/filesystem/mount_table.tests.cpp +++ b/kernel/src/filesystem/mount_table.tests.cpp @@ -38,14 +38,14 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] nullptr, kstd::make_shared(), "/"); auto mount_dentry1 = kstd::make_shared( nullptr, kstd::make_shared(), "/"); - auto mount1 = kstd::make_shared(mount_dentry1, root_dentry1, fs1, nullptr); + auto mount1 = kstd::make_shared(mount_dentry1, root_dentry1, fs1, nullptr, nullptr); auto fs2 = kstd::make_shared(); auto root_dentry2 = kstd::make_shared( nullptr, kstd::make_shared(), "/"); auto mount_dentry2 = kstd::make_shared( nullptr, kstd::make_shared(), "/mnt"); - auto mount2 = kstd::make_shared(mount_dentry2, root_dentry2, fs2, nullptr); + auto mount2 = kstd::make_shared(mount_dentry2, root_dentry2, fs2, nullptr, nullptr); table.add_mount(mount1); table.add_mount(mount2); @@ -89,14 +89,14 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] nullptr, kstd::make_shared(), "/"); auto mount_dentry1 = kstd::make_shared( nullptr, kstd::make_shared(), "/"); - auto mount1 = kstd::make_shared(mount_dentry1, root_dentry1, fs1, nullptr); + auto mount1 = kstd::make_shared(mount_dentry1, root_dentry1, fs1, nullptr, nullptr); auto fs2 = kstd::make_shared(); auto root_dentry2 = kstd::make_shared( nullptr, kstd::make_shared(), "/"); auto mount_dentry2 = kstd::make_shared( nullptr, kstd::make_shared(), "/"); - auto mount2 = kstd::make_shared(mount_dentry2, root_dentry2, fs2, nullptr); + auto mount2 = kstd::make_shared(mount_dentry2, root_dentry2, fs2, nullptr, nullptr); table.add_mount(mount1); table.add_mount(mount2); @@ -122,21 +122,21 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] nullptr, kstd::make_shared(), "/"); auto mount_dentry1 = kstd::make_shared( nullptr, kstd::make_shared(), "/"); - auto mount1 = kstd::make_shared(mount_dentry1, root_dentry1, fs1, nullptr); + auto mount1 = kstd::make_shared(mount_dentry1, root_dentry1, fs1, nullptr, nullptr); auto fs2 = kstd::make_shared(); auto root_dentry2 = kstd::make_shared( nullptr, kstd::make_shared(), "/"); auto mount_dentry2 = kstd::make_shared( mount_dentry1, kstd::make_shared(), "mnt"); - auto mount2 = kstd::make_shared(mount_dentry2, root_dentry2, fs2, mount1); + auto mount2 = kstd::make_shared(mount_dentry2, root_dentry2, fs2, mount1, nullptr); auto fs3 = kstd::make_shared(); auto root_dentry3 = kstd::make_shared( nullptr, kstd::make_shared(), "/"); auto mount_dentry3 = kstd::make_shared( mount_dentry2, kstd::make_shared(), "submnt"); - auto mount3 = kstd::make_shared(mount_dentry3, root_dentry3, fs3, mount2); + auto mount3 = kstd::make_shared(mount_dentry3, root_dentry3, fs3, mount2, nullptr); table.add_mount(mount1); table.add_mount(mount2); diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index bf9a77d..ae85291 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -47,7 +47,7 @@ namespace kernel::filesystem root_fs->mount(nullptr); auto root_fs_root_dentry = kstd::make_shared(nullptr, root_fs->root_inode(), "/"); - auto root_mount = kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, nullptr); + auto root_mount = kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, nullptr, nullptr); m_mount_table.add_mount(root_mount); // mount devfs at /dev (inside rootfs, temporary, will be shadowed) @@ -56,13 +56,14 @@ namespace kernel::filesystem graft_persistent_device_fs(device_fs); // mount boot fs at / (shadows rootfs), re-graft devfs - if (auto boot_device_dentry = resolve_path("/dev/ram0")) + auto [boot_device_dentry, boot_device_mount_context] = resolve_path_internal("/dev/ram0"); + if (boot_device_dentry && boot_device_mount_context) { if (auto boot_root_fs = kernel::filesystem::filesystem::probe_and_mount(boot_device_dentry->get_inode())) { if (auto root_dentry = resolve_path("/")) { - do_mount_internal(root_dentry, root_mount, boot_root_fs); + do_mount_internal(root_dentry, root_mount, boot_root_fs, boot_device_mount_context); graft_persistent_device_fs(device_fs); } } @@ -94,11 +95,8 @@ namespace kernel::filesystem { if (auto mount = find_mount(path)) { - if (mount->decrement_ref_count()) - { - return operation_result::success; - } - return operation_result::close_failed; + mount->decrement_ref_count(); + return operation_result::success; } return operation_result::invalid_path; } @@ -111,14 +109,14 @@ namespace kernel::filesystem } auto [mount_point_dentry, mount_context] = resolve_path_internal(target); - if (mount_point_dentry && mount_context) { - if (auto source_dentry = resolve_path(source)) + auto [source_dentry, source_mount_context] = resolve_path_internal(source); + if (source_dentry && source_mount_context) { if (auto fs = kernel::filesystem::filesystem::probe_and_mount(source_dentry->get_inode())) { - do_mount_internal(mount_point_dentry, mount_context, fs); + do_mount_internal(mount_point_dentry, mount_context, fs, source_mount_context); return operation_result::success; } return operation_result::invalid_filesystem; @@ -149,12 +147,12 @@ namespace kernel::filesystem } auto vfs::do_mount_internal(kstd::shared_ptr const & mount_point_dentry, - kstd::shared_ptr const & parent_mount, kstd::shared_ptr const & fs) - -> void + kstd::shared_ptr const & parent_mount, kstd::shared_ptr const & fs, + kstd::shared_ptr const & source_mount) -> void { auto new_fs_root = kstd::make_shared(mount_point_dentry->parent(), fs->root_inode(), mount_point_dentry->name()); - auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, parent_mount); + auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, parent_mount, source_mount); m_mount_table.add_mount(new_mount); } diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 6fcc84e..8ae206a 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -10,6 +10,7 @@ #include #include +#include #include SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS with dummy modules", @@ -156,7 +157,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("file with invalid path or not opened file cannot be closed") { REQUIRE(vfs.close("invalid_path") == kernel::filesystem::vfs::operation_result::invalid_path); - REQUIRE(vfs.close("/information/info_1.txt") == kernel::filesystem::vfs::operation_result::close_failed); + REQUIRE_THROWS_AS(vfs.close("/information/info_1.txt"), std::runtime_error); } THEN("file cannot be closed twice") @@ -165,7 +166,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(info_1 != nullptr); REQUIRE(vfs.close(info_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.close(info_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::close_failed); + REQUIRE_THROWS_AS(vfs.close(info_1->absolute_path().view()), std::runtime_error); } THEN("images can be stacked mounted and correct file system is unmounted again") -- cgit v1.2.3 From 90d4163c336348cd21db8cbdb292994ddcfa3908 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 25 May 2026 11:43:00 +0200 Subject: improve demo code --- kernel/src/main.cpp | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 22d2b1e..25b5c00 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -26,57 +26,83 @@ using namespace kstd::units_literals; auto run_demo() -> void { // 1) open a file + kstd::println("attempting to open /entrance/tickets.txt"); auto fd_1 = kapi::filesystem::open("/entrance/tickets.txt"); if (fd_1 == -1) { - kstd::os::panic("demo failed"); + kapi::system::panic("demo failed"); + } + else + { + kstd::println("--> successfully opened /entrance/tickets.txt with file descriptor {}", fd_1); } // 2) read from the file kstd::vector buffer_1{10}; auto bytes_read = kapi::filesystem::read(fd_1, buffer_1.data(), buffer_1.size()); auto buffer_as_str = std::string_view{reinterpret_cast(buffer_1.data()), static_cast(bytes_read)}; - kstd::println("Read {} bytes from /entrance/tickets.txt: {}", bytes_read, buffer_as_str); + kstd::println("--> read {} bytes from /entrance/tickets.txt: {}", bytes_read, buffer_as_str); + kstd::println(""); // 3) show that /entrance/information/info_1.txt is not accessible before mounting + kstd::println("attempting to open /entrance/information/info_1.txt before mounting"); auto fd_before_mount = kapi::filesystem::open("/entrance/information/info_1.txt"); if (fd_before_mount == -1) { - kstd::println("/entrance/information/info_1.txt is not accessible before mounting, as expected."); + kstd::println("--> as expected the file could not be opened before mounting"); } // 4) mount a new filesystem on top of /entrance - kapi::filesystem::mount("/dev/ram16", "/entrance"); + kstd::println("mount /dev/ram16 to /entrance"); + if (kapi::filesystem::mount("/dev/ram16", "/entrance") == 0) + { + kstd::println("--> successfully mounted /dev/ram16 to /entrance"); + } + else + { + kapi::system::panic("demo failed"); + } + kstd::println(""); // 5) open a file from the new filesystem + kstd::println("attempting to open /entrance/information/info_1.txt"); auto fd_2 = kapi::filesystem::open("/entrance/information/info_1.txt"); - if (fd_2 == -1) + if (fd_2 != -1) + { + kstd::println("--> successfully opened /entrance/information/info_1.txt with file descriptor {}", fd_2); + } + else { - kstd::os::panic("demo failed"); + kapi::system::panic("demo failed"); } // 6) read from the new file kstd::vector buffer_2{10}; bytes_read = kapi::filesystem::read(fd_2, buffer_2.data(), buffer_2.size()); buffer_as_str = std::string_view{reinterpret_cast(buffer_2.data()), static_cast(bytes_read)}; - kstd::println("Read {} bytes from /entrance/information/info_1.txt: {}", bytes_read, buffer_as_str); + kstd::println("--> read {} bytes from /entrance/information/info_1.txt: {} ", bytes_read, buffer_as_str); // 7) open device as file - auto fd_3 = kapi::filesystem::open("/dev/ram48"); - if (fd_3 == -1) + kstd::println("attempting to open /dev/ram32 as a file"); + auto fd_3 = kapi::filesystem::open("/dev/ram32"); + if (fd_3 != -1) + { + kstd::println("--> successfully opened /dev/ram32 as a file with file descriptor {}", fd_3); + } + else { - kstd::os::panic("demo failed"); + kapi::system::panic("demo failed"); } // 8) read from the device file kstd::vector buffer_3{2}; bytes_read = kapi::filesystem::read(fd_3, buffer_3.data(), buffer_3.size()); - kstd::println("Read {} bytes from /dev/ram48: {::#04x}", bytes_read, buffer_3); + kstd::println("--> read {} bytes from /dev/ram32: {::#04x} ", bytes_read, buffer_3); // 9) write to the device file kstd::vector write_buffer{std::byte{0xAA}, std::byte{0xAA}}; auto bytes_written = kapi::filesystem::write(fd_3, write_buffer.data(), write_buffer.size()); - kstd::println("Written {} bytes to /dev/ram48: {::#04x}", bytes_written, write_buffer); + kstd::println("--> written {} bytes to /dev/ram32: {::#04x}", bytes_written, write_buffer); // 10) do memory dump to show that the write to the device file had an effect } -- cgit v1.2.3 From d916ecfc94aab583d60bba94de257a675accab7a Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 25 May 2026 13:04:22 +0200 Subject: add vfs tests --- kernel/src/filesystem/vfs.tests.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 8ae206a..fc1ea0d 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -416,6 +416,37 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS } } + GIVEN("two real image files where the second contains as filesystem formatted files") + { + REQUIRE(std::filesystem::exists(image_path_1)); + REQUIRE(std::filesystem::exists(image_path_3)); + REQUIRE_NOTHROW( + setup_modules_from_img_and_init_vfs({"test_img_module_3", "test_img_module_1"}, {image_path_3, image_path_1})); + + auto & vfs = kernel::filesystem::vfs::get(); + + THEN("cannot unmount a filesystem if files are mounted") + { + REQUIRE(vfs.do_mount("/dev/ram16", "/entrance") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/entrance/archiv/2024.img", "/enclosures") == + kernel::filesystem::vfs::operation_result::success); + + REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::unmount_failed); + REQUIRE(vfs.unmount("/enclosures") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::success); + } + + THEN("can mount filesystem ontop of the path where this is inside") + { + REQUIRE(vfs.do_mount("/dev/ram16", "/entrance") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/entrance/archiv/2024.img", "/entrance") == + kernel::filesystem::vfs::operation_result::success); + + REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::success); + } + } + GIVEN("A real image files, containing symbolic links") { REQUIRE(std::filesystem::exists(image_path_1)); -- cgit v1.2.3 From 756854104db95f247ad9bed5eb59fb90a9a1cb69 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 25 May 2026 13:04:36 +0200 Subject: add mount table and mount tests --- kernel/src/filesystem/mount.tests.cpp | 3 ++- kernel/src/filesystem/mount_table.tests.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/mount.tests.cpp b/kernel/src/filesystem/mount.tests.cpp index 40b7cbb..c9ff82e 100644 --- a/kernel/src/filesystem/mount.tests.cpp +++ b/kernel/src/filesystem/mount.tests.cpp @@ -34,9 +34,10 @@ SCENARIO("Mount construction", "[filesystem][mount]") REQUIRE(mount.is_ready_to_unmount()); } - THEN("the mount has no parent mount") + THEN("the mount has no parent mount and no source mount") { REQUIRE(mount.parent_mount() == nullptr); + REQUIRE(mount.source_mount() == nullptr); } } diff --git a/kernel/src/filesystem/mount_table.tests.cpp b/kernel/src/filesystem/mount_table.tests.cpp index 8118e19..19b47b2 100644 --- a/kernel/src/filesystem/mount_table.tests.cpp +++ b/kernel/src/filesystem/mount_table.tests.cpp @@ -155,3 +155,30 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] } } } + +SCENARIO("Mount reference counting", "[filesystem][mount_table]") +{ + kernel::filesystem::mount_table table; + + GIVEN("a filesystem and a root dentry") + { + auto fs = kstd::make_shared(); + auto root_inode = kstd::make_shared(); + auto root_dentry = kstd::make_shared(nullptr, root_inode, "/"); + + auto source_mount = kstd::make_shared(root_dentry, root_dentry, fs, nullptr, nullptr); + auto mount = kstd::make_shared(root_dentry, root_dentry, fs, nullptr, source_mount); + + THEN("reference count of source mount is incremented when a mount is added to the mount table and decremented when " + "the mount is removed") + { + REQUIRE(source_mount->ref_count() == 0); + + table.add_mount(mount); + REQUIRE(source_mount->ref_count() == 1); + + REQUIRE(table.remove_mount("/") == kernel::filesystem::mount_table::operation_result::removed); + REQUIRE(source_mount->ref_count() == 0); + } + } +} -- cgit v1.2.3 From 685990ae8c4fad6847e8f90cccb52bb34280298c Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 25 May 2026 13:14:07 +0200 Subject: Apply 1 suggestion(s) to 1 file(s) Co-authored-by: Marcel Braun --- kernel/src/filesystem/vfs.tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index fc1ea0d..962e067 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -436,7 +436,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::success); } - THEN("can mount filesystem ontop of the path where this is inside") + THEN("can mount filesystem onto the directory that contains it") { REQUIRE(vfs.do_mount("/dev/ram16", "/entrance") == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.do_mount("/entrance/archiv/2024.img", "/entrance") == -- cgit v1.2.3 From 5d3222599c2af9241ac44718ede4ec9f4955f490 Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Mon, 25 May 2026 13:35:50 +0200 Subject: Fix mount parameter description --- kernel/include/kernel/filesystem/mount.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index 6c0c5b9..53d7f6d 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -24,8 +24,8 @@ namespace kernel::filesystem @param mount_dentry The dentry where the filesystem is mounted. @param root_dentry The root dentry of the mounted filesystem. @param fs The filesystem instance being mounted. - @param mount_path The path at which the filesystem is mounted. - @param parent_mount The parent mount that this mount is attached beneath. + @param parent_mount The mount that contains the mount_dentry. + @param source_mount The mount that the filesystem originates from. */ mount(kstd::shared_ptr const & mount_dentry, kstd::shared_ptr const & root_dentry, kstd::shared_ptr const & fs, kstd::shared_ptr const & parent_mount, -- cgit v1.2.3 From 649bf64b4d4ec0742e56539348761f5957d64922 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 25 May 2026 14:03:56 +0200 Subject: fix linter warnings --- kernel/src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 25b5c00..a84ca64 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -100,7 +99,8 @@ auto run_demo() -> void kstd::println("--> read {} bytes from /dev/ram32: {::#04x} ", bytes_read, buffer_3); // 9) write to the device file - kstd::vector write_buffer{std::byte{0xAA}, std::byte{0xAA}}; + auto const buffer_fill_byte = std::byte{0xAA}; + kstd::vector write_buffer{buffer_fill_byte, buffer_fill_byte}; auto bytes_written = kapi::filesystem::write(fd_3, write_buffer.data(), write_buffer.size()); kstd::println("--> written {} bytes to /dev/ram32: {::#04x}", bytes_written, write_buffer); -- cgit v1.2.3 From adb1b5f2d6858097227fa610e86d1152b79d0bfa Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 25 May 2026 14:05:38 +0200 Subject: renaming --- kernel/src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index a84ca64..6985e94 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -99,8 +99,8 @@ auto run_demo() -> void kstd::println("--> read {} bytes from /dev/ram32: {::#04x} ", bytes_read, buffer_3); // 9) write to the device file - auto const buffer_fill_byte = std::byte{0xAA}; - kstd::vector write_buffer{buffer_fill_byte, buffer_fill_byte}; + auto const default_buffer_value = std::byte{0xAA}; + kstd::vector write_buffer{default_buffer_value, default_buffer_value}; auto bytes_written = kapi::filesystem::write(fd_3, write_buffer.data(), write_buffer.size()); kstd::println("--> written {} bytes to /dev/ram32: {::#04x}", bytes_written, write_buffer); -- cgit v1.2.3 From e4dfaac871b9c0e38ed3e500f86ff1f74d8a3a52 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 31 May 2026 15:55:47 +0200 Subject: refactor and simplify mapping logic --- .../include/kernel/filesystem/ext2/filesystem.hpp | 16 ++-- kernel/src/filesystem/ext2/filesystem.cpp | 101 ++++++++------------- 2 files changed, 48 insertions(+), 69 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp index d5e5b8b..2284d7b 100644 --- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -86,16 +87,17 @@ namespace kernel::filesystem::ext2 -> kstd::ssize_t; private: + struct indirect_level + { + uint32_t slot_index; + size_t capacity; + }; + + [[nodiscard]] auto indirect_levels() const -> std::array; + [[nodiscard]] auto read_inode(uint32_t inode_number) const -> kstd::shared_ptr; [[nodiscard]] auto read_block_number_at_index(uint32_t block_number, size_t index) const -> uint32_t; - [[nodiscard]] auto read_singly_indirect_block_number(uint32_t singly_indirect_block_number, - size_t block_index_in_singly_indirect_block) const -> size_t; - [[nodiscard]] auto read_doubly_indirect_block_number(uint32_t doubly_indirect_block_number, - size_t block_index_in_doubly_indirect_block) const -> size_t; - [[nodiscard]] auto read_triply_indirect_block_number(uint32_t triply_indirect_block_number, - size_t block_index_in_triply_indirect_block) const -> size_t; - [[nodiscard]] auto inode_size() const -> uint16_t; [[nodiscard]] auto inode_block_count(inode_data const & data) const -> uint32_t; [[nodiscard]] auto block_group_descriptor_table_offset() const -> size_t; diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index a30149e..720f0a8 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -109,6 +110,15 @@ namespace kernel::filesystem::ext2 return kstd::make_shared(this, new_inode_data); } + auto filesystem::indirect_levels() const -> std::array + { + return { + {{constants::singly_indirect_block_index, block_numbers_per_singly_indirect_block()}, + {constants::doubly_indirect_block_index, block_numbers_per_doubly_indirect_block()}, + {constants::triply_indirect_block_index, block_numbers_per_triply_indirect_block()}} + }; + } + auto filesystem::map_inode_block_index_to_global_block_number(size_t inode_block_index, inode_data data) const -> kstd::ssize_t { @@ -116,78 +126,45 @@ namespace kernel::filesystem::ext2 { return data.block.at(inode_block_index); } - inode_block_index -= constants::direct_block_count; - - if (inode_block_index < block_numbers_per_singly_indirect_block()) - { - auto const singly_indirect_block_number = data.block.at(constants::singly_indirect_block_index); - return read_singly_indirect_block_number(singly_indirect_block_number, inode_block_index); - } - inode_block_index -= block_numbers_per_singly_indirect_block(); - - if (inode_block_index < block_numbers_per_doubly_indirect_block()) - { - auto const doubly_indirect_block_number = data.block.at(constants::doubly_indirect_block_index); - return read_doubly_indirect_block_number(doubly_indirect_block_number, inode_block_index); - } - inode_block_index -= block_numbers_per_doubly_indirect_block(); - if (inode_block_index < block_numbers_per_triply_indirect_block()) - { - auto const triply_indirect_block_number = data.block.at(constants::triply_indirect_block_index); - return read_triply_indirect_block_number(triply_indirect_block_number, inode_block_index); - } - - return -1; - } + inode_block_index -= constants::direct_block_count; + auto const levels = indirect_levels(); - auto filesystem::read_singly_indirect_block_number(uint32_t singly_indirect_block_number, - size_t block_index_in_singly_indirect_block) const -> size_t - { - if (singly_indirect_block_number == 0) + for (auto const & level : levels) { - return 0; - } - - return read_block_number_at_index(singly_indirect_block_number, block_index_in_singly_indirect_block); - } + if (inode_block_index >= level.capacity) + { + inode_block_index -= level.capacity; + continue; + } - auto filesystem::read_doubly_indirect_block_number(uint32_t doubly_indirect_block_number, - size_t block_index_in_doubly_indirect_block) const -> size_t - { - if (doubly_indirect_block_number == 0) - { - return 0; - } + auto block_number = data.block[level.slot_index]; + if (block_number == 0) + { + return 0; + } - auto const singly_indirect_block_index_in_doubly_indirect_block = - block_index_in_doubly_indirect_block / block_numbers_per_singly_indirect_block(); - auto const block_index_in_singly_indirect_block = - block_index_in_doubly_indirect_block % block_numbers_per_singly_indirect_block(); + for (auto stride = level.capacity / block_numbers_per_block();; stride /= block_numbers_per_block()) + { + auto const idx = inode_block_index / stride; + inode_block_index %= stride; - auto const singly_indirect_block_number = - read_block_number_at_index(doubly_indirect_block_number, singly_indirect_block_index_in_doubly_indirect_block); + block_number = read_block_number_at_index(block_number, idx); + if (block_number == 0) + { + return 0; + } - return read_singly_indirect_block_number(singly_indirect_block_number, block_index_in_singly_indirect_block); - } + if (stride == 1) + { + break; + } + } - auto filesystem::read_triply_indirect_block_number(uint32_t triply_indirect_block_number, - size_t block_index_in_triply_indirect_block) const -> size_t - { - if (triply_indirect_block_number == 0) - { - return 0; + return block_number; } - auto const doubly_indirect_block_index_in_triply_indirect_block = - block_index_in_triply_indirect_block / block_numbers_per_doubly_indirect_block(); - auto const block_index_in_doubly_indirect_block = - block_index_in_triply_indirect_block % block_numbers_per_doubly_indirect_block(); - - auto const doubly_indirect_block_number = - read_block_number_at_index(triply_indirect_block_number, doubly_indirect_block_index_in_triply_indirect_block); - - return read_doubly_indirect_block_number(doubly_indirect_block_number, block_index_in_doubly_indirect_block); + return -1; } auto filesystem::read_block_number_at_index(uint32_t block_number, size_t index) const -> uint32_t -- cgit v1.2.3 From f26569c6a4e5f0ed61b7efa81ebdddd532d542c5 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 31 May 2026 16:06:38 +0200 Subject: small refactoring --- kernel/src/filesystem/ext2/filesystem.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 720f0a8..12aeaaa 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -128,9 +128,8 @@ namespace kernel::filesystem::ext2 } inode_block_index -= constants::direct_block_count; - auto const levels = indirect_levels(); - for (auto const & level : levels) + for (auto const & level : indirect_levels()) { if (inode_block_index >= level.capacity) { -- cgit v1.2.3 From dc9bd3b44cbbd0235a176f05c27eb15ff31f5e09 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 22 May 2026 20:18:05 +0200 Subject: kernel/vfs: prepare fs type registration support --- kernel/include/kernel/filesystem/type.hpp | 33 ++++++++++++++++++++++++++++++ kernel/src/filesystem/devfs/filesystem.cpp | 22 ++++++++++++++++++++ kernel/src/filesystem/ext2/filesystem.cpp | 23 +++++++++++++++++++++ kernel/src/filesystem/vfs.cpp | 15 ++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 kernel/include/kernel/filesystem/type.hpp (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/type.hpp b/kernel/include/kernel/filesystem/type.hpp new file mode 100644 index 0000000..87e466b --- /dev/null +++ b/kernel/include/kernel/filesystem/type.hpp @@ -0,0 +1,33 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_TYPE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_TYPE_HPP + +#include + +#include + +#include + +namespace kernel::filesystem +{ + + //! A type descriptor for a filesystem driver. + //! + //! Each filesystem must expose an instance of a class derived from this type in order to be registered with the vfs + //! filesystem registry. + struct type + { + virtual ~type() = default; + + //! Get the name of the filesystem represented by this descriptor. + [[nodiscard]] virtual auto name() const noexcept -> std::string_view = 0; + + //! Check if filesystems of this type require a device to back them. + [[nodiscard]] virtual auto requires_device() const noexcept -> bool = 0; + + //! Create a new instance of the filesytem represented by this descriptor. + [[nodiscard]] virtual auto make_instance() const -> kstd::shared_ptr = 0; + }; + +} // namespace kernel::filesystem + +#endif diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp index f0d8bf7..c61a3d0 100644 --- a/kernel/src/filesystem/devfs/filesystem.cpp +++ b/kernel/src/filesystem/devfs/filesystem.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -15,6 +16,27 @@ namespace kernel::filesystem::devfs { + struct type final : kernel::filesystem::type + { + [[nodiscard]] auto name() const noexcept -> std::string_view override + { + return "devfs"; + } + + [[nodiscard]] auto requires_device() const noexcept -> bool override + { + return false; + } + + [[nodiscard]] auto make_instance() const -> kstd::shared_ptr override + { + return kstd::make_shared(); + } + } const constinit type_instance{}; + + [[gnu::section(".vfs_type_descriptors"), gnu::used]] + auto const * const type_descriptor_pointer = static_cast(&type_instance); + auto filesystem::mount(kstd::shared_ptr const &) -> operation_result { m_root_inode = kstd::make_shared(); diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 12aeaaa..6959653 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -18,6 +19,28 @@ namespace kernel::filesystem::ext2 { + + struct type final : kernel::filesystem::type + { + [[nodiscard]] auto name() const noexcept -> std::string_view override + { + return "ext2"; + } + + [[nodiscard]] auto requires_device() const noexcept -> bool override + { + return true; + } + + [[nodiscard]] auto make_instance() const -> kstd::shared_ptr override + { + return kstd::make_shared(); + } + } const constinit type_instance{}; + + [[gnu::section(".vfs_type_descriptors"), gnu::used]] + auto const * const type_descriptor_pointer = static_cast(&type_instance); + auto filesystem::mount(kstd::shared_ptr const & backing_inode) -> operation_result { kernel::filesystem::filesystem::mount(backing_inode); diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index ae85291..d22c74b 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -8,10 +8,12 @@ #include #include #include +#include #include #include +#include #include #include @@ -19,9 +21,16 @@ #include #include #include +#include #include #include +extern "C" +{ + extern kernel::filesystem::type const * const __vfs_type_descriptors_begin; + extern kernel::filesystem::type const * const __vfs_type_descriptors_end; +} + namespace { constinit auto static active_vfs = std::optional{}; @@ -42,6 +51,12 @@ namespace kernel::filesystem auto vfs::init_internal() -> void { + auto type_descriptors = std::span{&__vfs_type_descriptors_begin, &__vfs_type_descriptors_end} | + std::views::filter([](auto p) { return p != nullptr; }); + std::ranges::for_each(type_descriptors, [](auto descriptor) { + kstd::println("[OS] registering filesystem '{}'", descriptor->name()); + }); + // mount rootfs at / auto root_fs = kstd::make_shared(); root_fs->mount(nullptr); -- cgit v1.2.3 From 86170be29f6cb72b29865db0975de09bec89f854 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 1 Jun 2026 10:40:39 +0200 Subject: kernel/vfs: rename type descriptor section --- kernel/src/filesystem/devfs/filesystem.cpp | 2 +- kernel/src/filesystem/ext2/filesystem.cpp | 2 +- kernel/src/filesystem/vfs.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp index c61a3d0..1aaa0d1 100644 --- a/kernel/src/filesystem/devfs/filesystem.cpp +++ b/kernel/src/filesystem/devfs/filesystem.cpp @@ -34,7 +34,7 @@ namespace kernel::filesystem::devfs } } const constinit type_instance{}; - [[gnu::section(".vfs_type_descriptors"), gnu::used]] + [[gnu::section("vfs_type_descriptors"), gnu::used]] auto const * const type_descriptor_pointer = static_cast(&type_instance); auto filesystem::mount(kstd::shared_ptr const &) -> operation_result diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 6959653..7b5d2d7 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -38,7 +38,7 @@ namespace kernel::filesystem::ext2 } } const constinit type_instance{}; - [[gnu::section(".vfs_type_descriptors"), gnu::used]] + [[gnu::section("vfs_type_descriptors"), gnu::used]] auto const * const type_descriptor_pointer = static_cast(&type_instance); auto filesystem::mount(kstd::shared_ptr const & backing_inode) -> operation_result diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index d22c74b..c297210 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -27,8 +27,8 @@ extern "C" { - extern kernel::filesystem::type const * const __vfs_type_descriptors_begin; - extern kernel::filesystem::type const * const __vfs_type_descriptors_end; + extern kernel::filesystem::type const * const __start_vfs_type_descriptors; + extern kernel::filesystem::type const * const __stop_vfs_type_descriptors; } namespace @@ -51,7 +51,7 @@ namespace kernel::filesystem auto vfs::init_internal() -> void { - auto type_descriptors = std::span{&__vfs_type_descriptors_begin, &__vfs_type_descriptors_end} | + auto type_descriptors = std::span{&__start_vfs_type_descriptors, &__stop_vfs_type_descriptors} | std::views::filter([](auto p) { return p != nullptr; }); std::ranges::for_each(type_descriptors, [](auto descriptor) { kstd::println("[OS] registering filesystem '{}'", descriptor->name()); -- cgit v1.2.3 From 568e9586c036fc319fc36b12495e5deacb167be9 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 1 Jun 2026 20:10:57 +0200 Subject: kernel/vfs: simplify initialization --- kernel/include/kernel/filesystem/vfs.hpp | 5 ++--- kernel/src/filesystem/vfs.cpp | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index e6f2327..bbafa4f 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -35,6 +35,8 @@ namespace kernel::filesystem invalid_filesystem = -5 }; + vfs(); + /** @brief Initialize the virtual filesystem. @warning Panics if the VFS has already been initialized. @@ -83,9 +85,6 @@ namespace kernel::filesystem auto unmount(std::string_view path) -> operation_result; private: - vfs() = default; - auto init_internal() -> void; - /** * Note: Resolving a dentry requires traversing mount points; since the * associated 'mount' object is discovered as a byproduct of this diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index c297210..91afc13 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -45,12 +45,12 @@ namespace kernel::filesystem kapi::system::panic("[FILESYSTEM] vfs has already been initialized."); } - active_vfs.emplace(vfs{}); - active_vfs->init_internal(); + active_vfs.emplace(); } - auto vfs::init_internal() -> void + vfs::vfs() { + // Register all compiled-in filesystems auto type_descriptors = std::span{&__start_vfs_type_descriptors, &__stop_vfs_type_descriptors} | std::views::filter([](auto p) { return p != nullptr; }); std::ranges::for_each(type_descriptors, [](auto descriptor) { -- cgit v1.2.3 From 6c8b068c15e28e91117f84cb8d5789f5fe6fcbd0 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 1 Jun 2026 20:31:57 +0200 Subject: kstd/string: simplify comparisons --- kernel/kapi/filesystem.cpp | 2 +- kernel/src/filesystem/dentry.cpp | 2 +- kernel/src/filesystem/vfs.cpp | 8 ++++---- kernel/src/filesystem/vfs.tests.cpp | 32 ++++++++++++++------------------ 4 files changed, 20 insertions(+), 24 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index 838d2cb..68b51c9 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -45,7 +45,7 @@ namespace kapi::filesystem { if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().file(file_descriptor)) { - if (kernel::filesystem::vfs::get().close(open_file_descriptor->get_dentry()->absolute_path().view()) == + if (kernel::filesystem::vfs::get().close(open_file_descriptor->get_dentry()->absolute_path()) == kernel::filesystem::vfs::operation_result::success) { return kernel::filesystem::open_file_table::get().remove_file(file_descriptor); diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp index 14de875..3d8e01a 100644 --- a/kernel/src/filesystem/dentry.cpp +++ b/kernel/src/filesystem/dentry.cpp @@ -41,7 +41,7 @@ namespace kernel::filesystem auto dentry::name() const -> std::string_view { - return m_name.view(); + return m_name; } auto dentry::absolute_path() const -> kstd::string diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 91afc13..b0d63a2 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -241,22 +241,22 @@ namespace kernel::filesystem continue; } - auto next_dentry = current_dentry->find_child(part.view()); + auto next_dentry = current_dentry->find_child(part); if (!next_dentry) { auto current_fs = current_mount->get_filesystem(); - auto found_inode = current_fs->lookup(current_dentry->get_inode(), part.view()); + auto found_inode = current_fs->lookup(current_dentry->get_inode(), part); if (!found_inode) { return {nullptr, nullptr}; } - next_dentry = kstd::make_shared(current_dentry, found_inode, part.view()); + next_dentry = kstd::make_shared(current_dentry, found_inode, part); current_dentry->add_child(next_dentry); } else if (next_dentry->has_flag(dentry::dentry_flags::is_mount_point)) { - current_mount = m_mount_table.find_mount(next_dentry->absolute_path().view()); + current_mount = m_mount_table.find_mount(next_dentry->absolute_path()); if (!current_mount) { kapi::system::panic("[FILESYSTEM] mount for dentry with mounted flag not found."); diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index 962e067..f1d0df0 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -106,8 +106,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); REQUIRE(mounted_monkey_1 != nullptr); - REQUIRE(vfs.close(mounted_monkey_1->absolute_path().view()) == - kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_monkey_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); auto unmounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); @@ -129,9 +128,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(mounted_monkey_1 != nullptr); REQUIRE(mounted_fish1 != nullptr); - REQUIRE(vfs.close(mounted_monkey_1->absolute_path().view()) == - kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.close(mounted_fish1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_monkey_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_fish1->absolute_path()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); REQUIRE(vfs.unmount("/information/monkey_house/infrastructure") == @@ -148,8 +146,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); - REQUIRE(vfs.close(mounted_monkey_1->absolute_path().view()) == - kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_monkey_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); } @@ -165,8 +162,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1 != nullptr); - REQUIRE(vfs.close(info_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); - REQUIRE_THROWS_AS(vfs.close(info_1->absolute_path().view()), std::runtime_error); + REQUIRE(vfs.close(info_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE_THROWS_AS(vfs.close(info_1->absolute_path()), std::runtime_error); } THEN("images can be stacked mounted and correct file system is unmounted again") @@ -177,7 +174,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto mounted_tickets = vfs.open("/information/entrance/tickets.txt"); REQUIRE(mounted_tickets != nullptr); - REQUIRE(vfs.close(mounted_tickets->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_tickets->absolute_path()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); mounted_tickets = vfs.open("/information/entrance/tickets.txt"); @@ -200,7 +197,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto water = vfs.open("/monkey_house/infrastructure/water.txt"); REQUIRE(water != nullptr); - REQUIRE(vfs.close(water->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(water->absolute_path()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success); @@ -221,7 +218,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto water = vfs.open("/monkey_house/infrastructure/water.txt"); REQUIRE(water != nullptr); - REQUIRE(vfs.close(water->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(water->absolute_path()) == kernel::filesystem::vfs::operation_result::success); auto dev_ram_16 = vfs.open("/dev/ram16"); REQUIRE(dev_ram_16 == nullptr); @@ -239,7 +236,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1 != nullptr); - REQUIRE(vfs.close(info_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(info_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/dev") == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success); @@ -362,7 +359,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS std::string_view buffer_as_str{reinterpret_cast(buffer.data()), bytes_read}; REQUIRE(buffer_as_str == "sheep_1"); - REQUIRE(vfs.close(dentry->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(dentry->absolute_path()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); @@ -395,8 +392,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS buffer_as_str = std::string_view{reinterpret_cast(goat_buffer.data()), bytes_read}; REQUIRE(buffer_as_str == "goat_1"); - REQUIRE(vfs.close(sheep_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.close(goat_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(sheep_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(goat_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); @@ -407,8 +404,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto still_mounted_sheep_1 = vfs.open("/information/sheep_1.txt"); REQUIRE(still_mounted_sheep_1 != nullptr); - REQUIRE(vfs.close(still_mounted_sheep_1->absolute_path().view()) == - kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(still_mounted_sheep_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); -- cgit v1.2.3 From ad2319188269331f4873adbeb44380d63e8e83c5 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 1 Jun 2026 21:15:25 +0200 Subject: kernel/vfs: manage filesystem registrations --- kernel/include/kernel/filesystem/vfs.hpp | 7 ++++++- kernel/src/filesystem/vfs.cpp | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index bbafa4f..c8aae5c 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -6,8 +6,11 @@ #include #include #include +#include +#include #include +#include #include #include @@ -106,7 +109,9 @@ namespace kernel::filesystem auto graft_persistent_device_fs(kstd::shared_ptr const & device_fs) -> void; - mount_table m_mount_table; + //! A map from filesystem names (identifiers) to filesystem type descriptors. + kstd::flat_map> m_filesystems{}; + mount_table m_mount_table{}; }; } // namespace kernel::filesystem diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index b0d63a2..8dcae2c 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -53,8 +53,9 @@ namespace kernel::filesystem // Register all compiled-in filesystems auto type_descriptors = std::span{&__start_vfs_type_descriptors, &__stop_vfs_type_descriptors} | std::views::filter([](auto p) { return p != nullptr; }); - std::ranges::for_each(type_descriptors, [](auto descriptor) { - kstd::println("[OS] registering filesystem '{}'", descriptor->name()); + std::ranges::for_each(type_descriptors, [this](auto descriptor) { + kstd::println("[FILESYSTEM] registering '{}'", descriptor->name()); + m_filesystems.emplace(descriptor->name(), descriptor); }); // mount rootfs at / -- cgit v1.2.3 From d2d4fa3330a09f421b8658c077166cc493532b9e Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 2 Jun 2026 10:54:17 +0200 Subject: kernel/vfs: extract fs type registry --- kernel/CMakeLists.txt | 1 + kernel/include/kernel/filesystem/type.hpp | 9 +++ kernel/include/kernel/filesystem/type_registry.hpp | 47 +++++++++++++++ kernel/include/kernel/filesystem/vfs.hpp | 5 -- kernel/src/filesystem/devfs/filesystem.cpp | 6 +- kernel/src/filesystem/ext2/filesystem.cpp | 6 +- kernel/src/filesystem/type_registry.cpp | 67 ++++++++++++++++++++++ kernel/src/filesystem/vfs.cpp | 17 ------ kernel/src/main.cpp | 2 + 9 files changed, 132 insertions(+), 28 deletions(-) create mode 100644 kernel/include/kernel/filesystem/type_registry.hpp create mode 100644 kernel/src/filesystem/type_registry.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index cbc7fa5..3dd84ba 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -53,6 +53,7 @@ target_sources("kernel_lib" PRIVATE "src/filesystem/mount.cpp" "src/filesystem/open_file_descriptor.cpp" "src/filesystem/open_file_table.cpp" + "src/filesystem/type_registry.cpp" "src/filesystem/vfs.cpp" # DevFS Filesystem diff --git a/kernel/include/kernel/filesystem/type.hpp b/kernel/include/kernel/filesystem/type.hpp index 87e466b..0948e54 100644 --- a/kernel/include/kernel/filesystem/type.hpp +++ b/kernel/include/kernel/filesystem/type.hpp @@ -28,6 +28,15 @@ namespace kernel::filesystem [[nodiscard]] virtual auto make_instance() const -> kstd::shared_ptr = 0; }; + template + struct type_registration + { + constexpr auto static instance = Type{}; + [[using gnu: section("fs_types"), used, visibility("hidden")]] constexpr auto static pointer{ + kstd::make_observer(&instance), + }; + }; + } // namespace kernel::filesystem #endif diff --git a/kernel/include/kernel/filesystem/type_registry.hpp b/kernel/include/kernel/filesystem/type_registry.hpp new file mode 100644 index 0000000..2f5e708 --- /dev/null +++ b/kernel/include/kernel/filesystem/type_registry.hpp @@ -0,0 +1,47 @@ +#ifndef TEACH_OS_KERNEL_TYPE_REGISRY_HPP +#define TEACH_OS_KERNEL_TYPE_REGISRY_HPP + +#include + +#include +#include +#include + +#include +#include + +namespace kernel::filesystem +{ + + struct type_registry + { + using value_type = type; + using pointer = kstd::observer_ptr; + + auto static init() -> void; + auto static get() -> type_registry &; + + constexpr type_registry() noexcept = default; + + //! Add a type descriptor to this registry. + //! + //! This function will register the given descriptor with this registry, given that no descriptor for a filesystem + //! with the same name exists in this registry already. + //! + //! @param descriptor The filesystem type descriptor to add to the registry. + //! @return @p true iff. the descriptor was successfully added, @p false if not. + auto add(pointer descriptor) -> bool; + + //! Get all currently registered type descriptors. + //! + //! @return A span containing all currently registered filesystem type descriptors. + [[nodiscard]] auto all() const noexcept -> std::span; + + private: + //! A map from filesystem names (identifiers) to filesystem type descriptors. + kstd::flat_map m_descriptors{}; + }; + +} // namespace kernel::filesystem + +#endif diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index c8aae5c..ddc9a9b 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -6,11 +6,8 @@ #include #include #include -#include -#include #include -#include #include #include @@ -109,8 +106,6 @@ namespace kernel::filesystem auto graft_persistent_device_fs(kstd::shared_ptr const & device_fs) -> void; - //! A map from filesystem names (identifiers) to filesystem type descriptors. - kstd::flat_map> m_filesystems{}; mount_table m_mount_table{}; }; } // namespace kernel::filesystem diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp index 1aaa0d1..ce887ff 100644 --- a/kernel/src/filesystem/devfs/filesystem.cpp +++ b/kernel/src/filesystem/devfs/filesystem.cpp @@ -32,10 +32,10 @@ namespace kernel::filesystem::devfs { return kstd::make_shared(); } - } const constinit type_instance{}; + }; - [[gnu::section("vfs_type_descriptors"), gnu::used]] - auto const * const type_descriptor_pointer = static_cast(&type_instance); + [[gnu::used]] + constexpr auto registration = type_registration{}; auto filesystem::mount(kstd::shared_ptr const &) -> operation_result { diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 7b5d2d7..3180a19 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -36,10 +36,10 @@ namespace kernel::filesystem::ext2 { return kstd::make_shared(); } - } const constinit type_instance{}; + }; - [[gnu::section("vfs_type_descriptors"), gnu::used]] - auto const * const type_descriptor_pointer = static_cast(&type_instance); + [[gnu::used]] + constexpr auto registration = type_registration{}; auto filesystem::mount(kstd::shared_ptr const & backing_inode) -> operation_result { diff --git a/kernel/src/filesystem/type_registry.cpp b/kernel/src/filesystem/type_registry.cpp new file mode 100644 index 0000000..033b879 --- /dev/null +++ b/kernel/src/filesystem/type_registry.cpp @@ -0,0 +1,67 @@ +#include + +#include + +#include +#include + +#include +#include +#include +#include + +namespace kernel::filesystem +{ + + extern "C" + { + extern type_registry::pointer const __start_fs_types; + extern type_registry::pointer const __stop_fs_types; + } + + namespace + { + auto constinit instance = std::optional{}; + } + + auto type_registry::init() -> void + { + if (instance) + { + kapi::system::panic("[FILESYSTEM] tried to initialize type registry more than once!"); + } + + instance.emplace(); + + auto type_descriptors = std::span{&__start_fs_types, &__stop_fs_types} | // + std::views::filter([](auto p) { return p != nullptr; }); + + std::ranges::for_each(type_descriptors, [](auto descriptor) { + kstd::println("[FILESYSTEM] registering '{}'", descriptor->name()); + instance->add(descriptor); + }); + } + + auto type_registry::get() -> type_registry & + { + if (!instance) + { + kapi::system::panic("[FILESYSTEM] type registry has not been initialized!"); + } + + return *instance; + } + + auto type_registry::add(pointer descriptor) -> bool + { + auto result = m_descriptors.emplace(descriptor->name(), descriptor); + return result.second; + } + + [[nodiscard]] auto type_registry::all() const noexcept -> std::span + { + // TODO: implement value accessor for flat_map + return {}; + } + +} // namespace kernel::filesystem diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 8dcae2c..8d1fd23 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -8,29 +8,20 @@ #include #include #include -#include #include #include #include -#include #include #include #include #include #include -#include #include #include -extern "C" -{ - extern kernel::filesystem::type const * const __start_vfs_type_descriptors; - extern kernel::filesystem::type const * const __stop_vfs_type_descriptors; -} - namespace { constinit auto static active_vfs = std::optional{}; @@ -50,14 +41,6 @@ namespace kernel::filesystem vfs::vfs() { - // Register all compiled-in filesystems - auto type_descriptors = std::span{&__start_vfs_type_descriptors, &__stop_vfs_type_descriptors} | - std::views::filter([](auto p) { return p != nullptr; }); - std::ranges::for_each(type_descriptors, [this](auto descriptor) { - kstd::println("[FILESYSTEM] registering '{}'", descriptor->name()); - m_filesystems.emplace(descriptor->name(), descriptor); - }); - // mount rootfs at / auto root_fs = kstd::make_shared(); root_fs->mount(nullptr); diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 6985e94..5063d18 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,3 +1,4 @@ +#include "kernel/filesystem/type_registry.hpp" #include #include #include @@ -138,6 +139,7 @@ auto main() -> int kernel::filesystem::open_file_table::init(); kstd::println("[OS] Global open file table initialized."); + kernel::filesystem::type_registry::init(); kernel::filesystem::vfs::init(); kstd::println("[OS] Virtual filesystem initialized."); -- cgit v1.2.3 From b34db5a8acd0639fde9a81b38e96776f7c2ef61e Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 2 Jun 2026 11:38:48 +0200 Subject: kernel/vfs: add type descriptor for rootfs --- kernel/src/filesystem/rootfs/filesystem.cpp | 25 ++++++++++++++++++++++++- kernel/src/main.cpp | 2 ++ 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/src/filesystem/rootfs/filesystem.cpp b/kernel/src/filesystem/rootfs/filesystem.cpp index 0ba2936..7fe5c1e 100644 --- a/kernel/src/filesystem/rootfs/filesystem.cpp +++ b/kernel/src/filesystem/rootfs/filesystem.cpp @@ -1,8 +1,9 @@ #include -#include "kernel/filesystem/filesystem.hpp" +#include #include #include +#include #include @@ -10,6 +11,28 @@ namespace kernel::filesystem::rootfs { + + struct type final : kernel::filesystem::type + { + [[nodiscard]] auto name() const noexcept -> std::string_view override + { + return "rootfs"; + } + + [[nodiscard]] auto requires_device() const noexcept -> bool override + { + return true; + } + + [[nodiscard]] auto make_instance() const -> kstd::shared_ptr override + { + return kstd::make_shared(); + } + }; + + [[gnu::used]] + constexpr auto registration = type_registration{}; + auto filesystem::mount(kstd::shared_ptr const &) -> operation_result { m_root_inode = kstd::make_shared(); diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 5063d18..8dc1349 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -140,6 +140,8 @@ auto main() -> int kstd::println("[OS] Global open file table initialized."); kernel::filesystem::type_registry::init(); + kstd::println("[OS] Builtin filesystems registered."); + kernel::filesystem::vfs::init(); kstd::println("[OS] Virtual filesystem initialized."); -- cgit v1.2.3 From 772861fc5fae1c126fcc63a8809b0a9c729bd152 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 2 Jun 2026 13:43:49 +0200 Subject: kernel/vfs: add type registry tests --- kernel/CMakeLists.txt | 1 + kernel/include/kernel/filesystem/type_registry.hpp | 8 ++- kernel/src/filesystem/type_registry.cpp | 11 +++- kernel/src/filesystem/type_registry.tests.cpp | 77 ++++++++++++++++++++++ kernel/src/filesystem/vfs.cpp | 1 - 5 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 kernel/src/filesystem/type_registry.tests.cpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 3dd84ba..2388370 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -201,6 +201,7 @@ if(BUILD_TESTING) "src/filesystem/mount.tests.cpp" "src/filesystem/open_file_descriptor.tests.cpp" "src/filesystem/open_file_table.tests.cpp" + "src/filesystem/type_registry.tests.cpp" "src/filesystem/vfs.tests.cpp" # Storage Subsystem Tests diff --git a/kernel/include/kernel/filesystem/type_registry.hpp b/kernel/include/kernel/filesystem/type_registry.hpp index 2f5e708..3be7295 100644 --- a/kernel/include/kernel/filesystem/type_registry.hpp +++ b/kernel/include/kernel/filesystem/type_registry.hpp @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -35,7 +36,12 @@ namespace kernel::filesystem //! Get all currently registered type descriptors. //! //! @return A span containing all currently registered filesystem type descriptors. - [[nodiscard]] auto all() const noexcept -> std::span; + [[nodiscard]] auto all() const noexcept -> std::span; + + //! Get the number of registered filesystem types. + //! + //! @return The number of filesystem descriptors currently registered with this registry. + [[nodiscard]] auto size() const noexcept -> std::size_t; private: //! A map from filesystem names (identifiers) to filesystem type descriptors. diff --git a/kernel/src/filesystem/type_registry.cpp b/kernel/src/filesystem/type_registry.cpp index 033b879..d917c81 100644 --- a/kernel/src/filesystem/type_registry.cpp +++ b/kernel/src/filesystem/type_registry.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -58,10 +59,14 @@ namespace kernel::filesystem return result.second; } - [[nodiscard]] auto type_registry::all() const noexcept -> std::span + auto type_registry::all() const noexcept -> std::span { - // TODO: implement value accessor for flat_map - return {}; + return {m_descriptors.values().begin(), m_descriptors.values().end()}; + } + + auto type_registry::size() const noexcept -> std::size_t + { + return m_descriptors.size(); } } // namespace kernel::filesystem diff --git a/kernel/src/filesystem/type_registry.tests.cpp b/kernel/src/filesystem/type_registry.tests.cpp new file mode 100644 index 0000000..8382579 --- /dev/null +++ b/kernel/src/filesystem/type_registry.tests.cpp @@ -0,0 +1,77 @@ +#include + +#include +#include + +#include + +#include + +#include +#include + +struct test_type final : kernel::filesystem::type +{ + [[nodiscard]] auto name() const noexcept -> std::string_view override + { + return "bht_testfs"; + } + + [[nodiscard]] auto requires_device() const noexcept -> bool override + { + return false; + } + + [[nodiscard]] auto make_instance() const -> kstd::shared_ptr override + { + return nullptr; + } +}; + +SCENARIO("Filesystem type registry initialization and construction", "[filesystem]") +{ + GIVEN("A default constructed type_registry") + { + auto instance = kernel::filesystem::type_registry{}; + + WHEN("getting the span of filesystem descriptors") + { + auto descriptors = instance.all(); + + THEN("the span is empty") + { + REQUIRE(descriptors.empty()); + } + } + } +} + +SCENARIO("Filesystem type registry modifiers", "[filesystem]") +{ + GIVEN("A default constructed type_registry") + { + auto instance = kernel::filesystem::type_registry{}; + + WHEN("adding a type descriptor") + { + auto descriptor = test_type{}; + + instance.add(kstd::make_observer(&descriptor)); + + THEN("the size of the registry is one") + { + REQUIRE(instance.size() == 1); + } + + THEN("the span is not empty") + { + REQUIRE_FALSE(instance.all().empty()); + } + + THEN("the span's size is equal to the registry size") + { + REQUIRE(std::size(instance.all()) == std::size(instance)); + } + } + } +} diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 8d1fd23..e5dff8c 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include -- cgit v1.2.3 From 66ea58d7c5b41475e0be61172966613fbd14d43b Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sun, 7 Jun 2026 18:54:49 +0200 Subject: small refactoring --- kernel/include/kernel/filesystem/mount.hpp | 6 +++--- kernel/src/filesystem/mount_table.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp index 53d7f6d..ced4f81 100644 --- a/kernel/include/kernel/filesystem/mount.hpp +++ b/kernel/include/kernel/filesystem/mount.hpp @@ -85,12 +85,12 @@ namespace kernel::filesystem [[nodiscard]] auto ref_count() const -> size_t; private: - kstd::shared_ptr m_mount_dentry; - kstd::shared_ptr m_root_dentry; + kstd::shared_ptr m_mount_dentry{}; + kstd::shared_ptr m_root_dentry{}; kstd::shared_ptr m_filesystem{}; kstd::shared_ptr m_parent_mount{}; kstd::weak_ptr m_source_mount{}; - std::atomic_size_t m_ref_count; + std::atomic_size_t m_ref_count{0}; }; } // namespace kernel::filesystem diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index af8434b..e4baac7 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -18,7 +18,7 @@ namespace kernel::filesystem [&parent_mount](auto const & mount) { return mount->parent_mount() == parent_mount; }); } - void mount_table::add_mount(kstd::shared_ptr const & mount) + auto mount_table::add_mount(kstd::shared_ptr const & mount) -> void { m_mounts.push_back(mount); -- cgit v1.2.3