From 366d7054a8ad917a257a57e34953c7189bf43fa6 Mon Sep 17 00:00:00 2001 From: Andrew Leech <> Date: Wed, 24 Jan 2024 09:08:29 +1100 Subject: [PATCH] stm32/main: Catch and report corrupted lfs filesystem at startup. Signed-off-by: Andrew Leech --- ports/stm32/main.c | 10 ++++++--- ports/stm32/storage.c | 49 +++++++++++++++++++++++++------------------ ports/stm32/storage.h | 4 ++++ 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 06ba74f75967..bf2c8dd94f62 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -185,10 +185,14 @@ MP_NOINLINE STATIC bool init_flash_fs(uint reset_mode) { if (len != -1) { // Detected a littlefs filesystem so create correct block device for it - mp_obj_t args[] = { MP_OBJ_NEW_QSTR(MP_QSTR_len), MP_OBJ_NEW_SMALL_INT(len) }; - bdev = MP_OBJ_TYPE_GET_SLOT(&pyb_flash_type, make_new)(&pyb_flash_type, 0, 1, args); + mp_obj_t lfs_bdev = pyb_flash_new_obj(0, len); + if (lfs_bdev == mp_const_none) { + // Uncaught exception; len must be an invalid length. + mp_printf(&mp_plat_print, "MPY: corrupted filesystem\n"); + } else { + bdev = lfs_bdev; + } } - #endif // Try to mount the flash on "/flash" and chdir to it for the boot-up directory. diff --git a/ports/stm32/storage.c b/ports/stm32/storage.c index 4623225804ce..fc460d285e5e 100644 --- a/ports/stm32/storage.c +++ b/ports/stm32/storage.c @@ -273,6 +273,30 @@ const pyb_flash_obj_t pyb_flash_obj = { 0, // actual size handled in ioctl, MP_BLOCKDEV_IOCTL_BLOCK_COUNT case }; +mp_obj_t pyb_flash_new_obj(mp_int_t start, mp_int_t len) { + + uint32_t bl_len = (storage_get_block_count() - FLASH_PART1_START_BLOCK) * FLASH_BLOCK_SIZE; + + if (start == -1) { + start = 0; + } else if (!(0 <= start && start < bl_len && start % MICROPY_HW_BDEV_BLOCKSIZE_EXT == 0)) { + return mp_const_none; + } + + if (len == -1) { + len = bl_len - start; + } else if (!(0 < len && start + len <= bl_len && len % MICROPY_HW_BDEV_BLOCKSIZE_EXT == 0)) { + return mp_const_none; + } + + pyb_flash_obj_t *self = mp_obj_malloc(pyb_flash_obj_t, &pyb_flash_type); + self->use_native_block_size = false; + self->start = start; + self->len = len; + + return MP_OBJ_FROM_PTR(self); +} + STATIC void pyb_flash_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_flash_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self == &pyb_flash_obj) { @@ -296,30 +320,15 @@ STATIC mp_obj_t pyb_flash_make_new(const mp_obj_type_t *type, size_t n_args, siz // Default singleton object that accesses entire flash, including virtual partition table return MP_OBJ_FROM_PTR(&pyb_flash_obj); } - - pyb_flash_obj_t *self = mp_obj_malloc(pyb_flash_obj_t, &pyb_flash_type); - self->use_native_block_size = false; - - uint32_t bl_len = (storage_get_block_count() - FLASH_PART1_START_BLOCK) * FLASH_BLOCK_SIZE; - mp_int_t start = args[ARG_start].u_int; - if (start == -1) { - start = 0; - } else if (!(0 <= start && start < bl_len && start % MICROPY_HW_BDEV_BLOCKSIZE_EXT == 0)) { - mp_raise_ValueError(NULL); - } - mp_int_t len = args[ARG_len].u_int; - if (len == -1) { - len = bl_len - start; - } else if (!(0 < len && start + len <= bl_len && len % MICROPY_HW_BDEV_BLOCKSIZE_EXT == 0)) { + + mp_obj_t self = pyb_flash_new_obj(start, len); + if (self == mp_const_none) { + // Invalid start or end arg mp_raise_ValueError(NULL); } - - self->start = start; - self->len = len; - - return MP_OBJ_FROM_PTR(self); + return self; } STATIC mp_obj_t pyb_flash_readblocks(size_t n_args, const mp_obj_t *args) { diff --git a/ports/stm32/storage.h b/ports/stm32/storage.h index 05654855aa0e..accf6c390438 100644 --- a/ports/stm32/storage.h +++ b/ports/stm32/storage.h @@ -77,4 +77,8 @@ extern const struct _pyb_flash_obj_t pyb_flash_obj; struct _fs_user_mount_t; void pyb_flash_init_vfs(struct _fs_user_mount_t *vfs); +#if !BUILDING_MBOOT +mp_obj_t pyb_flash_new_obj(mp_int_t start, mp_int_t len); +#endif + #endif // MICROPY_INCLUDED_STM32_STORAGE_H