⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 编译后直接运行的MP3播放器全部C语言源代码 一个包含FAT文件系统、系统引导 Boot、FLASH Driver等内容的
💻 C
📖 第 1 页 / 共 5 页
字号:
/*************************************************************************** *             __________               __   ___. *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  / *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  < *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \ *                     \/            \/     \/    \/            \/ * $Id: fat.c,v 1.84 2004/01/26 10:14:46 linusnielsen Exp $ * * Copyright (C) 2002 by Linus Nielsen Feltzing * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/#include <stdio.h>#include <string.h>#include <math.h>#include <stdlib.h>#include <ctype.h>#include <stdbool.h>#include "fat.h"#include "ata.h"#include "debug.h"#include "panic.h"#include "system.h"#include "timefuncs.h"#define BYTES2INT16(array,pos) \          (array[pos] | (array[pos+1] << 8 ))#define BYTES2INT32(array,pos) \          (array[pos] | (array[pos+1] << 8 ) | \          (array[pos+2] << 16 ) | (array[pos+3] << 24 ))#define FATTYPE_FAT12       0#define FATTYPE_FAT16       1#define FATTYPE_FAT32       2/* BPB offsets; generic */#define BS_JMPBOOT          0#define BS_OEMNAME          3#define BPB_BYTSPERSEC      11#define BPB_SECPERCLUS      13#define BPB_RSVDSECCNT      14#define BPB_NUMFATS         16#define BPB_ROOTENTCNT      17#define BPB_TOTSEC16        19#define BPB_MEDIA           21#define BPB_FATSZ16         22#define BPB_SECPERTRK       24#define BPB_NUMHEADS        26#define BPB_HIDDSEC         28#define BPB_TOTSEC32        32/* fat12/16 */#define BS_DRVNUM           36#define BS_RESERVED1        37#define BS_BOOTSIG          38#define BS_VOLID            39#define BS_VOLLAB           43#define BS_FILSYSTYPE       54/* fat32 */#define BPB_FATSZ32         36#define BPB_EXTFLAGS        40#define BPB_FSVER           42#define BPB_ROOTCLUS        44#define BPB_FSINFO          48#define BPB_BKBOOTSEC       50#define BS_32_DRVNUM        64#define BS_32_BOOTSIG       66#define BS_32_VOLID         67#define BS_32_VOLLAB        71#define BS_32_FILSYSTYPE    82#define BPB_LAST_WORD       510/* attributes */#define FAT_ATTR_LONG_NAME   (FAT_ATTR_READ_ONLY | FAT_ATTR_HIDDEN | \                              FAT_ATTR_SYSTEM | FAT_ATTR_VOLUME_ID)#define FAT_ATTR_LONG_NAME_MASK (FAT_ATTR_READ_ONLY | FAT_ATTR_HIDDEN | \                                 FAT_ATTR_SYSTEM | FAT_ATTR_VOLUME_ID | \                                 FAT_ATTR_DIRECTORY | FAT_ATTR_ARCHIVE )#define FATDIR_NAME          0#define FATDIR_ATTR          11#define FATDIR_NTRES         12#define FATDIR_CRTTIMETENTH  13#define FATDIR_CRTTIME       14#define FATDIR_CRTDATE       16#define FATDIR_LSTACCDATE    18#define FATDIR_FSTCLUSHI     20#define FATDIR_WRTTIME       22#define FATDIR_WRTDATE       24#define FATDIR_FSTCLUSLO     26#define FATDIR_FILESIZE      28#define FATLONG_ORDER        0#define FATLONG_TYPE         12#define FATLONG_CHKSUM       13#define CLUSTERS_PER_FAT_SECTOR (SECTOR_SIZE / 4)#define DIR_ENTRIES_PER_SECTOR  (SECTOR_SIZE / DIR_ENTRY_SIZE)#define DIR_ENTRY_SIZE       32#define NAME_BYTES_PER_ENTRY 13#define FAT_BAD_MARK         0x0ffffff7#define FAT_EOF_MARK         0x0ffffff8/* filename charset conversion table */static const unsigned char unicode2iso8859_2[] = {    0x00, 0x00, 0xc3, 0xe3, 0xa1, 0xb1, 0xc6, 0xe6,  /* 0x0100 */    0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0xcf, 0xef,  /* 0x0108 */    0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0110 */    0xca, 0xea, 0xcc, 0xec, 0x00, 0x00, 0x00, 0x00,  /* 0x0118 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0120 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0128 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0130 */    0x00, 0xc5, 0xe5, 0x00, 0x00, 0xa5, 0xb5, 0x00,  /* 0x0138 */    0x00, 0xa3, 0xb3, 0xd1, 0xf1, 0x00, 0x00, 0xd2,  /* 0x0140 */    0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0148 */    0xd5, 0xf5, 0x00, 0x00, 0xc0, 0xe0, 0x00, 0x00,  /* 0x0150 */    0xd8, 0xf8, 0xa6, 0xb6, 0x00, 0x00, 0xaa, 0xba,  /* 0x0158 */    0xa9, 0xb9, 0xde, 0xfe, 0xab, 0xbb, 0x00, 0x00,  /* 0x0160 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0xf9,  /* 0x0168 */    0xdb, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0170 */    0x00, 0xac, 0xbc, 0xaf, 0xbf, 0xae, 0xbe, 0x00,  /* 0x0178 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0180 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0188 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0190 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0198 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x01a0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x01a8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x01b0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x01b8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x01c0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x01c8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x01d0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x01d8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x01e0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x01e8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x01f0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x01f8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0200 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0208 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0210 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0218 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0220 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0228 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0230 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0238 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0240 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0248 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0250 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0258 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0260 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0268 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0270 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0278 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0280 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0288 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0290 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x0298 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x02a0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x02a8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x02b0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x02b8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7,  /* 0x02c0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x02c8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x02d0 */    0xa2, 0xff, 0x00, 0xb2, 0x00, 0xbd, 0x00, 0x00,  /* 0x02d8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x02e0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x02e8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 0x02f0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* 0x02f8 */};struct fsinfo {    unsigned int freecount; /* last known free cluster count */    unsigned int nextfree;  /* first cluster to start looking for free                               clusters, or 0xffffffff for no hint */};/* fsinfo offsets */#define FSINFO_FREECOUNT 488#define FSINFO_NEXTFREE  492struct bpb{    char bs_oemname[9];  /* OEM string, ending with \0 */    int bpb_bytspersec;  /* Bytes per sectory, typically 512 */    unsigned int bpb_secperclus;  /* Sectors per cluster */    int bpb_rsvdseccnt;  /* Number of reserved sectors */    int bpb_numfats;     /* Number of FAT structures, typically 2 */    int bpb_rootentcnt;  /* Number of dir entries in the root */    int bpb_totsec16;    /* Number of sectors on the volume (old 16-bit) */    int bpb_media;       /* Media type (typically 0xf0 or 0xf8) */    int bpb_fatsz16;     /* Number of used sectors per FAT structure */    int bpb_secpertrk;   /* Number of sectors per track */    int bpb_numheads;    /* Number of heads */    int bpb_hiddsec;     /* Hidden sectors before the volume */    unsigned int bpb_totsec32;    /* Number of sectors on the volume                                     (new 32-bit) */    int last_word;       /* 0xAA55 */    /**** FAT12/16 specific *****/    int bs_drvnum;       /* Drive number */    int bs_bootsig;      /* Is 0x29 if the following 3 fields are valid */    unsigned int bs_volid; /* Volume ID */    char bs_vollab[12];    /* Volume label, 11 chars plus \0 */    char bs_filsystype[9]; /* File system type, 8 chars plus \0 */    /**** FAT32 specific *****/    int bpb_fatsz32;    int bpb_extflags;    int bpb_fsver;    int bpb_rootclus;    int bpb_fsinfo;    int bpb_bkbootsec;    /* variables for internal use */    unsigned int fatsize;    unsigned int totalsectors;    unsigned int rootdirsector;    unsigned int firstdatasector;    unsigned int startsector;    unsigned int dataclusters;    struct fsinfo fsinfo;};static struct bpb fat_bpb;static int update_fsinfo(void);static int first_sector_of_cluster(int cluster);static int bpb_is_sane(void);static void *cache_fat_sector(int secnum);static int create_dos_name(unsigned char *name, unsigned char *newname);static unsigned int find_free_cluster(unsigned int start);static int transfer( unsigned int start, int count, char* buf, bool write );#define FAT_CACHE_SIZE 0x20#define FAT_CACHE_MASK (FAT_CACHE_SIZE-1)struct fat_cache_entry{    int secnum;    bool inuse;    bool dirty;};static char fat_cache_sectors[FAT_CACHE_SIZE][SECTOR_SIZE];static struct fat_cache_entry fat_cache[FAT_CACHE_SIZE];static int sec2cluster(unsigned int sec){    if ( sec < fat_bpb.firstdatasector )    {        DEBUGF( "sec2cluster() - Bad sector number (%d)\n", sec);        return -1;    }    return ((sec - fat_bpb.firstdatasector) / fat_bpb.bpb_secperclus) + 2;}static int cluster2sec(int cluster){    int max_cluster = fat_bpb.totalsectors -        fat_bpb.firstdatasector / fat_bpb.bpb_secperclus + 1;        if(cluster > max_cluster)    {        DEBUGF( "cluster2sec() - Bad cluster number (%d)\n",                cluster);        return -1;    }    return first_sector_of_cluster(cluster);}static int first_sector_of_cluster(int cluster){    return (cluster - 2) * fat_bpb.bpb_secperclus + fat_bpb.firstdatasector;}int fat_startsector(void){    return fat_bpb.startsector;}void fat_size(unsigned int* size, unsigned int* free){    if (size)        *size = fat_bpb.dataclusters * fat_bpb.bpb_secperclus / 2;    if (free)        *free = fat_bpb.fsinfo.freecount * fat_bpb.bpb_secperclus / 2;}int fat_mount(int startsector){    unsigned char buf[SECTOR_SIZE];    int rc;    int datasec;    unsigned int i;    for(i = 0;i < FAT_CACHE_SIZE;i++)    {        fat_cache[i].secnum = 8; /* We use a "safe" sector just in case */        fat_cache[i].inuse = false;        fat_cache[i].dirty = false;    }    /* Read the sector */    rc = ata_read_sectors(startsector,1,buf);    if(rc)    {        DEBUGF( "fat_mount() - Couldn't read BPB (error code %d)\n", rc);        return rc * 10 - 1;    }    memset(&fat_bpb, 0, sizeof(struct bpb));    fat_bpb.startsector = startsector;        strncpy(fat_bpb.bs_oemname, &buf[BS_OEMNAME], 8);    fat_bpb.bs_oemname[8] = 0;    fat_bpb.bpb_bytspersec = BYTES2INT16(buf,BPB_BYTSPERSEC);    fat_bpb.bpb_secperclus = buf[BPB_SECPERCLUS];    fat_bpb.bpb_rsvdseccnt = BYTES2INT16(buf,BPB_RSVDSECCNT);    fat_bpb.bpb_numfats    = buf[BPB_NUMFATS];    fat_bpb.bpb_totsec16   = BYTES2INT16(buf,BPB_TOTSEC16);    fat_bpb.bpb_media      = buf[BPB_MEDIA];    fat_bpb.bpb_fatsz16    = BYTES2INT16(buf,BPB_FATSZ16);    fat_bpb.bpb_fatsz32    = BYTES2INT32(buf,BPB_FATSZ32);    fat_bpb.bpb_secpertrk  = BYTES2INT16(buf,BPB_SECPERTRK);    fat_bpb.bpb_numheads   = BYTES2INT16(buf,BPB_NUMHEADS);    fat_bpb.bpb_hiddsec    = BYTES2INT32(buf,BPB_HIDDSEC);    fat_bpb.bpb_totsec32   = BYTES2INT32(buf,BPB_TOTSEC32);    fat_bpb.last_word      = BYTES2INT16(buf,BPB_LAST_WORD);    /* calculate a few commonly used values */    if (fat_bpb.bpb_fatsz16 != 0)        fat_bpb.fatsize = fat_bpb.bpb_fatsz16;    else        fat_bpb.fatsize = fat_bpb.bpb_fatsz32;    if (fat_bpb.bpb_totsec16 != 0)        fat_bpb.totalsectors = fat_bpb.bpb_totsec16;    else        fat_bpb.totalsectors = fat_bpb.bpb_totsec32;    fat_bpb.firstdatasector = fat_bpb.bpb_rsvdseccnt +        fat_bpb.bpb_numfats * fat_bpb.fatsize;    /* Determine FAT type */    datasec = fat_bpb.totalsectors - fat_bpb.firstdatasector;    fat_bpb.dataclusters = datasec / fat_bpb.bpb_secperclus;#ifdef TEST_FAT    /*      we are sometimes testing with "illegally small" fat32 images,      so we don't use the proper fat32 test case for test code    */    if ( fat_bpb.bpb_fatsz16 )#else    if ( fat_bpb.dataclusters < 65525 )#endif    {        DEBUGF("This is not FAT32. Go away!\n");        return -2;    }    fat_bpb.bpb_extflags  = BYTES2INT16(buf,BPB_EXTFLAGS);    fat_bpb.bpb_fsver     = BYTES2INT16(buf,BPB_FSVER);    fat_bpb.bpb_rootclus  = BYTES2INT32(buf,BPB_ROOTCLUS);    fat_bpb.bpb_fsinfo    = BYTES2INT16(buf,BPB_FSINFO);    fat_bpb.bpb_bkbootsec = BYTES2INT16(buf,BPB_BKBOOTSEC);    fat_bpb.bs_drvnum     = buf[BS_32_DRVNUM];    fat_bpb.bs_bootsig    = buf[BS_32_BOOTSIG];    if(fat_bpb.bs_bootsig == 0x29)    {        fat_bpb.bs_volid = BYTES2INT32(buf,BS_32_VOLID);        strncpy(fat_bpb.bs_vollab, &buf[BS_32_VOLLAB], 11);        strncpy(fat_bpb.bs_filsystype, &buf[BS_32_FILSYSTYPE], 8);    }    rc = bpb_is_sane();    if (rc < 0)    {        DEBUGF( "fat_mount() - BPB is not sane\n");        return rc * 10 - 3;    }    fat_bpb.rootdirsector = cluster2sec(fat_bpb.bpb_rootclus);    /* Read the fsinfo sector */    rc = ata_read_sectors(startsector + fat_bpb.bpb_fsinfo, 1, buf);    if (rc < 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -