Profile
Back to NewsBack
GitHub Trending 14 min
Reader Mode
reinauer/AmiFUSE: Native AMIGA filesystems on macOS / Linux / Windows with FUSE

reinauer/AmiFUSE: Native AMIGA filesystems on macOS / Linux / Windows with FUSE

7 hours ago

AmiFUSE

Mount Amiga filesystem images on macOS/Linux/Windows using native AmigaOS filesystem handlers via FUSE.

AmiFUSE runs actual Amiga filesystem drivers (like PFS3) through m68k CPU emulation, allowing you to read Amiga hard disk images without relying on reverse-engineered implementations.

!amifuse

Requirements

  • macOS: macFUSE 5.3.3 or newer
  • Linux: FUSE for Linux
  • Windows: WinFSP
  • Python 3.9+
  • 7z: Required for make unpack (install via brew install p7zip on macOS)
  • A filesystem handler: e.g. pfs3aio (or use make download)

Installation

Quick install (recommended)

The bootstrap scripts handle everything: Python, FUSE provider, virtual environment, pip dependencies, and amifuse doctor --fix.

# Clone the repository with submodules
git clone --recursive https://github.com/reinauer/AmiFUSE.git
cd AmiFUSE

Windows (PowerShell):

.\tools\install-windows.ps1

macOS / Linux:

./tools/install.sh

From source (for development)

Use this if you are contributing to the project or need a custom setup.

git clone --recursive https://github.com/reinauer/AmiFUSE.git
cd AmiFUSE

Or if already cloned, initialize submodules

git submodule update --init

python3 -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate

pip install -e './amitools[vamos]' # Install amitools from submodule (includes machine68k) pip install -e . # Install AmiFUSE pip install -e '.[windows]' # Windows only: adds pystray + Pillow for tray/shell integration

macOS-specific

Install macFUSE 5.3.3 or newer from https://osxfuse.github.io/ or via Homebrew/MacPorts. Earlier releases can crash because they initialize DiskArbitration and CoreFoundation state before daemonizing:

# Homebrew
brew install --cask macfuse

MacPorts

port install macfuse +fs_link

You may need to reboot and allow the kernel extension in System Preferences > Security & Privacy.

Linux-specific

# Debian/Ubuntu
sudo apt install fuse libfuse-dev

Fedora

sudo dnf install fuse fuse-devel

Running from source (without installing)

To run AmiFUSE directly from a local checkout (useful for development/debugging):

python3 -m amifuse mount disk.hdf

Quick Start

To download a test PFS3 disk image and the pfs3aio handler:

make download   # Downloads pfs.7z and pfs3aio to Downloads/
make unpack     # Extracts pfs.hdf and copies pfs3aio to current directory

Then mount with:

# macOS: auto-mounts to /Volumes/<partition_name>, uses embedded driver from RDB
amifuse mount pfs.hdf

Linux: requires explicit mountpoint

mkdir -p ./mnt amifuse mount pfs.hdf --mountpoint ./mnt

Stay attached to the terminal if you want Ctrl+C to unmount

amifuse mount pfs.hdf --interactive

To compare this checkout against ../amifuse-0.2 using the bundled pfs.hdf and pfs3aio, run:

make bench-pfs

This benchmark bypasses macFUSE and measures the handler startup time, a full recursive directory walk equivalent to find, and a small set of file reads. You can override the defaults with PFS_BENCH_BASELINE, PFS_BENCH_IMAGE, PFS_BENCH_DRIVER, and PFS_BENCH_REPEAT.

Usage

See shared disk sessions for image locking, ownership and device compatibility policies.

amifuse uses subcommands for different operations:

amifuse inspect <image>                    # Inspect RDB partitions
amifuse mount <image>                      # Mount a filesystem
amifuse unmount <mountpoint>               # Unmount a filesystem
amifuse doctor                             # Check dependencies and configuration
amifuse register                           # Add Windows Explorer context menu entries
amifuse unregister                         # Remove Windows Explorer context menu entries

Inspecting Disk Images

View partition information and embedded filesystem drivers:

# Show partition summary
amifuse inspect /path/to/disk.hdf

Show full partition details

amifuse inspect --full /path/to/disk.hdf

| Argument | Description | |----------|-------------| | image | Path to the RDB image file | | --block-size | Block size in bytes (default: auto-detect or 512) | | --full | Show full partition details |

Mounting Filesystems

amifuse mount /path/to/disk.hdf

