This project provides two ways to work with FAT12 images:
fat12tool: interactive command shell for direct FAT12 read/write operations.fat12mount: filesystem driver that mounts a FAT12 image to a regular directory so any application can use it.
The code is split into:
fat12_core.c/.h: portable FAT12 engine (allocation, directory operations, file IO).fat12tool.c: interactive shell frontend.fat12mount.c,vfs_ops.h,vfs_fuse.c,vfs_winfsp.c: cross-platform mounting via FUSE (Linux/macOS) or WinFSP (Windows).
- Read/write FAT12 files and directories
- Create/remove files and directories
- Truncate files
- Persist metadata updates (write/access timestamps)
- Preserve file attributes (timestamps, read-only, hidden) on host-image roundtrips
- Open FAT12 at offset
0(partition image) or at MBR partition offset (--partition N) - Cross-platform: works on Linux, macOS, and Windows
- FAT12 only (not FAT16/FAT32/exFAT)
- 8.3 short filenames only (no long filename/LFN support)
- No journaling/crash recovery
- Root directory expansion is limited by FAT12 root entry table constraints
renamein mounting mode is implemented as copy+unlink for files, and directories are currently not supported for rename
makeInstall FUSE dependencies if needed:
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y libfuse3-dev fuse3 pkg-config
# Fedora
sudo dnf install -y fuse3-devel fuse3 pkgconf-pkg-configmakeInstall FUSE-T:
- Install FUSE-T (Homebrew cask
macos-fuse-t/homebrew-cask/fuse-t). - Ensure FUSE headers are available (
/usr/local/include/fuse/fuse.h) andlibfuse-tis present (/usr/local/lib/libfuse-t.dylib).
- Install WinFSP: Download the installer from the official website.
- Important: During installation, ensure you tick the "Developer" section (it is unticked by default). This is absolutely essential as it contains the header files required for the build.
- Configure PATH: The WinFSP installer does not automatically add its binary directory to your system
PATH. You must manually addC:\Program Files (x86)\WinFSP\bin(or your custom install path) to your environment variables. This is essential for the application to loadwinfsp-x64.dllat runtime. - Install make via Scoop:
scoop install make- Install MinGW-w64 via Scoop:
scoop install mingw- Build:
make fat12mount.exeTo create a new blank FAT12 image, use the provided Python script (defaults to 1.44MB):
# Create standard 1.44MB image
python3 scripts/create_fat12.py floppy.img
# Create a 10MB image
python3 scripts/create_fat12.py large.img 10240Note: FAT12 is technically limited to < 4085 clusters. The script automatically adjusts sectors per cluster to accommodate larger sizes (up to ~128MB with 64 sectors per cluster).
Alternatively, you can use system tools:
- macOS:
hdiutil create -size 1.44m -fs "MS-DOS FAT12" -volname "MYFAT" myfat.img - Linux:
mkfs.fat -F 12 -C myfat.img 1440(requiresdosfstools)
./fat12tool sample-fat12-p1.imgCommands:
ls [path](displays entries with size, date and time)cd <path>pwdcat <path>read <img_path> <host_path>(preserves timestamps and read-only status)write <host_path> <img_path>(preserves timestamps, read-only status, and hidden status for dot-files)touch <path>mkdir <path>rm <path>rmdir <path>stat <path>(displays detailed metadata including attribute bits)verify [--full] [--fix] [--verbose] [--yes](check and repair filesystem integrity)helpexit
Example session:
fat12:/> ls
README.TXT 62 2026-03-09 00:02:12
HELLO.TXT 14 2026-03-09 00:02:12
TESTDIR <DIR> 0 2026-03-09 00:02:12
fat12:/> cat /README.TXT
fat12:/> write ./local.txt /LOCAL.TXT
fat12:/> mkdir /DOCS
fat12:/> read /LOCAL.TXT ./copy.txt
fat12:/> exit
The verify command performs comprehensive checks on FAT12 images and can repair common filesystem issues.
fat12:/> verify # Run basic integrity checks
fat12:/> verify --verbose # Show detailed error information
fat12:/> verify --fix # Attempt to fix detected issues
fat12:/> verify --fix --yes # Auto-confirm fixes (no prompts)
fat12:/> verify --full --verbose # Comprehensive check with details- FAT Consistency: Verifies all FAT copies are identical
- Cross-linked Clusters: Detects cycles in cluster allocation chains
- Orphaned Clusters: Finds allocated clusters not referenced by any directory
- Cluster Allocation Analysis: Counts free, allocated, and bad clusters
- Root Directory Validation: Checks root directory entry limits
- FAT Inconsistencies: Synchronizes all FAT copies
- Cross-linked Clusters: Breaks cycles by marking shorter/unreferenced chains as bad
- Orphaned Clusters: Frees unreferenced clusters for reuse
- Automatic Backup: Creates timestamped backup before any repair
fat12:/> verify --verbose
Verifying FAT12 image integrity...
Verification Results:
FAT consistency: ✓ OK
Cross-linked clusters: ✗ 2 found
Orphaned clusters: ✓ None
Root directory: 15/224 entries (6.7%)
Free space: 124/2846 clusters (4.4%)
Total issues: 2
fat12:/> verify --fix
Verifying FAT12 image integrity...
✗ Found 2 cross-linked clusters
Proposed fixes:
• Fix 2 cross-linked clusters (mark shorter chains as bad)
• Create backup: sample.img.verify-backup-20260401-143022
Apply these fixes? [y/N]: y
Creating backup... ✓
Applying fixes...
✓ Fixed 2 cross-links
✓ All fixes applied successfully
--full: Perform comprehensive checks (currently always enabled)--fix: Attempt to repair detected issues--verbose: Show detailed progress and error information--yes: Auto-confirm fixes (use with--fix)
- Backup Creation: Automatic timestamped backup before any repair
- User Confirmation: Requires explicit confirmation before applying fixes (unless
--yesused) - Conservative Repair: Marks problematic clusters as bad (0xFF7) rather than freeing, allowing data recovery
- Memory Warnings: Alerts if verification may use significant memory (>50MB)
The mount point directory is created automatically (Windows) or must be created first (Linux/macOS). On all platforms, the directory is automatically removed after unmount.
# Windows: directory is created automatically
# Linux/macOS: create directory first
mkdir -p ./mnt
./fat12mount --image sample-fat12-p1.img --mount ./mntIn another shell:
ls -la ./mnt
cat ./mnt/README.TXT
echo "hello" > ./mnt/NEW.TXTmkdir -p ./mnt
./fat12mount --image sample-fat12-2part.img --partition 1 --mount ./mntUse --partition 2 for the second partition.
./fat12mount -u ./mntRun full tests:
make testBinary: fat12_core_test
Source: tests/test_fat12_core.c
Coverage includes:
- Open and stat root
- List root directory and validate fixture entries
- Read existing file contents
- Create new file
- Sparse write behaviour (
offset > file_sizezero-fills gap) - Truncate shrink behaviour
- Create/remove nested directories and files
- Proper error on
rmdirnon-empty directory - Timestamp update call
- Persistence across close/reopen
- Open FAT12 partition from MBR image offset and read expected content
Script: tests/test_cli.sh
Coverage includes:
- Launch
fat12tool pwd,ls,cattouch,write,readmkdir, nested file create/remove,rmdirstat- Host roundtrip verification for written/read file content
Provided fixtures:
sample-fat12-p1.img: standalone FAT12 partition imagesample-fat12-p2.img: standalone FAT12 partition imagesample-fat12-2part.img: MBR disk image with two FAT12 partitions
These include sample files for immediate testing.
If make prints:
Skipping fat12mount (FUSE not available in build environment).
Install FUSE development headers/libraries and rerun make.
- Confirm FUSE-T is installed (Homebrew cask
macos-fuse-t/homebrew-cask/fuse-t). - If prompted, allow access to Network Volumes in Privacy & Security.
- If
fat12mountexits immediately with SIGTRAP, double-check that your terminal app has Network Volumes permission. - Ensure the mountpoint directory exists and is writable.
- WinFSP Installation: Confirm WinFSP is installed. Download from https://winfsp.dev/.
- Missing Headers: Ensure you ticked the "Developer" section during WinFSP installation. Without it, the build will fail as headers like
winfsp/winfsp.hwon't be found. - Missing DLL: If the application fails to start with a "DLL not found" error, ensure
C:\Program Files (x86)\WinFSP\binis added to your systemPATH. This is essential for loadingwinfsp-x64.dll. - WinFSP Launcher: Confirm the "Launcher" component was included during installation. Run the installer as Administrator to ensure the WinFsp.Launcher service is registered.
- If you installed WinFSP without Administrator privileges, you can manually register the service:
sc create WinFsp.Launcher binPath= "C:\Program Files (x86)\WinFSP\bin\launcher-x64.exe" DisplayName= "WinFsp Launcher" start= demand sc start WinFsp.Launcher
- If unmount fails, check that no other applications are using the mounted volume.
Current implementation enforces FAT 8.3 names. Use names up to 8.3 format (NAME.TXT, DATA.BIN, etc.).
The FAT12 core is written to be embeddable and used by all frontends. If you add features (LFN, FAT16/32, better rename semantics), implement in fat12_core first, then expose via fat12tool and fat12mount.
The cross-platform mounting layer uses an abstraction via vfs_ops.h:
vfs_fuse.c: FUSE backend for Linux/macOSvfs_winfsp.c: WinFSP backend for Windows
This project is licensed under the 3-Clause BSD License. See the LICENSE file for details. Copyright (c) 2026, Vlad Shurupov.