diff options
author | Galen Sagarin <gps5307@rit.edu> | 2025-04-24 14:27:53 -0400 |
---|---|---|
committer | Galen Sagarin <gps5307@rit.edu> | 2025-04-24 14:27:53 -0400 |
commit | 923d9d3f62aa8dd75171298fac7bd40e15ed335e (patch) | |
tree | 0d1da389b1f4a2f7d0ce18ed98049a155da79b81 | |
parent | update paging code (diff) | |
download | comus-923d9d3f62aa8dd75171298fac7bd40e15ed335e.tar.gz comus-923d9d3f62aa8dd75171298fac7bd40e15ed335e.tar.bz2 comus-923d9d3f62aa8dd75171298fac7bd40e15ed335e.zip |
Started writing fat.c
-rw-r--r-- | kernel/fs/fat.c | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/kernel/fs/fat.c b/kernel/fs/fat.c new file mode 100644 index 0000000..9168301 --- /dev/null +++ b/kernel/fs/fat.c @@ -0,0 +1,247 @@ +#include <stdint.h> +#include <stdbool.h> + +#include <string.h> + +// various errors with fat32 +enum +{ + FAT_ERR_NONE = 0, + FAT_ERR_NOFAT = -1, + FAT_ERR_BROKEN = -2, + FAT_ERR_IO = -3, + FAT_ERR_PARAM = -4, + FAT_ERR_PATH = -5, + // also can tell if files don't exist. + FAT_ERR_EOF = -6, + // + FAT_ERR_DENIED = -7, + FAT_ERR_FULL = -8, +}; + +enum +{ + FAT_ATTR_NONE = 0x00, + FAT_ATTR_RO = 0x01, + FAT_ATTR_HIDDEN = 0x02, + FAT_ATTR_SYS = 0x04, + FAT_ATTR_LABEL = 0x08, + FAT_ATTR_DIR = 0x10, + FAT_ATTR_ARCHIVE = 0x20, + FAT_ATTR_LFN = 0x0f, +}; + +enum +{ + FAT_WRITE = 0x01, // Open file for writing + FAT_READ = 0x02, // Open file for reading + FAT_APPEND = 0x04, // Set file offset to the end of the file + FAT_TRUNC = 0x08, // Truncate the file after opening + FAT_CREATE = 0x10, // Create the file if it do not exist + + FAT_ACCESSED = 0x20, // do not use (internal) + FAT_MODIFIED = 0x40, // do not use (internal) + FAT_FILE_DIRTY = 0x80, // do not use (internal) +}; + +enum +{ + FAT_SEEK_START, + FAT_SEEK_CURR, + FAT_SEEK_END, +}; + + +typedef struct +{ + bool (*read)(uint8_t* buf, uint32_t sect); + bool (*write)(const uint8_t* buf, uint32_t sect); +} DiskOps; + +// time checker if I can be bothered to implement it. +typedef struct +{ + uint8_t hour; + uint8_t min; + uint8_t sec; + uint8_t day; + uint8_t month; + uint16_t year; +} Timestamp; + +typedef struct Fat +{ + struct Fat* next; + DiskOps ops; + uint32_t clust_msk; + uint32_t clust_cnt; + uint32_t info_sect; + uint32_t fat_sect[2]; + uint32_t data_sect; + uint32_t root_clust; + uint32_t last_used; + uint32_t free_cnt; + uint32_t sect; + uint8_t buf[512]; + uint8_t flags; + uint8_t clust_shift; + uint8_t name_len; + char name[32]; +} Fat; + +typedef struct +{ + //Timestamp created; + //Timestamp modified; + uint32_t size; + uint8_t attr; + char name[255]; + uint8_t name_len; +} DirInfo; + +typedef struct +{ + Fat* fat; + uint32_t sclust; + uint32_t clust; + uint32_t sect; + uint16_t idx; +} Dir; + +// file structure +typedef struct +{ + Fat* fat; + uint32_t dir_sect; + uint32_t sclust; + uint32_t clust; + uint32_t sect; + uint32_t size; + uint32_t offset; + uint16_t dir_idx; + uint8_t attr; + uint8_t flags; + uint8_t buf[512]; +} File; + + +typedef struct __attribute__((packed)) +{ + uint8_t jump[3]; + char name[8]; + uint16_t bytes_per_sect; + uint8_t sect_per_clust; + uint16_t res_sect_cnt; + uint8_t fat_cnt; + uint16_t root_ent_cnt; + uint16_t sect_cnt_16; + uint8_t media; + uint16_t sect_per_fat_16; + uint16_t sect_per_track; + uint16_t head_cnt; + uint32_t hidden_sect_cnt; + uint32_t sect_cnt_32; + uint32_t sect_per_fat_32; + uint16_t ext_flags; + uint8_t minor; + uint8_t major; + uint32_t root_cluster; + uint16_t info_sect; + uint16_t copy_bpb_sector; + uint8_t reserved_0[12]; + uint8_t drive_num; + uint8_t reserved_1; + uint8_t boot_sig; + uint32_t volume_id; + char volume_label[11]; + char fs_type[8]; + uint8_t reserved_2[420]; + uint8_t sign[2]; +} Bpb; + +typedef struct __attribute__((packed)) +{ + uint32_t head_sig; + uint8_t reserved_0[480]; + uint32_t struct_sig; + uint32_t free_cnt; + uint32_t next_free; + uint8_t reserved_1[12]; + uint32_t tail_sig; +} FsInfo; + +typedef struct __attribute__((packed)) +{ + uint8_t name[11]; + uint8_t attr; + uint8_t reserved; + uint8_t tenth; + uint16_t cre_time; + uint16_t cre_date; + uint16_t acc_date; + uint16_t clust_hi; + uint16_t mod_time; + uint16_t mod_date; + uint16_t clust_lo; + uint32_t size; +} Sfn; + +typedef union __attribute__((packed)) +{ + uint8_t raw[32]; + struct + { + uint8_t seq; + uint8_t name0[10]; + uint8_t attr; + uint8_t type; + uint8_t crc; + uint8_t name1[12]; + uint16_t clust; + uint8_t name2[4]; + }; +} Lfn; + +typedef struct +{ + uint32_t sect; + uint16_t idx; +} Loc; + + +static Fat* g_fat_list; +static uint8_t g_buf[512]; +static uint16_t g_len; +static uint8_t g_crc; + +static int sync_buf(Fat* fat) { + // checks whether the flag is active. If not, we + if(fat->flags & 0x01) { + // if write fails for whatever reason + if(!fat->ops.write(fat->buf, fat->sect)) { + return FAT_ERR_IO; + } + } +} +static int update_buf(Fat* fat, uint32_t sect) { + // if fat->sect already is sect, we are good + if(fat->sect != sect) { + + } +} +// attempts to sync the filesystem to fat32. Returns error code assuming one happens. +static int sync_fs(Fat* fat) +{ + int error = sync_buf(fat); + if (error) { + return error; + } + FsInfo* info = (FsInfo*)fat->buf; + fat->flags |= + +} + +static int get_fat(Fat* fat, uint32_t clust, uint32_t* out_val, uint8_t* out_flags) { + +} + |