stfs

st filesystem for embedded flash systems

OTHER License

Stars
12
Committers
4

stfs - simple tabular file system

this file system is meant for the embedded flash of cortex-m3
micro controller. I tried yaffs, but it used too much memory, and
since the cortex-M3 controller already handles the low level
stuff, is not really suited for this purpose. stfs uses no heap,
and is also otherwise as the name hints: simple.

stfs is a log-structured appending file system for embedded flash devices, that expose the flash mapped as memory.

  • assumes that you have only a few 4KB-128KB erasable blocks - all of the same size.

  • stfs provides only directories and files, but no other types like pipes, links, etc. also no file metadata like timestamps or access permissions.

  • filenames are max 32 bytes long, files max 64KB - both settings are configurable, but otherwise untested.

  • always reserves one empty block for vacuuming.

  • default chunksize is 128B with fs metadata included. unlike other flash file systems where the block size is usually limited by 512B.

  • totally single threaded

License

stfs is licensed LGPLV2.1+.

api

currently the api provides the following posix-like interfaces:

directory handling functions: mkdir, rmdir, opendir, readdir,

file handling functions: open, lseek, write, read, close, unlink, truncate

generic functions: init

how to play with it

1st of all this is a simulation, a toy. if you want to use it in
your micro controller you have to adapt a few things. like how you
write chunks and erase blocks. But you can play with it on your
computer. Compile everything with the makefile:

`CFLAGS="-DDEBUG_LEVEL=3" make all`

where the debug level can be:
   - 0 is quiet,
   - 1 - errors,
   - 2 - info,
   - 3 - debug.

if you want to fuzz, you probably want to go with level 0, when
you debug you can play with other levels.

after compiling, you get `stfs` and `afl`.

stfs test binary stfs demos how to use stfs, executes a few test cases and then dumps the whole fs into ./test.img.

afl afl is a simple script interpreter:

afl.c - reads stdin to execute script on in-RAM stfs and dump the result into test.img
commands are
m <path> - mkdir
x <path> - rmdir
o 0|64 <string> - open 64==O_CREAT
w <fd> <size> - write
r <fd> <size> - read
s <fd> <pos> <whence> - seek
c <fd> - close
t <size> <path> - truncate
d <path> - unlink

<path> is always length prefixed, space-separated, e.g.:
m 5 /root
    ^ path
  ^ length of path

./afl is also used by stfsfuzz.py, if you want to use it with afl,
you should compile without logging and dumping of the fs image.

you can find a few sample test cases in `testcases/`

python tools

there's two python tools: stfsfuzz.py and anaimg.py

stfsfuzz.py runs `afl` repeatedly each time testing a different
random command, if the command returns something else than -1, it
is recorded in ./fuzz.script and keep this command in the test
case for subsequent commands to be appended. in the background
`afl` always dumps the latest fs image into `test.img`

`anaimg.py` loads `test.img` and prints a condensed sequence of
the chunks, the directory layout with file sizes, and the block
statistics.

python deps

pip install construct sh

data structure

chunk_size = 128 chunks_per_block = 1024

4 different chunk types are used:

empty = 0xff (1B) irrelevant(all 0xff) (127B) inode (128B)- contain file meta information - chunktype (0xAA) (1B) - directory | file (1b) - size (2B) - parent_directory_obj_id (4B) - obj_id (4B) - name_len (6b) - name (32B) - data (84B) data (7B) - contain data - chunktype (0xCC) (1B) - seq_id (2B) - obj_id (4B) - data blob (chunksize-metasize) deleted = 0x00 (1B) irrelevant(all 0x00) (127B)

inode with oid 1 is the root directory and virtual

important implementation todo

In case you adapat this code, please replace the call to random(3) in stfs_init() and in vacuum() to the cryptographic random function of your system such as /dev/random or /dev/urandom on Unix-like systems, and CryptGenRandom on Windows.