diff --git a/components/badge23/espan.c b/components/badge23/espan.c
index f6a41e8a83aa717a721bdbaf216bd7833588b1a4..b493d818bbe0a1838206cec6f489e815640a56a9 100644
--- a/components/badge23/espan.c
+++ b/components/badge23/espan.c
@@ -6,6 +6,7 @@
 
 #include "flow3r_bsp.h"
 #include "st3m_gfx.h"
+#include "st3m_fs.h"
 
 #include "esp_log.h"
 #include "driver/i2c.h"
@@ -90,6 +91,8 @@ void os_app_early_init(void) {
         st3m_gfx_splash("st3m loading...");
     }
     flow3r_bsp_display_set_backlight(100);
+
+    st3m_fs_init();
 }
 
 void os_app_main(void)
diff --git a/components/st3m/CMakeLists.txt b/components/st3m/CMakeLists.txt
index 33bcf75e02a9823af8ffd3773aae2d82bf0c6001..2504ce806a0d2273bc21defa403e4debcdafd25b 100644
--- a/components/st3m/CMakeLists.txt
+++ b/components/st3m/CMakeLists.txt
@@ -2,9 +2,11 @@ idf_component_register(
     SRCS
         st3m_gfx.c
         st3m_counter.c
+        st3m_fs.c
     INCLUDE_DIRS
         .
     REQUIRES
         flow3r_bsp
         ctx
+        fatfs
 )
diff --git a/components/st3m/st3m_fs.c b/components/st3m/st3m_fs.c
new file mode 100644
index 0000000000000000000000000000000000000000..e39803ed8ebb0d90f99bfd523b03742a333a0b36
--- /dev/null
+++ b/components/st3m/st3m_fs.c
@@ -0,0 +1,28 @@
+#include "st3m_fs.h"
+
+#include "esp_vfs.h"
+#include "esp_vfs_fat.h"
+#include "esp_system.h"
+
+
+static const char *TAG = "st3m-fs";
+
+// Handle of the wear levelling library instance
+static wl_handle_t s_wl_handle = WL_INVALID_HANDLE;
+
+
+void st3m_fs_init(void) {
+	const esp_vfs_fat_mount_config_t mount_config = {
+        .max_files = 4,
+        .format_if_mount_failed = true,
+        .allocation_unit_size = CONFIG_WL_SECTOR_SIZE
+    };
+
+	esp_err_t err = esp_vfs_fat_spiflash_mount("", "vfs", &mount_config, &s_wl_handle);
+    if (err != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to mount FAT FS: %s", esp_err_to_name(err));
+        return;
+    }
+
+	ESP_LOGI(TAG, "Mounted Flash VFS Partition at /");
+}
diff --git a/components/st3m/st3m_fs.h b/components/st3m/st3m_fs.h
new file mode 100644
index 0000000000000000000000000000000000000000..a2ed18011c2c95bf1eeec6e39f0c2ab07831a670
--- /dev/null
+++ b/components/st3m/st3m_fs.h
@@ -0,0 +1,9 @@
+#pragma once
+
+// Mount filesystem. An error will be loged if the mount failed.
+//
+// Filesystem layout:
+//  / - FAT from flash ('vfat' partition, wear leveled)
+//
+// This function must not be called more than once.
+void st3m_fs_init(void);
\ No newline at end of file
diff --git a/main/include/mpconfigboard.h b/main/include/mpconfigboard.h
index 5cdc28059d58d05bc9efd3d738a3413248ea0ddc..4e1516f9094c4f36f499732984151ff4db17b122 100644
--- a/main/include/mpconfigboard.h
+++ b/main/include/mpconfigboard.h
@@ -7,17 +7,4 @@
 #define MICROPY_HW_I2C0_SDA (8)
 
 #define MICROPY_ESP_IDF_4 1
