Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

fat.h

Go to the documentation of this file.
00001 /*! \file fat.h \brief FAT16/32 file system driver. */
00002 //*****************************************************************************
00003 //
00004 // File Name    : 'fat.h'
00005 // Title        : FAT16/32 file system driver
00006 // Author       : Pascal Stang
00007 // Date         : 11/07/2000
00008 // Revised      : 12/12/2000
00009 // Version      : 0.3
00010 // Target MCU   : ATmega103 (should work for Atmel AVR Series)
00011 // Editor Tabs  : 4
00012 //
00013 // NOTE: This code is currently below version 1.0, and therefore is considered
00014 // to be lacking in some functionality or documentation, or may not be fully
00015 // tested.  Nonetheless, you can expect most functions to work.
00016 //
00017 // This code is distributed under the GNU Public License
00018 //      which can be found at http://www.gnu.org/licenses/gpl.txt
00019 //
00020 //*****************************************************************************
00021 
00022 #ifndef FAT_H
00023 #define FAT_H
00024 
00025 #include "global.h"
00026 #include "device.h"
00027 
00028 
00029 // Some useful cluster numbers
00030 #define MSDOSFSROOT     0               // cluster 0 means the root dir
00031 #define CLUST_FREE      0               // cluster 0 also means a free cluster
00032 #define MSDOSFSFREE     CLUST_FREE
00033 #define CLUST_FIRST     2               // first legal cluster number
00034 #define CLUST_RSRVD     0xfffffff6      // reserved cluster range
00035 #define CLUST_BAD       0xfffffff7      // a cluster with a defect
00036 #define CLUST_EOFS      0xfffffff8      // start of eof cluster range
00037 #define CLUST_EOFE      0xffffffff      // end of eof cluster range
00038 
00039 #define FAT12_MASK      0x00000fff      // mask for FAT12 bit cluster numbers
00040 #define FAT16_MASK      0x0000ffff      // mask for FAT16 bit cluster numbers
00041 #define FAT32_MASK      0x0fffffff      // mask for FAT32 cluster numbers
00042 
00043 // Format of a boot sector.  This is the first sector on a DOS floppy disk
00044 // or the first sector of a partition on a hard disk.  But, it is not the
00045 // first sector of a partitioned hard disk.
00046 struct bootsector33 {
00047     BYTE    bsJump[3];                  // jump inst E9xxxx or EBxx90
00048     CHAR    bsOemName[8];               // OEM name and version
00049     CHAR    bsBPB[19];                  // BIOS parameter block
00050     CHAR    bsDriveNumber;              // drive number (0x80)
00051     CHAR    bsBootCode[479];            // pad so struct is 512b
00052     BYTE    bsBootSectSig0;             // boot sector signature byte 0x55
00053     BYTE    bsBootSectSig1;             // boot sector signature byte 0xAA
00054 #define BOOTSIG0        0x55
00055 #define BOOTSIG1        0xaa
00056 } GNUC_PACKED;
00057 
00058 struct extboot {
00059     CHAR    exDriveNumber;              // drive number (0x80)
00060     CHAR    exReserved1;                // reserved
00061     CHAR    exBootSignature;            // ext. boot signature (0x29)
00062 #define EXBOOTSIG       0x29
00063     CHAR    exVolumeID[4];              // volume ID number
00064     CHAR    exVolumeLabel[11];          // volume label
00065     CHAR    exFileSysType[8];           // fs type (FAT12 or FAT16)
00066 } GNUC_PACKED;
00067 
00068 struct bootsector50 {
00069     BYTE    bsJump[3];                  // jump inst E9xxxx or EBxx90
00070     CHAR    bsOemName[8];               // OEM name and version
00071     CHAR    bsBPB[25];                  // BIOS parameter block
00072     CHAR    bsExt[26];                  // Bootsector Extension
00073     CHAR    bsBootCode[448];            // pad so structure is 512b
00074     BYTE    bsBootSectSig0;             // boot sector signature byte 0x55 
00075     BYTE    bsBootSectSig1;             // boot sector signature byte 0xAA
00076 #define BOOTSIG0        0x55
00077 #define BOOTSIG1        0xaa
00078 } GNUC_PACKED;
00079 
00080 struct bootsector710 {
00081     BYTE    bsJump[3];                  // jump inst E9xxxx or EBxx90
00082     CHAR    bsOEMName[8];               // OEM name and version
00083     CHAR    bsBPB[53];                  // BIOS parameter block
00084     CHAR    bsExt[26];                  // Bootsector Extension
00085     CHAR    bsBootCode[418];            // pad so structure is 512b
00086     BYTE    bsBootSectSig2;             // 2 & 3 are only defined for FAT32?
00087     BYTE    bsBootSectSig3;
00088     BYTE    bsBootSectSig0;             // boot sector signature byte 0x55
00089     BYTE    bsBootSectSig1;             // boot sector signature byte 0xAA
00090 #define BOOTSIG0        0x55
00091 #define BOOTSIG1        0xaa
00092 #define BOOTSIG2        0
00093 #define BOOTSIG3        0
00094 } GNUC_PACKED;
00095 
00096 
00097 /***************************************************************/
00098 /***************************************************************/
00099 
00100 // BIOS Parameter Block (BPB) for DOS 3.3
00101 struct bpb33 {
00102         WORD    bpbBytesPerSec; // bytes per sector
00103         BYTE    bpbSecPerClust; // sectors per cluster
00104         WORD    bpbResSectors;  // number of reserved sectors
00105         BYTE    bpbFATs;        // number of FATs
00106         WORD    bpbRootDirEnts; // number of root directory entries
00107         WORD    bpbSectors;     // total number of sectors
00108         BYTE    bpbMedia;       // media descriptor
00109         WORD    bpbFATsecs;     // number of sectors per FAT
00110         WORD    bpbSecPerTrack; // sectors per track
00111         WORD    bpbHeads;       // number of heads
00112         WORD    bpbHiddenSecs;  // number of hidden sectors
00113 } GNUC_PACKED;
00114 
00115 // BPB for DOS 5.0
00116 // The difference is bpbHiddenSecs is a short for DOS 3.3,
00117 // and bpbHugeSectors is not present in the DOS 3.3 bpb.
00118 struct bpb50 {
00119         WORD    bpbBytesPerSec; // bytes per sector
00120         BYTE    bpbSecPerClust; // sectors per cluster
00121         WORD    bpbResSectors;  // number of reserved sectors
00122         BYTE    bpbFATs;        // number of FATs
00123         WORD    bpbRootDirEnts; // number of root directory entries
00124         WORD    bpbSectors;     // total number of sectors
00125         BYTE    bpbMedia;       // media descriptor
00126         WORD    bpbFATsecs;     // number of sectors per FAT
00127         WORD    bpbSecPerTrack; // sectors per track
00128         WORD    bpbHeads;       // number of heads
00129         DWORD   bpbHiddenSecs;  // # of hidden sectors
00130 // 3.3 compat ends here
00131         DWORD   bpbHugeSectors; // # of sectors if bpbSectors == 0
00132 } GNUC_PACKED;
00133 
00134 // BPB for DOS 7.10 (FAT32)
00135 // This one has a few extensions to bpb50.
00136 struct bpb710 {
00137         WORD    bpbBytesPerSec; // bytes per sector
00138         BYTE    bpbSecPerClust; // sectors per cluster
00139         WORD    bpbResSectors;  // number of reserved sectors
00140         BYTE    bpbFATs;        // number of FATs
00141         WORD    bpbRootDirEnts; // number of root directory entries
00142         WORD    bpbSectors;     // total number of sectors
00143         BYTE    bpbMedia;       // media descriptor
00144         WORD    bpbFATsecs;     // number of sectors per FAT
00145         WORD    bpbSecPerTrack; // sectors per track
00146         WORD    bpbHeads;       // number of heads
00147         DWORD   bpbHiddenSecs;  // # of hidden sectors
00148 // 3.3 compat ends here
00149         DWORD   bpbHugeSectors; // # of sectors if bpbSectors == 0
00150 // 5.0 compat ends here
00151         DWORD     bpbBigFATsecs;// like bpbFATsecs for FAT32
00152         WORD      bpbExtFlags;  // extended flags:
00153 #define FATNUM    0xf           // mask for numbering active FAT
00154 #define FATMIRROR 0x80          // FAT is mirrored (like it always was)
00155         WORD      bpbFSVers;    // filesystem version
00156 #define FSVERS    0             // currently only 0 is understood
00157         DWORD     bpbRootClust; // start cluster for root directory
00158         WORD      bpbFSInfo;    // filesystem info structure sector
00159         WORD      bpbBackup;    // backup boot sector
00160         // There is a 12 byte filler here, but we ignore it
00161 } GNUC_PACKED;
00162 
00163 // ***************************************************************
00164 // * byte versions of the above structs                          *
00165 // ***************************************************************
00166 
00167 // BIOS Parameter Block (BPB) for DOS 3.3
00168 struct bpb33_byte {
00169         CHAR bpbBytesPerSec[2];     // bytes per sector
00170         CHAR bpbSecPerClust;        // sectors per cluster
00171         CHAR bpbResSectors[2];      // number of reserved sectors
00172         CHAR bpbFATs;               // number of FATs
00173         CHAR bpbRootDirEnts[2];     // number of root directory entries
00174         CHAR bpbSectors[2];         // total number of sectors
00175         CHAR bpbMedia;              // media descriptor
00176         CHAR bpbFATsecs[2];         // number of sectors per FAT
00177         CHAR bpbSecPerTrack[2];     // sectors per track
00178         CHAR bpbHeads[2];           // number of heads
00179         CHAR bpbHiddenSecs[2];      // number of hidden sectors
00180 } GNUC_PACKED;
00181 
00182 // BPB for DOS 5.0
00183 // The difference is bpbHiddenSecs is a short for DOS 3.3,
00184 // and bpbHugeSectors is not in the 3.3 bpb.
00185 struct bpb50_byte {
00186         CHAR bpbBytesPerSec[2];     // bytes per sector
00187         CHAR bpbSecPerClust;        // sectors per cluster
00188         CHAR bpbResSectors[2];      // number of reserved sectors
00189         CHAR bpbFATs;               // number of FATs
00190         CHAR bpbRootDirEnts[2];     // number of root directory entries
00191         CHAR bpbSectors[2];         // total number of sectors
00192         CHAR bpbMedia;              // media descriptor
00193         CHAR bpbFATsecs[2];         // number of sectors per FAT
00194         CHAR bpbSecPerTrack[2];     // sectors per track
00195         CHAR bpbHeads[2];           // number of heads
00196         CHAR bpbHiddenSecs[4];      // number of hidden sectors
00197         CHAR bpbHugeSectors[4];     // # of sectors if bpbSectors == 0
00198 } GNUC_PACKED;
00199 
00200 // BPB for DOS 7.10 (FAT32).
00201 // This one has a few extensions to bpb50.
00202 struct bpb710_byte {
00203         BYTE bpbBytesPerSec[2];     // bytes per sector
00204         BYTE bpbSecPerClust;        // sectors per cluster
00205         BYTE bpbResSectors[2];      // number of reserved sectors
00206         BYTE bpbFATs;               // number of FATs
00207         BYTE bpbRootDirEnts[2];     // number of root directory entries
00208         BYTE bpbSectors[2];         // total number of sectors
00209         BYTE bpbMedia;              // media descriptor
00210         BYTE bpbFATsecs[2];         // number of sectors per FAT
00211         BYTE bpbSecPerTrack[2];     // sectors per track
00212         BYTE bpbHeads[2];           // number of heads
00213         BYTE bpbHiddenSecs[4];      // # of hidden sectors
00214         BYTE bpbHugeSectors[4];     // # of sectors if bpbSectors == 0
00215         BYTE bpbBigFATsecs[4];      // like bpbFATsecs for FAT32
00216         BYTE bpbExtFlags[2];        // extended flags:
00217         BYTE bpbFSVers[2];          // filesystem version
00218         BYTE bpbRootClust[4];       // start cluster for root directory
00219         BYTE bpbFSInfo[2];          // filesystem info structure sector
00220         BYTE bpbBackup[2];          // backup boot sector
00221         // There is a 12 byte filler here, but we ignore it
00222 } GNUC_PACKED;
00223 
00224 // FAT32 FSInfo block.
00225 struct fsinfo {
00226         BYTE fsisig1[4];
00227         BYTE fsifill1[480];
00228         BYTE fsisig2[4];
00229         BYTE fsinfree[4];
00230         BYTE fsinxtfree[4];
00231         BYTE fsifill2[12];
00232         BYTE fsisig3[4];
00233         BYTE fsifill3[508];
00234         BYTE fsisig4[4];
00235 } GNUC_PACKED;
00236 
00237 
00238 /***************************************************************/
00239 /***************************************************************/
00240 
00241 // Structure of a dos directory entry.
00242 struct direntry {
00243         BYTE        deName[8];      // filename, blank filled
00244 #define SLOT_EMPTY      0x00            // slot has never been used
00245 #define SLOT_E5         0x05            // the real value is 0xE5
00246 #define SLOT_DELETED    0xE5            // file in this slot deleted
00247         BYTE        deExtension[3]; // extension, blank filled
00248         BYTE        deAttributes;   // file attributes
00249 #define ATTR_NORMAL     0x00            // normal file
00250 #define ATTR_READONLY   0x01            // file is readonly
00251 #define ATTR_HIDDEN     0x02            // file is hidden
00252 #define ATTR_SYSTEM     0x04            // file is a system file
00253 #define ATTR_VOLUME     0x08            // entry is a volume label
00254 #define ATTR_LONG_FILENAME  0x0F        // this is a long filename entry                
00255 #define ATTR_DIRECTORY  0x10            // entry is a directory name
00256 #define ATTR_ARCHIVE    0x20            // file is new or modified
00257         BYTE        deLowerCase;    // NT VFAT lower case flags  (set to zero)
00258 #define LCASE_BASE      0x08            // filename base in lower case
00259 #define LCASE_EXT       0x10            // filename extension in lower case
00260         BYTE        deCHundredth;   // hundredth of seconds in CTime
00261         BYTE        deCTime[2];     // create time
00262         BYTE        deCDate[2];     // create date
00263         BYTE        deADate[2];     // access date
00264         WORD        deHighClust;    // high bytes of cluster number
00265         BYTE        deMTime[2];     // last update time
00266         BYTE        deMDate[2];     // last update date
00267         WORD        deStartCluster; // starting cluster of file
00268         DWORD       deFileSize;     // size of file in bytes
00269 } GNUC_PACKED;
00270 
00271 // number of directory entries in one sector
00272 #define DIRENTRIES_PER_SECTOR   0x10
00273 
00274 // Structure of a Win95 long name directory entry
00275 struct winentry {
00276         BYTE        weCnt;          // 
00277 #define WIN_LAST        0x40
00278 #define WIN_CNT         0x3f
00279         BYTE        wePart1[10];
00280         BYTE        weAttributes;
00281 #define ATTR_WIN95      0x0f
00282         BYTE        weReserved1;
00283         BYTE        weChksum;
00284         BYTE        wePart2[12];
00285         WORD        weReserved2;
00286         BYTE        wePart3[4];
00287 } GNUC_PACKED;
00288 
00289 #define WIN_ENTRY_CHARS 13      // Number of chars per winentry
00290 
00291 // Maximum filename length in Win95
00292 // Note: Must be < sizeof(dirent.d_name)
00293 #define WIN_MAXLEN      255
00294 
00295 // This is the format of the contents of the deTime field in the direntry
00296 // structure.
00297 // We don't use bitfields because we don't know how compilers for
00298 // arbitrary machines will lay them out.
00299 #define DT_2SECONDS_MASK        0x1F    // seconds divided by 2
00300 #define DT_2SECONDS_SHIFT       0
00301 #define DT_MINUTES_MASK         0x7E0   // minutes
00302 #define DT_MINUTES_SHIFT        5
00303 #define DT_HOURS_MASK           0xF800  // hours
00304 #define DT_HOURS_SHIFT          11
00305 
00306 // This is the format of the contents of the deDate field in the direntry
00307 // structure.
00308 #define DD_DAY_MASK             0x1F    // day of month
00309 #define DD_DAY_SHIFT            0
00310 #define DD_MONTH_MASK           0x1E0   // month
00311 #define DD_MONTH_SHIFT          5
00312 #define DD_YEAR_MASK            0xFE00  // year - 1980
00313 #define DD_YEAR_SHIFT           9
00314 
00315 // Stuctures
00316 struct FileInfo_s
00317 {
00318     unsigned long StartCluster;         //< file starting cluster for last file accessed
00319     unsigned long Size;                 //< file size for last file accessed
00320     unsigned char Attr;                 //< file attr for last file accessed
00321     unsigned short CreateTime;          //< file creation time for last file accessed
00322     unsigned short CreateDate;          //< file creation date for last file accessed
00323 } GNUC_PACKED;
00324 
00325 typedef struct FileInfo_s FileInfo_t;
00326 
00327 // Prototypes
00328 unsigned char fatInit(DevDisk_t* disk);
00329 unsigned int fatClusterSize(void);
00330 unsigned char fatGetDirEntry(unsigned short entry);
00331 unsigned char fatChangeDirectory(unsigned short entry);
00332 void fatPrintDirEntry(void);
00333 void fatDumpDirSlot(unsigned short entry);
00334 FileInfo_t* fatGetFileInfo(void);
00335 unsigned long fatGetFilesize(void);
00336 char* fatGetFilename(void);
00337 char* fatGetDirname(void);
00338 void fatLoadCluster(unsigned long cluster, unsigned char *buffer);
00339 unsigned long fatClusterToSector(unsigned long cluster);
00340 
00341 unsigned long fatNextCluster(unsigned long cluster);
00342 unsigned long fatNextFreeCluster(void);
00343 unsigned long fatClusterValue(unsigned long cluster);
00344 int fatWriteClusterValue(unsigned long cluster, unsigned value);
00345 unsigned char* fatGetFatSector(unsigned long fatsector);
00346 
00347 int fatCreateFile(unsigned char* filename, FileInfo_t* fileInfo);
00348 int fatFormat(unsigned long volsize);
00349 
00350 #endif

Generated on Mon Nov 6 23:36:59 2006 for Procyon ARMlib by  doxygen 1.4.2