- always enable flash protect

- clean up code
- add illustrated memory layout for quick ref
This commit is contained in:
hathach committed 2026-02-03 18:47:04 +07:00
1 parent 3714bb727d
commit 8c45bf843c
4 files changed
+92 -86

No files matched your search

-5
View File
@@ -28,7 +28,6 @@ set(MBR_HEX ${SOFTDEVICE_DIR}/mbr/hex/mbr_nrf52_2.4.1_mbr.hex)
set(TINYUSB_DIR ${CMAKE_CURRENT_LIST_DIR}/lib/tinyusb/src)
set(TCRYPT_DIR ${CMAKE_CURRENT_LIST_DIR}/lib/tinycrypt/lib)
option(SKIP_FLASH_PROT "Skip enabling MBR/BL FLASH overwrite protection from user application" OFF)
option(DEFAULT_TO_OTA_DFU "Default to OTA DFU instead of Serial DFU" OFF)
option(SIGNED_FW "Enable signed firmware verification" OFF)
option(DUALBANK_FW "Enable dual bank DFU support" OFF)
@@ -202,10 +201,6 @@ if (DEFAULT_TO_OTA_DFU)
target_compile_definitions(bootloader PUBLIC DEFAULT_TO_OTA_DFU)
endif ()
if (SKIP_FLASH_PROT)
target_compile_definitions(bootloader PUBLIC SKIP_FLASH_PROT)
endif ()
if (TRACE_ETM STREQUAL "1")
# ENABLE_TRACE will cause system_nrf5x.c to set up ETM trace
target_compile_definitions(bootloader PUBLIC ENABLE_TRACE)
-4
View File
@@ -11,7 +11,6 @@
# - DUALBANK_FW : If bootloader will implement a dual bank feature to allow autorecover from failed
# - FORCE_UF2 : if SIGNED_FW is 1, will force to include UF2 support (UNSECURE, UF2 does NOT validate signature!)
# - DEFAULT_TO_OTA_DFU : if entering DFU, by default enter OTA DFU instead of Serial DFU
# - SKIP_FLASH_PROT : Skip enabling protection against user application writing to FLASH MBR/Bootloader
#------------------------------------------------------------------------------
PYTHON = python
@@ -377,9 +376,6 @@ ifeq ($(DEFAULT_TO_OTA_DFU), 1)
CFLAGS += -DDEFAULT_TO_OTA_DFU
endif
ifeq ($(SKIP_FLASH_PROT), 1)
CFLAGS += -DSKIP_FLASH_PROT
endif
_VER = $(subst ., ,$(word 1, $(subst -, ,$(GIT_VERSION))))
CFLAGS += -DMK_BOOTLOADER_VERSION='($(word 1,$(_VER)) << 16) + ($(word 2,$(_VER)) << 8) + $(word 3,$(_VER))'
@@ -12,6 +12,8 @@
#include "bootloader_util.h"
#include "dfu_types.h"
#include "nrf_peripherals.h"
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
@@ -165,94 +167,76 @@ static inline void bootloader_util_reset(uint32_t start_addr)
#error Compiler not supported.
#endif
#ifndef SKIP_FLASH_PROT
uint32_t bootloader_util_flash_protect(uint32_t address, uint32_t size, bool read_protect)
{
if ((size & (CODE_PAGE_SIZE - 1)) || (address > BOOTLOADER_SETTINGS_ADDRESS))
{
return NRF_ERROR_INVALID_PARAM;
}
// protect flash region from write access
static uint32_t bootloader_util_flash_protect(uint32_t address, uint32_t size) {
if ((size & (CODE_PAGE_SIZE - 1)) || (address > BOOTLOADER_SETTINGS_ADDRESS)) {
return NRF_ERROR_INVALID_PARAM;
}
#if defined(ACL_PRESENT)
// Protect using ACL.
static uint32_t acl_instance = 0;
// Protect using ACL.
static uint32_t acl_instance = 0;
volatile ACL_ACL_Type *p_acl;
const uint32_t mask = (ACL_ACL_PERM_WRITE_Disable << ACL_ACL_PERM_WRITE_Pos);
uint32_t const wmask = (ACL_ACL_PERM_WRITE_Disable << ACL_ACL_PERM_WRITE_Pos);
uint32_t const rwmask = wmask | (ACL_ACL_PERM_READ_Disable << ACL_ACL_PERM_READ_Pos);
uint32_t const mask = read_protect ? rwmask: wmask;
do
{
if (acl_instance >= ACL_REGIONS_COUNT)
{
return NRF_ERROR_NO_MEM;
}
NRF_ACL->ACL[acl_instance].ADDR = address;
NRF_ACL->ACL[acl_instance].SIZE = size;
NRF_ACL->ACL[acl_instance].PERM = mask;
acl_instance++;
} while (NRF_ACL->ACL[acl_instance - 1].ADDR != address
|| NRF_ACL->ACL[acl_instance - 1].SIZE != size
|| NRF_ACL->ACL[acl_instance - 1].PERM != mask); // Check whether the acl_instance has been used before.
#elif defined (BPROT_PRESENT)
// Protect using BPROT. BPROT does not support read protection.
uint32_t pagenum_start = address / CODE_PAGE_SIZE;
uint32_t pagenum_end = pagenum_start + ((size - 1) / CODE_PAGE_SIZE);
for (uint32_t i = pagenum_start; i <= pagenum_end; i++)
{
uint32_t config_index = i / 32;
uint32_t mask = (1 << (i - config_index * 32));
switch (config_index)
{
case 0:
NRF_BPROT->CONFIG0 = mask;
break;
case 1:
NRF_BPROT->CONFIG1 = mask;
break;
#if BPROT_REGIONS_NUM > 64
case 2:
NRF_BPROT->CONFIG2 = mask;
break;
case 3:
NRF_BPROT->CONFIG3 = mask;
break;
#endif
}
do {
if (acl_instance >= ACL_REGIONS_COUNT) {
return NRF_ERROR_NO_MEM;
}
p_acl = &NRF_ACL->ACL[acl_instance];
p_acl->ADDR = address;
p_acl->SIZE = size;
p_acl->PERM = mask;
acl_instance++;
} while (p_acl->ADDR != address || p_acl->SIZE != size ||
p_acl->PERM != mask); // Check whether the acl_instance has been used before.
#elif defined(BPROT_PRESENT)
// Protect using BPROT. BPROT does not support read protection.
uint32_t pagenum_start = address / CODE_PAGE_SIZE;
uint32_t pagenum_end = pagenum_start + ((size - 1) / CODE_PAGE_SIZE);
for (uint32_t i = pagenum_start; i <= pagenum_end; i++) {
uint32_t config_index = i / 32;
uint32_t mask = (1 << (i - config_index * 32));
switch (config_index) {
case 0:
NRF_BPROT->CONFIG0 = mask;
break;
case 1:
NRF_BPROT->CONFIG1 = mask;
break;
#if BPROT_REGIONS_NUM > 64
case 2:
NRF_BPROT->CONFIG2 = mask;
break;
case 3:
NRF_BPROT->CONFIG3 = mask;
break;
#endif
}
}
#endif
return NRF_SUCCESS;
return NRF_SUCCESS;
}
#endif
void bootloader_util_app_start(uint32_t start_addr)
{
void bootloader_util_app_start(uint32_t start_addr) {
// Protect MBR against user writes
bootloader_util_flash_protect(0, MBR_SIZE);
#ifndef SKIP_FLASH_PROT
uint32_t area_size;
// Size of the bootloader flash area to protect (Bootloader + MBR params + Bootloader settings)
const uint32_t area_size = BOOTLOADER_SETTINGS_ADDRESS + CODE_PAGE_SIZE - BOOTLOADER_REGION_START;
// Protect MBR against user writes
bootloader_util_flash_protect(0, MBR_SIZE, false);
// Protect bootloader code and params pages against user writes
bootloader_util_flash_protect(BOOTLOADER_REGION_START, area_size);
// Size of the bootloader flash area to protect (Bootloader + MBR params + Bootloader settings)
area_size = BOOTLOADER_SETTINGS_ADDRESS + CODE_PAGE_SIZE - BOOTLOADER_REGION_START;
// Protect bootloader code and params pages against user writes
bootloader_util_flash_protect(BOOTLOADER_REGION_START,
area_size,
false);
#endif
// Jump to user application
bootloader_util_reset(start_addr);
// Jump to user application
bootloader_util_reset(start_addr);
}
@@ -20,6 +20,37 @@
* @brief Device Firmware Update module type and definitions.
*/
/*
* Flash layout (nrf52840, see linker/nrf52840.ld):
*
* -------------------------
* | Bootloader Settings |
* | 4 KB |
* |-------------------------| 0xFF000 BOOTLOADER_SETTINGS_ADDRESS
* | MBR Params Page |
* | 4 KB |
* |-------------------------| 0xFE000
* | Bootloader Config |
* | 2 KB |
* |-------------------------| 0xFD800
* | Bootloader |
* | 38 KB |
* |-------------------------| 0xF4000 BOOTLOADER_REGION_START
* | App Data Reserved |
* | 40 KB |
* |-------------------------| 0xEA000
* | Application |
* | Single/ Dual Bank |
* | |
* |-------------------------| CODE_REGION_1_START
* | SoftDevice |
* | 0x26000 (optional) |
* |-------------------------| 0x01000
* | MBR |
* | 4 KB |
* ------------------------- 0x00000
*/
#ifndef DFU_TYPES_H__
#define DFU_TYPES_H__