/usr/local/DS-5_v5.27.1/bin/FVP_MPS2_AEMv8M \--parameter fvp_mps2.platform_type=2 \--parameter cpu0.baseline=0 \--parameter cpu0.INITVTOR_S=0x10000000 \--parameter cpu0.semihosting-enable=0 \--parameter fvp_mps2.DISABLE_GATING=0 \--parameter fvp_mps2.telnetterminal0.start_telnet=1 \--parameter fvp_mps2.telnetterminal1.start_telnet=0 \--parameter fvp_mps2.telnetterminal2.start_telnet=0 \--parameter fvp_mps2.telnetterminal0.quiet=0 \--parameter fvp_mps2.telnetterminal1.quiet=1 \--parameter fvp_mps2.telnetterminal2.quiet=1 \--application cpu0=~/TF-M/trusted-firmware-m/cmake_build/bl2/ext/mcuboot/mcuboot.axf \--data cpu0=~/TF-M/trusted-firmware-m/cmake_build/tfm_sign.bin@0x10080000
This will load tfm_sign.bin to 0x10080000.
The 1MB tfm_sign.bin has such a layout:
<1024B header><512K tfm_s.bin + pad><511K tfm_ns.bin + TLV + pad>
Therefore, we know tfm_s.bin is loaded to 0x10080400, and tfm_ns.bin is loaded to 0x10100400.
From trusted-firmware-m/platform/ext/target/mps2/an521/partition/region_defs.h, we know
NS_CODE_START = 0x100400,
and comparing the memory starts from 0x10100400 and the memory starts from 0x100400, we know these two ranges have the same content. In other word, after start the FVP_MPS2_AEMv8M, tfm_ns.bin, which should locate at 0x10100400, is loaded/mapped to address 0x100400. My question is how is this implemented.
Another observation is the memory content of 0x100400 and 0x10100400 are always the same. If I change the data stored at 0x100400, the data at 0x10100400 also changes, and vice versa. How to explain this? Thanks.
1. It depends on the type of systems you are using.
For simple SoC design, the IDAU might provide all necessary information, and SAU only need to set ALLNS bit and enable bit in SAU_CTRL register to enable the Non-secure memory map.
For microcontrollers, the designs need to be much more flexible and potentially IDAU define large portions of memory as Non-secure, and Secure software override that to decide how much Secure memory space it needed. In that case programming of SAU region registers are needed.
2. There might be a typo in your question. Do you mean 0x10000000-0x1FFFFFFF is Secure?
Assumed that is the case, it also depends on the memory partitioning hardware design. The memory protection controller we used in our example system is outside of the processor and is a part of the CoreLink SDK-200. With this design, we use the memory alias approach so address 0x00100000 and 0x10100000 are mapped to the same address location in a memory block (could be flash, SRAM, etc. This is device specific). Many microcontroller designs follow the same approach, but this is not a strict requirement for using Armv8-M processors.
The memory protection controller (MPC) design can potentially mask out the Non-secure data from Secure alias. So if a Non-secure data is in 0x00100000 (Non-secure alias range), Secure software can only read the data via Non-secure alias, but not from the Secure alias (0x10100000). This is the recommended approach for Normal memory as this reduce the risk of code injection attacks.
It is entirely possible to use bit 28 of the address line to define security domain in the IDAU, and have different contents in the two space. The alias approach used by MPC allow us to dynamically remap memory pages between security domains. But if dynamic memory page configuration is not required, you can have entirely different memory devices allocated in these address spaces.