-#define MICROPY_VFS_FAT 1
-#define MICROPY_VFS_LFS2 1
-
-// These kinda freak me out, but that's what micropython does...
-#define LFS1_NO_MALLOC
-#define LFS1_NO_DEBUG
-#define LFS1_NO_WARN
-#define LFS1_NO_ERROR
-#define LFS1_NO_ASSERT
-#define LFS2_NO_MALLOC
-#define LFS2_NO_DEBUG
-#define LFS2_NO_WARN
-#define LFS2_NO_ERROR
-#define LFS2_NO_ASSERT
+#define MICROPY_VFS_POSIX 1
diff --git a/micropython/extmod/vfs_posix.c b/micropython/extmod/vfs_posix.c
index 9b856e1f01cc6d2f633f1e0218191abc42a9efcb..4b6406a4609669db4c45987442befedc10dab590 100644
--- a/micropython/extmod/vfs_posix.c
+++ b/micropython/extmod/vfs_posix.c
@@ -1,9 +1,12 @@
 /*
  * This file is part of the MicroPython project, http://micropython.org/
  *
+ * Modified to use the ESP32 VFS layer.
+ *
  * The MIT License (MIT)
  *
  * Copyright (c) 2017-2018 Damien P. George
+ * Copyright (c) 2023 Serge 'q3k' Bazanski
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -43,9 +46,6 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <dirent.h>
-#ifdef _MSC_VER
-#include <direct.h> // For mkdir etc.
-#endif
 
 typedef struct _mp_obj_vfs_posix_t {
     mp_obj_base_t base;
@@ -311,72 +311,6 @@ STATIC mp_obj_t vfs_posix_rmdir(mp_obj_t self_in, mp_obj_t path_in) {
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_rmdir_obj, vfs_posix_rmdir);
 
-STATIC mp_obj_t vfs_posix_stat(mp_obj_t self_in, mp_obj_t path_in) {
-    mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in);
-    struct stat sb;
-    const char *path = vfs_posix_get_path_str(self, path_in);
-    int ret;
-    MP_HAL_RETRY_SYSCALL(ret, stat(path, &sb), mp_raise_OSError(err));
-    mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL));
-    t->items[0] = MP_OBJ_NEW_SMALL_INT(sb.st_mode);
-    t->items[1] = mp_obj_new_int_from_uint(sb.st_ino);
-    t->items[2] = mp_obj_new_int_from_uint(sb.st_dev);
-    t->items[3] = mp_obj_new_int_from_uint(sb.st_nlink);
-    t->items[4] = mp_obj_new_int_from_uint(sb.st_uid);
-    t->items[5] = mp_obj_new_int_from_uint(sb.st_gid);
-    t->items[6] = mp_obj_new_int_from_uint(sb.st_size);
-    t->items[7] = mp_obj_new_int_from_uint(sb.st_atime);
-    t->items[8] = mp_obj_new_int_from_uint(sb.st_mtime);
-    t->items[9] = mp_obj_new_int_from_uint(sb.st_ctime);
-    return MP_OBJ_FROM_PTR(t);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_stat_obj, vfs_posix_stat);
-
-#if MICROPY_PY_UOS_STATVFS
-
-#ifdef __ANDROID__
-#define USE_STATFS 1
-#endif
-
-#if USE_STATFS
-#include <sys/vfs.h>
-#define STRUCT_STATVFS struct statfs
-#define STATVFS statfs
-#define F_FAVAIL sb.f_ffree
-#define F_NAMEMAX sb.f_namelen
-#define F_FLAG sb.f_flags
-#else
-#include <sys/statvfs.h>
-#define STRUCT_STATVFS struct statvfs
-#define STATVFS statvfs
-#define F_FAVAIL sb.f_favail
-#define F_NAMEMAX sb.f_namemax
-#define F_FLAG sb.f_flag
-#endif
-
-STATIC mp_obj_t vfs_posix_statvfs(mp_obj_t self_in, mp_obj_t path_in) {
-    mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in);
-    STRUCT_STATVFS sb;
-    const char *path = vfs_posix_get_path_str(self, path_in);
-    int ret;
-    MP_HAL_RETRY_SYSCALL(ret, STATVFS(path, &sb), mp_raise_OSError(err));
-    mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL));
-    t->items[0] = MP_OBJ_NEW_SMALL_INT(sb.f_bsize);
-    t->items[1] = MP_OBJ_NEW_SMALL_INT(sb.f_frsize);
-    t->items[2] = MP_OBJ_NEW_SMALL_INT(sb.f_blocks);
-    t->items[3] = MP_OBJ_NEW_SMALL_INT(sb.f_bfree);
-    t->items[4] = MP_OBJ_NEW_SMALL_INT(sb.f_bavail);
-    t->items[5] = MP_OBJ_NEW_SMALL_INT(sb.f_files);
-    t->items[6] = MP_OBJ_NEW_SMALL_INT(sb.f_ffree);
-    t->items[7] = MP_OBJ_NEW_SMALL_INT(F_FAVAIL);
-    t->items[8] = MP_OBJ_NEW_SMALL_INT(F_FLAG);
-    t->items[9] = MP_OBJ_NEW_SMALL_INT(F_NAMEMAX);
-    return MP_OBJ_FROM_PTR(t);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_statvfs_obj, vfs_posix_statvfs);
-
-#endif
-
 STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
     { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&vfs_posix_mount_obj) },
     { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&vfs_posix_umount_obj) },
@@ -389,10 +323,6 @@ STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
     { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&vfs_posix_remove_obj) },
     { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&vfs_posix_rename_obj) },
     { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&vfs_posix_rmdir_obj) },
-    { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&vfs_posix_stat_obj) },
-    #if MICROPY_PY_UOS_STATVFS
-    { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&vfs_posix_statvfs_obj) },
-    #endif
 };
 STATIC MP_DEFINE_CONST_DICT(vfs_posix_locals_dict, vfs_posix_locals_dict_table);
 
@@ -409,4 +339,4 @@ MP_DEFINE_CONST_OBJ_TYPE(
     locals_dict, &vfs_posix_locals_dict
     );
 
-#endif // MICROPY_VFS_POSIX
+#endif // MICROPY_VFS_POSIX
\ No newline at end of file
diff --git a/micropython/extmod/vfs_posix_file.c b/micropython/extmod/vfs_posix_file.c
index ea19de7fd04afb0f8932ff80ce6c9b8eef1e6f04..f514a10beed95be6bebb29cb0cc5d6af0e0730ab 100644
--- a/micropython/extmod/vfs_posix_file.c
+++ b/micropython/extmod/vfs_posix_file.c
@@ -35,26 +35,26 @@
 #include <fcntl.h>
 #include <unistd.h>
 
-#ifdef _WIN32
-#define fsync _commit
-#else
-#include <poll.h>
-#endif
+#define MP_HAL_RETRY_SYSCALL(ret, syscall, raise) do { \
+        MP_THREAD_GIL_EXIT(); \
+        ret = syscall; \
+        MP_THREAD_GIL_ENTER(); \
+        if (ret == -1) { \
+            int err = errno; \
+            raise; \
+        } \
+    } while(0)
 
 typedef struct _mp_obj_vfs_posix_file_t {
     mp_obj_base_t base;
     int fd;
 } mp_obj_vfs_posix_file_t;
 
-#if MICROPY_CPYTHON_COMPAT
 STATIC void check_fd_is_open(const mp_obj_vfs_posix_file_t *o) {
     if (o->fd < 0) {
         mp_raise_ValueError(MP_ERROR_TEXT("I/O operation on closed file"));
     }
 }
-#else
-#define check_fd_is_open(o)
-#endif
 
 STATIC void vfs_posix_file_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
     (void)kind;
@@ -194,32 +194,6 @@ STATIC mp_uint_t vfs_posix_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_
             return 0;
         case MP_STREAM_GET_FILENO:
             return o->fd;
-        #if MICROPY_PY_USELECT
-        case MP_STREAM_POLL: {
-            #ifdef _WIN32
-            mp_raise_NotImplementedError(MP_ERROR_TEXT("poll on file not available on win32"));
-            #else
-            mp_uint_t ret = 0;
-            uint8_t pollevents = 0;
-            if (arg & MP_STREAM_POLL_RD) {
-                pollevents |= POLLIN;
-            }
-            if (arg & MP_STREAM_POLL_WR) {
-                pollevents |= POLLOUT;
-            }
-            struct pollfd pfd = { .fd = o->fd, .events = pollevents };
-            if (poll(&pfd, 1, 0) > 0) {
-                if (pfd.revents & POLLIN) {
-                    ret |= MP_STREAM_POLL_RD;
-                }
-                if (pfd.revents & POLLOUT) {
-                    ret |= MP_STREAM_POLL_WR;
-                }
-            }
-            return ret;
-            #endif
-        }
-        #endif
         default:
             *errcode = EINVAL;
             return MP_STREAM_ERROR;
@@ -279,4 +253,4 @@ const mp_obj_vfs_posix_file_t mp_sys_stdin_obj = {{&mp_type_vfs_posix_textio}, S
 const mp_obj_vfs_posix_file_t mp_sys_stdout_obj = {{&mp_type_vfs_posix_textio}, STDOUT_FILENO};
 const mp_obj_vfs_posix_file_t mp_sys_stderr_obj = {{&mp_type_vfs_posix_textio}, STDERR_FILENO};
 
-#endif // MICROPY_VFS_POSIX
+#endif // MICROPY_VFS_POSIX
\ No newline at end of file
diff --git a/micropython/ports/esp32/modules/_boot.py b/micropython/ports/esp32/modules/_boot.py
index a7d9813090bfde5245d992dc9c4c5c85e1914d99..e9680ea207641583241e7ccf06491c8bf505c7b8 100644
--- a/micropython/ports/esp32/modules/_boot.py
+++ b/micropython/ports/esp32/modules/_boot.py
@@ -1,13 +1,7 @@
 import gc
 import uos
-from flashbdev import bdev
 
-try:
-    if bdev:
-        uos.mount(bdev, "/")
-except OSError:
-    import inisetup
-
-    vfs = inisetup.setup()
+vfs = uos.VfsPosix()
+uos.mount(vfs, "/")
 
 gc.collect()
diff --git a/usermodule/micropython.cmake b/usermodule/micropython.cmake
index 03ce93dbd18fd63bb291f63b1a06ab53a3c2b09a..54beadee0f91a6ce10e1b11a09fb95e5e77a189a 100644
--- a/usermodule/micropython.cmake
+++ b/usermodule/micropython.cmake
@@ -18,4 +18,4 @@ target_include_directories(usermod_badge23 INTERFACE
     ${CMAKE_CURRENT_LIST_DIR}
 )
 
-target_link_libraries(usermod INTERFACE usermod_badge23)
\ No newline at end of file
+target_link_libraries(usermod INTERFACE usermod_badge23)