Skip to content

Commit

Permalink
stm32/mboot: Introduce MBOOT_ERRNO_xxx constants and use them.
Browse files Browse the repository at this point in the history
So that a failed update via fsload can be more easily diagnosed.

Signed-off-by: Damien George <damien@micropython.org>
  • Loading branch information
dpgeorge committed Jan 29, 2021
1 parent 0efa0b5 commit bd7110a
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 34 deletions.
30 changes: 15 additions & 15 deletions ports/stm32/mboot/fsload.c
Expand Up @@ -80,18 +80,18 @@ static int fsload_program_file(bool write_to_flash) {
// Read file header, <5sBIB
int res = input_stream_read(11, buf);
if (res != 11) {
return -1;
return -MBOOT_ERRNO_DFU_READ_ERROR;
}
file_offset = 11;

// Validate header, version 1
if (memcmp(buf, "DfuSe\x01", 6) != 0) {
return -1;
return -MBOOT_ERRNO_DFU_INVALID_HEADER;
}

// Must have only 1 target
if (buf[10] != 1) {
return -2;
return -MBOOT_ERRNO_DFU_TOO_MANY_TARGETS;
}

// Get total size
Expand All @@ -100,13 +100,13 @@ static int fsload_program_file(bool write_to_flash) {
// Read target header, <6sBi255sII
res = input_stream_read(274, buf);
if (res != 274) {
return -1;
return -MBOOT_ERRNO_DFU_READ_ERROR;
}
file_offset += 274;

// Validate target header, with alt being 0
if (memcmp(buf, "Target\x00", 7) != 0) {
return -1;
return -MBOOT_ERRNO_DFU_INVALID_TARGET;
}

// Get target size and number of elements
Expand All @@ -120,7 +120,7 @@ static int fsload_program_file(bool write_to_flash) {
// Read element header, <II
res = input_stream_read(8, buf);
if (res != 8) {
return -1;
return -MBOOT_ERRNO_DFU_READ_ERROR;
}
file_offset += 8;

Expand Down Expand Up @@ -149,12 +149,12 @@ static int fsload_program_file(bool write_to_flash) {
}
res = input_stream_read(l, buf);
if (res != l) {
return -1;
return -MBOOT_ERRNO_DFU_READ_ERROR;
}
if (write_to_flash) {
res = do_write(elem_addr, buf, l);
if (res != 0) {
return -1;
return res;
}
elem_addr += l;
}
Expand All @@ -165,17 +165,17 @@ static int fsload_program_file(bool write_to_flash) {
}

if (target_size != file_offset - file_offset_target) {
return -1;
return -MBOOT_ERRNO_DFU_INVALID_SIZE;
}

if (total_size != file_offset) {
return -1;
return -MBOOT_ERRNO_DFU_INVALID_SIZE;
}

// Read trailing info
res = input_stream_read(16, buf);
if (res != 16) {
return -1;
return -MBOOT_ERRNO_DFU_READ_ERROR;
}

// TODO validate CRC32
Expand Down Expand Up @@ -205,7 +205,7 @@ static int fsload_validate_and_program_file(void *stream, const stream_methods_t
int fsload_process(void) {
const uint8_t *elem = elem_search(ELEM_DATA_START, ELEM_TYPE_FSLOAD);
if (elem == NULL || elem[-1] < 2) {
return -1;
return -MBOOT_ERRNO_FSLOAD_NO_FSLOAD;
}

// Get mount point id and create null-terminated filename
Expand All @@ -220,7 +220,7 @@ int fsload_process(void) {
elem = elem_search(elem, ELEM_TYPE_MOUNT);
if (elem == NULL) {
// End of elements.
return -1;
return -MBOOT_ERRNO_FSLOAD_NO_MOUNT;
}
uint32_t block_size;
if (elem[-1] == 10) {
Expand All @@ -231,7 +231,7 @@ int fsload_process(void) {
block_size = get_le32(&elem[10]);
} else {
// Invalid MOUNT element.
return -1;
return -MBOOT_ERRNO_FSLOAD_INVALID_MOUNT;
}
if (elem[0] == mount_point) {
uint32_t base_addr = get_le32(&elem[2]);
Expand Down Expand Up @@ -270,7 +270,7 @@ int fsload_process(void) {
#endif
{
// Unknown filesystem type
return -1;
return -MBOOT_ERRNO_FSLOAD_INVALID_MOUNT;
}

if (ret == 0) {
Expand Down
2 changes: 1 addition & 1 deletion ports/stm32/mboot/gzstream.c
Expand Up @@ -80,7 +80,7 @@ int gz_stream_init_from_stream(void *stream_data, stream_read_t stream_read) {

int st = uzlib_gzip_parse_header(&gz_stream.tinf);
if (st != TINF_OK) {
return -1;
return -MBOOT_ERRNO_GUNZIP_FAILED;
}

uzlib_uncompress_init(&gz_stream.tinf, gz_stream.dict, DICT_SIZE);
Expand Down
6 changes: 3 additions & 3 deletions ports/stm32/mboot/main.c
Expand Up @@ -489,7 +489,7 @@ static int mboot_flash_page_erase(uint32_t addr, uint32_t *next_addr) {
dfu_context.status = DFU_STATUS_ERROR_ADDRESS;
dfu_context.error = (sector == 0) ? MBOOT_ERROR_STR_OVERWRITE_BOOTLOADER_IDX
: MBOOT_ERROR_STR_INVALID_ADDRESS_IDX;
return -1;
return -MBOOT_ERRNO_FLASH_ERASE_DISALLOWED;
}

*next_addr = sector_start + sector_size;
Expand All @@ -503,7 +503,7 @@ static int mboot_flash_page_erase(uint32_t addr, uint32_t *next_addr) {
// Check the erase set bits to 1, at least for the first 256 bytes
for (int i = 0; i < 64; ++i) {
if (((volatile uint32_t*)sector_start)[i] != 0xffffffff) {
return -2;
return -MBOOT_ERRNO_FLASH_ERASE_FAILED;
}
}

Expand All @@ -517,7 +517,7 @@ static int mboot_flash_write(uint32_t addr, const uint8_t *src8, size_t len) {
dfu_context.status = DFU_STATUS_ERROR_ADDRESS;
dfu_context.error = (sector == 0) ? MBOOT_ERROR_STR_OVERWRITE_BOOTLOADER_IDX
: MBOOT_ERROR_STR_INVALID_ADDRESS_IDX;
return -1;
return -MBOOT_ERRNO_FLASH_WRITE_DISALLOWED;
}

const uint32_t *src = (const uint32_t*)src8;
Expand Down
31 changes: 31 additions & 0 deletions ports/stm32/mboot/mboot.h
Expand Up @@ -39,6 +39,37 @@
#define NORETURN __attribute__((noreturn))
#define MP_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

enum {
MBOOT_ERRNO_FLASH_ERASE_DISALLOWED = 200,
MBOOT_ERRNO_FLASH_ERASE_FAILED,
MBOOT_ERRNO_FLASH_WRITE_DISALLOWED,

MBOOT_ERRNO_DFU_INVALID_HEADER = 210,
MBOOT_ERRNO_DFU_INVALID_TARGET,
MBOOT_ERRNO_DFU_INVALID_SIZE,
MBOOT_ERRNO_DFU_TOO_MANY_TARGETS,
MBOOT_ERRNO_DFU_READ_ERROR,

MBOOT_ERRNO_FSLOAD_NO_FSLOAD = 220,
MBOOT_ERRNO_FSLOAD_NO_MOUNT,
MBOOT_ERRNO_FSLOAD_INVALID_MOUNT,

MBOOT_ERRNO_PACK_INVALID_ADDR = 230,
MBOOT_ERRNO_PACK_INVALID_CHUNK,
MBOOT_ERRNO_PACK_INVALID_VERSION,
MBOOT_ERRNO_PACK_DECRYPT_FAILED,
MBOOT_ERRNO_PACK_SIGN_FAILED,

MBOOT_ERRNO_VFS_FAT_MOUNT_FAILED = 240,
MBOOT_ERRNO_VFS_FAT_OPEN_FAILED,
MBOOT_ERRNO_VFS_LFS1_MOUNT_FAILED,
MBOOT_ERRNO_VFS_LFS1_OPEN_FAILED,
MBOOT_ERRNO_VFS_LFS2_MOUNT_FAILED,
MBOOT_ERRNO_VFS_LFS2_OPEN_FAILED,

MBOOT_ERRNO_GUNZIP_FAILED = 250,
};

enum {
ELEM_TYPE_END = 1,
ELEM_TYPE_MOUNT,
Expand Down
22 changes: 11 additions & 11 deletions ports/stm32/mboot/pack.c
Expand Up @@ -112,7 +112,7 @@ static int mboot_pack_commit_chunk(uint32_t addr, uint8_t *data, size_t len) {
// Handle a chunk with the full firmware signature.
static int mboot_pack_handle_full_sig(void) {
if (firmware_chunk_buf.header.length < hydro_sign_BYTES) {
return -1;
return -MBOOT_ERRNO_PACK_INVALID_CHUNK;
}

uint8_t *full_sig = &firmware_chunk_buf.data[firmware_chunk_buf.header.length - hydro_sign_BYTES];
Expand All @@ -138,7 +138,7 @@ static int mboot_pack_handle_full_sig(void) {
}
int ret = hydro_sign_update(&sign_state, buf, l);
if (ret != 0) {
return -1;
return -MBOOT_ERRNO_PACK_SIGN_FAILED;
}
addr += l;
len -= l;
Expand All @@ -150,7 +150,7 @@ static int mboot_pack_handle_full_sig(void) {
if (ret != 0) {
dfu_context.status = DFU_STATUS_ERROR_VERIFY;
dfu_context.error = MBOOT_ERROR_STR_INVALID_SIG_IDX;
return -1;
return -MBOOT_ERRNO_PACK_SIGN_FAILED;
}

// Full firmware passed the signature check.
Expand All @@ -167,7 +167,7 @@ static int mboot_pack_handle_firmware(void) {
if (hydro_secretbox_decrypt(decrypted_buf, fw_data, fw_len, 0, MBOOT_PACK_HYDRO_CONTEXT, mboot_pack_secretbox_key) != 0) {
dfu_context.status = DFU_STATUS_ERROR_VERIFY;
dfu_context.error = MBOOT_ERROR_STR_INVALID_SIG_IDX;
return -1;
return -MBOOT_ERRNO_PACK_DECRYPT_FAILED;
}

// Use the decrypted message contents going formward.
Expand All @@ -182,7 +182,7 @@ static int mboot_pack_handle_firmware(void) {
if (read == 0) {
return 0; // finished decompressing
} else if (read < 0) {
return -1; // error reading
return -MBOOT_ERRNO_GUNZIP_FAILED; // error reading
}
int ret = mboot_pack_commit_chunk(addr, uncompressed_buf, read);
if (ret != 0) {
Expand Down Expand Up @@ -210,14 +210,14 @@ int mboot_pack_write(uint32_t addr, const uint8_t *src8, size_t len) {
if (addr < firmware_chunk_base_addr) {
// Address out of range.
firmware_chunk_base_addr = 0;
return -1;
return -MBOOT_ERRNO_PACK_INVALID_ADDR;
}

size_t offset = addr - firmware_chunk_base_addr;
if (offset + len > sizeof(firmware_chunk_buf)) {
// Address/length out of range.
firmware_chunk_base_addr = 0;
return -1;
return -MBOOT_ERRNO_PACK_INVALID_ADDR;
}

// Copy in the new data piece into the chunk buffer.
Expand All @@ -232,14 +232,14 @@ int mboot_pack_write(uint32_t addr, const uint8_t *src8, size_t len) {
// Chunk header has the wrong version.
dfu_context.status = DFU_STATUS_ERROR_FILE;
dfu_context.error = MBOOT_ERROR_STR_INVALID_SIG_IDX;
return -1;
return -MBOOT_ERRNO_PACK_INVALID_VERSION;
}

if (firmware_chunk_buf.header.address != firmware_chunk_base_addr) {
// Chunk address doesn't agree with dfu address, abort.
dfu_context.status = DFU_STATUS_ERROR_ADDRESS;
dfu_context.error = MBOOT_ERROR_STR_INVALID_SIG_IDX;
return -1;
return -MBOOT_ERRNO_PACK_INVALID_ADDR;
}

if (offset + len < sizeof(firmware_chunk_buf.header) + firmware_chunk_buf.header.length + sizeof(firmware_chunk_buf.signature)) {
Expand All @@ -260,7 +260,7 @@ int mboot_pack_write(uint32_t addr, const uint8_t *src8, size_t len) {
// Signature failed
dfu_context.status = DFU_STATUS_ERROR_VERIFY;
dfu_context.error = MBOOT_ERROR_STR_INVALID_SIG_IDX;
return -1;
return -MBOOT_ERRNO_PACK_SIGN_FAILED;
}

// Signature passed, we have valid chunk.
Expand All @@ -275,7 +275,7 @@ int mboot_pack_write(uint32_t addr, const uint8_t *src8, size_t len) {
return mboot_pack_handle_firmware();
} else {
// Unsupported contents.
return -1;
return -MBOOT_ERRNO_PACK_INVALID_CHUNK;
}
}

Expand Down
4 changes: 2 additions & 2 deletions ports/stm32/mboot/vfs_fat.c
Expand Up @@ -84,7 +84,7 @@ int vfs_fat_mount(vfs_fat_context_t *ctx, uint32_t base_addr, uint32_t byte_len)
ctx->fatfs.drv = ctx;
FRESULT res = f_mount(&ctx->fatfs);
if (res != FR_OK) {
return -1;
return -MBOOT_ERRNO_VFS_FAT_MOUNT_FAILED;
}
return 0;
}
Expand All @@ -93,7 +93,7 @@ static int vfs_fat_stream_open(void *stream_in, const char *fname) {
vfs_fat_context_t *stream = stream_in;
FRESULT res = f_open(&stream->fatfs, &stream->fp, fname, FA_READ);
if (res != FR_OK) {
return -1;
return -MBOOT_ERRNO_VFS_FAT_OPEN_FAILED;
}
return 0;
}
Expand Down
13 changes: 11 additions & 2 deletions ports/stm32/mboot/vfs_lfs.c
Expand Up @@ -37,6 +37,9 @@
#error Unsupported
#endif

#define MBOOT_ERRNO_VFS_LFS_MOUNT_FAILED MBOOT_ERRNO_VFS_LFS1_MOUNT_FAILED
#define MBOOT_ERRNO_VFS_LFS_OPEN_FAILED MBOOT_ERRNO_VFS_LFS1_OPEN_FAILED

#define LFSx_MACRO(s) LFS1##s
#define LFSx_API(x) lfs1_ ## x
#define VFS_LFSx_CONTEXT_T vfs_lfs1_context_t
Expand All @@ -49,6 +52,9 @@ static uint8_t lfs_lookahead_buffer[LFS_LOOKAHEAD_SIZE / 8];

#else

#define MBOOT_ERRNO_VFS_LFS_MOUNT_FAILED MBOOT_ERRNO_VFS_LFS2_MOUNT_FAILED
#define MBOOT_ERRNO_VFS_LFS_OPEN_FAILED MBOOT_ERRNO_VFS_LFS2_OPEN_FAILED

#define LFSx_MACRO(s) LFS2##s
#define LFSx_API(x) lfs2_ ## x
#define VFS_LFSx_CONTEXT_T vfs_lfs2_context_t
Expand Down Expand Up @@ -116,7 +122,7 @@ int VFS_LFSx_MOUNT(VFS_LFSx_CONTEXT_T *ctx, uint32_t base_addr, uint32_t byte_le

int ret = LFSx_API(mount)(&ctx->lfs, &ctx->config);
if (ret < 0) {
return -1;
return -MBOOT_ERRNO_VFS_LFS_MOUNT_FAILED;
}
return 0;
}
Expand All @@ -126,7 +132,10 @@ static int vfs_lfs_stream_open(void *stream_in, const char *fname) {
memset(&ctx->file, 0, sizeof(ctx->file));
memset(&ctx->filecfg, 0, sizeof(ctx->filecfg));
ctx->filecfg.buffer = &ctx->filebuf[0];
LFSx_API(file_opencfg)(&ctx->lfs, &ctx->file, fname, LFSx_MACRO(_O_RDONLY), &ctx->filecfg);
int ret = LFSx_API(file_opencfg)(&ctx->lfs, &ctx->file, fname, LFSx_MACRO(_O_RDONLY), &ctx->filecfg);
if (ret < 0) {
return -MBOOT_ERRNO_VFS_LFS_OPEN_FAILED;
}
return 0;
}

Expand Down

0 comments on commit bd7110a

Please sign in to comment.