161 lines
4.5 KiB
C
161 lines
4.5 KiB
C
#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 */
|
|
uint32_t root_cluster; /* Cluster number for (FAT32) root dir */
|
|
int root_size; /* The root dir size in sectors */
|
|
|
|
int clust_shift; /* based on sectors */
|
|
int clust_byte_shift; /* based on bytes */
|
|
int clust_mask; /* sectors per cluster mask */
|
|
int clust_size;
|
|
|
|
int fat_type;
|
|
|
|
uint32_t uuid; /* fs UUID */
|
|
} __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 {
|
|
uint32_t start_cluster; /* Starting cluster address */
|
|
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 */
|