| Argument | Required | Description | |----------|----------|-------------| | image | Yes | Path to the Amiga hard disk image file | | --driver | No | Path to filesystem handler binary (default: RDB, your drivers folder, then the bundled FastFileSystem for DOS0-5; see Bundled FastFileSystem) | | --mountpoint | macOS/Windows: No, Linux: Yes | Mount location (macOS: /Volumes/, Windows: first free drive letter) | | --partition | No | Partition name (e.g., DH0) or index (default: first partition) | | --block-size | No | Override block size (default: auto-detect or 512) | | --volname | No | Override the volume name shown in Finder | | --daemon | No | Detach after mounting (default on macOS/Linux) | | --interactive / --foreground | No | Stay attached to the terminal; Ctrl+C unmounts | | --debug | No | Enable debug logging of FUSE operations | | --profile | No | Enable cProfile profiling and write stats to profile.txt on exit | | --write | No | Enable read-write mode (experimental, use with caution) | | --icons | No | Convert Amiga .info icons to native icons (experimental, macOS only) |

Mount lifecycle:

  • macOS and Linux default to daemon mode. The mount keeps running after the
command returns, and you normally tear it down with amifuse unmount .
  • --interactive / --foreground keeps AmiFUSE attached to the terminal.
Use this for debugging or when you want Ctrl+C to unmount from the same shell.
  • Windows defaults to daemon mode. Double-click .hdf/.adf files to mount
and open Explorer (requires amifuse register). Unmount from the system tray icon or with amifuse unmount :. The WinFSP "Eject" action does not perform a clean unmount — use the tray or CLI instead.
  • --profile implies interactive mode.

Physical disks on Windows

With WinFsp installed, AmiFUSE can open a USB CF/SD card or other physical disk directly using its \\.\PhysicalDriveN device name. Open **PowerShell as Administrator**, then identify the disk by its name and size:

Get-Disk | Format-Table Number, FriendlyName, BusType, Size

Find the CF card by its FriendlyName, USB bus type, and Size. The Number column determines the device path: disk 2 is \\.\PhysicalDrive2, disk 3 is \\.\PhysicalDrive3, and so on. If you are unsure which disk is the card, compare the command's output with the reader unplugged and then plugged in, before mounting it.

For example, if the CF card is disk 2, inspect its Amiga partitions and mount DH0 at an unused drive letter:

amifuse inspect '\\.\PhysicalDrive2'
amifuse mount '\\.\PhysicalDrive2' --partition DH0 --mountpoint R:
amifuse unmount R:

The single quotes are PowerShell quoting; they are not part of the device name.

Elevated drive-letter mounts use the Windows mount manager, making R: visible in normal Explorer windows and unelevated applications. This also applies to image files mounted from an Administrator shell. Ordinary unelevated image mounts keep their existing per-session drive letters. You can explicitly request the global form with --mountpoint '\\.\R:'; this requires Administrator privileges. Both forms refer to the same drive for amifuse unmount.

The drive letter must be unused in both the Administrator shell and the normal desktop session. An elevated process cannot detect drive mappings that exist only in the normal session, such as network or subst drives; those mappings take precedence over a global drive with the same letter in that session, so Explorer would continue to show the existing drive.

Run amifuse unmount R: from an Administrator shell for an elevated mount. The normal desktop tray cannot reliably discover or unmount elevated mounts, even though Explorer can access their files. Global visibility does not change file permissions or grant the tray access to elevated control events.

On Windows, the mount root grants write access only to the mounting account. If you elevate using a different administrator account, your normal desktop account can read and list the mounted files but does not gain root write access.

Mounts are read-only by default. To enable writes to the card itself:

amifuse mount '\\.\PhysicalDrive2' --partition DH0 --mountpoint R: --write

Use the actual disk number and partition name from the commands above. Cancel any Windows prompt to initialize or format the Amiga disk.

AmiFUSE holds a global Windows process lock for the physical disk until its last stream closes. This excludes other AmiFUSE/vamos sessions even when a disk driver does not enforce exclusive handle sharing. It does not exclude unrelated raw-disk tools. Writable mounts also lock and dismount Windows volumes identified on that disk; close applications using those volumes first. If a required lock fails, the mount fails before AmiFUSE writes to the disk. Before unplugging the card, run amifuse unmount R: from an Administrator shell. This requests WinFsp shutdown and waits for handler flushing and disk cleanup. A timeout or flush failure is reported as an error; the unmount request never falls back to force-killing the process. Check the mount log and wait for a successful unmount before removing the card. No extra pywin32 dependency is required.

