Merge pull request #238 from Nitrokey/bootloader-downgrade-protection
Bootloader downgrade protection
This commit is contained in:
commit
9158453830
@ -1775,8 +1775,14 @@ void ctap_load_external_keys(uint8_t * keybytes){
|
|||||||
crypto_load_master_secret(STATE.key_space);
|
crypto_load_master_secret(STATE.key_space);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "version.h"
|
||||||
void ctap_init()
|
void ctap_init()
|
||||||
{
|
{
|
||||||
|
printf1(TAG_ERR,"Current firmware version address: %p\r\n", &firmware_version);
|
||||||
|
printf1(TAG_ERR,"Current firmware version: %d.%d.%d.%d (%02x.%02x.%02x.%02x)\r\n",
|
||||||
|
firmware_version.major, firmware_version.minor, firmware_version.patch, firmware_version.reserved,
|
||||||
|
firmware_version.major, firmware_version.minor, firmware_version.patch, firmware_version.reserved
|
||||||
|
);
|
||||||
crypto_ecc256_init();
|
crypto_ecc256_init();
|
||||||
|
|
||||||
authenticator_read_state(&STATE);
|
authenticator_read_state(&STATE);
|
||||||
|
13
fido2/version.c
Normal file
13
fido2/version.c
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
|
||||||
|
const version_t firmware_version __attribute__ ((section (".flag"))) __attribute__ ((__used__)) = {
|
||||||
|
.major = SOLO_VERSION_MAJ,
|
||||||
|
.minor = SOLO_VERSION_MIN,
|
||||||
|
.patch = SOLO_VERSION_PATCH,
|
||||||
|
.reserved = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
// from tinycbor, for a quick static_assert
|
||||||
|
#include <compilersupport_p.h>
|
||||||
|
cbor_static_assert(sizeof(version_t) == 4);
|
@ -17,5 +17,23 @@
|
|||||||
#define SOLO_VERSION __STR(SOLO_VERSION_MAJ) "." __STR(SOLO_VERSION_MIN) "." __STR(SOLO_VERSION_PATCH)
|
#define SOLO_VERSION __STR(SOLO_VERSION_MAJ) "." __STR(SOLO_VERSION_MIN) "." __STR(SOLO_VERSION_PATCH)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
union{
|
||||||
|
uint32_t raw;
|
||||||
|
struct {
|
||||||
|
uint8_t major;
|
||||||
|
uint8_t minor;
|
||||||
|
uint8_t patch;
|
||||||
|
uint8_t reserved;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} version_t;
|
||||||
|
|
||||||
|
bool is_newer(const version_t* const newer, const version_t* const older);
|
||||||
|
const version_t firmware_version ;
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -90,8 +90,7 @@ flash_dfu: solo.hex bootloader.hex
|
|||||||
# STM32_Programmer_CLI -c port=usb1 -halt -e all --readunprotect
|
# STM32_Programmer_CLI -c port=usb1 -halt -e all --readunprotect
|
||||||
STM32_Programmer_CLI -c port=usb1 -halt -rdu -d all.hex
|
STM32_Programmer_CLI -c port=usb1 -halt -rdu -d all.hex
|
||||||
|
|
||||||
flashboot: solo.hex bootloader.hex
|
flashboot: bootloader.hex
|
||||||
$(VENV) $(merge_hex) solo.hex bootloader.hex all.hex
|
|
||||||
STM32_Programmer_CLI -c port=SWD -halt -e all --readunprotect
|
STM32_Programmer_CLI -c port=SWD -halt -e all --readunprotect
|
||||||
STM32_Programmer_CLI -c port=SWD -halt -d bootloader.hex -rst
|
STM32_Programmer_CLI -c port=SWD -halt -d bootloader.hex -rst
|
||||||
|
|
||||||
|
@ -19,6 +19,12 @@
|
|||||||
#include "ctap_errors.h"
|
#include "ctap_errors.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
volatile version_t current_firmware_version __attribute__ ((section (".flag2"))) __attribute__ ((__used__)) = {
|
||||||
|
.major = SOLO_VERSION_MAJ,
|
||||||
|
.minor = SOLO_VERSION_MIN,
|
||||||
|
.patch = SOLO_VERSION_PATCH,
|
||||||
|
.reserved = 0
|
||||||
|
};
|
||||||
|
|
||||||
extern uint8_t REBOOT_FLAG;
|
extern uint8_t REBOOT_FLAG;
|
||||||
|
|
||||||
@ -56,8 +62,6 @@ static void erase_application()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LAST_ADDR (APPLICATION_END_ADDR-2048 + 8)
|
|
||||||
#define LAST_PAGE (APPLICATION_END_PAGE-1)
|
|
||||||
static void disable_bootloader()
|
static void disable_bootloader()
|
||||||
{
|
{
|
||||||
// Clear last 4 bytes of the last application page-1, which is 108th
|
// Clear last 4 bytes of the last application page-1, which is 108th
|
||||||
@ -102,6 +106,38 @@ int is_bootloader_disabled()
|
|||||||
uint32_t * auth = (uint32_t *)(AUTH_WORD_ADDR+4);
|
uint32_t * auth = (uint32_t *)(AUTH_WORD_ADDR+4);
|
||||||
return *auth == 0;
|
return *auth == 0;
|
||||||
}
|
}
|
||||||
|
uint8_t * last_written_app_address;
|
||||||
|
|
||||||
|
#include "version.h"
|
||||||
|
bool is_firmware_version_newer_or_equal()
|
||||||
|
{
|
||||||
|
|
||||||
|
printf1(TAG_BOOT,"Current firmware version: %u.%u.%u.%u (%02x.%02x.%02x.%02x)\r\n",
|
||||||
|
current_firmware_version.major, current_firmware_version.minor, current_firmware_version.patch, current_firmware_version.reserved,
|
||||||
|
current_firmware_version.major, current_firmware_version.minor, current_firmware_version.patch, current_firmware_version.reserved
|
||||||
|
);
|
||||||
|
volatile version_t * new_version = ((volatile version_t *) last_written_app_address);
|
||||||
|
printf1(TAG_BOOT,"Uploaded firmware version: %u.%u.%u.%u (%02x.%02x.%02x.%02x)\r\n",
|
||||||
|
new_version->major, new_version->minor, new_version->patch, new_version->reserved,
|
||||||
|
new_version->major, new_version->minor, new_version->patch, new_version->reserved
|
||||||
|
);
|
||||||
|
|
||||||
|
const bool allowed = is_newer(new_version, ¤t_firmware_version) || current_firmware_version.raw == 0xFFFFFFFF;
|
||||||
|
if (allowed){
|
||||||
|
printf1(TAG_BOOT, "Update allowed, setting new firmware version as current.\r\n");
|
||||||
|
// current_firmware_version.raw = new_version.raw;
|
||||||
|
uint8_t page[PAGE_SIZE];
|
||||||
|
memmove(page, (uint8_t*)BOOT_VERSION_ADDR, PAGE_SIZE);
|
||||||
|
memmove(page, new_version, 4);
|
||||||
|
printf1(TAG_BOOT, "Writing\r\n");
|
||||||
|
flash_erase_page(BOOT_VERSION_PAGE);
|
||||||
|
flash_write(BOOT_VERSION_ADDR, page, PAGE_SIZE);
|
||||||
|
printf1(TAG_BOOT, "Finish\r\n");
|
||||||
|
} else {
|
||||||
|
printf1(TAG_BOOT, "Firmware older - update not allowed.\r\n");
|
||||||
|
}
|
||||||
|
return allowed;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute bootloader commands
|
* Execute bootloader commands
|
||||||
@ -125,10 +161,7 @@ int bootloader_bridge(int klen, uint8_t * keyh)
|
|||||||
return CTAP1_ERR_INVALID_LENGTH;
|
return CTAP1_ERR_INVALID_LENGTH;
|
||||||
}
|
}
|
||||||
#ifndef SOLO_HACKER
|
#ifndef SOLO_HACKER
|
||||||
uint8_t * pubkey = (uint8_t*)"\xd2\xa4\x2f\x8f\xb2\x31\x1c\xc1\xf7\x0c\x7e\x64\x32\xfb\xbb\xb4\xa3\xdd\x32\x20"
|
extern uint8_t *pubkey_boot;
|
||||||
"\x0f\x1b\x88\x9c\xda\x62\xc2\x83\x25\x93\xdd\xb8\x75\x9d\xf9\x86\xee\x03\x6c\xce"
|
|
||||||
"\x34\x47\x71\x36\xb3\xb2\xad\x6d\x12\xb7\xbe\x49\x3e\x20\xa4\x61\xac\xc7\x71\xc7"
|
|
||||||
"\x1f\xa8\x14\xf2";
|
|
||||||
|
|
||||||
const struct uECC_Curve_t * curve = NULL;
|
const struct uECC_Curve_t * curve = NULL;
|
||||||
#endif
|
#endif
|
||||||
@ -165,12 +198,11 @@ int bootloader_bridge(int klen, uint8_t * keyh)
|
|||||||
}
|
}
|
||||||
// Do the actual write
|
// Do the actual write
|
||||||
flash_write((uint32_t)ptr,req->payload, len);
|
flash_write((uint32_t)ptr,req->payload, len);
|
||||||
|
last_written_app_address = (uint8_t *)ptr + len - 8 + 4;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case BootDone:
|
case BootDone:
|
||||||
// Writing to flash finished. Request code validation.
|
// Writing to flash finished. Request code validation.
|
||||||
printf1(TAG_BOOT, "BootDone: ");
|
printf1(TAG_BOOT, "BootDone: \r\n");
|
||||||
#ifndef SOLO_HACKER
|
#ifndef SOLO_HACKER
|
||||||
if (len != 64)
|
if (len != 64)
|
||||||
{
|
{
|
||||||
@ -185,17 +217,23 @@ int bootloader_bridge(int klen, uint8_t * keyh)
|
|||||||
crypto_sha256_final(hash);
|
crypto_sha256_final(hash);
|
||||||
curve = uECC_secp256r1();
|
curve = uECC_secp256r1();
|
||||||
// Verify incoming signature made over the SHA256 hash
|
// Verify incoming signature made over the SHA256 hash
|
||||||
if (! uECC_verify(pubkey,
|
if (
|
||||||
hash,
|
!uECC_verify(pubkey_boot, hash, 32, req->payload, curve)
|
||||||
32,
|
)
|
||||||
req->payload,
|
|
||||||
curve))
|
|
||||||
{
|
{
|
||||||
|
printf1(TAG_BOOT, "Signature invalid\r\n");
|
||||||
return CTAP2_ERR_OPERATION_DENIED;
|
return CTAP2_ERR_OPERATION_DENIED;
|
||||||
}
|
}
|
||||||
|
if (!is_firmware_version_newer_or_equal()){
|
||||||
|
printf1(TAG_BOOT, "Firmware older - update not allowed.\r\n");
|
||||||
|
printf1(TAG_BOOT, "Rebooting...\r\n");
|
||||||
|
REBOOT_FLAG = 1;
|
||||||
|
return CTAP2_ERR_OPERATION_DENIED;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
// Set the application validated, and mark for reboot.
|
// Set the application validated, and mark for reboot.
|
||||||
authorize_application();
|
authorize_application();
|
||||||
|
|
||||||
REBOOT_FLAG = 1;
|
REBOOT_FLAG = 1;
|
||||||
break;
|
break;
|
||||||
case BootCheck:
|
case BootCheck:
|
||||||
@ -218,6 +256,7 @@ int bootloader_bridge(int klen, uint8_t * keyh)
|
|||||||
break;
|
break;
|
||||||
case BootReboot:
|
case BootReboot:
|
||||||
printf1(TAG_BOOT, "BootReboot.\r\n");
|
printf1(TAG_BOOT, "BootReboot.\r\n");
|
||||||
|
printf1(TAG_BOOT, "Application authorized: %d.\r\n", is_authorized_to_boot());
|
||||||
REBOOT_FLAG = 1;
|
REBOOT_FLAG = 1;
|
||||||
break;
|
break;
|
||||||
case BootDisable:
|
case BootDisable:
|
||||||
|
@ -138,6 +138,14 @@ int main()
|
|||||||
|
|
||||||
printf1(TAG_GEN,"recv'ing hid msg \n");
|
printf1(TAG_GEN,"recv'ing hid msg \n");
|
||||||
|
|
||||||
|
extern volatile version_t current_firmware_version;
|
||||||
|
printf1(TAG_BOOT,"Current firmware version address: %p\r\n", ¤t_firmware_version);
|
||||||
|
printf1(TAG_BOOT,"Current firmware version: %d.%d.%d.%d (%02x.%02x.%02x.%02x)\r\n",
|
||||||
|
current_firmware_version.major, current_firmware_version.minor, current_firmware_version.patch, current_firmware_version.reserved,
|
||||||
|
current_firmware_version.major, current_firmware_version.minor, current_firmware_version.patch, current_firmware_version.reserved
|
||||||
|
);
|
||||||
|
dump_hex1(TAG_BOOT, (uint8_t*)(¤t_firmware_version) - 16, 32);
|
||||||
|
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
|
6
targets/stm32l432/bootloader/pubkey_bootloader.c
Normal file
6
targets/stm32l432/bootloader/pubkey_bootloader.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
uint8_t * pubkey_boot = (uint8_t*)"\xd2\xa4\x2f\x8f\xb2\x31\x1c\xc1\xf7\x0c\x7e\x64\x32\xfb\xbb\xb4\xa3\xdd\x32\x20"
|
||||||
|
"\x0f\x1b\x88\x9c\xda\x62\xc2\x83\x25\x93\xdd\xb8\x75\x9d\xf9\x86\xee\x03\x6c\xce"
|
||||||
|
"\x34\x47\x71\x36\xb3\xb2\xad\x6d\x12\xb7\xbe\x49\x3e\x20\xa4\x61\xac\xc7\x71\xc7"
|
||||||
|
"\x1f\xa8\x14\xf2";
|
8
targets/stm32l432/bootloader/version_check.c
Normal file
8
targets/stm32l432/bootloader/version_check.c
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
// FIXME test version check function
|
||||||
|
bool is_newer(const version_t* const newer, const version_t* const older){
|
||||||
|
return (newer->major > older->major) ||
|
||||||
|
(newer->major == older->major && newer->minor > older->minor) ||
|
||||||
|
(newer->major == older->major && newer->minor == older->minor && newer->patch >= older->patch);
|
||||||
|
}
|
@ -10,6 +10,7 @@ SRC += $(DRIVER_LIBS) $(USB_LIB)
|
|||||||
SRC += ../../fido2/apdu.c ../../fido2/util.c ../../fido2/u2f.c ../../fido2/test_power.c
|
SRC += ../../fido2/apdu.c ../../fido2/util.c ../../fido2/u2f.c ../../fido2/test_power.c
|
||||||
SRC += ../../fido2/stubs.c ../../fido2/log.c ../../fido2/ctaphid.c ../../fido2/ctap.c
|
SRC += ../../fido2/stubs.c ../../fido2/log.c ../../fido2/ctaphid.c ../../fido2/ctap.c
|
||||||
SRC += ../../fido2/ctap_parse.c ../../fido2/main.c
|
SRC += ../../fido2/ctap_parse.c ../../fido2/main.c
|
||||||
|
SRC += ../../fido2/version.c
|
||||||
SRC += ../../fido2/data_migration.c
|
SRC += ../../fido2/data_migration.c
|
||||||
SRC += ../../fido2/extensions/extensions.c ../../fido2/extensions/solo.c
|
SRC += ../../fido2/extensions/extensions.c ../../fido2/extensions/solo.c
|
||||||
SRC += ../../fido2/extensions/wallet.c
|
SRC += ../../fido2/extensions/wallet.c
|
||||||
@ -70,6 +71,7 @@ all: $(TARGET).elf
|
|||||||
|
|
||||||
%.elf: $(OBJ)
|
%.elf: $(OBJ)
|
||||||
$(CC) $^ $(HW) $(LDFLAGS) -o $@
|
$(CC) $^ $(HW) $(LDFLAGS) -o $@
|
||||||
|
@echo "Built version: $(VERSION_FLAGS)"
|
||||||
|
|
||||||
%.hex: %.elf
|
%.hex: %.elf
|
||||||
$(SZ) $^
|
$(SZ) $^
|
||||||
|
@ -2,6 +2,7 @@ include build/common.mk
|
|||||||
|
|
||||||
# ST related
|
# ST related
|
||||||
SRC = bootloader/main.c bootloader/bootloader.c
|
SRC = bootloader/main.c bootloader/bootloader.c
|
||||||
|
SRC += bootloader/pubkey_bootloader.c bootloader/version_check.c
|
||||||
SRC += src/init.c src/redirect.c src/flash.c src/rng.c src/led.c src/device.c
|
SRC += src/init.c src/redirect.c src/flash.c src/rng.c src/led.c src/device.c
|
||||||
SRC += src/fifo.c src/crypto.c src/attestation.c src/sense.c
|
SRC += src/fifo.c src/crypto.c src/attestation.c src/sense.c
|
||||||
SRC += src/startup_stm32l432xx.s src/system_stm32l4xx.c
|
SRC += src/startup_stm32l432xx.s src/system_stm32l4xx.c
|
||||||
@ -65,6 +66,7 @@ all: $(TARGET).elf
|
|||||||
|
|
||||||
%.elf: $(OBJ)
|
%.elf: $(OBJ)
|
||||||
$(CC) $^ $(HW) $(LDFLAGS) -o $@
|
$(CC) $^ $(HW) $(LDFLAGS) -o $@
|
||||||
|
arm-none-eabi-size $@
|
||||||
|
|
||||||
%.hex: %.elf
|
%.hex: %.elf
|
||||||
$(CP) -O ihex $^ $(TARGET).hex
|
$(CP) -O ihex $^ $(TARGET).hex
|
||||||
|
@ -12,9 +12,17 @@ _estack = 0x2000c000;
|
|||||||
|
|
||||||
_MIN_STACK_SIZE = 0x400;
|
_MIN_STACK_SIZE = 0x400;
|
||||||
|
|
||||||
|
/*
|
||||||
|
flash_cfg is for storing bootloader data, like last used firmware version.
|
||||||
|
bootloader_configuration should be equal to (APPLICATION_END_PAGE) page address, from targets/stm32l432/src/memory_layout.h:30; and equal to flash_cfg origin
|
||||||
|
*/
|
||||||
|
|
||||||
|
bootloader_configuration = 0x08000000 + 216*1024+8;
|
||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
flash (rx) : ORIGIN = 0x08000000, LENGTH = 20K
|
flash (rx) : ORIGIN = 0x08000000, LENGTH = 20K
|
||||||
|
flash_cfg (rx) : ORIGIN = 0x08000000 + 216*1024+8, LENGTH = 2K-8
|
||||||
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
|
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
|
||||||
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
|
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
|
||||||
}
|
}
|
||||||
@ -39,6 +47,11 @@ SECTIONS
|
|||||||
_etext = .;
|
_etext = .;
|
||||||
} >flash
|
} >flash
|
||||||
|
|
||||||
|
.flag2 bootloader_configuration :
|
||||||
|
{
|
||||||
|
KEEP(*(.flag2)) ;
|
||||||
|
} > flash_cfg
|
||||||
|
|
||||||
_sidata = LOADADDR(.data);
|
_sidata = LOADADDR(.data);
|
||||||
|
|
||||||
.data :
|
.data :
|
||||||
|
@ -12,9 +12,17 @@ _estack = 0x2000c000;
|
|||||||
|
|
||||||
_MIN_STACK_SIZE = 0x400;
|
_MIN_STACK_SIZE = 0x400;
|
||||||
|
|
||||||
|
/*
|
||||||
|
flash_cfg is for storing bootloader data, like last used firmware version.
|
||||||
|
bootloader_configuration should be equal to (APPLICATION_END_PAGE) page address, from targets/stm32l432/src/memory_layout.h:30; and equal to flash_cfg origin
|
||||||
|
*/
|
||||||
|
|
||||||
|
bootloader_configuration = 0x08000000 + 216*1024+8;
|
||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
flash (rx) : ORIGIN = 0x08000000, LENGTH = 32K
|
flash (rx) : ORIGIN = 0x08000000, LENGTH = 32K
|
||||||
|
flash_cfg (rx) : ORIGIN = 0x08000000 + 216*1024+8, LENGTH = 2K-8
|
||||||
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
|
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
|
||||||
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
|
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
|
||||||
}
|
}
|
||||||
@ -39,6 +47,11 @@ SECTIONS
|
|||||||
_etext = .;
|
_etext = .;
|
||||||
} >flash
|
} >flash
|
||||||
|
|
||||||
|
.flag2 bootloader_configuration :
|
||||||
|
{
|
||||||
|
KEEP(*(.flag2)) ;
|
||||||
|
} > flash_cfg
|
||||||
|
|
||||||
_sidata = LOADADDR(.data);
|
_sidata = LOADADDR(.data);
|
||||||
|
|
||||||
.data :
|
.data :
|
||||||
|
@ -13,14 +13,21 @@ _estack = 0x2000c000;
|
|||||||
_MIN_STACK_SIZE = 0x400;
|
_MIN_STACK_SIZE = 0x400;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Memory layout of device:
|
len | 20 KB/10p| 196KB-8-8/98p | 2kB/1p | 38 KB/19p |
|
||||||
20 KB 198KB-8 38 KB
|
pos | 0->20 KB | 20->216KB-8-8 | 216kB -> 218 kB | 218->256 KB |
|
||||||
| bootloader | application | secrets/data |
|
posp | 0-10 | 10-113 | 113-114 | 113-128 |
|
||||||
|
desc | bootloader | application | bootloader data | secrets/data |
|
||||||
|
|
||||||
|
Last 8 bytes in application space are occupied by bootloader flags - app
|
||||||
|
authorization and bootloader activation flag.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Current firmware version number is concatenated to the firmware code - see .flag marker */
|
||||||
|
/* flash length is (APPLICATION_END_PAGE-20*1024), where 20K is bootloader */
|
||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
flash (rx) : ORIGIN = 0x08005000, LENGTH = 198K - 8
|
flash (rx) : ORIGIN = 0x08000000 + 20K, LENGTH = 216K - 20K - 8
|
||||||
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
|
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
|
||||||
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
|
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
|
||||||
}
|
}
|
||||||
@ -56,6 +63,12 @@ SECTIONS
|
|||||||
_edata = .;
|
_edata = .;
|
||||||
} >ram AT> flash
|
} >ram AT> flash
|
||||||
|
|
||||||
|
.flag :
|
||||||
|
{
|
||||||
|
. = ALIGN(8);
|
||||||
|
KEEP(*(.flag)) ;
|
||||||
|
} > flash
|
||||||
|
|
||||||
.bss :
|
.bss :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
@ -12,9 +12,22 @@ _estack = 0x2000c000;
|
|||||||
|
|
||||||
_MIN_STACK_SIZE = 0x400;
|
_MIN_STACK_SIZE = 0x400;
|
||||||
|
|
||||||
|
/*
|
||||||
|
len | 32 KB/16p| 184KB-8-8/92p | 2kB/1p | 38 KB/19p |
|
||||||
|
pos | 0->32 KB | 32->216KB-8-8 | 216kB -> 218 kB | 218->256 KB |
|
||||||
|
posp | 0-16 | 16-113 | 113-114 | 113-128 |
|
||||||
|
desc | bootloader | application | bootloader data | secrets/data |
|
||||||
|
|
||||||
|
Last 8 bytes in application space are occupied by bootloader flags - app
|
||||||
|
authorization and bootloader activation flag.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Current firmware version number is concatenated to the firmware code - see .flag marker */
|
||||||
|
/* flash length is (APPLICATION_END_PAGE-20*1024), where 20K is bootloader */
|
||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
flash (rx) : ORIGIN = 0x08008000, LENGTH = 186K - 8
|
flash (rx) : ORIGIN = 0x08000000 + 20K + 12K, LENGTH = 216K - 20K - 12K - 8
|
||||||
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
|
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
|
||||||
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
|
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
|
||||||
}
|
}
|
||||||
@ -50,6 +63,12 @@ SECTIONS
|
|||||||
_edata = .;
|
_edata = .;
|
||||||
} >ram AT> flash
|
} >ram AT> flash
|
||||||
|
|
||||||
|
.flag :
|
||||||
|
{
|
||||||
|
. = ALIGN(8);
|
||||||
|
KEEP(*(.flag)) ;
|
||||||
|
} > flash
|
||||||
|
|
||||||
.bss :
|
.bss :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
@ -37,10 +37,33 @@
|
|||||||
|
|
||||||
// End of application code. Leave some extra room for future data storage.
|
// End of application code. Leave some extra room for future data storage.
|
||||||
// NOT included in application
|
// NOT included in application
|
||||||
#define APPLICATION_END_PAGE ((PAGES - 19))
|
#define APPLICATION_END_PAGE ((PAGES - 20))
|
||||||
#define APPLICATION_END_ADDR ((0x08000000 + ((APPLICATION_END_PAGE)*PAGE_SIZE))-8)
|
#define APPLICATION_END_ADDR ((0x08000000 + ((APPLICATION_END_PAGE)*PAGE_SIZE))-8)
|
||||||
|
|
||||||
// Bootloader state.
|
// Bootloader state.
|
||||||
#define AUTH_WORD_ADDR (APPLICATION_END_ADDR)
|
#define AUTH_WORD_ADDR (APPLICATION_END_ADDR)
|
||||||
|
|
||||||
|
#define LAST_ADDR (APPLICATION_END_ADDR-2048 + 8)
|
||||||
|
#define BOOT_VERSION_PAGE (APPLICATION_END_PAGE)
|
||||||
|
#define BOOT_VERSION_ADDR (0x08000000 + BOOT_VERSION_PAGE*FLASH_PAGE_SIZE + 8)
|
||||||
|
#define LAST_PAGE (APPLICATION_END_PAGE-1)
|
||||||
|
|
||||||
|
|
||||||
|
struct flash_memory_st{
|
||||||
|
uint8_t bootloader[APPLICATION_START_PAGE*2*1024];
|
||||||
|
uint8_t application[(APPLICATION_END_PAGE-APPLICATION_START_PAGE)*2*1024-8];
|
||||||
|
uint8_t auth_word[4];
|
||||||
|
uint8_t bootloader_disabled[4];
|
||||||
|
// place for more user data
|
||||||
|
uint8_t _reserved_application_end_mark[8];
|
||||||
|
uint8_t bootloader_data[2*1024-8];
|
||||||
|
uint8_t user_data[38*1024];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
typedef struct flash_memory_st flash_memory_st;
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
static_assert(sizeof(flash_memory_st) == 256*1024, "Data structure doesn't match flash size");
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user