aboutsummaryrefslogtreecommitdiff
path: root/kernel/include
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/include')
-rw-r--r--kernel/include/kernel/devices/block_device.hpp101
-rw-r--r--kernel/include/kernel/devices/device.hpp61
-rw-r--r--kernel/include/kernel/devices/storage/ram_disk/ram_disk_controller.hpp31
-rw-r--r--kernel/include/kernel/devices/storage/ram_disk/ram_disk_device.hpp52
-rw-r--r--kernel/include/kernel/devices/storage/storage_controller.hpp71
-rw-r--r--kernel/include/kernel/devices/storage/storage_management.hpp77
-rw-r--r--kernel/include/kernel/filesystem/custody.hpp23
-rw-r--r--kernel/include/kernel/filesystem/device_file.hpp32
-rw-r--r--kernel/include/kernel/filesystem/ext2/ext2_filesystem.hpp24
-rw-r--r--kernel/include/kernel/filesystem/file.hpp19
-rw-r--r--kernel/include/kernel/filesystem/file_descriptor_table.hpp31
-rw-r--r--kernel/include/kernel/filesystem/filesystem.hpp28
-rw-r--r--kernel/include/kernel/filesystem/inode.hpp38
-rw-r--r--kernel/include/kernel/filesystem/inode_file.hpp27
-rw-r--r--kernel/include/kernel/filesystem/inode_metadata.hpp24
-rw-r--r--kernel/include/kernel/filesystem/mount.hpp25
-rw-r--r--kernel/include/kernel/filesystem/open_file_description.hpp28
-rw-r--r--kernel/include/kernel/filesystem/vfs.hpp46
18 files changed, 738 insertions, 0 deletions
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 <cstddef>
+#include <string_view>
+
+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 <cstddef>
+#include <string_view>
+
+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 <cstddef>
+
+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 <kstd/memory>
+#include <kstd/vector>
+
+#include <cstddef>
+
+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<kstd::shared_ptr<devices::device>> 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<devices::device>;
+
+ protected:
+ size_t m_major{};
+ size_t m_minors_per_device{};
+ kstd::vector<kstd::shared_ptr<devices::device>> 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 <kstd/memory>
+#include <kstd/vector>
+
+#include <cstddef>
+
+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<storage_controller> const & controller) -> void;
+
+ /**
+ * @brief Return all registered storage controllers.
+ * @return Vector of all registered storage controllers.
+ */
+ [[nodiscard]] auto all_controllers() const -> kstd::vector<kstd::shared_ptr<storage_controller>> 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<device>;
+
+ /**
+ * @brief Determine the boot device.
+ * @return Boot device, or nullptr if it cannot be determined.
+ */
+ auto determine_boot_device() -> kstd::shared_ptr<device>;
+
+ private:
+ /**
+ * @brief Private default constructor for storage management singleton.
+ */
+ storage_management() = default;
+
+ kstd::vector<kstd::shared_ptr<storage_controller>> 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 <kstd/memory>
+
+namespace filesystem
+{
+ struct custody
+ {
+ custody(kstd::shared_ptr<custody> const & parent, kstd::shared_ptr<inode> const & node);
+
+ [[nodiscard]] auto get_inode() const -> kstd::shared_ptr<inode> const &;
+ [[nodiscard]] auto get_parent() const -> kstd::shared_ptr<custody> const &;
+
+ private:
+ kstd::shared_ptr<custody> m_parent;
+ kstd::shared_ptr<inode> 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 <kstd/memory>
+
+#include <cstddef>
+
+namespace filesystem
+{
+ struct device_file : file
+ {
+ explicit device_file(kstd::shared_ptr<devices::device> 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<devices::device> 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 <kstd/memory>
+
+#include <string_view>
+
+namespace filesystem::ext2
+{
+ struct ext2_filesystem : filesystem
+ {
+ auto mount(kstd::shared_ptr<devices::device> const & device) -> int override;
+ auto lookup(inode const & parent, std::string_view name) -> inode * override;
+
+ private:
+ kstd::shared_ptr<devices::device> 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 <cstddef>
+
+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 <kstd/vector>
+
+#include <optional>
+
+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<open_file_description>;
+ auto remove_file(int fd) -> void;
+
+ private:
+ file_descriptor_table() = default;
+
+ // TODO BA-FS26 use kstd::shared_ptr when available
+ kstd::vector<std::optional<open_file_description>> 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 <kstd/memory>
+
+#include <string_view>
+
+namespace filesystem
+{
+ struct filesystem
+ {
+ virtual ~filesystem() = default;
+
+ virtual auto mount(kstd::shared_ptr<devices::device> 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 <kstd/memory>
+
+#include <cstddef>
+
+namespace filesystem
+{
+ struct inode
+ {
+ inode() = default;
+ explicit inode(inode_kind kind);
+ explicit inode(kstd::shared_ptr<devices::device> 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<devices::device> 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<devices::device> 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 <kstd/memory>
+
+#include <cstddef>
+
+namespace filesystem
+{
+ struct inode_file : file
+ {
+ explicit inode_file(kstd::shared_ptr<inode> 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<inode> 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 <cstddef>
+#include <optional>
+
+namespace filesystem
+{
+ enum class inode_kind
+ {
+ regular,
+ directory,
+ device
+ };
+
+ struct inode_metadata
+ {
+ inode_kind kind{inode_kind::regular};
+ std::optional<size_t> major{};
+ std::optional<size_t> 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 <kstd/memory>
+
+#include <string_view>
+
+namespace filesystem
+{
+ struct mount
+ {
+ mount(std::string_view const & path, kstd::shared_ptr<filesystem> const & fs);
+
+ [[nodiscard]] auto path() const -> std::string_view;
+ [[nodiscard]] auto get_filesystem() const -> kstd::shared_ptr<filesystem> const &;
+
+ private:
+ std::string_view m_path;
+ kstd::shared_ptr<filesystem> 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 <kstd/memory>
+
+#include <cstddef>
+
+namespace filesystem
+{
+ struct open_file_description
+ {
+ open_file_description(kstd::shared_ptr<file> 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<file> 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 <kstd/memory>
+#include <kstd/vector>
+
+#include <optional>
+#include <string_view>
+
+namespace filesystem
+{
+ struct vfs
+ {
+ auto static init() -> void;
+ auto static get() -> vfs &;
+
+ ~vfs() = default;
+
+ auto open(std::string_view path) -> std::optional<open_file_description>;
+
+ private:
+ struct device_node_entry
+ {
+ std::string_view name;
+ kstd::shared_ptr<inode> node;
+ };
+
+ vfs() = default;
+ auto make_device_node(kstd::shared_ptr<devices::device> const & device) -> void;
+ [[nodiscard]] auto resolve_path(std::string_view path) -> std::optional<custody>;
+
+ kstd::shared_ptr<ext2::ext2_filesystem> m_root_fs;
+ std::optional<mount> m_root_mount;
+ // kstd::vector<mount> m_mounts; // TODO BA-FS26 really needed?
+ kstd::vector<std::optional<device_node_entry>> m_device_nodes; // TODO BA-FS26 remove again, use devtempfs
+ };
+} // namespace filesystem
+
+#endif \ No newline at end of file