FAT12/16/32 filesystem on Eio block devices, in pure OCaml
0

Configure Feed

Select the types of activity you want to include in your feed.

ocaml-fat / README.md
3.4 kB

fat#

Warning. This is a work-in-progress experimental fork of ocaml-fat. Do not use it in production; use ocaml-fat instead.

FAT12/FAT16/FAT32 filesystem on Eio block devices, in pure OCaml.

Overview#

nox-fat reads and writes FAT disk images that interoperate with mtools, dosfstools, Linux and Windows. The on-disk structures — the boot sector, the file allocation table and the 8.3 / long-filename directory entries — are described once with the wire combinator library and decoded and encoded through bytesrw. The filesystem itself runs on top of the block Eio device abstraction, so it works against in-memory disks, files, or any other block backend.

It is a descendant of mirage/ocaml-fat, ported from Lwt + cstruct + mirage-block to Eio + wire + block, with FAT12 support added.

Features#

  • Read and write files and directories on FAT12, FAT16 and FAT32 volumes.
  • Format fresh FAT12 and FAT16 volumes.
  • All on-disk structures expressed as wire codecs — no hand-rolled byte twiddling.
  • Direct-style Eio I/O over the block abstraction (in-memory, file, ...).
  • Interoperates with dosfstools and mtools (verified by interop tests).

Installation#

opam install nox-fat

If the package is not yet in the default repositories, add the overlay:

opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
opam install nox-fat

Usage#

Format an in-memory volume, then create, write and read a file:

let () =
  let blk = Block.of_memory ~sector_size:512 ~sectors:32768L in
  let t = Result.get_ok (Fat.Fs.format blk (Int64.mul 16L 1048576L)) in
  assert (Fat.Fs.file t "/HELLO.TXT" = Ok ());
  assert (Fat.Fs.write t "/HELLO.TXT" 0 "Hello, FAT world!" = Ok ());
  assert (Fat.Fs.mkdir t "/SUB" = Ok ());
  assert (Fat.Fs.file t "/SUB/INNER.DAT" = Ok ());
  assert (Fat.Fs.write t "/SUB/INNER.DAT" 0 "nested" = Ok ());
  assert (Fat.Fs.read t "/HELLO.TXT" 0 5 = Ok "Hello");
  assert (Fat.Fs.listdir t "/" = Ok [ "SUB"; "HELLO.TXT" ])

Mount an existing image read-only and list its root directory:

let mount_and_list bytes =
  let blk = Block.of_string ~sector_size:512 bytes in
  match Fat.Fs.connect blk with
  | Ok t -> Fat.Fs.listdir t "/"
  | Error msg -> failwith msg

Command line#

The fat executable inspects images produced by any FAT implementation:

fat info disk.img        # boot sector geometry and FAT variant
fat ls disk.img /        # list a directory
fat cat disk.img /A.TXT  # write a file's contents to stdout

API#

  • Fat.Fs — the filesystem: connect, format, read, write, create, mkdir, destroy, stat, listdir.
  • Fat.Boot_sector — the boot sector / BIOS parameter block codec.
  • Fat.Entry — FAT12/16/32 entry codec and cluster chains.
  • Fat.Name — 8.3 and long-filename directory entries.
  • Fat.Format, Fat.Path, Fat.Sector_map, Fat.Update — supporting types.

References#

  • Microsoft, FAT: General Overview of On-Disk Format.
  • ECMA-107, Volume and File Structure of Disk Cartridges for Information Interchange.

Licence#

ISC. See LICENSE.