@@ -88,6 +88,29 @@ int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr);
88
88
void s2ram_designate_slot (uint8_t slot );
89
89
#endif
90
90
91
+ #ifdef CONFIG_PARTITION_MANAGER_ENABLED
92
+ #define THREE_CAT_ (a , b , c ) (a##b##c)
93
+ #define THREE_CAT (a , b , c ) THREE_CAT_(a, b, c)
94
+
95
+ #ifdef CONFIG_NCS_IS_VARIANT_IMAGE
96
+ /* Running from slot 1, checking slot 0 */
97
+ #define NCS_VARIANT_SLOT_ID 0
98
+ #else /* CONFIG_NCS_IS_VARIANT_IMAGE */
99
+ /* Running from slot 0, checking slot 1 */
100
+ #define NCS_VARIANT_SLOT_ID 1
101
+ #endif /* CONFIG_NCS_IS_VARIANT_IMAGE */
102
+
103
+ #define NCS_VARIANT_SLOT_MIN_ADDR THREE_CAT(PM_S, NCS_VARIANT_SLOT_ID, _ADDRESS)
104
+ #define NCS_VARIANT_SLOT_MAX_ADDR ((NCS_VARIANT_SLOT_MIN_ADDR) + THREE_CAT(PM_S, NCS_VARIANT_SLOT_ID, _SIZE))
105
+
106
+ #if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER == -1
107
+ #define CHECK_MCUBOOT_IMAGE 0
108
+ #else
109
+ #define CHECK_MCUBOOT_IMAGE 1
110
+ #endif
111
+
112
+ #endif /* CONFIG_PARTITION_MANAGER_ENABLED */
113
+
91
114
BOOT_LOG_MODULE_DECLARE (mcuboot );
92
115
93
116
static struct boot_loader_state boot_data ;
@@ -1154,7 +1177,8 @@ boot_validate_slot(struct boot_loader_state *state, int slot,
1154
1177
goto out ;
1155
1178
}
1156
1179
1157
- #if MCUBOOT_IMAGE_NUMBER > 1 && !defined(MCUBOOT_ENC_IMAGES ) && defined(MCUBOOT_VERIFY_IMG_ADDRESS )
1180
+ #if defined(MCUBOOT_VERIFY_IMG_ADDRESS ) && !defined(MCUBOOT_ENC_IMAGES ) || \
1181
+ defined(CONFIG_MCUBOOT_USE_CHECK_LOAD_ADDRESS )
1158
1182
/* Verify that the image in the secondary slot has a reset address
1159
1183
* located in the primary slot. This is done to avoid users incorrectly
1160
1184
* overwriting an application written to the incorrect slot.
@@ -1171,58 +1195,72 @@ boot_validate_slot(struct boot_loader_state *state, int slot,
1171
1195
}
1172
1196
#endif
1173
1197
if (fap == BOOT_IMG_AREA (state , BOOT_SLOT_SECONDARY )) {
1174
- const struct flash_area * pri_fa = BOOT_IMG_AREA (state , BOOT_SLOT_PRIMARY );
1175
1198
struct image_header * secondary_hdr = boot_img_hdr (state , slot );
1176
- uint32_t reset_value = 0 ;
1177
- uint32_t reset_addr = secondary_hdr -> ih_hdr_size + sizeof (reset_value );
1178
- uint32_t min_addr , max_addr ;
1179
- bool check_addresses = false;
1199
+ uint32_t internal_img_addr = 0 ; /* either the reset handler addres or the image beginning addres */
1200
+ uint32_t min_addr ;
1201
+ uint32_t max_addr ;
1202
+
1203
+ min_addr = flash_area_get_off (BOOT_IMG_AREA (state , BOOT_SLOT_PRIMARY ));
1204
+ max_addr = flash_area_get_size (BOOT_IMG_AREA (state , BOOT_SLOT_PRIMARY )) + min_addr ;
1180
1205
1181
- if (flash_area_read (fap , reset_addr , & reset_value , sizeof (reset_value )) != 0 ) {
1206
+ #ifdef CONFIG_MCUBOOT_USE_CHECK_LOAD_ADDRESS
1207
+ internal_img_addr = secondary_hdr -> ih_load_addr ;
1208
+ #else
1209
+ const uint32_t offset = secondary_hdr -> ih_hdr_size + sizeof (internal_img_addr );
1210
+ BOOT_LOG_DBG ("Getting image %d internal addr from offset %u" ,
1211
+ BOOT_CURR_IMG (state ), offset );
1212
+ /* Read reset vector from ARM vector table */
1213
+ if (flash_area_read (fap , offset , & internal_img_addr , sizeof (internal_img_addr )) != 0 ) {
1214
+ BOOT_LOG_ERR ("Failed to read image %d load address" , BOOT_CURR_IMG (state ));
1182
1215
fih_rc = FIH_NO_BOOTABLE_IMAGE ;
1183
1216
goto out ;
1184
1217
}
1218
+ #endif
1219
+ BOOT_LOG_DBG ("Image %d expected load address 0x%x" , BOOT_CURR_IMG (state ), internal_img_addr );
1185
1220
1186
- #ifdef PM_CPUNET_APP_ADDRESS
1221
+ #ifdef CONFIG_PARTITION_MANAGER_ENABLED
1187
1222
/* The primary slot for the network core is emulated in RAM.
1188
1223
* Its flash_area hasn't got relevant boundaries.
1189
1224
* Therfore need to override its boundaries for the check.
1190
1225
*/
1226
+ #ifdef PM_CPUNET_APP_ADDRESS
1191
1227
if (BOOT_CURR_IMG (state ) == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER ) {
1228
+
1229
+ BOOT_LOG_DBG ("Image %d is NETCORE image" , BOOT_CURR_IMG (state ));
1230
+
1192
1231
min_addr = PM_CPUNET_APP_ADDRESS ;
1193
1232
max_addr = PM_CPUNET_APP_ADDRESS + PM_CPUNET_APP_SIZE ;
1194
- check_addresses = true;
1195
- } else
1196
- #endif
1197
- #if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != - 1
1233
+ }
1234
+ #endif /* PM_CPUNET_APP_SIZE */
1235
+
1236
+ #if CHECK_MCUBOOT_IMAGE == 1
1198
1237
if (BOOT_CURR_IMG (state ) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER ) {
1199
- #if (CONFIG_NCS_IS_VARIANT_IMAGE )
1200
- min_addr = PM_S0_ADDRESS ;
1201
- max_addr = (PM_S0_ADDRESS + PM_S0_SIZE );
1202
- #else
1203
- min_addr = PM_S1_ADDRESS ;
1204
- max_addr = (PM_S1_ADDRESS + PM_S1_SIZE );
1205
- #endif
1206
- check_addresses = true;
1207
- } else
1208
- #endif
1238
+
1239
+ BOOT_LOG_DBG ("Image %d is another stage MCBoot image" , BOOT_CURR_IMG (state ));
1240
+
1241
+ min_addr = NCS_VARIANT_SLOT_MIN_ADDR ;
1242
+ max_addr = NCS_VARIANT_SLOT_MAX_ADDR ;
1243
+ }
1244
+ #endif /* CHECK_MCUBOOT_IMAGE */
1245
+
1246
+ #if CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER != -1
1209
1247
if (BOOT_CURR_IMG (state ) == CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER ) {
1210
- #if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1
1211
- #if (CONFIG_NCS_IS_VARIANT_IMAGE )
1212
- min_addr = MIN (pri_fa -> fa_off , PM_S0_ADDRESS );
1213
- max_addr = MAX ((pri_fa -> fa_off + pri_fa -> fa_size ), (PM_S0_ADDRESS + PM_S0_SIZE ));
1214
- #else
1215
- min_addr = MIN (pri_fa -> fa_off , PM_S1_ADDRESS );
1216
- max_addr = MAX ((pri_fa -> fa_off + pri_fa -> fa_size ), (PM_S1_ADDRESS + PM_S1_SIZE ));
1217
- #endif
1218
- #else
1219
- min_addr = pri_fa -> fa_off ;
1220
- max_addr = pri_fa -> fa_off + pri_fa -> fa_size ;
1248
+
1249
+ BOOT_LOG_DBG ("Image %d is application MCBoot image" , BOOT_CURR_IMG (state ));
1250
+
1251
+ /* If not checking the MCUboot image, then we leave the original
1252
+ * min/max assignments from the primary slot read. */
1253
+ #if CHECK_MCUBOOT_IMAGE == 1
1254
+ min_addr = MIN (min_addr , NCS_VARIANT_SLOT_MIN_ADDR );
1255
+ max_addr = MAX (max_addr , NCS_VARIANT_SLOT_MAX_ADDR );
1221
1256
#endif
1222
- check_addresses = true;
1223
1257
}
1258
+ #endif
1259
+ #endif /* CONFIG_PARTITION_MANAGER_ENABLED */
1224
1260
1225
- if (check_addresses == true && (reset_value < min_addr || reset_value > max_addr )) {
1261
+ BOOT_LOG_DBG ("Check 0x%x is within [min_addr, max_addr] = [0x%x, 0x%x)" ,
1262
+ internal_img_addr , min_addr , max_addr );
1263
+ if (internal_img_addr < min_addr || internal_img_addr >= max_addr ) {
1226
1264
BOOT_LOG_ERR ("Reset address of image in secondary slot is not in the primary slot" );
1227
1265
BOOT_LOG_ERR ("Erasing image from secondary slot" );
1228
1266
@@ -1236,6 +1274,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot,
1236
1274
fih_rc = FIH_NO_BOOTABLE_IMAGE ;
1237
1275
goto out ;
1238
1276
}
1277
+ BOOT_LOG_DBG ("Image %d validation OK" , BOOT_CURR_IMG (state ));
1239
1278
}
1240
1279
#endif
1241
1280
@@ -1439,6 +1478,18 @@ static inline void sec_slot_cleanup_if_unusable(void)
1439
1478
#endif /* defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\
1440
1479
defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) */
1441
1480
1481
+ #define IS_IN_RANGE_CPUNET_APP_ADDR (_addr ) (((_addr) >= PM_CPUNET_APP_ADDRESS) && ((_addr) < PM_CPUNET_APP_END_ADDRESS))
1482
+ #define _IS_IN_RANGE_S_VARIANT_ADDR (_addr , x ) (((_addr) >= PM_S##x##_ADDRESS) && ((_addr) <= (PM_S##x##_ADDRESS + PM_S##x##_SIZE)))
1483
+ #if defined(CONFIG_NCS_IS_VARIANT_IMAGE )
1484
+ #define IS_IN_RANGE_S_ALTERNATE_ADDR (_addr ) _IS_IN_RANGE_S_VARIANT_ADDR(_addr, 0)
1485
+ #define IS_IN_RANGE_S_CURRENT_ADDR (_addr ) _IS_IN_RANGE_S_VARIANT_ADDR(_addr, 1)
1486
+ #else
1487
+ #define IS_IN_RANGE_S_ALTERNATE_ADDR (_addr ) _IS_IN_RANGE_S_VARIANT_ADDR(_addr, 1)
1488
+ #define IS_IN_RANGE_S_CURRENT_ADDR (_addr ) _IS_IN_RANGE_S_VARIANT_ADDR(_addr, 0)
1489
+ #endif
1490
+ #define IS_IN_RANGE_IMAGE_ADDR (_addr , _fa ) \
1491
+ (((_addr) >= flash_area_get_off(_fa)) && (_addr) < (flash_area_get_off(_fa) + flash_area_get_size(_fa)))
1492
+
1442
1493
/**
1443
1494
* Determines which swap operation to perform, if any. If it is determined
1444
1495
* that a swap operation is required, the image in the secondary slot is checked
@@ -1462,8 +1513,9 @@ boot_validated_swap_type(struct boot_loader_state *state,
1462
1513
const struct flash_area * secondary_fa =
1463
1514
BOOT_IMG_AREA (state , BOOT_SLOT_SECONDARY );
1464
1515
struct image_header * hdr = boot_img_hdr (state , BOOT_SLOT_SECONDARY );
1465
- uint32_t reset_addr = 0 ;
1516
+ uint32_t internal_img_addr = 0 ; /* either the reset handler addres or the image beginning addres */
1466
1517
int rc = 0 ;
1518
+
1467
1519
/* Patch needed for NCS. Since image 0 (the app) and image 1 (the other
1468
1520
* B1 slot S0 or S1) share the same secondary slot, we need to check
1469
1521
* whether the update candidate in the secondary slot is intended for
@@ -1473,18 +1525,22 @@ boot_validated_swap_type(struct boot_loader_state *state,
1473
1525
*/
1474
1526
1475
1527
if (hdr -> ih_magic == IMAGE_MAGIC ) {
1528
+ #ifdef CONFIG_MCUBOOT_USE_CHECK_LOAD_ADDRESS
1529
+ internal_img_addr = hdr -> ih_load_addr ;
1530
+ #else
1476
1531
rc = flash_area_read (secondary_fa , hdr -> ih_hdr_size +
1477
- sizeof (uint32_t ), & reset_addr ,
1478
- sizeof (reset_addr ));
1532
+ sizeof (uint32_t ), & internal_img_addr ,
1533
+ sizeof (internal_img_addr ));
1479
1534
if (rc != 0 ) {
1480
1535
return BOOT_SWAP_TYPE_FAIL ;
1481
1536
}
1537
+ #endif /* CONFIG_MCUBOOT_USE_CHECK_LOAD_ADDRESS */
1482
1538
1483
1539
sec_slot_touch (state );
1484
1540
1485
1541
#ifdef PM_S1_ADDRESS
1486
1542
#ifdef PM_CPUNET_B0N_ADDRESS
1487
- if (!( reset_addr >= PM_CPUNET_APP_ADDRESS && reset_addr < PM_CPUNET_APP_END_ADDRESS ))
1543
+ if (!IS_IN_RANGE_CPUNET_APP_ADDR ( internal_img_addr ))
1488
1544
#endif
1489
1545
{
1490
1546
const struct flash_area * primary_fa ;
@@ -1496,11 +1552,7 @@ boot_validated_swap_type(struct boot_loader_state *state,
1496
1552
}
1497
1553
1498
1554
/* Check start and end of primary slot for current image */
1499
- #if (CONFIG_NCS_IS_VARIANT_IMAGE )
1500
- if (reset_addr >= PM_S0_ADDRESS && reset_addr <= (PM_S0_ADDRESS + PM_S0_SIZE )) {
1501
- #else
1502
- if (reset_addr >= PM_S1_ADDRESS && reset_addr <= (PM_S1_ADDRESS + PM_S1_SIZE )) {
1503
- #endif
1555
+ if (IS_IN_RANGE_S_ALTERNATE_ADDR (internal_img_addr )) {
1504
1556
if (BOOT_CURR_IMG (state ) == CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER ) {
1505
1557
/* This is not the s0/s1 upgrade image but the application image, pretend
1506
1558
* there is no image so the NSIB update can be loaded
@@ -1509,18 +1561,14 @@ boot_validated_swap_type(struct boot_loader_state *state,
1509
1561
}
1510
1562
1511
1563
owner_nsib [BOOT_CURR_IMG (state )] = true;
1512
- #if (CONFIG_NCS_IS_VARIANT_IMAGE )
1513
- } else if (reset_addr >= PM_S1_ADDRESS && reset_addr <= (PM_S1_ADDRESS + PM_S1_SIZE )) {
1514
- #else
1515
- } else if (reset_addr >= PM_S0_ADDRESS && reset_addr <= (PM_S0_ADDRESS + PM_S0_SIZE )) {
1516
- #endif
1564
+ } else if (IS_IN_RANGE_S_CURRENT_ADDR (internal_img_addr )) {
1517
1565
/* NSIB upgrade but for the wrong slot, must be erased */
1518
1566
BOOT_LOG_ERR ("Image in slot is for wrong s0/s1 image" );
1519
1567
flash_area_erase (secondary_fa , 0 , secondary_fa -> fa_size );
1520
1568
sec_slot_untouch (state );
1521
1569
BOOT_LOG_ERR ("Cleaned-up secondary slot of image %d" , BOOT_CURR_IMG (state ));
1522
1570
return BOOT_SWAP_TYPE_FAIL ;
1523
- } else if (reset_addr < primary_fa -> fa_off || reset_addr > ( primary_fa -> fa_off + primary_fa -> fa_size )) {
1571
+ } else if (! IS_IN_RANGE_IMAGE_ADDR ( internal_img_addr , primary_fa )) {
1524
1572
/* The image in the secondary slot is not intended for any */
1525
1573
return BOOT_SWAP_TYPE_NONE ;
1526
1574
}
@@ -1557,8 +1605,7 @@ boot_validated_swap_type(struct boot_loader_state *state,
1557
1605
* update and indicate to the caller of this function that no update is
1558
1606
* available
1559
1607
*/
1560
- if (upgrade_valid && reset_addr >= PM_CPUNET_APP_ADDRESS &&
1561
- reset_addr < PM_CPUNET_APP_END_ADDRESS ) {
1608
+ if (upgrade_valid && IS_IN_RANGE_CPUNET_APP_ADDR (internal_img_addr )) {
1562
1609
struct image_header * hdr = (struct image_header * )secondary_fa -> fa_off ;
1563
1610
uint32_t vtable_addr = (uint32_t )hdr + hdr -> ih_hdr_size ;
1564
1611
uint32_t * net_core_fw_addr = (uint32_t * )(vtable_addr );
0 commit comments