Skip to content

Commit 1057f55

Browse files
michalek-nonordicjm
authored andcommitted
bootloader: NSIB writes lock
Generate BOOTCONF contents to hex file and merge it. Signed-off-by: Mateusz Michalek <mateusz.michalek@nordicsemi.no> Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
1 parent be7d5bd commit 1057f55

File tree

8 files changed

+160
-5
lines changed

8 files changed

+160
-5
lines changed

CODEOWNERS

+1
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,7 @@
696696
/scripts/west_commands/thingy91x_dfu.py @nrfconnect/ncs-cia
697697
/scripts/west_commands/ncs_provision.py @nrfconnect/ncs-pluto
698698
/scripts/bootloader/ @nrfconnect/ncs-pluto
699+
/scripts/reglock.py @nrfconnect/ncs-pluto
699700
/scripts/ncs-docker-version.txt @nrfconnect/ncs-ci
700701
/scripts/print_docker_image.sh @nrfconnect/ncs-ci
701702
/scripts/print_toolchain_checksum.sh @nrfconnect/ncs-ci

cmake/sysbuild/bootconf.cmake

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
function(setup_bootconf_data)
8+
if(SB_CONFIG_PARTITION_MANAGER)
9+
add_custom_target(bootconf_target
10+
DEPENDS ${CMAKE_BINARY_DIR}/bootconf.hex
11+
)
12+
13+
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/bootconf.hex
14+
COMMAND ${Python3_EXECUTABLE}
15+
${ZEPHYR_NRF_MODULE_DIR}/scripts/reglock.py
16+
--output ${CMAKE_BINARY_DIR}/bootconf.hex
17+
--size $<TARGET_PROPERTY:partition_manager,PM_B0_SIZE>
18+
DEPENDS ${APPLICATION_BINARY_DIR}/pm.config
19+
VERBATIM
20+
)
21+
22+
set_property(
23+
GLOBAL PROPERTY
24+
bootconf_PM_HEX_FILE
25+
${CMAKE_BINARY_DIR}/bootconf.hex
26+
)
27+
28+
set_property(
29+
GLOBAL PROPERTY
30+
bootconf_PM_TARGET
31+
bootconf_target
32+
)
33+
endif()
34+
endfunction()
35+
36+
setup_bootconf_data()

cmake/sysbuild/partition_manager.cmake

+20-5
Original file line numberDiff line numberDiff line change
@@ -498,19 +498,25 @@ foreach(d APP ${PM_DOMAINS})
498498

499499
sysbuild_get(${image_name}_CONFIG_SOC_SERIES_NRF91X IMAGE ${image_name} VAR CONFIG_SOC_SERIES_NRF91X KCONFIG)
500500
sysbuild_get(${image_name}_CONFIG_SOC_NRF5340_CPUAPP IMAGE ${image_name} VAR CONFIG_SOC_NRF5340_CPUAPP KCONFIG)
501+
sysbuild_get(${image_name}_CONFIG_SOC_SERIES_NRF54LX IMAGE ${image_name} VAR CONFIG_SOC_SERIES_NRF54LX KCONFIG)
501502
sysbuild_get(${image_name}_CONFIG_SOC_NRF54L15_CPUAPP IMAGE ${image_name} VAR CONFIG_SOC_NRF54L15_CPUAPP KCONFIG)
502503

503-
if (${image_name}_CONFIG_SOC_SERIES_NRF91X)
504+
if(${image_name}_CONFIG_SOC_SERIES_NRF91X)
504505
# See nRF9160 Product Specification, chapter "UICR"
505506
set(otp_start_addr "0xff8108")
506507
set(otp_size 756) # 189 * 4
507-
elseif (${image_name}_CONFIG_SOC_NRF5340_CPUAPP)
508+
elseif(${image_name}_CONFIG_SOC_NRF5340_CPUAPP)
508509
# See nRF5340 Product Specification, chapter Application Core -> ... "UICR"
509510
set(otp_start_addr "0xff8100")
510511
set(otp_size 764) # 191 * 4
511-
elseif (DEFINED ${image_name}_CONFIG_SOC_NRF54L15_CPUAPP)
512-
set(otp_start_addr "0xffd500")
513-
set(otp_size 1276) # 319 * 4
512+
elseif(${image_name}_CONFIG_SOC_SERIES_NRF54LX)
513+
set(bootconf_start_addr "0xffd080")
514+
set(bootconf_size 4)
515+
516+
if(DEFINED ${image_name}_CONFIG_SOC_NRF54L15_CPUAPP)
517+
set(otp_start_addr "0xffd500")
518+
set(otp_size 1276) # 319 * 4
519+
endif()
514520
endif()
515521