When running this change from source, install the accompanying amitools checkout as well as AmiFUSE into your Python environment:

python -m pip install -e './amitools[vamos]'
python -m pip install -e '.[windows]'

The published amitools-amifuse 0.8.0.post10 dependency includes physical-disk support and partition range locks; the source installation above is only needed to test unreleased amitools changes.

Diagnosing Issues

amifuse doctor checks that all dependencies (Python, FUSE provider, handlers) are correctly installed and configured.

amifuse doctor            # Human-readable report
amifuse doctor --json     # Machine-readable JSON output
amifuse doctor --fix      # Auto-fix what it can (PATH, shell registration)

Examples

# macOS: Mount using embedded filesystem driver from RDB (simplest)
amifuse mount disk.hdf

macOS: Mount with explicit driver

amifuse mount pfs.hdf --driver pfs3aio

Mount a specific partition by name

amifuse mount multi-partition.hdf --partition DH0

Mount a specific partition by index

amifuse mount multi-partition.hdf --partition 2

Linux: Explicit mountpoint required

mkdir -p ./mnt amifuse mount disk.hdf --mountpoint ./mnt

Mount an ADF floppy image (uses the bundled FastFileSystem for DOS0-5)

amifuse mount workbench.adf

Enable native icons (macOS only, converts Amiga .info files)

amifuse mount disk.hdf --icons

Keep the mount attached for debugging

amifuse mount disk.hdf --interactive

Browse the filesystem

ls /Volumes/PDH0 # macOS ls ./mnt # Linux

Unmount a daemon mount when done

amifuse unmount /Volumes/PDH0 # macOS amifuse unmount ./mnt # Linux

Different, nonoverlapping RDB partitions in one image can be mounted in separate sessions concurrently, including with --write. Read-only sessions can also share the same partition. A writable session excludes all other access to its partition, and whole-image sessions exclude partition mounts. Each handler is restricted to its selected partition; physical disks, ADFs, and ISOs retain whole-device or whole-image locking.

Without --partition, a session uses the first partition, so it can run alongside sessions on other partitions. Whole-image sessions are ADF, ISO and physical-disk sessions, and sessions from tools that lock the entire file. On platforms without byte-range locks (for example 32-bit Linux and the BSDs), every session locks the whole image.

Additional Tools

rdb-inspect

Inspect RDB (Rigid Disk Block) images to view partition information and embedded filesystem drivers.

# Show partition summary
rdb-inspect /path/to/disk.hdf

Show full partition details

rdb-inspect --full /path/to/disk.hdf

Output as JSON

rdb-inspect --json /path/to/disk.hdf

Extract embedded filesystem driver #0 to a file

rdb-inspect --extract-fs 0 --out pfs3.bin /path/to/disk.hdf

| Argument | Description | |----------|-------------| | image | Path to the RDB image file | | --block-size | Block size in bytes (default: auto-detect or 512) | | --full | Show full partition details | | --json | Output parsed RDB as JSON | | --extract-fs N | Extract filesystem entry N (0-based) to a file | | --out | Output path for extracted filesystem (default: auto-derived) |

driver-info

Inspect Amiga filesystem handler binaries to verify they can be relocated and display segment information.

# Inspect a filesystem handler
driver-info pfs3aio

Use a custom base address

driver-info --base 0x200000 pfs3aio

| Argument | Description | |----------|-------------| | binary | Path to the filesystem handler binary | | --base | Base address for relocation (default: 0x100000) | | --padding | Padding between segments when relocating |

Supported Image Formats

  • HDF/RDB - Hard disk images with Rigid Disk Block. Filesystem drivers can be embedded in the RDB or specified via --driver. An FFS/OFS partition whose RDB has no driver for its DOS type uses the bundled FastFileSystem.
  • Emu68-style MBR images - Disk images with MBR partition table containing an RDB partition, as used by Emu68 on Raspberry Pi.
  • ADF - Amiga Disk File floppy images (DD and HD). ADFs contain no driver, so DOS0-5 floppies use the bundled FastFileSystem; DOS6/7 floppies need your own FastFileSystem or --driver.

Supported Filesystems

