FatFormatter.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /**
  2. * Copyright (c) 2011-2021 Bill Greiman
  3. * This file is part of the SdFat library for SD memory cards.
  4. *
  5. * MIT License
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included
  15. * in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. * DEALINGS IN THE SOFTWARE.
  24. */
  25. #include "FatLib.h"
  26. // Set nonzero to use calculated CHS in MBR. Should not be required.
  27. #define USE_LBA_TO_CHS 1
  28. // Constants for file system structure optimized for flash.
  29. uint16_t const BU16 = 128;
  30. uint16_t const BU32 = 8192;
  31. // Assume 512 byte sectors.
  32. const uint16_t BYTES_PER_SECTOR = 512;
  33. const uint16_t SECTORS_PER_MB = 0X100000/BYTES_PER_SECTOR;
  34. const uint16_t FAT16_ROOT_ENTRY_COUNT = 512;
  35. const uint16_t FAT16_ROOT_SECTOR_COUNT =
  36. 32*FAT16_ROOT_ENTRY_COUNT/BYTES_PER_SECTOR;
  37. //------------------------------------------------------------------------------
  38. #define PRINT_FORMAT_PROGRESS 1
  39. #if !PRINT_FORMAT_PROGRESS
  40. #define writeMsg(str)
  41. #elif defined(__AVR__)
  42. #define writeMsg(str) if (m_pr) m_pr->print(F(str))
  43. #else // PRINT_FORMAT_PROGRESS
  44. #define writeMsg(str) if (m_pr) m_pr->write(str)
  45. #endif // PRINT_FORMAT_PROGRESS
  46. //------------------------------------------------------------------------------
  47. bool FatFormatter::format(BlockDevice* dev, uint8_t* secBuf, print_t* pr) {
  48. bool rtn;
  49. m_dev = dev;
  50. m_secBuf = secBuf;
  51. m_pr = pr;
  52. m_sectorCount = m_dev->sectorCount();
  53. m_capacityMB = (m_sectorCount + SECTORS_PER_MB - 1)/SECTORS_PER_MB;
  54. if (m_capacityMB <= 6) {
  55. writeMsg("Card is too small.\r\n");
  56. return false;
  57. } else if (m_capacityMB <= 16) {
  58. m_sectorsPerCluster = 2;
  59. } else if (m_capacityMB <= 32) {
  60. m_sectorsPerCluster = 4;
  61. } else if (m_capacityMB <= 64) {
  62. m_sectorsPerCluster = 8;
  63. } else if (m_capacityMB <= 128) {
  64. m_sectorsPerCluster = 16;
  65. } else if (m_capacityMB <= 1024) {
  66. m_sectorsPerCluster = 32;
  67. } else if (m_capacityMB <= 32768) {
  68. m_sectorsPerCluster = 64;
  69. } else {
  70. // SDXC cards
  71. m_sectorsPerCluster = 128;
  72. }
  73. rtn = m_sectorCount < 0X400000 ? makeFat16() : makeFat32();
  74. if (rtn) {
  75. writeMsg("Format Done\r\n");
  76. } else {
  77. writeMsg("Format Failed\r\n");
  78. }
  79. return rtn;
  80. }
  81. //------------------------------------------------------------------------------
  82. bool FatFormatter::initFatDir(uint8_t fatType, uint32_t sectorCount) {
  83. size_t n;
  84. memset(m_secBuf, 0, BYTES_PER_SECTOR);
  85. writeMsg("Writing FAT ");
  86. for (uint32_t i = 1; i < sectorCount; i++) {
  87. if (!m_dev->writeSector(m_fatStart + i, m_secBuf)) {
  88. return false;
  89. }
  90. if ((i%(sectorCount/32)) == 0) {
  91. writeMsg(".");
  92. }
  93. }
  94. writeMsg("\r\n");
  95. // Allocate reserved clusters and root for FAT32.
  96. m_secBuf[0] = 0XF8;
  97. n = fatType == 16 ? 4 : 12;
  98. for (size_t i = 1; i < n; i++) {
  99. m_secBuf[i] = 0XFF;
  100. }
  101. return m_dev->writeSector(m_fatStart, m_secBuf) &&
  102. m_dev->writeSector(m_fatStart + m_fatSize, m_secBuf);
  103. }
  104. //------------------------------------------------------------------------------
  105. void FatFormatter::initPbs() {
  106. PbsFat_t* pbs = reinterpret_cast<PbsFat_t*>(m_secBuf);
  107. memset(m_secBuf, 0, BYTES_PER_SECTOR);
  108. pbs->jmpInstruction[0] = 0XEB;
  109. pbs->jmpInstruction[1] = 0X76;
  110. pbs->jmpInstruction[2] = 0X90;
  111. for (uint8_t i = 0; i < sizeof(pbs->oemName); i++) {
  112. pbs->oemName[i] = ' ';
  113. }
  114. setLe16(pbs->bpb.bpb16.bytesPerSector, BYTES_PER_SECTOR);
  115. pbs->bpb.bpb16.sectorsPerCluster = m_sectorsPerCluster;
  116. setLe16(pbs->bpb.bpb16.reservedSectorCount, m_reservedSectorCount);
  117. pbs->bpb.bpb16.fatCount = 2;
  118. // skip rootDirEntryCount
  119. // skip totalSectors16
  120. pbs->bpb.bpb16.mediaType = 0XF8;
  121. // skip sectorsPerFat16
  122. // skip sectorsPerTrack
  123. // skip headCount
  124. setLe32(pbs->bpb.bpb16.hidddenSectors, m_relativeSectors);
  125. setLe32(pbs->bpb.bpb16.totalSectors32, m_totalSectors);
  126. // skip rest of bpb
  127. setLe16(pbs->signature, PBR_SIGNATURE);
  128. }
  129. //------------------------------------------------------------------------------
  130. bool FatFormatter::makeFat16() {
  131. uint32_t nc;
  132. uint32_t r;
  133. PbsFat_t* pbs = reinterpret_cast<PbsFat_t*>(m_secBuf);
  134. for (m_dataStart = 2*BU16; ; m_dataStart += BU16) {
  135. nc = (m_sectorCount - m_dataStart)/m_sectorsPerCluster;
  136. m_fatSize = (nc + 2 + (BYTES_PER_SECTOR/2) - 1)/(BYTES_PER_SECTOR/2);
  137. r = BU16 + 1 + 2*m_fatSize + FAT16_ROOT_SECTOR_COUNT;
  138. if (m_dataStart >= r) {
  139. m_relativeSectors = m_dataStart - r + BU16;
  140. break;
  141. }
  142. }
  143. // check valid cluster count for FAT16 volume
  144. if (nc < 4085 || nc >= 65525) {
  145. writeMsg("Bad cluster count\r\n");
  146. return false;
  147. }
  148. m_reservedSectorCount = 1;
  149. m_fatStart = m_relativeSectors + m_reservedSectorCount;
  150. m_totalSectors = nc*m_sectorsPerCluster
  151. + 2*m_fatSize + m_reservedSectorCount + 32;
  152. if (m_totalSectors < 65536) {
  153. m_partType = 0X04;
  154. } else {
  155. m_partType = 0X06;
  156. }
  157. // write MBR
  158. if (!writeMbr()) {
  159. return false;
  160. }
  161. initPbs();
  162. setLe16(pbs->bpb.bpb16.rootDirEntryCount, FAT16_ROOT_ENTRY_COUNT);
  163. setLe16(pbs->bpb.bpb16.sectorsPerFat16, m_fatSize);
  164. pbs->bpb.bpb16.physicalDriveNumber = 0X80;
  165. pbs->bpb.bpb16.extSignature = EXTENDED_BOOT_SIGNATURE;
  166. setLe32(pbs->bpb.bpb16.volumeSerialNumber, 1234567);
  167. for (size_t i = 0; i < sizeof(pbs->bpb.bpb16.volumeLabel); i++) {
  168. pbs->bpb.bpb16.volumeLabel[i] = ' ';
  169. }
  170. pbs->bpb.bpb16.volumeType[0] = 'F';
  171. pbs->bpb.bpb16.volumeType[1] = 'A';
  172. pbs->bpb.bpb16.volumeType[2] = 'T';
  173. pbs->bpb.bpb16.volumeType[3] = '1';
  174. pbs->bpb.bpb16.volumeType[4] = '6';
  175. if (!m_dev->writeSector(m_relativeSectors, m_secBuf)) {
  176. return false;
  177. }
  178. return initFatDir(16, m_dataStart - m_fatStart);
  179. }
  180. //------------------------------------------------------------------------------
  181. bool FatFormatter::makeFat32() {
  182. uint32_t nc;
  183. uint32_t r;
  184. PbsFat_t* pbs = reinterpret_cast<PbsFat_t*>(m_secBuf);
  185. FsInfo_t* fsi = reinterpret_cast<FsInfo_t*>(m_secBuf);
  186. m_relativeSectors = BU32;
  187. for (m_dataStart = 2*BU32; ; m_dataStart += BU32) {
  188. nc = (m_sectorCount - m_dataStart)/m_sectorsPerCluster;
  189. m_fatSize = (nc + 2 + (BYTES_PER_SECTOR/4) - 1)/(BYTES_PER_SECTOR/4);
  190. r = m_relativeSectors + 9 + 2*m_fatSize;
  191. if (m_dataStart >= r) {
  192. break;
  193. }
  194. }
  195. // error if too few clusters in FAT32 volume
  196. if (nc < 65525) {
  197. writeMsg("Bad cluster count\r\n");
  198. return false;
  199. }
  200. m_reservedSectorCount = m_dataStart - m_relativeSectors - 2*m_fatSize;
  201. m_fatStart = m_relativeSectors + m_reservedSectorCount;
  202. m_totalSectors = nc*m_sectorsPerCluster + m_dataStart - m_relativeSectors;
  203. // type depends on address of end sector
  204. // max CHS has lba = 16450560 = 1024*255*63
  205. if ((m_relativeSectors + m_totalSectors) <= 16450560) {
  206. // FAT32 with CHS and LBA
  207. m_partType = 0X0B;
  208. } else {
  209. // FAT32 with only LBA
  210. m_partType = 0X0C;
  211. }
  212. if (!writeMbr()) {
  213. return false;
  214. }
  215. initPbs();
  216. setLe32(pbs->bpb.bpb32.sectorsPerFat32, m_fatSize);
  217. setLe32(pbs->bpb.bpb32.fat32RootCluster, 2);
  218. setLe16(pbs->bpb.bpb32.fat32FSInfoSector, 1);
  219. setLe16(pbs->bpb.bpb32.fat32BackBootSector, 6);
  220. pbs->bpb.bpb32.physicalDriveNumber = 0X80;
  221. pbs->bpb.bpb32.extSignature = EXTENDED_BOOT_SIGNATURE;
  222. setLe32(pbs->bpb.bpb32.volumeSerialNumber, 1234567);
  223. for (size_t i = 0; i < sizeof(pbs->bpb.bpb32.volumeLabel); i++) {
  224. pbs->bpb.bpb32.volumeLabel[i] = ' ';
  225. }
  226. pbs->bpb.bpb32.volumeType[0] = 'F';
  227. pbs->bpb.bpb32.volumeType[1] = 'A';
  228. pbs->bpb.bpb32.volumeType[2] = 'T';
  229. pbs->bpb.bpb32.volumeType[3] = '3';
  230. pbs->bpb.bpb32.volumeType[4] = '2';
  231. if (!m_dev->writeSector(m_relativeSectors, m_secBuf) ||
  232. !m_dev->writeSector(m_relativeSectors + 6, m_secBuf)) {
  233. return false;
  234. }
  235. // write extra boot area and backup
  236. memset(m_secBuf, 0 , BYTES_PER_SECTOR);
  237. setLe32(fsi->trailSignature, FSINFO_TRAIL_SIGNATURE);
  238. if (!m_dev->writeSector(m_relativeSectors + 2, m_secBuf) ||
  239. !m_dev->writeSector(m_relativeSectors + 8, m_secBuf)) {
  240. return false;
  241. }
  242. // write FSINFO sector and backup
  243. setLe32(fsi->leadSignature, FSINFO_LEAD_SIGNATURE);
  244. setLe32(fsi->structSignature, FSINFO_STRUCT_SIGNATURE);
  245. setLe32(fsi->freeCount, 0XFFFFFFFF);
  246. setLe32(fsi->nextFree, 0XFFFFFFFF);
  247. if (!m_dev->writeSector(m_relativeSectors + 1, m_secBuf) ||
  248. !m_dev->writeSector(m_relativeSectors + 7, m_secBuf)) {
  249. return false;
  250. }
  251. return initFatDir(32, 2*m_fatSize + m_sectorsPerCluster);
  252. }
  253. //------------------------------------------------------------------------------
  254. bool FatFormatter::writeMbr() {
  255. memset(m_secBuf, 0, BYTES_PER_SECTOR);
  256. MbrSector_t* mbr = reinterpret_cast<MbrSector_t*>(m_secBuf);
  257. #if USE_LBA_TO_CHS
  258. lbaToMbrChs(mbr->part->beginCHS, m_capacityMB, m_relativeSectors);
  259. lbaToMbrChs(mbr->part->endCHS, m_capacityMB,
  260. m_relativeSectors + m_totalSectors -1);
  261. #else // USE_LBA_TO_CHS
  262. mbr->part->beginCHS[0] = 1;
  263. mbr->part->beginCHS[1] = 1;
  264. mbr->part->beginCHS[2] = 0;
  265. mbr->part->endCHS[0] = 0XFE;
  266. mbr->part->endCHS[1] = 0XFF;
  267. mbr->part->endCHS[2] = 0XFF;
  268. #endif // USE_LBA_TO_CHS
  269. mbr->part->type = m_partType;
  270. setLe32(mbr->part->relativeSectors, m_relativeSectors);
  271. setLe32(mbr->part->totalSectors, m_totalSectors);
  272. setLe16(mbr->signature, MBR_SIGNATURE);
  273. return m_dev->writeSector(0, m_secBuf);
  274. }