Main Page   Data Structures   File List   Data Fields   Globals  

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 
00027 
00028 // Some useful cluster numbers
00029 #define MSDOSFSROOT     0               /* cluster 0 means the root dir */
00030 #define CLUST_FREE      0               /* cluster 0 also means a free cluster */
00031 #define MSDOSFSFREE     CLUST_FREE
00032 #define CLUST_FIRST     2               /* first legal cluster number */
00033 #define CLUST_RSRVD     0xfffffff6      /* reserved cluster range */
00034 #define CLUST_BAD       0xfffffff7      /* a cluster with a defect */
00035 #define CLUST_EOFS      0xfffffff8      /* start of eof cluster range */
00036 #define CLUST_EOFE      0xffffffff      /* end of eof cluster range */
00037 
00038 #define FAT12_MASK      0x00000fff      /* mask for 12 bit cluster numbers */
00039 #define FAT16_MASK      0x0000ffff      /* mask for 16 bit cluster numbers */
00040 #define FAT32_MASK      0x0fffffff      /* mask for FAT32 cluster numbers */
00041 
00042 
00043 // Partition Type used in the partition record
00044 #define PART_TYPE_UNKNOWN       0x00
00045 #define PART_TYPE_FAT12         0x01
00046 #define PART_TYPE_XENIX         0x02
00047 #define PART_TYPE_DOSFAT16      0x04
00048 #define PART_TYPE_EXTDOS        0x05
00049 #define PART_TYPE_FAT16         0x06
00050 #define PART_TYPE_NTFS          0x07
00051 #define PART_TYPE_FAT32         0x0B
00052 #define PART_TYPE_FAT32LBA      0x0C
00053 #define PART_TYPE_FAT16LBA      0x0E
00054 #define PART_TYPE_EXTDOSLBA     0x0F
00055 #define PART_TYPE_ONTRACK       0x33
00056 #define PART_TYPE_NOVELL        0x40
00057 #define PART_TYPE_PCIX          0x4B
00058 #define PART_TYPE_PHOENIXSAVE   0xA0
00059 #define PART_TYPE_CPM           0xDB
00060 #define PART_TYPE_DBFS          0xE0
00061 #define PART_TYPE_BBT           0xFF
00062 
00063 struct partrecord // length 16 bytes
00064 {           
00065     BYTE    prIsActive;                 // 0x80 indicates active partition
00066     BYTE    prStartHead;                // starting head for partition
00067     WORD    prStartCylSect;             // starting cylinder and sector
00068     BYTE    prPartType;                 // partition type (see above)
00069     BYTE  prEndHead;                    // ending head for this partition
00070     WORD    prEndCylSect;               // ending cylinder and sector
00071     DWORD   prStartLBA;                 // first LBA sector for this partition
00072     DWORD   prSize;                     // size of this partition (bytes or sectors ?)
00073 };
00074 
00075         
00076 struct partsector
00077 {
00078     CHAR        psPartCode[512-64-2];   // pad so struct is 512b
00079     BYTE        psPart[64];             // four partition records (64 bytes)
00080     BYTE        psBootSectSig0;         // two signature bytes (2 bytes)
00081     BYTE        psBootSectSig1;
00082 #define BOOTSIG0        0x55
00083 #define BOOTSIG1        0xaa
00084 };
00085 
00086 
00087 
00088 // Format of a boot sector.  This is the first sector on a DOS floppy disk
00089 // or the first sector of a partition on a hard disk.  But, it is not the
00090 // first sector of a partitioned hard disk.
00091 struct bootsector33 {
00092     BYTE        bsJump[3];              // jump inst E9xxxx or EBxx90
00093     CHAR        bsOemName[8];           // OEM name and version
00094     CHAR        bsBPB[19];              // BIOS parameter block
00095     CHAR        bsDriveNumber;          // drive number (0x80)
00096     CHAR        bsBootCode[479];        // pad so struct is 512b
00097     BYTE        bsBootSectSig0;
00098     BYTE        bsBootSectSig1;
00099 #define BOOTSIG0        0x55
00100 #define BOOTSIG1        0xaa
00101 };
00102 
00103 struct extboot {
00104     CHAR        exDriveNumber;          // drive number (0x80)
00105     CHAR        exReserved1;            // reserved
00106     CHAR        exBootSignature;        // ext. boot signature (0x29)
00107 #define EXBOOTSIG       0x29
00108     CHAR        exVolumeID[4];          // volume ID number
00109     CHAR        exVolumeLabel[11];      // volume label
00110     CHAR        exFileSysType[8];       // fs type (FAT12 or FAT16)
00111 };
00112 
00113 struct bootsector50 {
00114     BYTE        bsJump[3];              // jump inst E9xxxx or EBxx90
00115     CHAR        bsOemName[8];           // OEM name and version
00116     CHAR        bsBPB[25];              // BIOS parameter block
00117     CHAR        bsExt[26];              // Bootsector Extension
00118     CHAR        bsBootCode[448];        // pad so structure is 512b
00119     BYTE        bsBootSectSig0;
00120     BYTE        bsBootSectSig1;
00121 #define BOOTSIG0        0x55
00122 #define BOOTSIG1        0xaa
00123 };
00124 
00125 struct bootsector710 {
00126     BYTE        bsJump[3];              // jump inst E9xxxx or EBxx90
00127     CHAR        bsOEMName[8];           // OEM name and version
00128     CHAR        bsBPB[53];              // BIOS parameter block
00129     CHAR        bsExt[26];              // Bootsector Extension
00130     CHAR        bsBootCode[418];        // pad so structure is 512b
00131     BYTE        bsBootSectSig2;         // 2 & 3 are only defined for FAT32?
00132     BYTE        bsBootSectSig3;
00133     BYTE        bsBootSectSig0;
00134     BYTE        bsBootSectSig1;
00135 #define BOOTSIG0        0x55
00136 #define BOOTSIG1        0xaa
00137 #define BOOTSIG2        0
00138 #define BOOTSIG3        0
00139 };
00140 
00141 
00142 /***************************************************************/
00143 /***************************************************************/
00144 
00145 
00146 // BIOS Parameter Block (BPB) for DOS 3.3
00147 struct bpb33 {
00148         WORD    bpbBytesPerSec; // bytes per sector
00149         BYTE    bpbSecPerClust; // sectors per cluster
00150         WORD    bpbResSectors;  // number of reserved sectors
00151         BYTE    bpbFATs;        // number of FATs
00152         WORD    bpbRootDirEnts; // number of root directory entries
00153         WORD    bpbSectors;     // total number of sectors
00154         BYTE    bpbMedia;       // media descriptor
00155         WORD    bpbFATsecs;     // number of sectors per FAT
00156         WORD    bpbSecPerTrack; // sectors per track
00157         WORD    bpbHeads;       // number of heads
00158         WORD    bpbHiddenSecs;  // number of hidden sectors
00159 };
00160 
00161 // BPB for DOS 5.0
00162 // The difference is bpbHiddenSecs is a short for DOS 3.3,
00163 // and bpbHugeSectors is not in the 3.3 bpb.
00164 struct bpb50 {
00165         WORD        bpbBytesPerSec; // bytes per sector
00166         BYTE        bpbSecPerClust; // sectors per cluster
00167         WORD        bpbResSectors;  // number of reserved sectors
00168         BYTE        bpbFATs;        // number of FATs
00169         WORD        bpbRootDirEnts; // number of root directory entries
00170         WORD        bpbSectors;     // total number of sectors
00171         BYTE        bpbMedia;       // media descriptor
00172         WORD        bpbFATsecs;     // number of sectors per FAT
00173         WORD        bpbSecPerTrack; // sectors per track
00174         WORD        bpbHeads;       // number of heads
00175         DWORD       bpbHiddenSecs;  // # of hidden sectors
00176 // 3.3 compat ends here
00177         DWORD       bpbHugeSectors; // # of sectors if bpbSectors == 0
00178 };
00179 
00180 // BPB for DOS 7.10 (FAT32)
00181 // This one has a few extensions to bpb50.
00182 struct bpb710 {
00183         WORD        bpbBytesPerSec; // bytes per sector
00184         BYTE      bpbSecPerClust;   // sectors per cluster
00185         WORD      bpbResSectors;        // number of reserved sectors
00186         BYTE      bpbFATs;              // number of FATs
00187         WORD      bpbRootDirEnts;   // number of root directory entries
00188         WORD      bpbSectors;           // total number of sectors
00189           BYTE      bpbMedia;           // media descriptor
00190         WORD      bpbFATsecs;           // number of sectors per FAT
00191         WORD      bpbSecPerTrack;   // sectors per track
00192         WORD      bpbHeads;         // number of heads
00193         DWORD     bpbHiddenSecs;        // # of hidden sectors
00194 // 3.3 compat ends here
00195         DWORD       bpbHugeSectors; // # of sectors if bpbSectors == 0
00196 // 5.0 compat ends here
00197         DWORD     bpbBigFATsecs;        // like bpbFATsecs for FAT32
00198         WORD      bpbExtFlags;      // extended flags:
00199 #define FATNUM    0xf                   // mask for numbering active FAT
00200 #define FATMIRROR 0x80                  // FAT is mirrored (like it always was)
00201         WORD      bpbFSVers;            // filesystem version
00202 #define FSVERS    0                     // currently only 0 is understood
00203         DWORD     bpbRootClust;     // start cluster for root directory
00204         WORD      bpbFSInfo;            // filesystem info structure sector
00205         WORD      bpbBackup;            // backup boot sector
00206         // There is a 12 byte filler here, but we ignore it
00207 };
00208 
00209 
00210 
00211 
00212 // ***************************************************************
00213 // * byte versions of the above structs                          *
00214 // ***************************************************************
00215 
00216 
00217 // BIOS Parameter Block (BPB) for DOS 3.3
00218 struct byte_bpb33 {
00219         CHAR bpbBytesPerSec[2];     // bytes per sector
00220         CHAR bpbSecPerClust;        // sectors per cluster
00221         CHAR bpbResSectors[2];      // number of reserved sectors
00222         CHAR bpbFATs;               // number of FATs
00223         CHAR bpbRootDirEnts[2];     // number of root directory entries
00224         CHAR bpbSectors[2];         // total number of sectors
00225         CHAR bpbMedia;              // media descriptor
00226         CHAR bpbFATsecs[2];         // number of sectors per FAT
00227         CHAR bpbSecPerTrack[2];     // sectors per track
00228         CHAR bpbHeads[2];           // number of heads
00229         CHAR bpbHiddenSecs[2];      // number of hidden sectors
00230 };
00231 
00232 // BPB for DOS 5.0
00233 // The difference is bpbHiddenSecs is a short for DOS 3.3,
00234 // and bpbHugeSectors is not in the 3.3 bpb.
00235 struct byte_bpb50 {
00236         CHAR bpbBytesPerSec[2];     // bytes per sector
00237         CHAR bpbSecPerClust;        // sectors per cluster
00238         CHAR bpbResSectors[2];      // number of reserved sectors
00239         CHAR bpbFATs;               // number of FATs
00240         CHAR bpbRootDirEnts[2];     // number of root directory entries
00241         CHAR bpbSectors[2];         // total number of sectors
00242         CHAR bpbMedia;              // media descriptor
00243         CHAR bpbFATsecs[2];         // number of sectors per FAT
00244         CHAR bpbSecPerTrack[2];     // sectors per track
00245         CHAR bpbHeads[2];           // number of heads
00246         CHAR bpbHiddenSecs[4];      // number of hidden sectors
00247         CHAR bpbHugeSectors[4];     // # of sectors if bpbSectors == 0
00248 };
00249 
00250 // BPB for DOS 7.10 (FAT32).
00251 // This one has a few extensions to bpb50.
00252 struct byte_bpb710 {
00253         BYTE bpbBytesPerSec[2];     // bytes per sector
00254         BYTE bpbSecPerClust;        // sectors per cluster
00255         BYTE bpbResSectors[2];      // number of reserved sectors
00256         BYTE bpbFATs;               // number of FATs
00257         BYTE bpbRootDirEnts[2];     // number of root directory entries
00258         BYTE bpbSectors[2];         // total number of sectors
00259         BYTE bpbMedia;              // media descriptor
00260         BYTE bpbFATsecs[2];         // number of sectors per FAT
00261         BYTE bpbSecPerTrack[2];     // sectors per track
00262         BYTE bpbHeads[2];           // number of heads
00263         BYTE bpbHiddenSecs[4];      // # of hidden sectors
00264         BYTE bpbHugeSectors[4];     // # of sectors if bpbSectors == 0
00265         BYTE bpbBigFATsecs[4];      // like bpbFATsecs for FAT32
00266         BYTE bpbExtFlags[2];        // extended flags:
00267         BYTE bpbFSVers[2];          // filesystem version
00268         BYTE bpbRootClust[4];       // start cluster for root directory
00269         BYTE bpbFSInfo[2];          // filesystem info structure sector
00270         BYTE bpbBackup[2];          // backup boot sector
00271         // There is a 12 byte filler here, but we ignore it
00272 };
00273 
00274 // FAT32 FSInfo block.
00275 struct fsinfo {
00276         BYTE fsisig1[4];
00277         BYTE fsifill1[480];
00278         BYTE fsisig2[4];
00279         BYTE fsinfree[4];
00280         BYTE fsinxtfree[4];
00281         BYTE fsifill2[12];
00282         BYTE fsisig3[4];
00283         BYTE fsifill3[508];
00284         BYTE fsisig4[4];
00285 };
00286 
00287 
00288 
00289 /***************************************************************/
00290 /***************************************************************/
00291 
00292 
00293 // Structure of a dos directory entry.
00294 struct direntry {
00295         BYTE        deName[8];      /* filename, blank filled */
00296 #define SLOT_EMPTY      0x00            /* slot has never been used */
00297 #define SLOT_E5         0x05            /* the real value is 0xe5 */
00298 #define SLOT_DELETED    0xe5            /* file in this slot deleted */
00299         BYTE        deExtension[3]; /* extension, blank filled */
00300         BYTE        deAttributes;   /* file attributes */
00301 #define ATTR_NORMAL     0x00            /* normal file */
00302 #define ATTR_READONLY   0x01            /* file is readonly */
00303 #define ATTR_HIDDEN     0x02            /* file is hidden */
00304 #define ATTR_SYSTEM     0x04            /* file is a system file */
00305 #define ATTR_VOLUME     0x08            /* entry is a volume label */
00306 #define ATTR_LONG_FILENAME  0x0f        /* this is a long filename entry */             
00307 #define ATTR_DIRECTORY  0x10            /* entry is a directory name */
00308 #define ATTR_ARCHIVE    0x20            /* file is new or modified */
00309         BYTE        deLowerCase;    /* NT VFAT lower case flags */
00310 #define LCASE_BASE      0x08            /* filename base in lower case */
00311 #define LCASE_EXT       0x10            /* filename extension in lower case */
00312         BYTE        deCHundredth;   /* hundredth of seconds in CTime */
00313         BYTE        deCTime[2];     /* create time */
00314         BYTE        deCDate[2];     /* create date */
00315         BYTE        deADate[2];     /* access date */
00316         WORD        deHighClust;    /* high bytes of cluster number */
00317         BYTE        deMTime[2];     /* last update time */
00318         BYTE        deMDate[2];     /* last update date */
00319         WORD        deStartCluster; /* starting cluster of file */
00320         DWORD       deFileSize;     /* size of file in bytes */
00321 };
00322 
00323 // number of directory entries in one sector
00324 #define DIRENTRIES_PER_SECTOR   0x10
00325 
00326 // Structure of a Win95 long name directory entry
00327 struct winentry {
00328         BYTE        weCnt;
00329 #define WIN_LAST        0x40
00330 #define WIN_CNT         0x3f
00331         BYTE        wePart1[10];
00332         BYTE        weAttributes;
00333 #define ATTR_WIN95      0x0f
00334         BYTE        weReserved1;
00335         BYTE        weChksum;
00336         BYTE        wePart2[12];
00337         WORD        weReserved2;
00338         BYTE        wePart3[4];
00339 };
00340 
00341 #define WIN_CHARS       13      /* Number of chars per winentry */
00342 
00343 // Maximum filename length in Win95
00344 // Note: Must be < sizeof(dirent.d_name)
00345 #define WIN_MAXLEN      255
00346 
00347 // This is the format of the contents of the deTime field in the direntry
00348 // structure.
00349 // We don't use bitfields because we don't know how compilers for
00350 // arbitrary machines will lay them out.
00351 #define DT_2SECONDS_MASK        0x1F    /* seconds divided by 2 */
00352 #define DT_2SECONDS_SHIFT       0
00353 #define DT_MINUTES_MASK         0x7E0   /* minutes */
00354 #define DT_MINUTES_SHIFT        5
00355 #define DT_HOURS_MASK           0xF800  /* hours */
00356 #define DT_HOURS_SHIFT          11
00357 
00358 // This is the format of the contents of the deDate field in the direntry
00359 // structure.
00360 #define DD_DAY_MASK             0x1F    /* day of month */
00361 #define DD_DAY_SHIFT            0
00362 #define DD_MONTH_MASK           0x1E0   /* month */
00363 #define DD_MONTH_SHIFT          5
00364 #define DD_YEAR_MASK            0xFE00  /* year - 1980 */
00365 #define DD_YEAR_SHIFT           9
00366 
00367 // Prototypes
00368 unsigned char fatInit( unsigned char device);
00369 unsigned int fatClusterSize(void);
00370 unsigned long fatGetDirEntry(unsigned int entry, unsigned int count);
00371 unsigned long fatGetFilesize(void);
00372 char* fatGetFilename(void);
00373 char* fatGetDirname(void);
00374 void fatLoadCluster(unsigned long cluster, unsigned char *buffer);
00375 unsigned long fatNextCluster(unsigned long cluster);
00376 
00377 #endif

Generated on Tue Feb 4 20:18:36 2003 for Procyon AVRlib by doxygen1.3-rc2