aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/CMakeLists.txt29
-rw-r--r--kernel/include/kernel/devices/block_device_utils.hpp29
-rw-r--r--kernel/include/kernel/filesystem/dentry.hpp57
-rw-r--r--kernel/include/kernel/filesystem/devfs/filesystem.hpp21
-rw-r--r--kernel/include/kernel/filesystem/devfs/inode.hpp22
-rw-r--r--kernel/include/kernel/filesystem/device_inode.hpp31
-rw-r--r--kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp5
-rw-r--r--kernel/include/kernel/filesystem/ext2/filesystem.hpp70
-rw-r--r--kernel/include/kernel/filesystem/ext2/inode.hpp49
-rw-r--r--kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp8
-rw-r--r--kernel/include/kernel/filesystem/ext2/superblock.hpp10
-rw-r--r--kernel/include/kernel/filesystem/file_descriptor_table.hpp34
-rw-r--r--kernel/include/kernel/filesystem/filesystem.hpp51
-rw-r--r--kernel/include/kernel/filesystem/inode.hpp47
-rw-r--r--kernel/include/kernel/filesystem/mount.hpp38
-rw-r--r--kernel/include/kernel/filesystem/mount_table.hpp35
-rw-r--r--kernel/include/kernel/filesystem/open_file_description.hpp34
-rw-r--r--kernel/include/kernel/filesystem/rootfs/filesystem.hpp21
-rw-r--r--kernel/include/kernel/filesystem/rootfs/inode.hpp34
-rw-r--r--kernel/include/kernel/filesystem/vfs.hpp52
-rw-r--r--kernel/include/kernel/test_support/boot_modules.hpp10
-rw-r--r--kernel/include/kernel/test_support/devices/block_device.hpp31
-rw-r--r--kernel/include/kernel/test_support/devices/character_device.hpp23
-rw-r--r--kernel/include/kernel/test_support/devices/storage/management.hpp10
-rw-r--r--kernel/include/kernel/test_support/filesystem/ext2.hpp17
-rw-r--r--kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp10
-rw-r--r--kernel/include/kernel/test_support/filesystem/filesystem.hpp22
-rw-r--r--kernel/include/kernel/test_support/filesystem/inode.hpp19
-rw-r--r--kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp32
-rw-r--r--kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp24
-rw-r--r--kernel/include/kernel/test_support/filesystem/vfs.hpp10
-rw-r--r--kernel/kapi/boot_modules.cpp19
-rw-r--r--kernel/src/devices/block_device.cpp3
-rw-r--r--kernel/src/devices/block_device.tests.cpp46
-rw-r--r--kernel/src/devices/block_device_utils.cpp7
-rw-r--r--kernel/src/devices/block_device_utils.tests.cpp219
-rw-r--r--kernel/src/devices/storage/management.cpp28
-rw-r--r--kernel/src/filesystem/dentry.cpp9
-rw-r--r--kernel/src/filesystem/dentry.tests.cpp135
-rw-r--r--kernel/src/filesystem/devfs/filesystem.cpp5
-rw-r--r--kernel/src/filesystem/devfs/filesystem.tests.cpp72
-rw-r--r--kernel/src/filesystem/devfs/inode.tests.cpp54
-rw-r--r--kernel/src/filesystem/device_inode.cpp4
-rw-r--r--kernel/src/filesystem/device_inode.tests.cpp108
-rw-r--r--kernel/src/filesystem/ext2/filesystem.cpp241
-rw-r--r--kernel/src/filesystem/ext2/filesystem.tests.cpp132
-rw-r--r--kernel/src/filesystem/ext2/inode.cpp47
-rw-r--r--kernel/src/filesystem/ext2/inode.tests.cpp159
-rw-r--r--kernel/src/filesystem/file_descriptor_table.cpp20
-rw-r--r--kernel/src/filesystem/file_descriptor_table.tests.cpp113
-rw-r--r--kernel/src/filesystem/filesystem.cpp44
-rw-r--r--kernel/src/filesystem/mount.cpp11
-rw-r--r--kernel/src/filesystem/mount.tests.cpp49
-rw-r--r--kernel/src/filesystem/mount_table.cpp71
-rw-r--r--kernel/src/filesystem/mount_table.tests.cpp163
-rw-r--r--kernel/src/filesystem/open_file_description.cpp6
-rw-r--r--kernel/src/filesystem/open_file_description.tests.cpp114
-rw-r--r--kernel/src/filesystem/rootfs/filesystem.cpp5
-rw-r--r--kernel/src/filesystem/rootfs/filesystem.tests.cpp45
-rw-r--r--kernel/src/filesystem/rootfs/inode.tests.cpp83
-rw-r--r--kernel/src/filesystem/vfs.cpp74
-rw-r--r--kernel/src/filesystem/vfs.tests.cpp166
-rw-r--r--kernel/src/main.cpp79
-rw-r--r--kernel/src/test_support/devices/block_device.cpp61
-rw-r--r--kernel/src/test_support/devices/character_device.cpp20
-rw-r--r--kernel/src/test_support/filesystem/ext2.cpp62
-rw-r--r--kernel/src/test_support/filesystem/filesystem.cpp17
-rw-r--r--kernel/src/test_support/filesystem/inode.cpp22
-rw-r--r--kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp109
-rw-r--r--kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp32
-rw-r--r--kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img3
-rw-r--r--kernel/src/test_support/filesystem/test_assets/ext2_2KB_fs.img3
-rw-r--r--kernel/src/test_support/filesystem/test_assets/ext2_4KB_fs.img3
-rw-r--r--kernel/src/test_support/state_reset_listener.cpp12
74 files changed, 3385 insertions, 175 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index 74233cb..2f6113a 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -101,7 +101,13 @@ else()
"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/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/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"
"src/test_support/page_mapper.cpp"
"src/test_support/simulated_memory.cpp"
@@ -126,7 +132,24 @@ else()
"src/memory/bitmap_allocator.tests.cpp"
"src/memory/block_list_allocator.tests.cpp"
+ # 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"
+ "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"
+ "src/filesystem/vfs.tests.cpp"
+
# 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")
@@ -136,6 +159,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/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<kapi::devices::device> 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<kapi::devices::device> 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<kapi::devices::device> 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..58a918f 100644
--- a/kernel/include/kernel/filesystem/dentry.hpp
+++ b/kernel/include/kernel/filesystem/dentry.hpp
@@ -12,23 +12,78 @@
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
};
- dentry(kstd::shared_ptr<dentry> const & parent, kstd::shared_ptr<inode> const & node, std::string_view name = {});
+ /**
+ @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<dentry> const & parent, kstd::shared_ptr<inode> const & inode, std::string_view name = {});
+ /**
+ @brief Get the associated inode.
+ @return A reference to the associated inode.
+ */
[[nodiscard]] auto get_inode() const -> kstd::shared_ptr<inode> const &;
+
+ /**
+ @brief Get the parent dentry.
+ @return A reference to the parent dentry.
+ */
[[nodiscard]] auto get_parent() const -> kstd::shared_ptr<dentry> 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.
+ */
auto add_child(kstd::shared_ptr<dentry> 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<dentry>;
+ /**
+ @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 29ae388..137eca3 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"
@@ -12,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
{
- auto mount(kstd::shared_ptr<kapi::devices::device> const & device) -> int override;
+ /**
+ @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 The result of the mount operation.
+ */
+ auto mount(kstd::shared_ptr<kapi::devices::device> const & device) -> operation_result 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<kernel::filesystem::inode> const & parent, std::string_view name)
-> kstd::shared_ptr<kernel::filesystem::inode> 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 <kstd/memory>
@@ -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<kapi::devices::device> 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<kapi::devices::device> 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 a23c045..7fbba3f 100644
--- a/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp
+++ b/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp
@@ -6,7 +6,10 @@
namespace kernel::filesystem::ext2
{
- struct block_group_descriptor
+ /**
+ @brief Represents a block group descriptor in the ext2 filesystem.
+ */
+ 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 078da31..a71385f 100644
--- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp
+++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp
@@ -2,20 +2,88 @@
#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"
#include "kernel/filesystem/filesystem.hpp"
#include "kernel/filesystem/inode.hpp"
#include <kstd/memory>
+#include <kstd/vector>
+#include <cstddef>
+#include <cstdint>
#include <string_view>
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.
+ */
struct filesystem : kernel::filesystem::filesystem