UbixOS  2.0
fat_format.c
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 //-----------------------------------------------------------------------------
3 // FAT16/32 File IO Library
4 // V2.6
5 // Ultra-Embedded.com
6 // Copyright 2003 - 2012
7 //
8 // Email: admin@ultra-embedded.com
9 //
10 // License: GPL
11 // If you would like a version with a more permissive license for use in
12 // closed source commercial applications please contact me for details.
13 //-----------------------------------------------------------------------------
14 //
15 // This file is part of FAT File IO Library.
16 //
17 // FAT File IO Library is free software; you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation; either version 2 of the License, or
20 // (at your option) any later version.
21 //
22 // FAT File IO Library is distributed in the hope that it will be useful,
23 // but WITHOUT ANY WARRANTY; without even the implied warranty of
24 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 // GNU General Public License for more details.
26 //
27 // You should have received a copy of the GNU General Public License
28 // along with FAT File IO Library; if not, write to the Free Software
29 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 //-----------------------------------------------------------------------------
31 //-----------------------------------------------------------------------------
32 #include <string.h>
33 #include "fat_defs.h"
34 #include "fat_access.h"
35 #include "fat_table.h"
36 #include "fat_write.h"
37 #include "fat_string.h"
38 #include "fat_misc.h"
39 #include "fat_format.h"
40 
41 #if FATFS_INC_FORMAT_SUPPORT
42 
43 //-----------------------------------------------------------------------------
44 // Tables
45 //-----------------------------------------------------------------------------
47 {
50 };
51 
53 {
54  { 32680, 2}, // 16MB - 1K
55  { 262144, 4}, // 128MB - 2K
56  { 524288, 8}, // 256MB - 4K
57  { 1048576, 16}, // 512MB - 8K
58  { 2097152, 32}, // 1GB - 16K
59  { 4194304, 64}, // 2GB - 32K
60  { 8388608, 128},// 2GB - 64K [Warning only supported by Windows XP onwards]
61  { 0 , 0 } // Invalid
62 };
63 
65 {
66  { 532480, 1}, // 260MB - 512b
67  { 16777216, 8}, // 8GB - 4K
68  { 33554432, 16}, // 16GB - 8K
69  { 67108864, 32}, // 32GB - 16K
70  { 0xFFFFFFFF, 64},// >32GB - 32K
71  { 0 , 0 } // Invalid
72 };
73 
74 //-----------------------------------------------------------------------------
75 // fatfs_calc_cluster_size: Calculate what cluster size should be used
76 //-----------------------------------------------------------------------------
77 static uint8 fatfs_calc_cluster_size(uint32 sectors, int is_fat32)
78 {
79  int i;
80 
81  if (!is_fat32)
82  {
83  for (i=0; _cluster_size_table16[i].sectors_per_cluster != 0;i++)
86  }
87  else
88  {
89  for (i=0; _cluster_size_table32[i].sectors_per_cluster != 0;i++)
92  }
93 
94  return 0;
95 }
96 //-----------------------------------------------------------------------------
97 // fatfs_erase_sectors: Erase a number of sectors
98 //-----------------------------------------------------------------------------
99 static int fatfs_erase_sectors(struct fatfs *fs, uint32 lba, int count)
100 {
101  int i;
102 
103  // Zero sector first
104  memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE);
105 
106  for (i=0;i<count;i++)
107  if (!fs->disk_io.write_media(lba + i, fs->currentsector.sector, 1))
108  return 0;
109 
110  return 1;
111 }
112 //-----------------------------------------------------------------------------
113 // fatfs_create_boot_sector: Create the boot sector
114 //-----------------------------------------------------------------------------
115 static int fatfs_create_boot_sector(struct fatfs *fs, uint32 boot_sector_lba, uint32 vol_sectors, const char *name, int is_fat32)
116 {
117  uint32 total_clusters;
118  int i;
119 
120  // Zero sector initially
121  memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE);
122 
123  // OEM Name & Jump Code
124  fs->currentsector.sector[0] = 0xEB;
125  fs->currentsector.sector[1] = 0x3C;
126  fs->currentsector.sector[2] = 0x90;
127  fs->currentsector.sector[3] = 0x4D;
128  fs->currentsector.sector[4] = 0x53;
129  fs->currentsector.sector[5] = 0x44;
130  fs->currentsector.sector[6] = 0x4F;
131  fs->currentsector.sector[7] = 0x53;
132  fs->currentsector.sector[8] = 0x35;
133  fs->currentsector.sector[9] = 0x2E;
134  fs->currentsector.sector[10] = 0x30;
135 
136  // Bytes per sector
137  fs->currentsector.sector[11] = (FAT_SECTOR_SIZE >> 0) & 0xFF;
138  fs->currentsector.sector[12] = (FAT_SECTOR_SIZE >> 8) & 0xFF;
139 
140  // Get sectors per cluster size for the disk
141  fs->sectors_per_cluster = fatfs_calc_cluster_size(vol_sectors, is_fat32);
142  if (!fs->sectors_per_cluster)
143  return 0; // Invalid disk size
144 
145  // Sectors per cluster
146  fs->currentsector.sector[13] = fs->sectors_per_cluster;
147 
148  // Reserved Sectors
149  if (!is_fat32)
150  fs->reserved_sectors = 8;
151  else
152  fs->reserved_sectors = 32;
153  fs->currentsector.sector[14] = (fs->reserved_sectors >> 0) & 0xFF;
154  fs->currentsector.sector[15] = (fs->reserved_sectors >> 8) & 0xFF;
155 
156  // Number of FATS
157  fs->num_of_fats = 2;
158  fs->currentsector.sector[16] = fs->num_of_fats;
159 
160  // Max entries in root dir (FAT16 only)
161  if (!is_fat32)
162  {
163  fs->root_entry_count = 512;
164  fs->currentsector.sector[17] = (fs->root_entry_count >> 0) & 0xFF;
165  fs->currentsector.sector[18] = (fs->root_entry_count >> 8) & 0xFF;
166  }
167  else
168  {
169  fs->root_entry_count = 0;
170  fs->currentsector.sector[17] = 0;
171  fs->currentsector.sector[18] = 0;
172  }
173 
174  // [FAT16] Total sectors (use FAT32 count instead)
175  fs->currentsector.sector[19] = 0x00;
176  fs->currentsector.sector[20] = 0x00;
177 
178  // Media type
179  fs->currentsector.sector[21] = 0xF8;
180 
181 
182  // FAT16 BS Details
183  if (!is_fat32)
184  {
185  // Count of sectors used by the FAT table (FAT16 only)
186  total_clusters = (vol_sectors / fs->sectors_per_cluster) + 1;
187  fs->fat_sectors = (total_clusters/(FAT_SECTOR_SIZE/2)) + 1;
188  fs->currentsector.sector[22] = (uint8)((fs->fat_sectors >> 0) & 0xFF);
189  fs->currentsector.sector[23] = (uint8)((fs->fat_sectors >> 8) & 0xFF);
190 
191  // Sectors per track
192  fs->currentsector.sector[24] = 0x00;
193  fs->currentsector.sector[25] = 0x00;
194 
195  // Heads
196  fs->currentsector.sector[26] = 0x00;
197  fs->currentsector.sector[27] = 0x00;
198 
199  // Hidden sectors
200  fs->currentsector.sector[28] = 0x20;
201  fs->currentsector.sector[29] = 0x00;
202  fs->currentsector.sector[30] = 0x00;
203  fs->currentsector.sector[31] = 0x00;
204 
205  // Total sectors for this volume
206  fs->currentsector.sector[32] = (uint8)((vol_sectors>>0)&0xFF);
207  fs->currentsector.sector[33] = (uint8)((vol_sectors>>8)&0xFF);
208  fs->currentsector.sector[34] = (uint8)((vol_sectors>>16)&0xFF);
209  fs->currentsector.sector[35] = (uint8)((vol_sectors>>24)&0xFF);
210 
211  // Drive number
212  fs->currentsector.sector[36] = 0x00;
213 
214  // Reserved
215  fs->currentsector.sector[37] = 0x00;
216 
217  // Boot signature
218  fs->currentsector.sector[38] = 0x29;
219 
220  // Volume ID
221  fs->currentsector.sector[39] = 0x12;
222  fs->currentsector.sector[40] = 0x34;
223  fs->currentsector.sector[41] = 0x56;
224  fs->currentsector.sector[42] = 0x78;
225 
226  // Volume name
227  for (i=0;i<11;i++)
228  {
229  if (i < (int)strlen(name))
230  fs->currentsector.sector[i+43] = name[i];
231  else
232  fs->currentsector.sector[i+43] = ' ';
233  }
234 
235  // File sys type
236  fs->currentsector.sector[54] = 'F';
237  fs->currentsector.sector[55] = 'A';
238  fs->currentsector.sector[56] = 'T';
239  fs->currentsector.sector[57] = '1';
240  fs->currentsector.sector[58] = '6';
241  fs->currentsector.sector[59] = ' ';
242  fs->currentsector.sector[60] = ' ';
243  fs->currentsector.sector[61] = ' ';
244 
245  // Signature
246  fs->currentsector.sector[510] = 0x55;
247  fs->currentsector.sector[511] = 0xAA;
248  }
249  // FAT32 BS Details
250  else
251  {
252  // Count of sectors used by the FAT table (FAT16 only)
253  fs->currentsector.sector[22] = 0;
254  fs->currentsector.sector[23] = 0;
255 
256  // Sectors per track (default)
257  fs->currentsector.sector[24] = 0x3F;
258  fs->currentsector.sector[25] = 0x00;
259 
260  // Heads (default)
261  fs->currentsector.sector[26] = 0xFF;
262  fs->currentsector.sector[27] = 0x00;
263 
264  // Hidden sectors
265  fs->currentsector.sector[28] = 0x00;
266  fs->currentsector.sector[29] = 0x00;
267  fs->currentsector.sector[30] = 0x00;
268  fs->currentsector.sector[31] = 0x00;
269 
270  // Total sectors for this volume
271  fs->currentsector.sector[32] = (uint8)((vol_sectors>>0)&0xFF);
272  fs->currentsector.sector[33] = (uint8)((vol_sectors>>8)&0xFF);
273  fs->currentsector.sector[34] = (uint8)((vol_sectors>>16)&0xFF);
274  fs->currentsector.sector[35] = (uint8)((vol_sectors>>24)&0xFF);
275 
276  total_clusters = (vol_sectors / fs->sectors_per_cluster) + 1;
277  fs->fat_sectors = (total_clusters/(FAT_SECTOR_SIZE/4)) + 1;
278 
279  // BPB_FATSz32
280  fs->currentsector.sector[36] = (uint8)((fs->fat_sectors>>0)&0xFF);
281  fs->currentsector.sector[37] = (uint8)((fs->fat_sectors>>8)&0xFF);
282  fs->currentsector.sector[38] = (uint8)((fs->fat_sectors>>16)&0xFF);
283  fs->currentsector.sector[39] = (uint8)((fs->fat_sectors>>24)&0xFF);
284 
285  // BPB_ExtFlags
286  fs->currentsector.sector[40] = 0;
287  fs->currentsector.sector[41] = 0;
288 
289  // BPB_FSVer
290  fs->currentsector.sector[42] = 0;
291  fs->currentsector.sector[43] = 0;
292 
293  // BPB_RootClus
294  fs->currentsector.sector[44] = (uint8)((fs->rootdir_first_cluster>>0)&0xFF);
295  fs->currentsector.sector[45] = (uint8)((fs->rootdir_first_cluster>>8)&0xFF);
296  fs->currentsector.sector[46] = (uint8)((fs->rootdir_first_cluster>>16)&0xFF);
297  fs->currentsector.sector[47] = (uint8)((fs->rootdir_first_cluster>>24)&0xFF);
298 
299  // BPB_FSInfo
300  fs->currentsector.sector[48] = (uint8)((fs->fs_info_sector>>0)&0xFF);
301  fs->currentsector.sector[49] = (uint8)((fs->fs_info_sector>>8)&0xFF);
302 
303  // BPB_BkBootSec
304  fs->currentsector.sector[50] = 6;
305  fs->currentsector.sector[51] = 0;
306 
307  // Drive number
308  fs->currentsector.sector[64] = 0x00;
309 
310  // Boot signature
311  fs->currentsector.sector[66] = 0x29;
312 
313  // Volume ID
314  fs->currentsector.sector[67] = 0x12;
315  fs->currentsector.sector[68] = 0x34;
316  fs->currentsector.sector[69] = 0x56;
317  fs->currentsector.sector[70] = 0x78;
318 
319  // Volume name
320  for (i=0;i<11;i++)
321  {
322  if (i < (int)strlen(name))
323  fs->currentsector.sector[i+71] = name[i];
324  else
325  fs->currentsector.sector[i+71] = ' ';
326  }
327 
328  // File sys type
329  fs->currentsector.sector[82] = 'F';
330  fs->currentsector.sector[83] = 'A';
331  fs->currentsector.sector[84] = 'T';
332  fs->currentsector.sector[85] = '3';
333  fs->currentsector.sector[86] = '2';
334  fs->currentsector.sector[87] = ' ';
335  fs->currentsector.sector[88] = ' ';
336  fs->currentsector.sector[89] = ' ';
337 
338  // Signature
339  fs->currentsector.sector[510] = 0x55;
340  fs->currentsector.sector[511] = 0xAA;
341  }
342 
343  if (fs->disk_io.write_media(boot_sector_lba, fs->currentsector.sector, 1))
344  return 1;
345  else
346  return 0;
347 }
348 //-----------------------------------------------------------------------------
349 // fatfs_create_fsinfo_sector: Create the FSInfo sector (FAT32)
350 //-----------------------------------------------------------------------------
351 static int fatfs_create_fsinfo_sector(struct fatfs *fs, uint32 sector_lba)
352 {
353  // Zero sector initially
354  memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE);
355 
356  // FSI_LeadSig
357  fs->currentsector.sector[0] = 0x52;
358  fs->currentsector.sector[1] = 0x52;
359  fs->currentsector.sector[2] = 0x61;
360  fs->currentsector.sector[3] = 0x41;
361 
362  // FSI_StrucSig
363  fs->currentsector.sector[484] = 0x72;
364  fs->currentsector.sector[485] = 0x72;
365  fs->currentsector.sector[486] = 0x41;
366  fs->currentsector.sector[487] = 0x61;
367 
368  // FSI_Free_Count
369  fs->currentsector.sector[488] = 0xFF;
370  fs->currentsector.sector[489] = 0xFF;
371  fs->currentsector.sector[490] = 0xFF;
372  fs->currentsector.sector[491] = 0xFF;
373 
374  // FSI_Nxt_Free
375  fs->currentsector.sector[492] = 0xFF;
376  fs->currentsector.sector[493] = 0xFF;
377  fs->currentsector.sector[494] = 0xFF;
378  fs->currentsector.sector[495] = 0xFF;
379 
380  // Signature
381  fs->currentsector.sector[510] = 0x55;
382  fs->currentsector.sector[511] = 0xAA;
383 
384  if (fs->disk_io.write_media(sector_lba, fs->currentsector.sector, 1))
385  return 1;
386  else
387  return 0;
388 }
389 //-----------------------------------------------------------------------------
390 // fatfs_erase_fat: Erase FAT table using fs details in fs struct
391 //-----------------------------------------------------------------------------
392 static int fatfs_erase_fat(struct fatfs *fs, int is_fat32)
393 {
394  uint32 i;
395 
396  // Zero sector initially
397  memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE);
398 
399  // Initialise default allocate / reserved clusters
400  if (!is_fat32)
401  {
402  SET_16BIT_WORD(fs->currentsector.sector, 0, 0xFFF8);
403  SET_16BIT_WORD(fs->currentsector.sector, 2, 0xFFFF);
404  }
405  else
406  {
407  SET_32BIT_WORD(fs->currentsector.sector, 0, 0x0FFFFFF8);
408  SET_32BIT_WORD(fs->currentsector.sector, 4, 0xFFFFFFFF);
409  SET_32BIT_WORD(fs->currentsector.sector, 8, 0x0FFFFFFF);
410  }
411 
412  if (!fs->disk_io.write_media(fs->fat_begin_lba + 0, fs->currentsector.sector, 1))
413  return 0;
414 
415  // Zero remaining FAT sectors
416  memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE);
417  for (i=1;i<fs->fat_sectors*fs->num_of_fats;i++)
418  if (!fs->disk_io.write_media(fs->fat_begin_lba + i, fs->currentsector.sector, 1))
419  return 0;
420 
421  return 1;
422 }
423 //-----------------------------------------------------------------------------
424 // fatfs_format_fat16: Format a FAT16 partition
425 //-----------------------------------------------------------------------------
426 int fatfs_format_fat16(struct fatfs *fs, uint32 volume_sectors, const char *name)
427 {
428  fs->currentsector.address = FAT32_INVALID_CLUSTER;
429  fs->currentsector.dirty = 0;
430 
431  fs->next_free_cluster = 0; // Invalid
432 
434 
435  // Make sure we have read + write functions
436  if (!fs->disk_io.read_media || !fs->disk_io.write_media)
438 
439  // Volume is FAT16
440  fs->fat_type = FAT_TYPE_16;
441 
442  // Not valid for FAT16
443  fs->fs_info_sector = 0;
444  fs->rootdir_first_cluster = 0;
445 
446  // Sector 0: Boot sector
447  // NOTE: We don't need an MBR, it is a waste of a good sector!
448  fs->lba_begin = 0;
449  if (!fatfs_create_boot_sector(fs, fs->lba_begin, volume_sectors, name, 0))
450  return 0;
451 
452  // For FAT16 (which this may be), rootdir_first_cluster is actuall rootdir_first_sector
453  fs->rootdir_first_sector = fs->reserved_sectors + (fs->num_of_fats * fs->fat_sectors);
454  fs->rootdir_sectors = ((fs->root_entry_count * 32) + (FAT_SECTOR_SIZE - 1)) / FAT_SECTOR_SIZE;
455 
456  // First FAT LBA address
457  fs->fat_begin_lba = fs->lba_begin + fs->reserved_sectors;
458 
459  // The address of the first data cluster on this volume
460  fs->cluster_begin_lba = fs->fat_begin_lba + (fs->num_of_fats * fs->fat_sectors);
461 
462  // Initialise FAT sectors
463  if (!fatfs_erase_fat(fs, 0))
464  return 0;
465 
466  // Erase Root directory
467  if (!fatfs_erase_sectors(fs, fs->lba_begin + fs->rootdir_first_sector, fs->rootdir_sectors))
468  return 0;
469 
470  return 1;
471 }
472 //-----------------------------------------------------------------------------
473 // fatfs_format_fat32: Format a FAT32 partition
474 //-----------------------------------------------------------------------------
475 int fatfs_format_fat32(struct fatfs *fs, uint32 volume_sectors, const char *name)
476 {
477  fs->currentsector.address = FAT32_INVALID_CLUSTER;
478  fs->currentsector.dirty = 0;
479 
480  fs->next_free_cluster = 0; // Invalid
481 
483 
484  // Make sure we have read + write functions
485  if (!fs->disk_io.read_media || !fs->disk_io.write_media)
487 
488  // Volume is FAT32
489  fs->fat_type = FAT_TYPE_32;
490 
491  // Basic defaults for normal FAT32 partitions
492  fs->fs_info_sector = 1;
493  fs->rootdir_first_cluster = 2;
494 
495  // Sector 0: Boot sector
496  // NOTE: We don't need an MBR, it is a waste of a good sector!
497  fs->lba_begin = 0;
498  if (!fatfs_create_boot_sector(fs, fs->lba_begin, volume_sectors, name, 1))
499  return 0;
500 
501  // First FAT LBA address
502  fs->fat_begin_lba = fs->lba_begin + fs->reserved_sectors;
503 
504  // The address of the first data cluster on this volume
505  fs->cluster_begin_lba = fs->fat_begin_lba + (fs->num_of_fats * fs->fat_sectors);
506 
507  // Initialise FSInfo sector
508  if (!fatfs_create_fsinfo_sector(fs, fs->fs_info_sector))
509  return 0;
510 
511  // Initialise FAT sectors
512  if (!fatfs_erase_fat(fs, 1))
513  return 0;
514 
515  // Erase Root directory
516  if (!fatfs_erase_sectors(fs, fatfs_lba_of_cluster(fs, fs->rootdir_first_cluster), fs->sectors_per_cluster))
517  return 0;
518 
519  return 1;
520 }
521 //-----------------------------------------------------------------------------
522 // fatfs_format: Format a partition with either FAT16 or FAT32 based on size
523 //-----------------------------------------------------------------------------
524 int fatfs_format(struct fatfs *fs, uint32 volume_sectors, const char *name)
525 {
526  // 2GB - 32K limit for safe behaviour for FAT16
527  if (volume_sectors <= 4194304)
528  return fatfs_format_fat16(fs, volume_sectors, name);
529  else
530  return fatfs_format_fat32(fs, volume_sectors, name);
531 }
532 #endif /*FATFS_INC_FORMAT_SUPPORT*/
FAT_TYPE_32
Definition: fat_access.h:54
fat_write.h
fat_access.h
FAT_INIT_MEDIA_ACCESS_ERROR
#define FAT_INIT_MEDIA_ACCESS_ERROR
Definition: fat_access.h:11
fat_table.h
uint8
unsigned char uint8
Definition: fat_types.h:15
string.h
fatfs_format_fat32
int fatfs_format_fat32(struct fatfs *fs, uint32 volume_sectors, const char *name)
Definition: fat_format.c:475
fatfs_format_fat16
int fatfs_format_fat16(struct fatfs *fs, uint32 volume_sectors, const char *name)
Definition: fat_format.c:426
strlen
int strlen(const char *str)
Definition: strlen.c:55
fat_defs.h
fs
Definition: fs.h:260
FAT_SECTOR_SIZE
#define FAT_SECTOR_SIZE
Definition: fat_opts.h:70
fat_misc.h
fatfs_lba_of_cluster
uint32 fatfs_lba_of_cluster(struct fatfs *fs, uint32 Cluster_Number)
Definition: fat_access.c:191
fat_string.h
SET_16BIT_WORD
#define SET_16BIT_WORD(buffer, location, value)
Definition: fat_misc.h:24
FAT32_INVALID_CLUSTER
#define FAT32_INVALID_CLUSTER
Definition: fat_defs.h:109
SET_32BIT_WORD
#define SET_32BIT_WORD(buffer, location, value)
Definition: fat_misc.h:19
name
const char * name
Definition: pci.c:37
_cluster_size_table16
struct sec_per_clus_table _cluster_size_table16[]
Definition: fat_format.c:52
memset
void * memset(void *dst, int c, size_t length)
fatfs_fat_init
void fatfs_fat_init(struct fatfs *fs)
Definition: fat_table.c:60
sec_per_clus_table::sectors
uint32 sectors
Definition: fat_format.c:48
uint32
unsigned long uint32
Definition: fat_types.h:23
fat_format.h
fatfs_format
int fatfs_format(struct fatfs *fs, uint32 volume_sectors, const char *name)
Definition: fat_format.c:524
FAT_TYPE_16
Definition: fat_access.h:53
sec_per_clus_table::sectors_per_cluster
uint8 sectors_per_cluster
Definition: fat_format.c:49
sec_per_clus_table
Definition: fat_format.c:46
_cluster_size_table32
struct sec_per_clus_table _cluster_size_table32[]
Definition: fat_format.c:64
fatfs
Definition: fat_access.h:57