#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 "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" #include #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(); 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 auto fd_table = kernel::filesystem::file_descriptor_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 { // TODO BA-FS26 auto vfs = kernel::filesystem::vfs::get(); auto ofd = vfs.open("/dev/ram0"); if (!ofd) { kstd::os::panic("test code failed"); } 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); 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 { // 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 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 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"); } } 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("---------------------------------"); kstd::println("[TEST] file lookup"); test_file_lookup(); kstd::println("---------------------------------"); } auto main() -> int { kapi::cio::init(); kstd::println("[OS] IO subsystem initialized."); kapi::cpu::init(); kapi::memory::init(); kernel::memory::init_heap(kapi::memory::heap_base); kapi::system::memory_initialized(); kapi::memory::init_mmio(kapi::memory::mmio_base, 1_GiB / kapi::memory::page::size); kstd::println("[OS] Memory subsystem initialized."); kapi::devices::init(); kstd::println("[OS] System root bus initialized."); 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."); 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::vfs::init(); kstd::println("[OS] Virtual filesystem initialized."); run_test_code(); kstd::println("[TEST] All tests completed."); kapi::system::panic("Returning from kernel main!"); }