aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/kernel/filesystems/fat32/boot_sector.hpp46
-rw-r--r--kernel/kernel/filesystems/fat32/filesystem.cpp69
-rw-r--r--kernel/kernel/filesystems/fat32/filesystem.hpp3
3 files changed, 97 insertions, 21 deletions
diff --git a/kernel/kernel/filesystems/fat32/boot_sector.hpp b/kernel/kernel/filesystems/fat32/boot_sector.hpp
index c66e2fc5..10f31672 100644
--- a/kernel/kernel/filesystems/fat32/boot_sector.hpp
+++ b/kernel/kernel/filesystems/fat32/boot_sector.hpp
@@ -1,18 +1,54 @@
#ifndef TEACHOS_KERNEL_FILESYSTEMS_FAT32_BOOT_SECTOR_HPP
#define TEACHOS_KERNEL_FILESYSTEMS_FAT32_BOOT_SECTOR_HPP
-#include <kstd/bitfield_enum.hpp>
-
+#include <array>
#include <cstdint>
namespace kernel::filesystems::fat32
{
- //! The boot-sector in the fat32 filesystem.
- struct boot_sector // todo gnu::packed?
+ //! The boot sector in the fat32 filesystem.
+ //!
+ //! The layout follows the "Microsoft Extensible Firmware Initiative FAT32 File System Specification" (fatgen103).
+ //! The sector consists of the BIOS Parameter Block (BPB) common to all FAT variants, followed by the FAT32 specific
+ //! extension.
+ // cspell:ignore fatgen
+ struct [[gnu::packed]] boot_sector
{
+ // Common BIOS Parameter Block
+ std::array<std::uint8_t, 3> jump_boot;
+ std::array<char, 8> oem_name;
std::uint16_t bytes_per_sector;
+ std::uint8_t sectors_per_cluster;
+ std::uint16_t reserved_sector_count;
+ std::uint8_t number_of_fats;
+ std::uint16_t root_entry_count;
+ std::uint16_t total_sectors_16;
+ std::uint8_t media;
+ std::uint16_t fat_size_16;
+ std::uint16_t sectors_per_track;
+ std::uint16_t number_of_heads;
+ std::uint32_t hidden_sectors;
+ std::uint32_t total_sectors_32;
+
+ // FAT32 Extended BIOS Parameter Block
+ std::uint32_t fat_size_32;
+ std::uint16_t extended_flags;
+ std::uint16_t filesystem_version;
+ std::uint32_t root_cluster;
+ std::uint16_t filesystem_info_sector;
+ std::uint16_t backup_boot_sector;
+ std::array<std::uint8_t, 12> reserved;
+ std::uint8_t drive_number;
+ std::uint8_t reserved1;
+ std::uint8_t extended_boot_signature;
+ std::uint32_t volume_id;
+ std::array<char, 11> volume_label; // NOLINT
+ std::array<char, 8> filesystem_type;
+ std::array<std::uint8_t, 420> boot_code; // NOLINT
std::uint16_t boot_signature;
};
+
+ static_assert(sizeof(boot_sector) == 512, "The fat32 boot sector must be exactly 512 bytes in size.");
} // namespace kernel::filesystems::fat32
-#endif \ No newline at end of file
+#endif
diff --git a/kernel/kernel/filesystems/fat32/filesystem.cpp b/kernel/kernel/filesystems/fat32/filesystem.cpp
index 4899f0bd..30f1b286 100644
--- a/kernel/kernel/filesystems/fat32/filesystem.cpp
+++ b/kernel/kernel/filesystems/fat32/filesystem.cpp
@@ -15,6 +15,8 @@
#include <kstd/system_error.hpp>
#include <kstd/units.hpp>
+#include <array>
+#include <cstddef>
#include <cstdint>
#include <optional>
#include <string_view>
@@ -23,15 +25,63 @@ namespace kernel::filesystems::fat32
{
static_assert(sizeof(kernel::vfs::filesystem) == sizeof(fat32::filesystem));
+ //! Hidden implementation details.
+ namespace
+ {
+ //! Convert a fixed size, space padded character array of the boot sector into a string view.
+ //!
+ //! @param array The array to convert.
+ //! @return A view of the array contents.
+ template<std::size_t Size>
+ [[nodiscard]] constexpr auto to_string_view(std::array<char, Size> const & array) -> std::string_view
+ {
+ return {array.data(), array.size()};
+ }
+
+ //! Print all fields of a boot sector.
+ //!
+ //! @param boot_sector The boot sector to print.
+ auto print_boot_sector(boot_sector const & boot_sector) -> void
+ {
+ kstd::println("[OS:FAT32] jump_boot: {:#04X} {:#04X} {:#04X}", boot_sector.jump_boot[0], boot_sector.jump_boot[1],
+ boot_sector.jump_boot[2]);
+ kstd::println("[OS:FAT32] oem_name: '{}'", to_string_view(boot_sector.oem_name));
+ kstd::println("[OS:FAT32] bytes_per_sector: {}", boot_sector.bytes_per_sector);
+ kstd::println("[OS:FAT32] sectors_per_cluster: {}", boot_sector.sectors_per_cluster);
+ kstd::println("[OS:FAT32] reserved_sector_count: {}", boot_sector.reserved_sector_count);
+ kstd::println("[OS:FAT32] number_of_fats: {}", boot_sector.number_of_fats);
+ kstd::println("[OS:FAT32] root_entry_count: {}", boot_sector.root_entry_count);
+ kstd::println("[OS:FAT32] total_sectors_16: {}", boot_sector.total_sectors_16);
+ kstd::println("[OS:FAT32] media: {:#04X}", boot_sector.media);
+ kstd::println("[OS:FAT32] fat_size_16: {}", boot_sector.fat_size_16);
+ kstd::println("[OS:FAT32] sectors_per_track: {}", boot_sector.sectors_per_track);
+ kstd::println("[OS:FAT32] number_of_heads: {}", boot_sector.number_of_heads);
+ kstd::println("[OS:FAT32] hidden_sectors: {}", boot_sector.hidden_sectors);
+ kstd::println("[OS:FAT32] total_sectors_32: {}", boot_sector.total_sectors_32);
+ kstd::println("[OS:FAT32] fat_size_32: {}", boot_sector.fat_size_32);
+ kstd::println("[OS:FAT32] extended_flags: {:#06X}", boot_sector.extended_flags);
+ kstd::println("[OS:FAT32] filesystem_version: {:#06X}", boot_sector.filesystem_version);
+ kstd::println("[OS:FAT32] root_cluster: {}", boot_sector.root_cluster);
+ kstd::println("[OS:FAT32] filesystem_info_sector: {}", boot_sector.filesystem_info_sector);
+ kstd::println("[OS:FAT32] backup_boot_sector: {}", boot_sector.backup_boot_sector);
+ kstd::println("[OS:FAT32] drive_number: {:#04X}", boot_sector.drive_number);
+ kstd::println("[OS:FAT32] extended_boot_signature: {:#04X}", boot_sector.extended_boot_signature);
+ kstd::println("[OS:FAT32] volume_id: {:#010X}", boot_sector.volume_id);
+ kstd::println("[OS:FAT32] volume_label: '{}'", to_string_view(boot_sector.volume_label));
+ kstd::println("[OS:FAT32] filesystem_type: '{}'", to_string_view(boot_sector.filesystem_type));
+ kstd::println("[OS:FAT32] boot_signature: {:#06X}", boot_sector.boot_signature);
+ }
+ } // namespace
+
auto filesystem::probe(inode_ptr const & inode) const -> kstd::result<std::uint32_t>
{
auto boot_sector = fat32::boot_sector{};
- auto const boot_signature_bytes = kstd::raw_bytes(boot_sector.boot_signature);
- auto boot_signature_result = inode->read(boot_signature_bytes, kstd::bytes{constants::boot_signature_offset});
+ auto const bytes = kstd::raw_bytes(boot_sector);
+ auto const read_result = inode->read(bytes, constants::boot_sector_offset);
- if (!boot_signature_result)
+ if (!read_result)
{
- return kstd::failure(boot_signature_result.error());
+ return kstd::failure(read_result.error());
}
if (boot_sector.boot_signature != constants::boot_signature)
@@ -39,16 +89,7 @@ namespace kernel::filesystems::fat32
return kstd::failure(errc::invalid_boot_signature);
}
- auto const bytes_per_sector_bytes = kstd::raw_bytes(boot_sector.bytes_per_sector);
- auto bytes_per_sector_result = inode->read(bytes_per_sector_bytes, kstd::bytes{constants::bytes_per_sector_offset});
-
- if (!bytes_per_sector_result)
- {
- return kstd::failure(bytes_per_sector_result.error());
- }
-
- kstd::println("[OS:FAT32] bytes_per_sector: {}", boot_sector.bytes_per_sector);
- kstd::println("[OS:FAT32] boot_signature: {:#06X}", boot_sector.boot_signature);
+ print_boot_sector(boot_sector);
return 0;
}
diff --git a/kernel/kernel/filesystems/fat32/filesystem.hpp b/kernel/kernel/filesystems/fat32/filesystem.hpp
index 9c516ca9..54c8035c 100644
--- a/kernel/kernel/filesystems/fat32/filesystem.hpp
+++ b/kernel/kernel/filesystems/fat32/filesystem.hpp
@@ -22,8 +22,7 @@ namespace kernel::filesystems::fat32
//! Constants related to the fat32 filesystem.
namespace constants
{
- constexpr kstd::bytes inline bytes_per_sector_offset = kstd::bytes{0x0B};
- constexpr kstd::bytes inline boot_signature_offset = kstd::bytes{0x1FE};
+ constexpr kstd::bytes inline boot_sector_offset = kstd::bytes{0};
constexpr std::uint16_t inline boot_signature = 0xAA55;
} // namespace constants