dosformt.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:16k
源码类别:

VxWorks

开发平台:

C/C++

  1. /*
  2.  * $Log:   V:/dosformt.c_v  $
  3.  * 
  4.  *    Rev 1.16   05 May 1998 15:02:00   yogu
  5.  * renamed MIN_CLUSTER_SIZE to flMinClusterSize and made it
  6.  * a global int so it's customizable
  7.  *
  8.  *    Rev 1.16   25 Mar 1998 15:02:00   ANDRY, Hdei
  9.  * Added bootCode[] table.
  10.  *
  11.  *    Rev 1.16   11 Nov 1997 15:27:14   ANDRY
  12.  * () in complex expressions to get rid of compiler warnings
  13.  *
  14.  *    Rev 1.15   28 Aug 1997 16:40:32   danig
  15.  * Moved big-endian to flbase.c
  16.  *
  17.  *    Rev 1.14   21 Aug 1997 14:06:34   unknown
  18.  * Unaligned4
  19.  *
  20.  *    Rev 1.13   19 Aug 1997 20:08:58   danig
  21.  * Andray's changes
  22.  *
  23.  *    Rev 1.12   14 Aug 1997 16:06:34   danig
  24.  * Moved MIN_CLUSTER_SIZE to flcustom.h
  25.  *
  26.  *    Rev 1.11   24 Jul 1997 17:53:42   amirban
  27.  * FAR -> FAR0, UNALIGNED -> Unaligned
  28.  *
  29.  *    Rev 1.10   20 Jul 1997 17:16:20   amirban
  30.  * Get rid of warnings
  31.  *
  32.  *    Rev 1.9   07 Jul 1997 15:21:00   amirban
  33.  * Ver 2.0
  34.  *
  35.  *    Rev 1.8   03 Jun 1997 17:18:56   amirban
  36.  * Min cluster size
  37.  *
  38.  *    Rev 1.7   13 May 1997 14:04:40   amirban
  39.  * Big-endian bug fix (reverse order)
  40.  *
  41.  *    Rev 1.6   09 Apr 1997 17:35:36   amirban
  42.  * Partition table redefined
  43.  *
  44.  *    Rev 1.5   02 Apr 1997 16:55:34   amirban
  45.  * BBP redefined
  46.  *
  47.  *    Rev 1.4   16 Oct 1996 16:01:40   danig
  48.  * Big-Endian bug
  49.  *
  50.  *    Rev 1.3   03 Oct 1996 14:37:28   amirban
  51.  * New Big-Endian
  52.  *
  53.  *    Rev 1.3   03 Oct 1996 11:56:36   amirban
  54.  * New Big-Endian
  55.  *
  56.  *    Rev 1.2   18 Aug 1996 13:48:34   amirban
  57.  * Comments
  58.  *
  59.  *    Rev 1.1   14 Jul 1996 16:48:24   amirban
  60.  * format params
  61.  *
  62.  *    Rev 1.0   20 Mar 1996 13:33:06   amirban
  63.  * Initial revision.
  64.  */
  65. /************************************************************************/
  66. /*                                                                      */
  67. /* FAT-FTL Lite Software Development Kit */
  68. /* Copyright (C) M-Systems Ltd. 1995-1996 */
  69. /* */
  70. /************************************************************************/
  71. #include "fltl.h"
  72. #ifdef FORMAT_VOLUME
  73. #include "dosformt.h"
  74. #define FAT12bit  (LE4(bpb->totalSectorsInVolume) < 
  75.    4086LU * bpb->sectorsPerCluster)
  76. int flMinClusterSize = 4;
  77. /*----------------------------------------------------------------------*/
  78. /*             g e t D r i v e G e o m e t r y */
  79. /* */
  80. /* Calculates the geometry parameters for BIOS/DOS media */
  81. /* */
  82. /* Parameters:                                                          */
  83. /* vol : Pointer identifying drive */
  84. /*                                                                      */
  85. /* Returns:                                                             */
  86. /* bpb : volume BIOS parameter block */
  87. /* cylinders : Number of "cylinders" in volume */
  88. /* noOfFATs : Number of FAT copies */
  89. /*----------------------------------------------------------------------*/
  90. static void getDriveGeometry(TL vol,
  91.      BPB *bpb,
  92.      unsigned int *cylinders,
  93.      unsigned noOfFATs)
  94. {
  95.   unsigned long heads, sectors, temp;
  96.   long int sizeInSectors, noOfClusters;
  97.   int directorySectors;
  98.   SectorNo capacity = vol.sectorsInVolume(vol.rec); /* Volume size in sectors */
  99.   *cylinders = 1024;                 /* Set number of cylinders to max value */
  100.   heads = 16L;                      /* Max out number of heads */
  101.   temp = *cylinders * heads;        /* Compute divisor for heads */
  102.   sectors = capacity / temp;        /* Compute value for sectors per track */
  103.   if (capacity % temp) {      /* If no remainder, done! */
  104.     sectors++;                      /* Else, increment number of sectors */
  105.     temp = *cylinders * sectors;    /* Compute divisor for heads */
  106.     heads = capacity / temp;        /* Compute value for heads */
  107.     if (capacity % temp) {          /* If no remainder, done! */
  108.       heads++;                      /* Else, increment number of heads */
  109.       temp = heads * sectors;       /* Compute divisor for cylinders */
  110.       *cylinders = (unsigned) (capacity / temp);
  111.     }
  112.   }
  113.   toLE2(bpb->sectorsPerTrack,(unsigned short) sectors);
  114.   toLE2(bpb->noOfHeads,(unsigned short) heads);
  115.   toUNAL2(bpb->bytesPerSector,SECTOR_SIZE);
  116.   toLE2(bpb->reservedSectors,1);
  117.   bpb->noOfFATS = noOfFATs;
  118.   bpb->mediaDescriptor = 0xf8; /* hard disk */
  119.   toLE4(bpb->noOfHiddenSectors,sectors);
  120.   sizeInSectors = (long) (*cylinders) * heads * sectors - sectors;
  121.   toLE4(bpb->totalSectorsInVolume,sizeInSectors);
  122.   toUNAL2(bpb->totalSectorsInVolumeDOS3,sizeInSectors > 65535l ? 0 : (unsigned short) sizeInSectors);
  123.   noOfClusters = sizeInSectors / flMinClusterSize;
  124.   for (bpb->sectorsPerCluster = flMinClusterSize;
  125.        noOfClusters > (bpb->sectorsPerCluster < 8 ? 32766l : 65534l);
  126.        bpb->sectorsPerCluster <<= 1, noOfClusters >>= 1);
  127.   if (FAT12bit)
  128.     toLE2(bpb->sectorsPerFAT,
  129.   (unsigned short) ((((noOfClusters + 2L) * 3 + 1) / 2 - 1) / SECTOR_SIZE + 1));
  130.   else
  131.     toLE2(bpb->sectorsPerFAT,
  132.   (unsigned short) (((noOfClusters + 2L) * 2 - 1) / SECTOR_SIZE + 1));
  133.   directorySectors = capacity / 200;
  134.   if (directorySectors < 1) directorySectors = 1;
  135.   if (directorySectors > 15) directorySectors = 15;
  136.   toUNAL2(bpb->rootDirectoryEntries,
  137.  directorySectors * (SECTOR_SIZE / sizeof(DirectoryEntry)));
  138. }
  139. /*----------------------------------------------------------------------*/
  140. /*        c r e a t e M a s t e r B o o t R e c o r d */
  141. /* */
  142. /* Creates the Master Boot Record (Sector 0) */
  143. /* */
  144. /* Parameters:                                                          */
  145. /* vol : Pointer identifying drive */
  146. /* bpb : volume BIOS parameter block */
  147. /*                                                                      */
  148. /* Returns:                                                             */
  149. /* FLStatus : 0 on success, failed otherwise */
  150. /* cylinders : Number of "cylinders" in volume */
  151. /*----------------------------------------------------------------------*/
  152. static FLStatus createMasterBootRecord(TL vol,
  153.      BPB *bpb,
  154.      unsigned cylinders)
  155. {
  156.   /* create partition table */
  157.   PartitionTable partitionTable;
  158.   static unsigned char bootCode[] = {
  159.     0xFA, 0x33, 0xC0, 0x8E, 0xD0, 0xBC, 0x00, 0x7C,
  160.     0x8B, 0xF4, 0x50, 0x07, 0x50, 0x1F, 0xFB, 0xFC,
  161.     0xBF, 0x00, 0x06, 0xB9, 0x00, 0x01, 0xF2, 0xA5,
  162.     0xEA, 0x1D, 0x06, 0x00, 0x00, 0xBE, 0xBE, 0x07,
  163.     0xB3, 0x04, 0x80, 0x3C, 0x80, 0x74, 0x0E, 0x80,
  164.     0x3C, 0x00, 0x75, 0x1C, 0x83, 0xC6, 0x10, 0xFE,
  165.     0xCB, 0x75, 0xEF, 0xCD, 0x18, 0x8B, 0x14, 0x8B,
  166.     0x4C, 0x02, 0x8B, 0xEE, 0x83, 0xC6, 0x10, 0xFE,
  167.     0xCB, 0x74, 0x1A, 0x80, 0x3C, 0x00, 0x74, 0xF4,
  168.     0xBE, 0x8B, 0x06, 0xAC, 0x3C, 0x00, 0x74, 0x0B,
  169.     0x56, 0xBB, 0x07, 0x00, 0xB4, 0x0E, 0xCD, 0x10,
  170.     0x5E, 0xEB, 0xF0, 0xEB, 0xFE, 0xBF, 0x05, 0x00,
  171.     0xBB, 0x00, 0x7C, 0xB8, 0x01, 0x02, 0x57, 0xCD,
  172.     0x13, 0x5F, 0x73, 0x0C, 0x33, 0xC0, 0xCD, 0x13,
  173.     0x4F, 0x75, 0xED, 0xBE, 0xA3, 0x06, 0xEB, 0xD3,
  174.     0xBE, 0xC2, 0x06, 0xBF, 0xFE, 0x7D, 0x81, 0x3D,
  175.     0x55, 0xAA, 0x75, 0xC7, 0x8B, 0xF5, 0xEA, 0x00,
  176.     0x7C, 0x00, 0x00, 0x49, 0x6E, 0x76, 0x61, 0x6C,
  177.     0x69, 0x64, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69,
  178.     0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x61, 0x62,
  179.     0x6C, 0x65, 0x00, 0x45, 0x72, 0x72, 0x6F, 0x72,
  180.     0x20, 0x6C, 0x6F, 0x61, 0x64, 0x69, 0x6E, 0x67,
  181.     0x20, 0x6F, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
  182.     0x6E, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
  183.     0x6D, 0x00, 0x4D, 0x69, 0x73, 0x73, 0x69, 0x6E,
  184.     0x67, 0x20, 0x6F, 0x70, 0x65, 0x72, 0x61, 0x74,
  185.     0x69, 0x6E, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74,
  186.     0x65, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  187.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  188.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  189.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  190.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  191.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  192.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  193.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  194.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  195.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  196.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  197.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  198.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  199.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  200.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  201.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  202.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  203.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  204.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  205.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  206.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  207.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  208.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  209.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  210.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  211.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  212.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  213.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  214.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01,
  215.     0x01, 0x00, 0x06, 0x07, 0xE3, 0x66, 0x23, 0x00,
  216.     0x00, 0x00, 0x85, 0xB8, 0x03, 0x00, 0x00, 0x00,
  217.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  218.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  219.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  220.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  221.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  222.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA};
  223.   tffscpy(&partitionTable,bootCode,sizeof partitionTable);
  224.   partitionTable.activeFlag = 0x80; /* bootable */
  225.   if (LE2(bpb->noOfHeads) > 1) {
  226.     partitionTable.startingHead = 1;
  227.     toLE2(partitionTable.startingCylinderSector,CYLINDER_SECTOR(0,1));
  228.   }
  229.   else {
  230.     partitionTable.startingHead = 0;
  231.     toLE2(partitionTable.startingCylinderSector,CYLINDER_SECTOR(1,1));
  232.   }
  233.   partitionTable.type = FAT12bit ? 1 : 4;
  234.   partitionTable.endingHead = LE2(bpb->noOfHeads) - 1;
  235.   toLE2(partitionTable.endingCylinderSector,
  236. CYLINDER_SECTOR((cylinders - 1),LE2(bpb->sectorsPerTrack)));
  237.   toUNAL4(partitionTable.startingSectorOfPartition,LE2(bpb->sectorsPerTrack));
  238.   toUNAL4(partitionTable.sectorsInPartition,LE4(bpb->totalSectorsInVolume));
  239.   toLE2(partitionTable.signature,PARTITION_SIGNATURE);
  240.   return vol.writeSector(vol.rec,0,&partitionTable);
  241. }
  242. /*----------------------------------------------------------------------*/
  243. /*            c r e a t e D O S B o o t S e c t o r */
  244. /* */
  245. /* Creates the DOS boot sector */
  246. /* */
  247. /* Parameters:                                                          */
  248. /* vol : Pointer identifying drive */
  249. /* bpb : volume BIOS parameter block */
  250. /* volumeId : 32-bit volume id */
  251. /* volumeLabel : volume label */
  252. /*                                                                      */
  253. /* Returns:                                                             */
  254. /* FLStatus : 0 on success, failed otherwise */
  255. /*----------------------------------------------------------------------*/
  256. static FLStatus createDOSbootSector(TL vol,
  257.   BPB *bpb,
  258.   const char FAR1 *volumeId,
  259.   const char FAR1 *volumeLabel)
  260. {
  261.   DOSBootSector bootSector;
  262.   tffsset(&bootSector,0,sizeof bootSector);
  263.   bootSector.physicalDriveNo = 0x80;
  264.   bootSector.extendedBootSignature = 0x29;
  265.   tffscpy(bootSector.volumeId,volumeId,sizeof bootSector.volumeId);
  266.   tffsset(bootSector.volumeLabel,' ',sizeof bootSector.volumeLabel);
  267.   if (volumeLabel)
  268.     tffscpy(bootSector.volumeLabel,volumeLabel,sizeof bootSector.volumeLabel);
  269.   tffscpy(bootSector.systemId,
  270.   FAT12bit ? "FAT12   " : "FAT16   ",
  271.   sizeof bootSector.systemId);
  272.   bootSector.bpb = *bpb;
  273. #if FALSE
  274.   tffscpy (&bootSector.bpb, bpb, sizeof(BPB));
  275. #endif /* FALSE */
  276.   bootSector.bpb.jumpInstruction[0] = 0xe9;
  277.   tffscpy(bootSector.bpb.OEMname,"MSystems",sizeof bootSector.bpb.OEMname);
  278.   toLE2(bootSector.signature,PARTITION_SIGNATURE);
  279.   return vol.writeSector(vol.rec,(SectorNo) LE4(bpb->noOfHiddenSectors),&bootSector);
  280. }
  281. /*----------------------------------------------------------------------*/
  282. /*                 c r e a t e F A T s */
  283. /* */
  284. /* Creates the FAT's */
  285. /* */
  286. /* Parameters:                                                          */
  287. /* vol : Pointer identifying drive */
  288. /* bpb : volume BIOS parameter block */
  289. /*                                                                      */
  290. /* Returns:                                                             */
  291. /* FLStatus : 0 on success, failed otherwise */
  292. /*----------------------------------------------------------------------*/
  293. static FLStatus createFATs(TL vol, BPB *bpb)
  294. {
  295.   int iFAT;
  296.   SectorNo sectorNo = (SectorNo) (LE4(bpb->noOfHiddenSectors) +
  297.   LE2(bpb->reservedSectors));
  298.   /* create the FATs */
  299.   for (iFAT = 0; iFAT < bpb->noOfFATS; iFAT++) {
  300.     int iSector;
  301.     unsigned char FATEntry[SECTOR_SIZE];
  302.     for (iSector = 0; iSector < LE2(bpb->sectorsPerFAT); iSector++) {
  303.       tffsset(FATEntry,0,SECTOR_SIZE);
  304.       if (iSector == 0) { /* write the reserved FAT entries */
  305. FATEntry[0] = bpb->mediaDescriptor;
  306. FATEntry[1] = 0xff;
  307. FATEntry[2] = 0xff;
  308. if (!FAT12bit)
  309.   FATEntry[3] = 0xff;
  310.       }
  311.       checkStatus(vol.writeSector(vol.rec,sectorNo++,FATEntry));
  312.     }
  313.   }
  314.   return flOK;
  315. }
  316. /*----------------------------------------------------------------------*/
  317. /*            c r e a t e R o o t D i r e c t o r y */
  318. /* */
  319. /* Creates the root directory */
  320. /* */
  321. /* Parameters:                                                          */
  322. /* vol : Pointer identifying drive */
  323. /* bpb : volume BIOS parameter block */
  324. /* volumeLabel : volume label */
  325. /*                                                                      */
  326. /* Returns:                                                             */
  327. /* FLStatus : 0 on success, failed otherwise */
  328. /*----------------------------------------------------------------------*/
  329. static FLStatus createRootDirectory(TL vol,
  330.   BPB *bpb,
  331.   const char FAR1 *volumeLabel)
  332. {
  333.   int iEntry;
  334.   SectorNo sectorNo = (SectorNo) (LE4(bpb->noOfHiddenSectors) +
  335.   LE2(bpb->reservedSectors) +
  336.   bpb->noOfFATS * LE2(bpb->sectorsPerFAT));
  337.   /* create the root directory */
  338.   for (iEntry = 0; iEntry < UNAL2(bpb->rootDirectoryEntries);
  339.        iEntry += (SECTOR_SIZE / sizeof(DirectoryEntry))) {
  340.     DirectoryEntry rootDirectorySector[SECTOR_SIZE / sizeof(DirectoryEntry)];
  341.     tffsset(rootDirectorySector,0,SECTOR_SIZE);
  342.     if (iEntry == 0 && volumeLabel) {
  343.       tffsset(rootDirectorySector[0].name,' ',sizeof rootDirectorySector[0].name);
  344.       tffscpy(rootDirectorySector[0].name,volumeLabel,sizeof rootDirectorySector[0].name);
  345.       rootDirectorySector[0].attributes = 0x28; /* VOL + ARC */
  346.       toLE2(rootDirectorySector[0].updateTime,0);
  347.       toLE2(rootDirectorySector[0].updateDate,0x21); /* 1/1/80 */
  348.     }
  349.     checkStatus(vol.writeSector(vol.rec,sectorNo++,rootDirectorySector));
  350.   }
  351.   return flOK;
  352. }
  353. /*----------------------------------------------------------------------*/
  354. /*                 f l D o s F o r m a t */
  355. /* */
  356. /* Writes a DOS-FAT file system on the Flash volume */
  357. /* */
  358. /* Parameters:                                                          */
  359. /* vol : Pointer identifying drive */
  360. /* formatParams : Address of FormatParams structure to use */
  361. /*                                                                      */
  362. /* Returns:                                                             */
  363. /* FLStatus : 0 on success, failed otherwise */
  364. /*----------------------------------------------------------------------*/
  365. FLStatus flDosFormat(TL vol, FormatParams FAR1 *formatParams)
  366. {
  367.   unsigned int cylinders;
  368.   BPB bpb;
  369.   getDriveGeometry(&vol,&bpb,&cylinders,formatParams->noOfFATcopies);
  370.   checkStatus(createMasterBootRecord(&vol,&bpb,cylinders));
  371.   checkStatus(createDOSbootSector(&vol,&bpb,formatParams->volumeId,formatParams->volumeLabel));
  372.   checkStatus(createFATs(&vol,&bpb));
  373.   checkStatus(createRootDirectory(&vol,&bpb,formatParams->volumeLabel));
  374.   return flOK;
  375. }
  376. #endif