diff options
| author | Lukas Oesch <lukas.oesch@ost.ch> | 2026-03-30 19:39:34 +0200 |
|---|---|---|
| committer | Lukas Oesch <lukas.oesch@ost.ch> | 2026-03-30 19:39:34 +0200 |
| commit | 9058bbed061602cdf41013d5e5d91ce892f63c94 (patch) | |
| tree | b2db129522c6d3e7d939926d5ab91bc3ca207f42 | |
| parent | c946cf6a89bbeae7fb96a67b55d91b7ae0cfa48d (diff) | |
| parent | 7ad07a735759dc93b668ec92896f57c0c0df0025 (diff) | |
| download | teachos-9058bbed061602cdf41013d5e5d91ce892f63c94.tar.xz teachos-9058bbed061602cdf41013d5e5d91ce892f63c94.zip | |
Merge branch 'ext2' into 'develop-BA-FS26'
Ext2-initial-structure
See merge request teachos/kernel!17
| -rw-r--r-- | kernel/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | kernel/include/kernel/devices/block_device_utils.hpp | 17 | ||||
| -rw-r--r-- | kernel/include/kernel/filesystem/device_inode.hpp | 5 | ||||
| -rw-r--r-- | kernel/include/kernel/filesystem/ext2/ext2_block_group_descriptor.hpp | 21 | ||||
| -rw-r--r-- | kernel/include/kernel/filesystem/ext2/ext2_file.hpp | 15 | ||||
| -rw-r--r-- | kernel/include/kernel/filesystem/ext2/ext2_inode.hpp | 27 | ||||
| -rw-r--r-- | kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp | 20 | ||||
| -rw-r--r-- | kernel/include/kernel/filesystem/ext2/ext2_superblock.hpp | 76 | ||||
| -rw-r--r-- | kernel/src/devices/block_device_utils.cpp | 103 | ||||
| -rw-r--r-- | kernel/src/filesystem/device_inode.cpp | 76 | ||||
| -rw-r--r-- | kernel/src/filesystem/ext2/ext2_file.cpp | 20 | ||||
| -rw-r--r-- | kernel/src/filesystem/ext2/ext2_filesystem.cpp | 35 |
12 files changed, 299 insertions, 118 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index cadc373..5cc6f2d 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -19,13 +19,13 @@ 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" "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/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 <kstd/memory> + +#include <cstddef> + +namespace devices::block_device_utils +{ + auto read(kstd::shared_ptr<devices::device> const & device, void * buffer, size_t offset, size_t size) -> size_t; + auto write(kstd::shared_ptr<devices::device> 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<devices::device> 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<devices::device> m_device; }; } // namespace filesystem 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 <array> +#include <cstdint> + +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<uint8_t, 2> padding; + std::array<uint8_t, 12> 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_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 <cstddef> - -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..c35f84c 100644 --- a/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp +++ b/kernel/include/kernel/filesystem/ext2/ext2_inode.hpp @@ -1,24 +1,43 @@ #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 <kstd/memory> +#include <array> #include <cstddef> +#include <cstdint> 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; - private: - kstd::shared_ptr<ext2_file> m_file; + 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<uint32_t, 15> 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<uint8_t, 12> 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..3128617 --- /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 <array> +#include <cstdint> + +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<uint8_t, 255> name; // NOLINT(readability-magic-numbers) + }; +} // namespace 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 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 <array> +#include <cstdint> + +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<uint8_t, 16> uuid; + // uint8_t volume_name[16]; // TODO BA-FS26 really correct? + std::array<uint8_t, 16> volume_name; + // uint8_t last_mounted[64]; // TODO BA-FS26 really correct? + std::array<uint8_t, 64> 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<uint8_t, 16> 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<uint32_t, 4> hash_seed; + uint8_t def_hash_version; + std::array<uint8_t, 3> padding2; + + // Other options + uint32_t default_mount_options; + uint32_t first_meta_bg; + std::array<uint8_t, 760> unused; // NOLINT(readability-magic-numbers) + }; +} // namespace filesystem::ext2 +#endif
\ No newline at end of file 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 <kstd/cstring> +#include <kstd/memory> +#include <kstd/vector> + +#include <algorithm> +#include <cstddef> + +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<devices::device> 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<devices::block_device *>(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<std::byte> 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<devices::device> 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<std::byte *>(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<devices::device> const & device, void const * buffer, size_t offset, size_t size) + -> size_t + { + return process_blocks(device, offset, size, const_cast<void *>(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<std::byte const *>(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 <kstd/memory> #include <kstd/vector> -#include <algorithm> #include <cstddef> 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<std::byte *>(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<void *>(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<std::byte const *>(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<devices::block_device *>(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<std::byte> 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_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 <cstddef> - -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_filesystem.cpp b/kernel/src/filesystem/ext2/ext2_filesystem.cpp index 373c6a2..ea6fe0d 100644 --- a/kernel/src/filesystem/ext2/ext2_filesystem.cpp +++ b/kernel/src/filesystem/ext2/ext2_filesystem.cpp @@ -1,16 +1,50 @@ #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 <kstd/memory> +#include <cstddef> +#include <cstdint> #include <string_view> 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<devices::device> const & device) -> int { filesystem::mount(device); // TODO BA-FS26 error handling? @@ -19,6 +53,7 @@ namespace filesystem::ext2 // TODO BA-FS26 implement m_root_inode = kstd::make_shared<ext2_inode>(); + // devices::block_device_utils::read(device, nullptr, 0, 0); // TODO BA-FS26 just for testing return 0; } |
