stm32/mboot: Introduce MBOOT_ERRNO_xxx constants and use them.

So that a failed update via fsload can be more easily diagnosed.

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George 2021-01-29 00:40:49 +11:00
parent 0efa0b5437
commit bd7110a3d5
7 changed files with 74 additions and 34 deletions

View File

@ -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
@ -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
@ -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;
@ -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;
}
@ -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
@ -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
@ -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) {
@ -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]);
@ -270,7 +270,7 @@ int fsload_process(void) {
#endif
{
// Unknown filesystem type
return -1;
return -MBOOT_ERRNO_FSLOAD_INVALID_MOUNT;
}
if (ret == 0) {

View File

@ -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);

View File

@ -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;
@ -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;
}
}
@ -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;

View File

@ -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,

View File

@ -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];
@ -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;
@ -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.
@ -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.
@ -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) {
@ -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.
@ -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)) {
@ -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.
@ -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;
}
}

View File

@ -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;
}
@ -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;
}

View File

@ -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
@ -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
@ -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;
}
@ -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;
}