diff --git a/lib/ff13/meson.build b/lib/ff13/meson.build
index 48a2634991bfaee9e3f3eee91409eba5dd8a7b48..6336bf286498c0b4e89c720cc2e0e8a78beb0fe6 100644
--- a/lib/ff13/meson.build
+++ b/lib/ff13/meson.build
@@ -1,5 +1,6 @@
 includes = include_directories(
   './Source/',
+  './util/',
 )
 
 sources = files(
@@ -7,6 +8,7 @@ sources = files(
   './Source/ff.c',
   './Source/ffsystem.c',
   './Source/ffunicode.c',
+  './util/fs_util.c',
 )
 
 lib = static_library(
diff --git a/lib/ff13/util/fs_util.c b/lib/ff13/util/fs_util.c
new file mode 100644
index 0000000000000000000000000000000000000000..54a9f6d48d56b61ef81ee9590d0215fc5daf61be
--- /dev/null
+++ b/lib/ff13/util/fs_util.c
@@ -0,0 +1,106 @@
+#include <fs_util.h>
+#include <ff.h>
+#include <stdint.h>
+#include <string.h>
+
+FATFS FatFs;          /* File system object for logical drive */
+FS_USAGE FsUsage;
+
+
+int fs_info(FATFS *fs)
+{
+    memcpy(fs, &FatFs, sizeof(FATFS));
+    return 0;
+}
+int fs_usage(FATFS *fs, FS_USAGE *fs_usage)
+{
+    FRESULT res;
+    DWORD tot_clust, fre_clust, sec_size;
+
+    res = f_getfree("/", &fre_clust, &fs);
+    if(res != FR_OK)
+        return -res;
+
+    // sectore size = sectors per cluster *  sector size
+#if FF_MAX_SS == FF_MIN_SS
+    sec_size = fs->csize * FF_MAX_SS;
+#else
+    sec_size = fs->csize * fs.ssize;
+#endif
+
+    // total/free sectors * sectore size
+    tot_clust = fs->n_fatent - 2;
+    fs_usage->total = tot_clust * sec_size; //FatFs.ssize;
+    fs_usage->free = fre_clust * sec_size; //FatFs.ssize;
+
+    return 0;
+}
+
+int fs_read_file(char * filename, void * data, int len){
+    FIL file;
+    UINT readbytes;
+    int res;
+
+    res=f_open(&file, filename, FA_OPEN_EXISTING|FA_READ);
+    if(res){
+        return -1;
+    };
+
+    res = f_read(&file, data, len, &readbytes);
+    if(res){
+        return -1;
+    };
+
+    f_close(&file);
+
+	return readbytes;
+}
+
+int fs_read_text_file(char * filename, char * data, int len){
+    int readbytes;
+
+    if(len<1) return -1;
+    readbytes=fs_read_file(filename,data,len-1);
+    if(readbytes<0){
+        data[0]=0;
+        return readbytes;
+    };
+    data[readbytes]=0;
+    while(readbytes>0 && data[readbytes-1]<0x20){
+        data[--readbytes]=0;
+    };
+    return readbytes;
+}
+
+
+int fs_write_file(char * filename, const void * data, int len){
+    FIL file;
+    UINT writebytes;
+    int res;
+
+	res=f_open(&file, filename, FA_CREATE_ALWAYS|FA_WRITE);
+    if(res){
+        return -res;
+    };
+
+    res = f_write(&file, data, len, &writebytes);
+    if(res){
+        return -res;
+    };
+    f_close(&file);
+
+	return writebytes;
+}
+
+int fs_get_file_size(char * filename){
+    FILINFO finfo;
+    int res;
+
+    /// XXX: Untested
+    res=f_stat(filename, &finfo);
+    if(res){
+        return -1;
+    }
+
+    return finfo.fsize;
+}
diff --git a/lib/ff13/util/fs_util.h b/lib/ff13/util/fs_util.h
new file mode 100644
index 0000000000000000000000000000000000000000..0d8bbeb46c0bb4f5144196a0fa5a71702b705c47
--- /dev/null
+++ b/lib/ff13/util/fs_util.h
@@ -0,0 +1,24 @@
+#ifndef _FS_UTIL_H
+#define _FS_UTIL_H 1
+
+#include <ff.h>
+
+#define FLEN 13
+
+typedef struct {
+    DWORD total;
+    DWORD free;
+} FS_USAGE;
+
+void fsInit(void);
+void fsReInit(void);
+
+int fsInfo(FATFS *fs);
+int fsUsage(FATFS *fs, FS_USAGE *fs_usage);
+int readFile(char * filename, void * data, int len);
+int readTextFile(char * filename, char * data, int len);
+int writeFile(char * filename, const void * data, int len);
+int getFileSize(char * filename);
+const char* f_get_rc_string (FRESULT rc);
+
+#endif /* _FS_UTIL_H */