#include "kernel/filesystem/type_registry.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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) { kapi::system::panic("demo failed"); } else { kstd::println("--> successfully opened /entrance/tickets.txt with file descriptor {}", fd_1.value()); } // 2) read from the file kstd::vector buffer_1{10}; auto bytes_read = kapi::filesystem::read(fd_1.value(), buffer_1)->value; auto buffer_as_str = std::string_view{reinterpret_cast(buffer_1.data()), bytes_read}; 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 && fd_before_mount.error() == kstd::errc::no_such_file_or_directory) { kstd::println("--> as expected the file could not be opened before mounting"); } // 4) mount a new filesystem on top of /entrance kstd::println("mount /dev/ram1 to /entrance"); if (kapi::filesystem::mount("/dev/ram1", "/entrance")) { kstd::println("--> successfully mounted /dev/ram1 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) { kstd::println("--> successfully opened /entrance/information/info_1.txt with file descriptor {}", fd_2.value()); } else { kapi::system::panic("demo failed"); } // 6) read from the new file kstd::vector buffer_2{10}; bytes_read = kapi::filesystem::read(fd_2.value(), buffer_2)->value; 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 kstd::println("attempting to open /dev/ram2 as a file"); auto fd_3 = kapi::filesystem::open("/dev/ram2"); if (fd_3) { kstd::println("--> successfully opened /dev/ram2 as a file with file descriptor {}", fd_3.value()); } else { kapi::system::panic("demo failed"); } // 8) read from the device file kstd::vector buffer_3{2}; bytes_read = kapi::filesystem::read(fd_3.value(), buffer_3)->value; kstd::println("--> read {} bytes from /dev/ram2: {::#04x} ", bytes_read, buffer_3); // 9) write to the device file 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.value(), write_buffer)->value; kstd::println("--> written {} bytes to /dev/ram2: {::#04x}", bytes_written, write_buffer); // 10) do memory dump to show that the write to the device file had an effect // 11) dmp the module before create new directory and file // -exec monitor memsave 0xffffffff8025b000 0xA00000 dump_before.bin // 12) create new folder and file auto creation_result = kapi::filesystem::mkdir("/test_files").and_then([] { return kapi::filesystem::create("/test_files/test_file.txt"); }); if (!creation_result) { kapi::system::panic("demo failed", creation_result.error()); } // 13) write to the new file auto fd_4 = kapi::filesystem::open("/test_files/test_file.txt"); if (fd_4) { kstd::println("--> successfully opened /test_files/test_file.txt as a file with file descriptor {}", fd_4.value()); } else { kapi::system::panic("demo failed"); } kstd::vector test_write_buffer{ std::byte{'H'}, std::byte{'e'}, std::byte{'l'}, std::byte{'l'}, std::byte{'o'}, std::byte{' '}, std::byte{'T'}, std::byte{'e'}, std::byte{'a'}, std::byte{'c'}, std::byte{'h'}, std::byte{'O'}, std::byte{'S'}}; bytes_written = kapi::filesystem::write(*fd_4, test_write_buffer)->value; kstd::println("--> written {} bytes to /test_files/test_file.txt: {::#04x}", bytes_written, test_write_buffer); // 14) dmp the module after create new directory and file // -exec monitor memsave 0xffffffff8025b000 0xA00000 dump_after.bin } 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] Basic device and driver subsystem initialized."); kernel::drivers::init(); kstd::println("[OS] Generic drivers initialized."); kapi::devices::init_platform_drivers(); kstd::println("[OS] Platform drivers initialized."); kapi::devices::init_platform_devices(); kstd::println("[OS] Platform devices initialized."); kapi::interrupts::enable(); kstd::println("[OS] Interrupts enabled."); auto modules_bus = kernel::devices::storage::init(); kstd::println("[OS] Storage subsystem initialized."); kapi::boot_modules::init(*modules_bus); kstd::println("[OS] Boot modules attached."); kernel::filesystem::open_file_table::init(); 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."); // TODO BA-FS26 remove demo code? run_demo(); kapi::system::panic("Returning from kernel main!"); }