Chris Giese
Homepage:
http://www.execpc.com/~geezer/
$Date: 2002/07/02 07:43:38 $
$Revision: 1.1.1.1 $
A discussion and comparison of various file systems
1. FAT filesystem
2. Layout of a FAT volume
3. FAT bootsector and BPB
4. FAT directory entries
5. The FAT
6. ext2 filesystem
7. ISO-9660 (CD-ROM) filesystem
8. Overview of common filesystems
9. Filesystem code snippets
10. Links
11. TO DO
FAT stands for File Allocation Table, the main feature of this filesystem. The FAT filesystem is associated with DOS and some versions of Windows. VFAT (virtual FAT) is FAT with long filenames.
Newly-purchased floppy disks advertised as 'formatted' usually contain a FAT12 filesystem.
| Figure 1 |
![]() |
A FAT volume contains:
The FAT boot sector contains:
Layout of FAT12/FAT16 bootsector with minimal BPB:
| Code listing 1 |
typedef unsigned char u8;
typedef unsigned short u16; /* Note: multi-byte values are little-endian */
typedef unsigned long u32;
struct fat_bootsector /* Warning: this struct must be packed */
{
u8 jump[3]; /* 16-bit JMP to boot code, or 8-bit JMP + NOP */
u8 oem_id[8]; /* e.g. 'MSWIN4.0' */
u16 bytes_per_sector; /* usu. =512 */
u8 sectors_per_cluster;
u16 num_boot_sectors; /* usu. =1 */
u8 num_fats; /* usu. =2 */
u16 num_root_dir_ents;
u16 total_sectors; /* 16-bit; 0 if num sectors > 65535 */
u8 media_ID_byte; /* usu. =0F0h */
u16 sectors_per_fat;
u16 sectors_per_track;
u16 heads;
u32 hidden_sectors; /* =LBA partition start */
u32 total_sectors_large;/* 32-bit; 0 if num sectors < 65536 */
u8 boot_code[474];
u8 magic[2]; /* 55h, 0AAh */
}; /* 512 bytes total */
|
FAT32 uses additional fields (xxx - todo)
FAT directory entries are 32 bytes long:
| Code listing 2 |
typedef unsigned char u8;
typedef unsigned short u16; /* Note: multi-byte values are little-endian */
typedef unsigned long u32;
struct fat_dirent /* Warning: this struct must be packed */
{
u8 name[8]; /* ALL-CAPS, pad right with spaces */
u8 ext[3]; /* ALL-CAPS, pad right with spaces */
u8 attrib; /* attribute byte */
u8 reserved; /* =0 */
u8 ctime_ms; /* file creation time, 10ms units */
u16 ctime; /* file creation time, in DOS format */
u16 cdate; /* file creation date, in DOS format */
u16 adate; /* DOS date of last file access */
u16 st_clust_msw; /* high 16 bits of starting cluster (FAT32) */
u16 mtime; /* DOS time of last file modification */
u16 mdate; /* DOS date of last file modification */
u16 st_clust; /* starting cluster */
u32 file_size; /* in bytes */
}; /* 32 bytes total */ |
DOS times and dates are stored in these formats:
| Code listing 3 |
struct dos_time /* Warning: this struct must be packed */
{
unsigned two_secs : 5; /* low 5 bits: 2-second increments */
unsigned minutes : 6; /* middle 6 bits: minutes */
unsigned hours : 5; /* high 5 bits: hours (0-23) */
}; /* 2 bytes total */
struct dos_date /* Warning: this struct must be packed */
{
unsigned date : 5; /* low 5 bits: date (1-31) */
unsigned month : 4; /* middle 4 bits: month (1-12) */
unsigned year : 7; /* high 7 bits: year - 1980 */
}; /* 2 bytes total */ |
The Attribute byte is similar to the file 'mode' under UNIX filesystems:
| Code listing 4 |
struct attrib /* Warning: this struct must be packed */
{
int read_only : 1; /* b0 */
int hidden : 1;
int system : 1;
int volume_label : 1;
int directory : 1;
int archive : 1;
int reserved : 2; /* b6, b7 */
}; /* 1 byte total */ |
FAT directory entries contain all metadata for a particular file. This is different from UNIX filesystems, which store metadata separately from the directory entries (in inodes). FAT directory entries are also used for disk volume labels and VFAT long filenames (xxx - todo).
Entries in the FAT can be 12 bits wide (FAT12), 16 bits wide (FAT16), or 32 bits wide (FAT32). FAT entries do not necessarily refer to disk sectors, but to clusters, which are groups of contiguous sectors. The number of sectors per cluster is always a power of 2. The FAT format used is determined solely by the number of clusters in the volume:
Used FAT entries form singly linked lists, indicating which clusters are used by each file or subdirectory. Some FAT entry values are special:
| FAT special value | FAT12 | FAT16 | FAT32 |
|---|---|---|---|
| Free cluster | 0 | 0 | 0 |
| Used cluster; pointer to next | 2-0FF4h | 2-0FFF4h | 2-0FFFFFF4h (28-bit) |
| Bad cluster | 0FF7h | 0FFF7h | 0FFFFFF7h (28-bit) |
| Used cluster; last in chain | 0FFFh | 0FFFFh | 0FFFFFFFh (28-bit) |
xxx - to do
http://mobius.sf.net/tutes/iso9660.txt
Thanks to Peter Montagner for information on Macintosh HFS+ filesystem.
| FAT12/16 (DOS) | VFAT (Win95), FAT32 (Win98) | NTFS | ext2 (Linux) | |
|---|---|---|---|---|
| Filename length | 8.3 | 255 | 255 | 255 |
| Path length | 80 | 260 | 32767 | |
| Illegal characters in filenames | (nul) " * + , . / : ; < = > ? [ \ ] | | (nul) " * / : < > ? \ | | (nul) / | |
| Legal characters in filenames |
(space) ! # $ % & ' ( ) - 0-9 @ A-Z ^ _ ` a-z { } ~ Leading . or space is illegal |
(space) ! # $ % & ' ( ) + , - . 0-9 ; = @ A-Z [ ] ^ _ ` a-z { } ~ Leading space ignored |
everything but (nul) / |
|
| Limit to number of root directory entries | YES | VFAT12/16: YES FAT32: no |
no | no ? |
| Maximum subdirectory depth | no | no | no ? | no |
| Directories sorted by name | NO | NO | ? | yes? |
| Block size | FAT12: 512 bytes-4K FAT16: 2K-32K |
4K-32K | 512 bytes-64K | 1K- |
| Character set | UCS-2 Unicode | UCS-2 Unicode | Undefined; can be ASCII, Latin-1, UTF-8 Unicode, etc. | |
| Endian | little | little | ? | little |
| ISO9660 (CD-ROM) | Joliet | Mac HFS+ | ||
|---|---|---|---|---|
| Filename length | Level 1: 8.3 files, 8 for subdirectories Level 2/3: 31 |
64 | 255 | |
| Path length | ||||
| Illegal characters in filenames |
(nul) (space) ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ ` { | } ~ Extension with directory name is not allowed |
(nul) : | ||
| Legal characters in filenames | 0-9 A-Z _ | everything but (nul) : |
||
| Limit to number of root directory entries | no ? | no | no | |
| Maximum subdirectory depth | 8 | no | ||
| Directories sorted by name | yes | yes | ||
| Block size | 2K | 2K ? | ||
| Character set | ASCII | UCS-2 Unicode | UCS-2 Unicode | |
| Endian | Big AND little (committee invention :) | big |
| Code listing 5: Illegal characters in filenames |
#include <sys/stat.h>
#include <stdio.h>
#if defined(__TURBOC__)
#include <io.h>
#elif defined(__GNUC__)
#include <unistd.h>
#include <fcntl.h>
#endif
/*****************************************************************************
*****************************************************************************/
int main(void)
{
char buf[16];
int i, j;
printf("These characters are illegal for file names:\n");
for(i = ' '; i < 256; i++)
{
sprintf(buf, "%c", i);
j = creat(buf, S_IWRITE);
if(j >= 0)
{
close(j);
unlink(buf);
}
else
printf("%c (0x%02X) ", i, i);
}
printf("\n");
return 0;
}
|
Check disk for FAT filesystem, display info
Check disk for ext2 filesystem, display info
Information on FAT12/FAT16 (DOS) filesystems:
Information on ext2fs (Linux filesystem):