📄 fat_ioct.c
字号:
/*
**********************************************************************
* Micrium, Inc.
* 949 Crestview Circle
* Weston, FL 33327-1848
*
* uC/FS
*
* (c) Copyright 2001 - 2003, Micrium, Inc.
* All rights reserved.
*
***********************************************************************
----------------------------------------------------------------------
File : fat_ioctc.c
Purpose : FAT File System Layer IOCTL
----------------------------------------------------------------------
Known problems or limitations with current version
----------------------------------------------------------------------
None.
---------------------------END-OF-HEADER------------------------------
*/
/*********************************************************************
*
* #include Section
*
**********************************************************************
*/
#include "fs_conf.h"
#include "fs_port.h"
#include "fs_dev.h"
#include "fs_api.h"
#include "fs_fsl.h"
#include "fs_int.h"
#include "fs_os.h"
#include "fs_lbl.h"
#include "fs_fat.h"
#include "fs_clib.h"
/*********************************************************************
*
* #define constants
*
**********************************************************************
*/
#define FS_KNOWNMEDIA_NUM sizeof(_FS_wd_format_media_table) / sizeof(_FS_wd_format_media_type)
#ifndef FS_FAT_NOFORMAT
#define FS_FAT_NOFORMAT 0
#endif
#ifndef FS_FAT_DISKINFO
#define FS_FAT_DISKINFO 1
#endif
#ifndef FS_SUPPORT_SEC_ACCESS
#define FS_SUPPORT_SEC_ACCESS 1
#endif
/*********************************************************************
*
* Local data types
*
**********************************************************************
*/
#if (FS_FAT_NOFORMAT==0)
typedef struct {
FS_i32 media_id;
FS_u32 totsec32;
FS_u32 hiddsec;
FS_u16 totsec16;
FS_u16 rootentcnt;
FS_u16 fatsz16;
FS_u16 secpertrk;
FS_u16 numheads;
char secperclus;
char media;
char fsystype;
} _FS_wd_format_media_type;
typedef struct {
FS_u32 SecNum;
FS_u32 Num;
} _FS_FAT_ROOTENTCNT ;
typedef struct {
FS_u32 SecNum;
FS_u16 Num;
} _FS_FAT_SECPERCLUST;
/*********************************************************************
*
* Local Variables
*
**********************************************************************
*/
/* media_id totsec32 hidsec totsec16 rootent fatsz16 secpertrk numheads secperclus media fstype */
static const _FS_wd_format_media_type _FS_wd_format_media_table[] = {
{ FS_MEDIA_RAM_16KB, 0x00000000UL, 0x00000000UL, 0x0020, 0x0040, 0x0001, 0x0004, 0x0004, 0x01, (char) 0xf8, 0 },
{ FS_MEDIA_RAM_64KB, 0x00000000UL, 0x00000000UL, 0x0080, 0x0040, 0x0001, 0x0004, 0x0004, 0x01, (char) 0xf8, 0 },
{ FS_MEDIA_RAM_128KB, 0x00000000UL, 0x00000000UL, 0x0100, 0x0080, 0x0001, 0x0004, 0x0004, 0x01, (char) 0xf8, 0 },
{ FS_MEDIA_RAM_256KB, 0x00000000UL, 0x00000000UL, 0x0200, 0x0080, 0x0002, 0x0004, 0x0004, 0x01, (char) 0xf8, 0 },
{ FS_MEDIA_RAM_512KB, 0x00000000UL, 0x00000000UL, 0x0400, 0x00e0, 0x0003, 0x0004, 0x0004, 0x01, (char) 0xf8, 0 },
{ FS_MEDIA_FD_144MB, 0x00000000UL, 0x00000000UL, 0x0b40, 0x00e0, 0x0009, 0x0012, 0x0002, 0x01, (char) 0xf0, 0 },
{ FS_MEDIA_SMC_1MB, 0x00000000UL, 0x0000000DUL, 0x07c3, 0x0100, 0x0001, 0x0004, 0x0004, 0x08, (char) 0xf8, 0 },
{ FS_MEDIA_SMC_2MB, 0x00000000UL, 0x0000000bUL, 0x0f95, 0x0100, 0x0002, 0x0008, 0x0004, 0x08, (char) 0xf8, 0 },
{ FS_MEDIA_SMC_4MB, 0x00000000UL, 0x0000001bUL, 0x1f25, 0x0100, 0x0002, 0x0008, 0x0004, 0x10, (char) 0xf8, 0 },
{ FS_MEDIA_SMC_8MB, 0x00000000UL, 0x00000019UL, 0x3e67, 0x0100, 0x0003, 0x0010, 0x0004, 0x10, (char) 0xf8, 0 },
{ FS_MEDIA_SMC_16MB, 0x00000000UL, 0x00000029UL, 0x7cd7, 0x0100, 0x0003, 0x0010, 0x0004, 0x20, (char) 0xf8, 0 },
{ FS_MEDIA_SMC_32MB, 0x00000000UL, 0x00000023UL, 0xf9dd, 0x0100, 0x0006, 0x0010, 0x0008, 0x20, (char) 0xf8, 0 },
{ FS_MEDIA_SMC_64MB, 0x0001f3c9UL, 0x00000037UL, 0x0000, 0x0100, 0x000c, 0x0020, 0x0008, 0x20, (char) 0xf8, 0 },
{ FS_MEDIA_SMC_128MB, 0x0003e7d1UL, 0x0000002fUL, 0x0000, 0x0100, 0x0020, 0x0020, 0x0010, 0x20, (char) 0xf8, 1 },
{ FS_MEDIA_MMC_32MB, 0x00000000UL, 0x00000020UL, 0xf460, 0x0200, 0x003d, 0x0020, 0x0004, 0x04, (char) 0xf8, 1 },
{ FS_MEDIA_MMC_64MB, 0x0001e8e0UL, 0x00000020UL, 0x0000, 0x0200, 0x007a, 0x0020, 0x0008, 0x04, (char) 0xf8, 1 },
{ FS_MEDIA_MMC_128MB, 0x0003d2e0UL, 0x00000020UL, 0x0000, 0x0200, 0x00f5, 0x0020, 0x0008, 0x04, (char) 0xf8, 1 },
{ FS_MEDIA_SD_16MB, 0x00000000UL, 0x00000039UL, 0x7187, 0x0200, 0x0003, 0x0020, 0x0002, 0x20, (char) 0xf8, 0 },
{ FS_MEDIA_SD_64MB, 0x0001dbd9UL, 0x00000027UL, 0x0000, 0x0200, 0x000c, 0x0020, 0x0008, 0x20, (char) 0xf8, 0 },
{ FS_MEDIA_SD_128MB, 0x0003c09fUL, 0x00000061UL, 0x0000, 0x0200, 0x001f, 0x0020, 0x0008, 0x20, (char) 0xf8, 1 },
{ FS_MEDIA_CF_32MB, 0x00000000UL, 0x00000020UL, 0xf760, 0x0200, 0x007c, 0x0020, 0x0004, 0x02, (char) 0xf8, 1 },
{ FS_MEDIA_CF_16KB, 0x00000000UL, 0x00000000UL, 0x0020, 0x0040, 0x0001, 0x0004, 0x0004, 0x01, (char) 0xf8, 1 },
{ FS_MEDIA_CF_64MB, 0x0001e860UL, 0x00000020UL, 0x0000, 0x0200, 0x007b, 0x0020, 0x0004, 0x04, (char) 0xf8, 1 },
{ FS_MEDIA_CF_1GB, 0x001fffadUL, 0x00000000UL, 0x0000, 0x0200, 0x0020, 0x0020, 0x0004, 0x20, (char) 0xf8, 1 },
{ FS_MEDIA_NAND_64MB, 0x00020000UL, 0x00000000UL, 0x0000, 0x0200, 0x0081, 0x0100, 0x0008, 0x04, (char) 0xf8, 1 }
};
/* table for getting number of root entries for a given media size */
static const _FS_FAT_ROOTENTCNT _FS_auto_rootcnt[] = {
{ 0x100, 0x40 },
{ 0x200, 0x80 },
{ 0x0b40UL, 0xe0 },
{ 0x0001f3c9UL, 0x100 },
{ 0xffffffffUL, 0x200 }
};
/* table for calculating cluster size */
static const _FS_FAT_SECPERCLUST _FS_auto_secperclust[] = {
/* medias up to 512MB are formatted with FAT16 */
{ 0x0b40UL, 0x0001 },
{ 32680UL, 0x0002 },
{ 262144UL, 0x0004 },
{ 524288UL, 0x0008 },
{ 1048576UL, 0x0010 },
/* medias bigger than 512MB are formatted with FAT32 */
{ 16777216UL, 0x0008 },
{ 33554432UL, 0x0010 },
{ 67108864UL, 0x0020 },
{ 0xffffffffUL, 0x0040 }
};
#endif /* FS_FAT_NOFORMAT==0 */
/*********************************************************************
*
* Local functions
*
**********************************************************************
*/
#if (FS_FAT_NOFORMAT==0)
/*********************************************************************
*
* _FS_fat_format
*
Description:
FS internal function. Format a media using specified parameters.
Currently this function needs many parameters. The function will be
improved.
Parameters:
pDriver - Pointer to a device driver function table.
Unit - Unit number.
SecPerClus - Number of sector per allocation unit.
RootEntCnt - For FAT12/FAT16, this is the number of 32 byte root
directory entries. 0 for FAT32.
TotSec16 - 16-bit total count of sectors. If zero, TotSec32 must
be none-zero.
TotSec32 - 32-bit total count of sectors. If zero, TotSec16 must
be none-zero.
Media - Media byte.
FATSz16 - 16-bit count of sectors occupied by one FAT. 0 for
FAT32 volumes, which use FATSz32.
FATSz32 - 32-bit count of sectors occupied by one FAT. This is
valid for FAT32 medias only.
SecPerTrk - Sectors per track.
NumHeads - Number of heads.
HiddSec - Count of hidden sectors preceding the partition.
FSysType - ==0 => FAT12
==1 => FAT16
==2 => FAT32
Return value:
>=0 - Media has been formatted.
<0 - An error has occured.
*/
static int _FS_fat_format(const FS__device_type *pDriver,FS_u32 Unit, char SecPerClus,
FS_u16 RootEntCnt, FS_u16 TotSec16, FS_u32 TotSec32, char Media,
FS_u16 FATSz16, FS_u32 FATSz32, FS_u16 SecPerTrk,FS_u16 NumHeads,
FS_u32 HiddSec, char FSysType) {
FS__FAT_BPB bpb;
FS_u32 sector;
FS_u32 value;
char *buffer;
int i;
int j;
int n;
buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
if (!buffer) {
return -1;
}
FS__CLIB_memset(buffer, 0x00, (FS_size_t)FS_FAT_SEC_SIZE);
/* Setup BPB */
FS__CLIB_memset(&bpb, 0x00, (FS_size_t)sizeof(bpb));
bpb.BytesPerSec = 0x0200; /* _512_,1024,2048,4096 */
bpb.SecPerClus = SecPerClus; /* sec in allocation unit */
if (FSysType != 2) {
bpb.RsvdSecCnt = 0x0001; /* 1 for FAT12 & FAT16 */
}
#if (FS_FAT_NOFAT32==0)
else {
bpb.RsvdSecCnt = 0x0020; /* 32 for FAT32 */
}
#else
/* FAT32 disabled */
else {
FS__fat_free(buffer);
return -1;
}
#endif /* FS_FAT_NOFAT32==0 */
bpb.NumFATs = 0x02; /* 2 */
bpb.RootEntCnt = RootEntCnt; /* number of root dir entries */
bpb.TotSec16 = TotSec16; /* RSVD+FAT+ROOT+DATA (<64k) */
bpb.FATSz16 = FATSz16; /* number of FAT sectors */
bpb.TotSec32 = TotSec32; /* RSVD+FAT+ROOT+FATA (>=64k) */
bpb.Signature = 0xaa55; /* 0xAA55 Signature */
/* setup BPB specifics for FAT32 */
bpb.FATSz32 = FATSz32; /* number of FAT sectors */
bpb.ExtFlags = 0x0000; /* mirroring info */
bpb.RootClus = 0x00000002UL; /* root dir clus for FAT32 */
bpb.FSInfo = 0x0001; /* position of FSInfo structure */
/*
Prepare buffer with information of the BPB
offset 0 - 35 is same for FAT12/FAT16 and FAT32
*/
/* jmpBoot = 0xe9 0x0000 */
buffer[0] = (char)0xe9;
buffer[1] = (char)0x00;
buffer[2] = (char)0x00;
/* OEMName = ' ' */
for (i = 3; i < 11; i++) {
buffer[i] = (char)0x20;
}
/* BytesPerSec */
buffer[11] = (char)(bpb.BytesPerSec & 0xff);
buffer[12] = (char)((unsigned int)(bpb.BytesPerSec & 0xff00) >> 8);
/* SecPerClus */
buffer[13] = (char)bpb.SecPerClus;
/* RsvdSecCnt */
buffer[14] = (char)(bpb.RsvdSecCnt & 0xff);
buffer[15] = (char)((unsigned int)(bpb.RsvdSecCnt & 0xff00) >> 8);
/* NumFATs */
buffer[16] = (char)bpb.NumFATs;
/* RootEntCnt */
buffer[17] = (char)(bpb.RootEntCnt & 0xff);
buffer[18] = (char)((unsigned int)(bpb.RootEntCnt & 0xff00) >> 8);
/* TotSec16 */
buffer[19] = (char)(bpb.TotSec16 & 0xff);
buffer[20] = (char)((unsigned int)(bpb.TotSec16 & 0xff00) >> 8);
/* Media */
buffer[21] = Media;
/* FATSz16 */
buffer[22] = (char)(bpb.FATSz16 & 0xff);
buffer[23] = (char)((unsigned int)(bpb.FATSz16 & 0xff00) >> 8);
/* SecPerTrk */
buffer[24] = (char)(SecPerTrk & 0xff);
buffer[25] = (char)((unsigned int)(SecPerTrk & 0xff00) >> 8);
/* NumHeads */
buffer[26] = (char)(NumHeads & 0xff);
buffer[27] = (char)((unsigned int)(NumHeads & 0xff00) >> 8);
/* HiddSec */
buffer[28] = (char)(HiddSec & 0xff);
buffer[29] = (char)((FS_u32)(HiddSec & 0x0000ff00UL) >> 8);
buffer[30] = (char)((FS_u32)(HiddSec & 0x00ff0000UL) >> 16);
buffer[31] = (char)((FS_u32)(HiddSec & 0xff000000UL) >> 24);
/* TotSec32 */
buffer[32] = (char)(bpb.TotSec32 & 0xff);
buffer[33] = (char)((FS_u32)(bpb.TotSec32 & 0x0000ff00UL) >> 8);
buffer[34] = (char)((FS_u32)(bpb.TotSec32 & 0x00ff0000UL) >> 16);
buffer[35] = (char)((FS_u32)(bpb.TotSec32 & 0xff000000UL) >> 24);
/* Offset 36 and above have different meanings for FAT12/FAT16 and FAT32 */
if (FSysType != 2) {
/* FAT12/FAT16 */
/* DrvNum = 0x00 (floppy) */
buffer[36] = (char)0x00;
/* Reserved1 = 0x00 (floppy) */
buffer[37] = (char)0x00;
/* BootSig = 0x00 (next three fields are not 'present') */
buffer[38] = (char)0x00;
/* VolID = 0x00000000 (serial number, e.g. date/time) */
for (i = 39; i < 43; i++) {
buffer[i] = (char)0x00;
}
/* VolLab = ' ' */
for (i = 43; i < 54; i++) {
buffer[i] = (char)0x20;
}
/* FilSysType = 'FAT12' */
if (FSysType == 0) {
FS__CLIB_strncpy(&buffer[54], "FAT12 ", 8);
}
else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -