#ifndef FAT_FS_H #define FAT_FS_H #include #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)) u; 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 */ int root_size; /* The root dir size in sectores */ sector_t data; /* The data region */ 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 nt_reserved; 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)); 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 fat_bpb *fat) { int sector_size = 1 << SECTOR_SHIFT; return (fat->bxRootDirEnts + sector_size / sizeof(struct fat_dir_entry) - 1) >> (SECTOR_SHIFT - 5); } #endif /* fat_fs.h */