1 #ifndef FAT_FS_H
2 #define FAT_FS_H
3 
4 #include <stdint.h>
5 
6 #define FAT_DIR_ENTRY_SIZE 32
7 #define DIRENT_SHIFT 5
8 
9 #define FAT_ATTR_READ_ONLY 0x01
10 #define FAT_ATTR_HIDDEN	   0x02
11 #define FAT_ATTR_SYSTEM	   0x04
12 #define FAT_ATTR_VOLUME_ID 0x08
13 #define FAT_ATTR_DIRECTORY 0x10
14 #define FAT_ATTR_ARCHIVE   0x20
15 
16 #define FAT_MAXFILE	   256
17 
18 #define FAT_ATTR_LONG_NAME (FAT_ATTR_READ_ONLY             \
19                             | FAT_ATTR_HIDDEN              \
20                             | FAT_ATTR_SYSTEM              \
21                             | FAT_ATTR_VOLUME_ID)
22 
23 #define FAT_ATTR_VALID	   (FAT_ATTR_READ_ONLY             \
24                             | FAT_ATTR_HIDDEN              \
25                             | FAT_ATTR_SYSTEM              \
26                             | FAT_ATTR_DIRECTORY           \
27                             | FAT_ATTR_ARCHIVE)
28 
29 enum fat_type{ FAT12, FAT16, FAT32 };
30 
31 /*
32  * The fat file system structures
33  */
34 
35 struct fat_bpb {
36         uint8_t  jmp_boot[3];
37         uint8_t  oem_name[8];
38         uint16_t sector_size;
39         uint8_t  bxSecPerClust;
40         uint16_t bxResSectors;
41         uint8_t  bxFATs;
42         uint16_t bxRootDirEnts;
43         uint16_t bxSectors;
44         uint8_t  media;
45         uint16_t bxFATsecs;
46         uint16_t sectors_per_track;
47         uint16_t num_heads;
48         uint32_t num_hidden_sectors;
49         uint32_t bsHugeSectors;
50 
51         union {
52                 struct {
53                         uint8_t  num_ph_drive;
54                         uint8_t  reserved;
55                         uint8_t  boot_sig;
56                         uint32_t num_serial;
57                         uint8_t  label[11];
58                         uint8_t  fstype[8];
59                 } __attribute__ ((packed)) fat12_16;
60 
61                 struct {
62                         uint32_t bxFATsecs_32;
63                         uint16_t extended_flags;
64                         uint16_t fs_version;
65                         uint32_t root_cluster;
66                         uint16_t fs_info;
67                         uint16_t backup_boot_sector;
68                         uint8_t  reserved[12];
69                         uint8_t  num_ph_drive;
70                         uint8_t  reserved1;
71                         uint8_t  boot_sig;
72                         uint32_t num_serial;
73                         uint8_t  label[11];
74                         uint8_t  fstype[8];
75                 } __attribute__ ((packed)) fat32;
76 
77         } __attribute__ ((packed));
78 
79         uint8_t pad[422];  /* padding to 512 Bytes (one sector) */
80 
81 } __attribute__ ((packed));
82 
83 /*
84  * The fat file system info in memory
85  */
86 struct fat_sb_info {
87 	sector_t fat;             /* The FAT region */
88 	sector_t root;            /* The root dir region */
89 	sector_t data;            /* The data region */
90 
91 	uint32_t clusters;	  /* Total number of clusters */
92 	uint32_t root_cluster;	  /* Cluster number for (FAT32) root dir */
93 	int      root_size;       /* The root dir size in sectors */
94 
95 	int      clust_shift;      /* based on sectors */
96 	int      clust_byte_shift; /* based on bytes   */
97 	int      clust_mask;	   /* sectors per cluster mask */
98 	int      clust_size;
99 
100 	int      fat_type;
101 
102 	uint32_t uuid;             /* fs UUID */
103 } __attribute__ ((packed));
104 
105 struct fat_dir_entry {
106         char     name[11];
107         uint8_t  attr;
108         uint8_t  lcase;
109         uint8_t  c_time_tenth;
110         uint16_t c_time;
111         uint16_t c_date;
112         uint16_t a_date;
113         uint16_t first_cluster_high;
114         uint16_t w_time;
115         uint16_t w_date;
116         uint16_t first_cluster_low;
117         uint32_t file_size;
118 } __attribute__ ((packed));
119 
120 #define LCASE_BASE 8       /* basename is lower case */
121 #define LCASE_EXT  16      /* extension is lower case */
122 
123 struct fat_long_name_entry {
124         uint8_t  id;
125         uint16_t name1[5];
126         uint8_t  attr;
127         uint8_t  reserved;
128         uint8_t  checksum;
129         uint16_t name2[6];
130         uint16_t first_cluster;
131         uint16_t name3[2];
132 } __attribute__ ((packed));
133 
FAT_SB(struct fs_info * fs)134 static inline struct fat_sb_info *FAT_SB(struct fs_info *fs)
135 {
136         return fs->fs_info;
137 }
138 
139 /*
140  * Count the root dir size in sectors
141  */
root_dir_size(struct fs_info * fs,struct fat_bpb * fat)142 static inline int root_dir_size(struct fs_info *fs, struct fat_bpb *fat)
143 {
144     return (fat->bxRootDirEnts + SECTOR_SIZE(fs)/32 - 1)
145 	>> (SECTOR_SHIFT(fs) - 5);
146 }
147 
148 /*
149  * FAT private inode information
150  */
151 struct fat_pvt_inode {
152     uint32_t start_cluster;	/* Starting cluster address */
153     sector_t start;		/* Starting sector */
154     sector_t offset;		/* Current sector offset */
155     sector_t here;		/* Sector corresponding to offset */
156 };
157 
158 #define PVT(i) ((struct fat_pvt_inode *)((i)->pvt))
159 
160 #endif /* fat_fs.h */
161