diff options
Diffstat (limited to 'core/fs/fat/fat_fs.h')
-rw-r--r-- | core/fs/fat/fat_fs.h | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/core/fs/fat/fat_fs.h b/core/fs/fat/fat_fs.h new file mode 100644 index 00000000..60b5aee1 --- /dev/null +++ b/core/fs/fat/fat_fs.h @@ -0,0 +1,156 @@ +#ifndef FAT_FS_H +#define FAT_FS_H + +#include <stdint.h> + +#define FAT_DIR_ENTRY_SIZE 32 +#define DIRENT_SHIFT 5 + +#define FAT_ATTR_READ_ONLY 0x01 +#define FAT_ATTR_HIDDEN 0x02 +#define FAT_ATTR_SYSTEM 0x04 +#define FAT_ATTR_VOLUME_ID 0x08 +#define FAT_ATTR_DIRECTORY 0x10 +#define FAT_ATTR_ARCHIVE 0x20 + +#define FAT_MAXFILE 256 + +#define FAT_ATTR_LONG_NAME (FAT_ATTR_READ_ONLY \ + | FAT_ATTR_HIDDEN \ + | FAT_ATTR_SYSTEM \ + | FAT_ATTR_VOLUME_ID) + +#define FAT_ATTR_VALID (FAT_ATTR_READ_ONLY \ + | FAT_ATTR_HIDDEN \ + | FAT_ATTR_SYSTEM \ + | FAT_ATTR_DIRECTORY \ + | FAT_ATTR_ARCHIVE) + +enum fat_type{ FAT12, FAT16, FAT32 }; + +/* + * The fat file system structures + */ + +struct fat_bpb { + uint8_t jmp_boot[3]; + uint8_t oem_name[8]; + uint16_t sector_size; + uint8_t bxSecPerClust; + uint16_t bxResSectors; + uint8_t bxFATs; + uint16_t bxRootDirEnts; + uint16_t bxSectors; + uint8_t media; + uint16_t bxFATsecs; + uint16_t sectors_per_track; + uint16_t num_heads; + uint32_t num_hidden_sectors; + uint32_t bsHugeSectors; + + union { + struct { + uint8_t num_ph_drive; + uint8_t reserved; + uint8_t boot_sig; + uint32_t num_serial; + uint8_t label[11]; + uint8_t fstype[8]; + } __attribute__ ((packed)) fat12_16; + + struct { + uint32_t bxFATsecs_32; + uint16_t extended_flags; + uint16_t fs_version; + uint32_t root_cluster; + uint16_t fs_info; + uint16_t backup_boot_sector; + uint8_t reserved[12]; + uint8_t num_ph_drive; + uint8_t reserved1; + uint8_t boot_sig; + uint32_t num_serial; + uint8_t label[11]; + uint8_t fstype[8]; + } __attribute__ ((packed)) fat32; + + } __attribute__ ((packed)); + + uint8_t pad[422]; /* padding to 512 Bytes (one sector) */ + +} __attribute__ ((packed)); + +/* + * The fat file system info in memory + */ +struct fat_sb_info { + sector_t fat; /* The FAT region */ + sector_t root; /* The root dir region */ + sector_t data; /* The data region */ + + uint32_t clusters; /* Total number of clusters */ + int root_size; /* The root dir size in sectores */ + + int clust_shift; /* based on sectors */ + int clust_byte_shift; /* based on bytes */ + int clust_mask; + int clust_size; + + int fat_type; +} __attribute__ ((packed)); + +struct fat_dir_entry { + char name[11]; + uint8_t attr; + uint8_t lcase; + uint8_t c_time_tenth; + uint16_t c_time; + uint16_t c_date; + uint16_t a_date; + uint16_t first_cluster_high; + uint16_t w_time; + uint16_t w_date; + uint16_t first_cluster_low; + uint32_t file_size; +} __attribute__ ((packed)); + +#define LCASE_BASE 8 /* basename is lower case */ +#define LCASE_EXT 16 /* extension is lower case */ + +struct fat_long_name_entry { + uint8_t id; + uint16_t name1[5]; + uint8_t attr; + uint8_t reserved; + uint8_t checksum; + uint16_t name2[6]; + uint16_t first_cluster; + uint16_t name3[2]; +} __attribute__ ((packed)); + +static inline struct fat_sb_info *FAT_SB(struct fs_info *fs) +{ + return fs->fs_info; +} + +/* + * Count the root dir size in sectors + */ +static inline int root_dir_size(struct fs_info *fs, struct fat_bpb *fat) +{ + return (fat->bxRootDirEnts + SECTOR_SIZE(fs)/32 - 1) + >> (SECTOR_SHIFT(fs) - 5); +} + +/* + * FAT private inode information + */ +struct fat_pvt_inode { + sector_t start; /* Starting sector */ + sector_t offset; /* Current sector offset */ + sector_t here; /* Sector corresponding to offset */ +}; + +#define PVT(i) ((struct fat_pvt_inode *)((i)->pvt)) + +#endif /* fat_fs.h */ |