📄 dosfsfmtlib.c
字号:
/* dosFsFmtLib.c - MS-DOS media-compatible file system formatting library */ /* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02b,29apr02,jkf SPR#76013, dosFsVolFormat shall cbioUnlock all it cbioLock's02a,12dec01,jkf fixing diab warnings01z,10dec01,jkf SPR#72039, MSDOS FAT32 fsInfo sector now using hard coded offsets to properly support blkSize > 512bps. increase check for bytesPerBlk minimum in dosFsFmtAutoParams.01y,15nov01,jkf SPR#71720, avoid unaligned pointer access.01x,09nov01,jkf SPR#71633, dont set errno when VolFormat suceeded.01w,20sep01,jkf SPR#69031, common code for both AE & 5.x.01v,08dec00,jkf SPR#34704,FAT12/FAT16 determination, SPR#62415 sig location.01u,15sep00,jkf cleaning warning01t,29feb00,jkf T3 changes, cleanup01s,18oct99,jkf avoiding div by zero if nHeads*blksPerTrack = 0, SPR#2950801r,27oct99,jkf Documentation correction for compatibility section.01q,03oct99,jkf setup a pseudo LCHS translation to mimic MSDOS more. This helps VxLd on large disks formatted by us.01p,03oct99,jkf removed random signature, breaks vxsys booting. Correction from vxsys investigation, removed random signature, configure hidden sectors to sec per track, change nClust calculation to match Microsoft.01o,03oct99,jkf added sysId check to dosFsFmtReadBootBlock, changed reserved sectors setting to one in dosFsVolFormat. Disabled the ret instructions being written in dosFsFmtNonFsBootInit.01n,15sep99,jkf changes for new CBIO API.01m,31jul99,jkf FAT12/FAT16 calculation per NT, SPR#28274. improved media byte support, SPR#27282. added support FSTYPE (0x36) in boot sector, SPR#28273.01l,16jun99,jkf correctly set FS ID for FAT32, SPR#28275.01k,12jul99,jkf T2 merge, tidiness & spelling. (allows Windows to mount our FAT32)01j,30nov98,lrn changed JMP instruction to be Win98 compatible (SPR#23442)01i,07sep98,lrn fixed formatting of 4 MB disks to be FAT1601h,30jul98,wlf partial doc cleanup01g,14jul98,lrn replaced perror() with printErr01f,12jul98,lrn fixed: option may force format to FAT1601e,22jun98,lrn vol desc name change01d,03jun98,lrn Libinit, integ, increased max root dirs for small disks01c,03jun98,lrn polished main function and interactive params control, doc01b,14may98,lrn added VxLong names 01a,12may98,lrn initial version*//*DESCRIPTIONThis module is a scaleable companion module for dosFsLib, and is intended to facilitate high level formatting of disk volumes.There are two ways to high level format a volume:.IP "(1)"Directly calling dosFsVolFormat() routine allows to have completecontrol over the format used, parameters and allows to supply a hookroutine which for instance could interactively prompt the user tomodify disk parameters..IP "(2)"Calling ioctl command FIODISKINIT will invoke the formatting routinevia dosFsLib. This uses the default volume format and parameters.AVAILABILITYThis routine is an optional part of the MS-DOS file system,and may be included in a target system if it is required tobe able to format new volumes.In order to include this option, the following function needsto be invoked during system initialization:.CSvoid dosFsFmtLibInit( void );.CESee reference page dosFsVolFormat() for complete description ofsupported formats, options and arguments.SEE ALSOdosFsLib*//* includes */#include "vxWorks.h"#include "private/dosFsVerP.h"#include "string.h"#include "stdio.h"#include "stdlib.h"#include "ctype.h"#include "errnoLib.h"#include "memLib.h"#include "tickLib.h"#include "dosFsLib.h"#include "private/dosFsLibP.h"#include "private/dosDirLibP.h"/* defines *//* defines - FAT Boot Sector values */#define DOS_BOOT_SEC_NUM 0 /* sector number of boot sector */#define DOS_MIN_CLUST 2 /* lowest cluster number used *//* most of these are old defaults which are now calculated */#define DEFAULT_ROOT_ENTS 112 /* default # of root dir entries */#define DEFAULT_MAX_ROOT_ENTS 512 /* default max # of root dir entries */#define DEFAULT_SEC_PER_CLUST 2 /* default sectors per cluster */#define DEFAULT_MEDIA_BYTE 0xF8 /* default media byte value */#define DEFAULT_NFATS 2 /* default number FAT copies */#define MAX_NFATS 16 /* maximum number FAT copies */#define DEFAULT_NRESERVED 1 /* default # of reserved sec's (min=1)*/#define DOS_FAT_12BIT_MAX 4085 /* max clusters, 12 bit FAT entries *//* * FIXME - these are not really -2, but -11, but it is ok because * we then should take into account the FAT sectors overhead when * calculating cluster size. */#define DOS_FAT_16BIT_MAX (0x10000-2) /* max clusters, 16 bit FAT */#define DOS_FAT_32BIT_MAX (0x200000-2) /* max clusters, 32-bit FAT entries */#define DOS32_INFO_SEC 1 /* FAT32 info sector location */#define DOS32_BACKUP_BOOT 6 /* FAT32 backup boot block location *//********************************************************************************* dosFsFmtShow - print volume parameters to stdout**/LOCAL void dosFsFmtShow( DOS_VOL_CONFIG * pConf ) { printf("Volume Parameters: FAT type: FAT%d, sectors per cluster %d\n", pConf->fatType, pConf->secPerClust); printf(" %d FAT copies, %ld clusters, %ld sectors per FAT\n", pConf->nFats, pConf->nClust, pConf->secPerFat ); printf(" Sectors reserved %d, hidden %ld, FAT sectors %ld\n", pConf->nResrvd, pConf->nHidden, pConf->secPerFat* pConf->nFats); printf(" Root dir entries %d, sysId %-8s, serial number %lx\n", pConf->maxRootEnts, pConf->sysId, pConf->volSerial ); printf(" Label:\"%-11s\" ...\n", pConf->volLabel ); }/********************************************************************************* dosFsFmtAutoParams - automatically calculate FAT formatting params** This function attempts to imitate MSFT formulae for setting* disk parameters for maximum compatibility.* For fully automatic configuration, the configuration structure* should be all zeroed out.* If any of the modifiable fields are non-zero, this function will* calculate the rest of the parameters, honoring the values filled* in prior to the call.** Note however that MSFT compatibility can not be always maintained* unless fully automatic configuration is performed.**/LOCAL STATUS dosFsFmtAutoParams ( DOS_VOL_CONFIG * pConf, /* config params structure */ ULONG nBlks, /* # of secs on volume */ int bytesPerBlk, /* sector size */ int opt /* VxLongs */ ) { ULONG nClust, maxClust, minClust ; int rootSecs, fatBytes ; int dirEntrySize = DOS_DIRENT_STD_LEN; /* * adjust the directory entry size if using vxLongnames which * use a unique directory entry size. */ if( opt & DOS_OPT_VXLONGNAMES ) dirEntrySize = DOS_VX_DIRENT_LEN; /* verify bytes per block supports the file system */ if( (bytesPerBlk < (dirEntrySize *3)) || (bytesPerBlk < 64 && nBlks > 0xfffe) ) { errno = EINVAL; return ERROR; } /* setup some pConf field based on disk size */ if( bytesPerBlk < 512 ) { /* most likely a tiny RAMdisks */ if(pConf->secPerClust == 0 ) pConf->secPerClust = 1 ; if(pConf->mediaByte == 0 ) pConf->mediaByte = 0xfd; /* TODO, what to use for RAMDISK? */ if(pConf->nFats == 0 ) pConf->nFats = 1; rootSecs = (((DEFAULT_ROOT_ENTS * dirEntrySize) + (bytesPerBlk -1)) / bytesPerBlk); minClust = 1 ; } else if (nBlks <= 720) /* i.e. 360KB 5.25" */ { /* temporary value, later scaled up as needed */ if(pConf->secPerClust == 0) pConf->secPerClust = 1 ; if(pConf->mediaByte == 0) pConf->mediaByte = 0xfd; /* per NT Resource Kit */ if(pConf->fatType == _AUTO) pConf->fatType = _FAT12; /* floppies use FAT12 */ pConf->maxRootEnts = DEFAULT_ROOT_ENTS; /* always 112 for 360KB */ rootSecs = (((DEFAULT_ROOT_ENTS * dirEntrySize) + (bytesPerBlk -1)) / bytesPerBlk); minClust = 2; } else if (nBlks <= 1440 ) /* i.e. 720KB 3.5" */ { /* temporary value, later scaled up as needed */ if( pConf->secPerClust == 0) pConf->secPerClust = 1 ; if( pConf->mediaByte == 0) pConf->mediaByte = 0xf9; /* per NT Resource Kit */ if(pConf->fatType == _AUTO) pConf->fatType = _FAT12; /* floppies use FAT12 */ pConf->maxRootEnts = DEFAULT_ROOT_ENTS; /* always 112 for 720KB */ rootSecs = (((DEFAULT_ROOT_ENTS * dirEntrySize) + (bytesPerBlk -1)) / bytesPerBlk); minClust = 2; } else if (nBlks <= 2400 ) /* i.e. 1.2Mb 5.25" */ { /* temporary value, later scaled up as needed */ if(pConf->secPerClust == 0) pConf->secPerClust = 1 ; if(pConf->mediaByte == 0) pConf->mediaByte = 0xf9;/* per NT Resource Kit */ if(pConf->fatType == _AUTO) pConf->fatType = _FAT12; /* floppies use FAT12 */ pConf->maxRootEnts = DEFAULT_ROOT_ENTS; rootSecs = (((DEFAULT_ROOT_ENTS * dirEntrySize) + (bytesPerBlk -1)) / bytesPerBlk); minClust = 2; } else if( nBlks <= 2880 ) /* i.e. 1.44MB 3.5" floppy */ { /* temporary value, later scaled up as needed */ if(pConf->secPerClust == 0) pConf->secPerClust = 1 ; if(pConf->mediaByte == 0) pConf->mediaByte = 0xf0;/* Per NT Resource Kit */ if(pConf->fatType == _AUTO) pConf->fatType = _FAT12; /* floppies use FAT12 */ pConf->maxRootEnts = DEFAULT_ROOT_ENTS; rootSecs = (((DEFAULT_ROOT_ENTS * dirEntrySize) + (bytesPerBlk -1)) / bytesPerBlk); minClust = 2; } else if( nBlks <= 4000 ) /* probally a hard disk or PCMCIA, FLASH etc.*/ { /* temporary value, later scaled up as needed */ if(pConf->secPerClust == 0) pConf->secPerClust = 1; if(pConf->mediaByte == 0) pConf->mediaByte = DEFAULT_MEDIA_BYTE; if(pConf->fatType == _AUTO) pConf->fatType = _FAT12; /* floppies use FAT12 */ pConf->maxRootEnts = DEFAULT_ROOT_ENTS; rootSecs = (((DEFAULT_ROOT_ENTS * dirEntrySize) + (bytesPerBlk -1)) / bytesPerBlk); minClust = 1 ; } else { /* temporary value, later scaled up as needed */ if(pConf->secPerClust == 0) pConf->secPerClust = 2; if(pConf->mediaByte == 0) pConf->mediaByte = DEFAULT_MEDIA_BYTE; pConf->maxRootEnts = DEFAULT_MAX_ROOT_ENTS; rootSecs = (((DEFAULT_ROOT_ENTS * dirEntrySize) + (bytesPerBlk -1)) / bytesPerBlk); minClust = 2; } /* fixup root directory entries */ if( pConf->maxRootEnts != 0 ) { rootSecs = (((pConf->maxRootEnts * dirEntrySize) + (bytesPerBlk -1)) / bytesPerBlk); } if( pConf->nFats == 0 ) pConf->nFats = DEFAULT_NFATS; pConf->nFats = min( pConf->nFats, MAX_NFATS ); /* temporary value, may be way too large */ nClust = nBlks / pConf->secPerClust ; /* define FAT type first, many other params depend on it */ if( pConf->fatType == _AUTO ) { /* * Here we decide which FAT format to use. */ if(nClust < DOS_FAT_12BIT_MAX) pConf->fatType = _FAT12 ; /* <16MB volume, FAT12 */ else if ( nBlks < 0x400000 ) pConf->fatType = _FAT16 ; /* 16MB+ <2GB, FAT16 */ else pConf->fatType = _FAT32 ; /* 2GB+ volume, FAT32 */ } switch(pConf->fatType) { case _FAT32: if( pConf->nResrvd == 0) pConf->nResrvd = 32; maxClust = DOS_FAT_32BIT_MAX; minClust = 8; break; default: case _FAT16: if( pConf->nResrvd == 0) pConf->nResrvd = 1; maxClust = DOS_FAT_16BIT_MAX; minClust = 2; break; case _FAT12: if( pConf->nResrvd == 0) pConf->nResrvd = 1; maxClust = DOS_FAT_12BIT_MAX; minClust = 1; break; } /* now, we know the FAT type, so we can really calculate secs per clust */ while( (nClust > maxClust ) || ((ULONG)pConf->secPerClust < minClust) ) { pConf->secPerClust <<= 1 ; /* multiply secs/clust by 2 */ nClust = nBlks / pConf->secPerClust ; /* recalc */ } /* max secs/clust is limited to 254 */ pConf->secPerClust = min( pConf->secPerClust, 254 ); nClust = nBlks / pConf->secPerClust ; /* recalc */ switch( pConf->fatType ) { case _FAT32: fatBytes = nClust * 4; rootSecs = 0 ; /* root dir is a normal cluster */ if(pConf->sysId==NULL) pConf->sysId = "VX5DOS32"; break; default: case _FAT16: fatBytes = nClust * 2; if(pConf->sysId==NULL) pConf->sysId = "VXDOS16"; break; case _FAT12: fatBytes = nClust * 3 / 2; if(pConf->sysId==NULL) pConf->sysId = "VXDOS12"; break; } /* setup a special id for longnames */ if( opt & DOS_OPT_VXLONGNAMES ) { pConf->sysId = "VXEXT1.1"; } /* calculate sectors per fat */ pConf->secPerFat = (fatBytes + bytesPerBlk - 1) / bytesPerBlk ; /* figure out root dir size */ pConf->maxRootEnts = rootSecs * bytesPerBlk / dirEntrySize ; /* root entries are never bigger than 512 */ if ((pConf->fatType != _FAT32) && (pConf->maxRootEnts > DEFAULT_MAX_ROOT_ENTS))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -