Browse Source

flash internal: check enforced flash size

spark_strober
King Kévin 5 years ago
parent
commit
7b90696b6c
  1. 2
      bootloader.c
  2. 10
      global.h
  3. 53
      lib/flash_internal.c
  4. 12
      lib/usb_dfu.c

2
bootloader.c

@ -77,7 +77,7 @@ void main(void) @@ -77,7 +77,7 @@ void main(void)
* if the SP is not in this range (e.g. flash has been erased) there is no valid application
* the second entry in the vector table is the reset address, corresponding to the application start
*/
volatile uint32_t* application = &__application_beginning; // get the value of the application address symbol (use a register instead on the stack since the stack pointer will be changed)
volatile uint32_t* application = (uint32_t*)&__application_beginning; // get the value of the application address symbol (use a register instead on the stack since the stack pointer will be changed)
if (!dfu_force && (((*application)&0xFFFE0000)==0x20000000)) { // application at address seems valid
SCB_VTOR = (volatile uint32_t)(application); // set vector table to application vector table (store at the beginning of the application)
__asm__ volatile ("MSR msp,%0" : :"r"(*application)); // set stack pointer to address provided in the beginning of the application (loaded into a register first)

10
global.h

@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
#pragma once
/** enable debugging functionalities */
#define DEBUG false
#define DEBUG true
/** get the length of an array */
#define LENGTH(x) (sizeof(x) / sizeof((x)[0]))
@ -422,11 +422,15 @@ @@ -422,11 +422,15 @@
/** symbol for beginning of the application
* @note this symbol will be provided by the linker script
*/
extern uint32_t __application_beginning;
extern char __application_beginning;
/** symbol for end of the application
* @note this symbol will be provided by the linker script
*/
extern uint32_t __application_end;
extern char __application_end;
/** symbol for end of flash
* @note this symbol will be provided by the linker script
*/
extern char __flash_end;
/** flag set when board user button has been pressed/released */
extern volatile bool button_flag;
/** flag set when user input is available */

53
lib/flash_internal.c

@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
/** library to read/write internal flash (code)
* @file flash_internal.c
* @author King Kévin <kingkevin@cuvoodoo.info>
* @date 2016
* @date 2016-2018
* @note peripherals used: none
*/
/* standard libraries */
@ -30,20 +30,37 @@ @@ -30,20 +30,37 @@
#include "flash_internal.h" // flash storage library API
#include "global.h" // global definitions
/** verify if the data is in the internal flash area
* @param[in] address start address of the data to read
* @param[in] size how much data to read or write, in bytes
* @return if the data is in the internal flash area
*/
static bool flash_internal_range(uint32_t address, size_t size) {
if (address>(UINT32_MAX-size)) { // on integer overflow will occur
return false;
}
if (address<FLASH_BASE) { // start address is before the start of the internal flash
return false;
}
if ((uint32_t)&__flash_end>=FLASH_BASE) { // check if the end for the internal flash is enforce by the linker script
if ((address+size)>(uint32_t)&__flash_end) { // end address is after the end of the enforced internal flash
return false;
}
} else {
if ((address+size)>(FLASH_BASE+DESIG_FLASH_SIZE*1024)) { // end address is after the end of the advertised flash
return false;
}
}
return true;
}
bool flash_internal_read(uint32_t address, uint8_t *buffer, size_t size)
{
// sanity checks
if (address<FLASH_BASE || address>(UINT32_MAX-size) || buffer==NULL || size==0) {
if (buffer==NULL || size==0) {
return false;
}
// verify if it's in the flash area
#if defined(__flash_end)
if (address<FLASH_BASE || (address+size)>(uint32_t)&__flash_end)
#else
if (address<FLASH_BASE || (address+size)>(FLASH_BASE+DESIG_FLASH_SIZE*1024))
#endif
{
if (!flash_internal_range(address, size)) {
return false;
}
@ -58,17 +75,19 @@ bool flash_internal_read(uint32_t address, uint8_t *buffer, size_t size) @@ -58,17 +75,19 @@ bool flash_internal_read(uint32_t address, uint8_t *buffer, size_t size)
bool flash_internal_write(uint32_t address, uint8_t *buffer, size_t size)
{
// sanity checks
if (address<FLASH_BASE || address>(UINT32_MAX-size) || buffer==NULL || size==0 || size%2) {
if (buffer==NULL || size==0 || size%2) {
return false;
}
if (!flash_internal_range(address, size)) {
return false;
}
// verify if it's in the flash area
#if defined(__flash_end)
if (address<FLASH_BASE || (address+size)>(uint32_t)&__flash_end)
#else
if (address<FLASH_BASE || (address+size)>(FLASH_BASE+DESIG_FLASH_SIZE*1024))
#endif
{
if (address<FLASH_BASE) {
return false;
} else if ((uint32_t)&__flash_end>=FLASH_BASE && (address+size)>(uint32_t)&__flash_end) {
return false;
} else if ((uint32_t)&__flash_end<FLASH_BASE && (address+size)>(FLASH_BASE+DESIG_FLASH_SIZE*1024)) {
return false;
}

12
lib/usb_dfu.c

@ -223,12 +223,12 @@ static int usb_dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data @@ -223,12 +223,12 @@ static int usb_dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data
// we can only write half words
usb_dfu_status = DFU_STATUS_ERR_PROG;
usb_dfu_state = STATE_DFU_ERROR;
#if defined(__application_end)
} else if (flash_pointer+*len>=(uint32_t)&__application_end) {
#else
} else if (flash_pointer+*len>=(uint32_t)(FLASH_BASE+DESIG_FLASH_SIZE*1024)) {
#endif
// application data is too large
} else if ((uint32_t)&__application_end>=FLASH_BASE && flash_pointer+*len>=(uint32_t)&__application_end) {
// application data is exceeding enforced flash size for application
usb_dfu_status = DFU_STATUS_ERR_ADDRESS;
usb_dfu_state = STATE_DFU_ERROR;
} else if ((uint32_t)&__application_end<FLASH_BASE && flash_pointer+*len>=(uint32_t)(FLASH_BASE+DESIG_FLASH_SIZE*1024)) {
// application data is exceeding advertised flash size
usb_dfu_status = DFU_STATUS_ERR_ADDRESS;
usb_dfu_state = STATE_DFU_ERROR;
} else {

Loading…
Cancel
Save