aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Oesch <lukas.oesch@ost.ch>2026-03-30 19:39:34 +0200
committerLukas Oesch <lukas.oesch@ost.ch>2026-03-30 19:39:34 +0200
commit9058bbed061602cdf41013d5e5d91ce892f63c94 (patch)
treeb2db129522c6d3e7d939926d5ab91bc3ca207f42
parentc946cf6a89bbeae7fb96a67b55d91b7ae0cfa48d (diff)
parent7ad07a735759dc93b668ec92896f57c0c0df0025 (diff)
downloadteachos-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.txt2
-rw-r--r--kernel/include/kernel/devices/block_device_utils.hpp17
-rw-r--r--kernel/include/kernel/filesystem/device_inode.hpp5
-rw-r--r--kernel/include/kernel/filesystem/ext2/ext2_block_group_descriptor.hpp21
-rw-r--r--kernel/include/kernel/filesystem/ext2/ext2_file.hpp15
-rw-r--r--kernel/include/kernel/filesystem/ext2/ext2_inode.hpp27
-rw-r--r--kernel/include/kernel/filesystem/ext2/ext2_linked_directory_entry.hpp20
-rw-r--r--kernel/include/kernel/filesystem/ext2/ext2_superblock.hpp76
-rw-r--r--kernel/src/devices/block_device_utils.cpp103
-rw-r--r--kernel/src/filesystem/device_inode.cpp76
-rw-r--r--kernel/src/filesystem/ext2/ext2_file.cpp20
-rw-r--r--kernel/src/filesystem/ext2/ext2_filesystem.cpp35
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;
}