516522
sysbuild_get(${image_name}_CONFIG_SOC_SERIES_NRF54LX IMAGE ${image_name} VAR CONFIG_SOC_SERIES_NRF54LX KCONFIG)
@@ -543,6 +549,15 @@ foreach(d APP ${PM_DOMAINS})
543549
DOMAIN ${d}
544550
)
545551
endif()
552+
if(${image_name}_CONFIG_SOC_SERIES_NRF54LX)
553+
add_region(
554+
NAME bootconf
555+
SIZE ${bootconf_size}
556+
BASE ${bootconf_start_addr}
557+
PLACEMENT start_to_end
558+
DOMAIN ${d}
559+
)
560+
endif()
546561
sysbuild_get(${image_name}_CONFIG_FLASH_BASE_ADDRESS IMAGE ${image_name} VAR CONFIG_FLASH_BASE_ADDRESS KCONFIG)
547562
add_region(
548563
NAME flash_primary

scripts/reglock.py

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Copyright 2025 Nordic Semiconductor ASA
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""
18+
NRF54L15 BOOTCONF generator.
19+
"""
20+
21+
from intelhex import IntelHex
22+
import argparse
23+
import sys
24+
25+
SIZE_MAX_KB = 31
26+
27+
BOOTCONF_ADDR = 0x00FFD080
28+
29+
READ_ALLOWED = 0x01
30+
WRITE_ALLOWED = 0x02
31+
EXECUTE_ALLOWED = 0x04
32+
SECURE = 0x08
33+
OWNER_NONE = 0x00
34+
OWNER_APP = 0x10
35+
OWNER_KMU = 0x20
36+
WRITEONCE = 0x10
37+
LOCK = 0x20
38+
39+
def parse_args():
40+
parser = argparse.ArgumentParser(
41+
description="Generate RRAMC's BOOTCONF configuration hex",
42+
formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False)
43+
44+
parser.add_argument("-o", "--output", required=False, default="b0_lock.hex",
45+
type=argparse.FileType('w', encoding='UTF-8'),
46+
help="Output file name.")
47+
parser.add_argument("-s", "--size", required=False, default="0x7C00",
48+
type=lambda x: hex(int(x, 0)),
49+
help="Size to lock.")
50+
return parser.parse_args()
51+
52+
53+
def main():
54+
args = parse_args()
55+
size = int(args.size, 16)
56+
if size % 1024:
57+
sys.exit("error: requested size not aligned to 1k")
58+
size = size // 1024
59+
if size > SIZE_MAX_KB:
60+
sys.exit("error: requested size too big")
61+
62+
payload = bytearray([
63+
READ_ALLOWED | EXECUTE_ALLOWED | SECURE | OWNER_NONE,
64+
LOCK,
65+
size,
66+
0x0
67+
])
68+
69+
h = IntelHex()
70+
h.frombytes(bytes=payload, offset=BOOTCONF_ADDR)
71+
h.tofile(args.output, 'hex')
72+
73+
if __name__ == "__main__":
74+
main()

subsys/partition_manager/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ if (CONFIG_NRF_MODEM_LIB)
7777
ncs_add_partition_manager_config(pm.yml.libmodem)
7878
endif()
7979

80+
if(CONFIG_SOC_NRF54L15_CPUAPP)
81+
ncs_add_partition_manager_config(pm.yml.bootconf)
82+
endif()
83+
8084
# The default DTS configuration for the nRF5340 CPUAPP includes the
8185
# the shared SRAM region, so, inform the partition manager about this
8286
# region.
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#if defined(CONFIG_SOC_SERIES_NRF54LX)
2+
bootconf:
3+
address: 0xffd080
4+
region: bootconf
5+
size: 0x4
6+
#endif /* CONFIG_SOC_SERIES_NRF54LX */

sysbuild/CMakeLists.txt

+8
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,10 @@ function(${SYSBUILD_CURRENT_MODULE_NAME}_pre_cmake)
506506
endif()
507507
endif()
508508

509+
if(SB_CONFIG_SECURE_BOOT_BOOTCONF_LOCK_WRITES)
510+
set_config_bool(b0 CONFIG_FPROTECT_ALLOW_COMBINED_REGIONS n)
511+
endif()
512+
509513
if(SB_CONFIG_SECURE_BOOT_NETCORE)
510514
if(NOT SB_CONFIG_NETCORE_NONE)
511515
set_config_bool(${SB_CONFIG_NETCORE_IMAGE_NAME} CONFIG_SECURE_BOOT y)
@@ -736,6 +740,10 @@ function(${SYSBUILD_CURRENT_MODULE_NAME}_post_cmake)
736740
include(${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/nrf700x.cmake)
737741
endif()
738742

743+
if(SB_CONFIG_SECURE_BOOT_BOOTCONF_LOCK_WRITES)
744+
include(${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/bootconf.cmake)
745+
endif()
746+
739747
if(SB_CONFIG_DFU_ZIP)
740748
if(SB_CONFIG_BOOTLOADER_MCUBOOT)
741749
include(${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/zip.cmake)

sysbuild/Kconfig.secureboot

+11
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,17 @@ config SECURE_BOOT_PUBLIC_KEY_FILES
339339
empty string then only the public key hash corresponding to the private signing key used
340340
to sign the image is included in provision.hex.
341341

342+
config SUPPORT_SECURE_BOOT_BOOTCONF_LOCK_WRITES
343+
bool
344+
depends on !FPROTECT_ALLOW_COMBINED_REGIONS
345+
default y if SOC_NRF54L15_CPUAPP
346+
347+
config SECURE_BOOT_BOOTCONF_LOCK_WRITES
348+
bool "Protect bootloader's NVM from writes"
349+
depends on SUPPORT_SECURE_BOOT_BOOTCONF_LOCK_WRITES
350+
help
351+
Sets RRAMC's BOOTCONF region protection to disable writes.
352+
342353
config SECURE_BOOT_DEBUG_SIGNATURE_PUBLIC_KEY_LAST
343354
bool "[DEBUG] Place signing public key last"
344355
default n

0 commit comments

Comments
 (0)