Currently tested with:

  • FFS/OFS (Fast/Old File System) via the bundled FastFileSystem for DOS0-5, or your own L:FastFileSystem from Workbench (tested with 3.2), which also serves DOS6/7 and wins when present
  • CDFileSystem via L:CDFileSystem from Workbench (tested with 3.2)
  • PFS3 (Professional File System 3) via pfs3aio handler
  • SFS (Smart File System 1.279) via SmartFileSystem handler
  • BFFS (Berkeley Fast File System) via Chris Hooper's BFFSFilesystem handler
  • ODFileSystem (Optical Disc Filesystem) via Stefan Reinauer's ODFileSystem handler
Other Amiga filesystem handlers may work but have not been tested. Reports are welcome.

Bundled FastFileSystem

AmiFUSE ships Stefan Reinauer's FastFileSystem (release alpha1, an early version) for FFS/OFS volumes that carry no driver of their own. It supports DOS0-DOS5; DOS6/DOS7 (long file names) need another FFS.

Without --driver, AmiFUSE picks the driver in this order:

  1. The driver in the RDB for the partition's exact DOS type. If that driver is
damaged, AmiFUSE stops and asks for --driver instead of using another. It also stops when part of the RDB's driver list is unreadable and may hide the partition's driver. A driver the RDB holds for a different DOS type is not used, as on an Amiga, where the FFS in ROM then serves the partition.
  1. FastFileSystem in your drivers folder (%LOCALAPPDATA%\amifuse\drivers on
Windows, ~/.local/share/amifuse/drivers elsewhere), for DOS0-DOS7. Place the one from AmigaOS 3.2 there to use it instead of the bundled one, or to mount DOS6/DOS7 volumes.
  1. The bundled FastFileSystem, for DOS0-DOS5.
  2. In a development checkout, ../AmiFUSE-testing/drivers/FastFileSystem.
The mount banner, amifuse doctor and amifuse inspect name the driver in use; inspect names it for an ADF and for each partition of a hard disk image.

The handler ships in amifuse/drivers/ as the release asset FastFileSystem.OS3, unchanged, with its licence (FastFileSystem.OS3.LICENSE, BSD-2-Clause) and provenance (FastFileSystem.OS3.json: repository, tag, commit, size, sha256, covered DOS types and the build). To move to a new release, replace the asset and the licence, and update the provenance file; the unit tests check that the three agree. Messages from doctor, inspect and failed mounts take the covered DOS types from the provenance file. If dos_types changes, also update the ranges written out in the --driver help in amifuse/fuse_fs.py and in this README (the --driver row, the ADF example, Supported Image Formats, Supported Filesystems and this section); the unit tests check them against the provenance file.

Icon Support

The --icons flag enables conversion of Amiga .info icon files to native Finder icons:

  • Folder and file icons from .info files are displayed in Finder
  • Supports Traditional, NewIcons, and GlowIcons formats
  • The .info files are hidden in directory listings
  • Volume icons are displayed on the Desktop
This feature is experimental and macOS-only.

Windows Shell Integration

On Windows, AmiFUSE can integrate with Explorer for double-click mounting, right-click context menus, and a system tray mount manager.

Context menu registration

amifuse register      # Add "Mount with AmiFUSE" to .hdf/.adf context menus
amifuse unregister    # Remove the context menu entries

Registration writes to HKCU (current user only) — no administrator privileges are required.

After registering:

  • Double-click an .hdf or .adf file to mount it and open Explorer at the
mounted drive
  • Right-click for "Mount with AmiFUSE" (read-only) or "Mount Read-Write with
AmiFUSE"

Tray mount manager

When a filesystem is mounted in daemon mode on Windows, the amifuse-tray helper appears in the system tray. From the tray icon you can see active mounts and unmount them cleanly. Each mount shows its drive letter, image name, and provides Inspect/Unmount actions.

The tray requires optional dependencies: install them with pip install amifuse[windows] (provides pystray and Pillow).

Removing shell integration

amifuse unregister

Or use the installer's uninstall mode:

.\tools\install-windows.ps1 -Uninstall

Notes

  • The filesystem is mounted read-only by default; use --write for experimental read-write support
  • macOS and Linux default to daemon mode; use --interactive if you want
Ctrl+C to unmount from the same terminal
  • Use amifuse unmount to tear down daemon mounts
  • Windows defaults to daemon mode; unmount via the system tray icon or
amifuse unmount
  • macOS Finder/Spotlight indexing is automatically disabled to improve performance
  • First directory traversal may be slow as the handler processes each path; subsequent accesses are cached
Chat with me