📄 blockdev.c
字号:
/* Taken form microsoft "HardWare White Paper" */
/* retrieve values from MBR */
FLDword DataSec;
FLDword RootDirSectors;
FLDword CountOfClusters;
FLDword BPB_RootEntCnt = UNAL2(bootSector->bpb.rootDirectoryEntries);
FLDword BPB_BytesPerSec = UNAL2(bootSector->bpb.bytesPerSector);
FLDword FATSz = LE2(bootSector->bpb.sectorsPerFAT);
FLDword BPB_ResvdSecCnt = LE2(bootSector->bpb.reservedSectors);
FLDword BPB_NumFats = bootSector->bpb.noOfFATS;
FLDword BPB_SecPerClus = bootSector->bpb.sectorsPerCluster;
FLDword TotSec = UNAL2(bootSector->bpb.totalSectorsInVolumeDOS3);
if( TotSec == 0 )
TotSec = (SectorNo) LE4(bootSector->bpb.totalSectorsInVolume);
/* Find basic needed Values */
RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytesPerSec-1)) / BPB_BytesPerSec;
/* How many Sectors are in the data section */
DataSec = TotSec - (BPB_ResvdSecCnt + (BPB_NumFats * FATSz) + RootDirSectors);
/* No Of Clusters on the media */
CountOfClusters = DataSec / BPB_SecPerClus;
vol.maxCluster = (unsigned)CountOfClusters;
}
/* fat12 or fat16 ? */
if( vol.maxCluster < 4085LU )
{
#ifdef FAT_12BIT
vol.flags |= VOLUME_12BIT_FAT; /* 12-bit FAT */
#else
DBG_PRINT_ERR(FLZONE_BLKDEV,"ERROR - FAT_12BIT must be defined.\r\n");
return flFormatNotSupported;
#endif
}
/* fat 32 limitation */
if( vol.maxCluster >= 65525LU )
{
DBG_PRINT_ERR(FLZONE_BLKDEV,"ERROR - FAT_32BIT not supported.\r\n");
return flFormatNotSupported;
}
vol.bytesPerCluster = vol.sectorsPerCluster * FL_SECTOR_SIZE;
vol.allocationRover = 2; /* Set rover at first cluster */
vol.flags |= VOLUME_MOUNTED; /* That's it */
#if (defined(FL_FILES) && (FL_FILES > 0))
#ifndef FL_NO_SURE_FS_SUPPORT
checkStatus(autoRepair(&vol));
#endif /* FL_NO_SURE_FS_SUPPORT */
#endif /* FL_FILES > 0 */
return flOK;
}
#ifndef FL_READ_ONLY
#ifdef DEFRAGMENT_VOLUME
/*----------------------------------------------------------------------*/
/* d e f r a g m e n t V o l u m e */
/* */
/* Performs a general defragmentation and recycling of non-writable */
/* Flash areas, to achieve optimal write speed. */
/* */
/* NOTE: The required number of sectors (in irLength) may be changed */
/* (from another execution thread) while defragmentation is active. In */
/* particular, the defragmentation may be cut short after it began by */
/* modifying the irLength field to 0. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* ioreq->irLength : Minimum number of sectors to make available */
/* for writes. */
/* */
/* Returns: */
/* ioreq->irLength : Actual number of sectors available for writes */
/* FLStatus : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
static FLStatus defragmentVolume(Volume vol, IOreq FAR2 *ioreq)
{
return vol.tl.defragment(vol.tl.rec,&ioreq->irLength);
}
#endif /* DEFRAGMENT_VOLUME */
#ifdef FORMAT_VOLUME
/*-----------------------------------------------------------------------*/
/* f l F o r m a t V o l u m e */
/* */
/* Formats a volume, writing a new and empty file-system. All existing */
/* data is destroyed. Optionally, a low-level FTL formatting is also */
/* done. */
/* Formatting leaves the volume in the dismounted state, so that a */
/* flMountVolume call is necessary after it. */
/* */
/* Note: This routine was left for backwards compatibility with OSAK 4.2 */
/* and down therfore it is strongly recommended to use the */
/* flFormatPhysicalDrive routine instead. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* irHandle : Drive number (0, 1, ...) */
/* irFlags : FAT_ONLY_FORMAT : Do FAT formatting only */
/* TL_FORMAT_ONLY : Do TL format only */
/* TL_FORMAT : Translation layer + FAT */
/* TL_FORMAT_IF_NEEDED: Do TL formatting only if */
/* current format is invalid */
/* but perform FAT anyway */
/* irData : Address of FormatParams structure to use */
/* (defined in flformat.h) */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failed */
/*-----------------------------------------------------------------------*/
static FLStatus bdFormatVolume(Volume vol, IOreq FAR2 *ioreq)
{
FormatParams FAR2 *userFp = (FormatParams FAR2 *) ioreq->irData;
BDTLPartitionFormatParams bdtlFp;
TLFormatParams tlFp;
FLBoolean mountOK = FALSE;
FLStatus status;
FLByte socket = FL_GET_SOCKET_FROM_HANDLE(ioreq);
/* Convert argument to TLFormatParmas */
tlFp.noOfBinaryPartitions = 0;
tlFp.noOfBDTLPartitions = 1;
tlFp.BDTLPartitionInfo = &bdtlFp;
tlFp.binaryPartitionInfo = NULL;
tlFp.bootImageLen = userFp->bootImageLen;
tlFp.percentUse = (FLByte )userFp->percentUse;
tlFp.noOfCascadedDevices = 0;
tlFp.progressCallback = userFp->progressCallback;
tlFp.vmAddressingLimit = userFp->vmAddressingLimit;
tlFp.embeddedCISlength = (FLWord)userFp->embeddedCISlength;
tlFp.embeddedCIS = (FLByte FAR1 *)userFp->embeddedCIS;
tlFp.flags = TL_LEAVE_BINARY_AREA;
bdtlFp.noOfSpareUnits = (FLByte )userFp->noOfSpareUnits;
bdtlFp.flags = 0; /* Advanced Matching */
#ifdef WRITE_EXB_IMAGE
tlFp.exbLen = 0;
#endif /* WRITE_EXB_IMAGE */
#ifdef HW_PROTECTION
/* protectionKey[8]; */
bdtlFp.protectionType = 0;
#endif /* HW_PROTECTION */
/* Dismount all physical drive volumes and set handle to the first */
checkStatus(dismountPhysicalDrive(socket));
pVol = &vols[socket];
/* Format according to the irFlags argument */
if ((ioreq->irFlags & TL_FORMAT)||(ioreq->irFlags & TL_FORMAT_ONLY))
{
checkStatus(flFormat(socket,&tlFp,vol.flash));
}
else
{
status = flMount(socket,socket,&vol.tl,FALSE,vol.flash); /* Try to mount translation layer */
mountOK = TRUE;
if ((status == flUnknownMedia || status == flBadFormat) &&
(ioreq->irFlags & TL_FORMAT_IF_NEEDED))
{
status = flFormat(socket,&tlFp,vol.flash);
mountOK = FALSE;
}
else
{
/* assume sector 0 is DOS boot block */
vol.bootSectorNo = 0;
/* Disable FAT monitoring */
vol.firstFATSectorNo = vol.secondFATSectorNo = 0;
/* Enough to do abs operations */
vol.flags |= VOLUME_ABS_MOUNTED;
}
if (status != flOK)
return status;
}
if (!mountOK)
checkStatus(absMountVolume(&vol)); /* Mount the first partition */
#if (defined(VERIFY_WRITE) || defined(VERIFY_VOLUME))
if(vol.tl.checkVolume != NULL)
checkStatus(vol.tl.checkVolume(vol.tl.rec));
#endif /* VERIFY_WRITE || VERIFY_VOLUME */
if(!(ioreq->irFlags & TL_FORMAT_ONLY))
{
/* build BDTL record for dos format routine */
tffscpy(bdtlFp.volumeId,userFp->volumeId,4);
bdtlFp.volumeLabel = (FLByte FAR1 *)userFp->volumeLabel;
bdtlFp.noOfFATcopies = (FLByte )userFp->noOfFATcopies;
bdtlFp.flags = TL_FORMAT_FAT;
checkStatus(flDosFormat(&vol.tl,&bdtlFp));
checkStatus(dismountVolume(&vol));
}
#ifdef BDK_ACCESS
bdkInit();
#endif /* BDK_ACCESS */
return flOK;
}
/*----------------------------------------------------------------------*/
/* f l F o r m a t P h y s i c a l D r i v e */
/* */
/* Low Level formats the media while partitioning it. */
/* optionaly the followng additional formats are placed */
/* 1) writing a new and empty file-system */
/* 2) Compressed media format */
/* 3) Quick Mount format */
/* */
/* 4) Place M-systems EXB file on the media */
/* All existing data is destroyed. */
/* Formatting leaves the volume in the dismounted state, so that a */
/* flMountVolume call is necessary after it. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* irHandle : Drive number (0, 1, ...) */
/* irFlags : */
/* TL_NORMAL_FORMAT : Normal format */
/* TL_LEAVE_BINARY_AREA : Leave binary area unchanged */
/* TL_LEAVE_SOME_BINARY_AREA : Leave some binary partitions unchanged */
/* */
/* irData : Address of FormatParams2 structure to use */
/* (defined in flformat.h) */
/* irLength : Number of binary partition to leave , provided */
/* TL_LEAVE_SOME_BINARY_AREA is set */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
static FLStatus bdFormatPhysicalDrive(Volume vol, IOreq FAR2 *ioreq)
{
FormatParams2 FAR2* userFp = (FormatParams2 FAR2 *) ioreq->irData;
BDTLPartitionFormatParams FAR2* bdtl;
TLFormatParams tlFp;
FLByte socket = FL_GET_SOCKET_FROM_HANDLE(ioreq);
FLByte partition;
FLByte volNo;
FLStatus status = flOK; /* Initialized for dumb compilers */
/***********************************************/
/* Convert format parameters to TLFormatParams */
/***********************************************/
if (userFp->BDTLPartitionInfo == NULL)
return flBadParameter;
if((userFp->noOfBDTLPartitions == 0) ||
(userFp->noOfBDTLPartitions > FL_MAX_TL_PARTITIONS))
{
return flBadParameter;
}
/* Note that the the BDTL partition are shiftet so that the second
becomes the first ... . This is for backwards compatibility with
FTP \ NFTL where the first partition is not given as an array */
if((ioreq->irFlags & TL_LEAVE_SOME_BINARY_AREA) ==
TL_LEAVE_SOME_BINARY_AREA )
{
/* Leave only some of the binary partition */
tlFp.bootImageLen = ioreq->irLength;
}
else
{
tlFp.bootImageLen = -1; /* leave all of the binary partitions */
}
tlFp.percentUse = userFp->percentUse;
tlFp.noOfBDTLPartitions = userFp->noOfBDTLPartitions;
tlFp.noOfBinaryPartitions = userFp->noOfBinaryPartitions;
tlFp.BDTLPartitionInfo = userFp->BDTLPartitionInfo;
tlFp.binaryPartitionInfo = userFp->binaryPartitionInfo;
tlFp.progressCallback = userFp->progressCallback;
tlFp.vmAddressingLimit = userFp->vmAddressingLimit;
tlFp.embeddedCISlength = userFp->embeddedCISlength;
tlFp.embeddedCIS = userFp->embeddedCIS;
tlFp.cascadedDeviceNo = userFp->cascadedDeviceNo;
tlFp.noOfCascadedDevices = userFp->noOfCascadedDevices;
tlFp.flags = (FLByte )ioreq->irFlags;
/* Convert last partition arguments from array to dedicated fields */
bdtl = userFp->BDTLPartitionInfo;
bdtl += (userFp->noOfBDTLPartitions - 1);
tffscpy(tlFp.volumeId,bdtl->volumeId,4);
tlFp.noOfSpareUnits = (FLByte )bdtl->noOfSpareUnits;
tlFp.volumeLabel = bdtl->volumeLabel;
tlFp.noOfFATcopies = bdtl->noOfFATcopies;
#ifdef HW_PROTECTION
tffscpy(tlFp.protectionKey,bdtl->protectionKey,PROTECTION_KEY_LENGTH);
tlFp.protectionType = bdtl->protectionType;
#endif /* H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -