From bbb91f4afae45b19b056692e64ee18edd8e65f66 Mon Sep 17 00:00:00 2001 From: Gregory Bowne Date: Sun, 18 Jan 2026 18:11:25 -0800 Subject: [PATCH] Create fat16.c Add implementation for fat16 filesystem --- kernel/fat16.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 kernel/fat16.c diff --git a/kernel/fat16.c b/kernel/fat16.c new file mode 100644 index 0000000..9435776 --- /dev/null +++ b/kernel/fat16.c @@ -0,0 +1,107 @@ +#include "fat16.h" +#include "ata.h" // Use ata_read_sector and ata_write_sector +#include "print.h" // For debugging +#include // For string manipulation + +// Global variables +static fat16_boot_sector_t boot_sector; +static uint32_t root_dir_sector = FAT16_ROOT_DIR_SECTOR; + +// Read a sector from the disk using ATA +bool read_sector(uint32_t lba, uint8_t* buffer) { + return ata_read_sector(lba, buffer); +} + +// Write a sector to the disk using ATA +bool write_sector(uint32_t lba, const uint8_t* buffer) { + return ata_write_sector(lba, buffer); +} + +// Parse the boot sector to retrieve basic file system info +bool parse_fat16_boot_sector(void) { + uint8_t sector_buffer[FAT16_SECTOR_SIZE]; + + // Read the boot sector + if (!read_sector(FAT16_BOOT_SECTOR, sector_buffer)) { + print_string("[FAT16] Failed to read boot sector\n"); + return false; + } + + // Cast to boot sector structure + memcpy(&boot_sector, sector_buffer, sizeof(fat16_boot_sector_t)); + + // Check for FAT16 signature + if (boot_sector.oem_name[0] != 'F' || boot_sector.oem_name[1] != 'A' || boot_sector.oem_name[2] != 'T') { + print_string("[FAT16] Invalid FAT16 boot sector signature\n"); + return false; + } + + print_string("[FAT16] FAT16 boot sector parsed successfully\n"); + return true; +} + +// Parse the root directory +bool parse_fat16_root_dir(void) { + uint8_t sector_buffer[FAT16_SECTOR_SIZE]; + + for (int i = 0; i < (boot_sector.max_root_entries / (FAT16_SECTOR_SIZE / sizeof(fat16_dir_entry_t))); i++) { + // Read root directory sector + if (!read_sector(root_dir_sector + i, sector_buffer)) { + print_string("[FAT16] Failed to read root directory sector\n"); + return false; + } + + // Parse the root directory entries + for (int j = 0; j < (FAT16_SECTOR_SIZE / sizeof(fat16_dir_entry_t)); j++) { + fat16_dir_entry_t* entry = (fat16_dir_entry_t*)§or_buffer[j * sizeof(fat16_dir_entry_t)]; + if (entry->name[0] == 0x00) { + // End of directory entries + return true; + } + if (entry->name[0] != 0xE5) { + // Print file name (8.3 format) + char filename[12]; + strncpy(filename, (char*)entry->name, 8); + filename[8] = '.'; + strncpy(&filename[9], (char*)entry->ext, 3); + filename[11] = '\0'; + print_string(filename); + print_string("\n"); + } + } + } + return true; +} + +// Read a specific directory entry from the FAT16 root directory +bool read_fat16_entry(uint16_t entry_index, fat16_dir_entry_t* entry) { + uint8_t sector_buffer[FAT16_SECTOR_SIZE]; + uint32_t sector_num = FAT16_ROOT_DIR_SECTOR + (entry_index / (FAT16_SECTOR_SIZE / sizeof(fat16_dir_entry_t))); + uint16_t entry_offset = entry_index % (FAT16_SECTOR_SIZE / sizeof(fat16_dir_entry_t)); + + // Read the sector + if (!read_sector(sector_num, sector_buffer)) { + print_string("[FAT16] Failed to read root directory sector\n"); + return false; + } + + // Get the entry + memcpy(entry, §or_buffer[entry_offset * sizeof(fat16_dir_entry_t)], sizeof(fat16_dir_entry_t)); + return true; +} + +// Mount the FAT16 filesystem +bool mount_fat16(void) { + // Parse the boot sector + if (!parse_fat16_boot_sector()) { + return false; + } + + // Parse the root directory + if (!parse_fat16_root_dir()) { + return false; + } + + print_string("[FAT16] Filesystem mounted successfully\n"); + return true; +}