build(bl31): support separated memory for RW DATA

Update linker file and init codes to allow using separated
memory region for RW DATA. Init codes will copy the RW DATA
from the image to the linked address.

On some NXP platforms, after the BL31 image has been verified,
the bl31 image space will be locked/protected as RO only, so
need to move the RW DATA and NOBITS out of the bl31 image.

Signed-off-by: Ye Li <ye.li@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Jacky Bai <ping.bai@nxp.com>
Change-Id: I361d9a715890961bf30790a3325f8085a40c0c39
This commit is contained in:
Ye Li 2022-08-26 13:48:31 +08:00 committed by Jacky Bai
parent 0a4cecadd7
commit 86acbbe2d8
4 changed files with 50 additions and 2 deletions

View file

@ -1189,6 +1189,7 @@ $(eval $(call assert_booleans,\
SEPARATE_CODE_AND_RODATA \
SEPARATE_BL2_NOLOAD_REGION \
SEPARATE_NOBITS_REGION \
SEPARATE_RWDATA_REGION \
SEPARATE_SIMD_SECTION \
SPIN_ON_BL1_EXIT \
SPM_MM \
@ -1367,6 +1368,7 @@ $(eval $(call add_defines,\
SEPARATE_CODE_AND_RODATA \
SEPARATE_BL2_NOLOAD_REGION \
SEPARATE_NOBITS_REGION \
SEPARATE_RWDATA_REGION \
SEPARATE_SIMD_SECTION \
RECLAIM_INIT_CODE \
SPD_${SPD} \

View file

@ -19,6 +19,12 @@ MEMORY {
#else /* SEPARATE_NOBITS_REGION */
# define NOBITS RAM
#endif /* SEPARATE_NOBITS_REGION */
#if SEPARATE_RWDATA_REGION
RAM_RW (rw): ORIGIN = BL31_RWDATA_BASE, LENGTH = BL31_RWDATA_LIMIT - BL31_RWDATA_BASE
#else /* SEPARATE_RWDATA_REGION */
#define RAM_RW RAM
#endif /* SEPARATE_RWDATA_REGION */
}
#ifdef PLAT_EXTRA_LD_SCRIPT
@ -136,10 +142,36 @@ SECTIONS {
. = LOADADDR(.spm_shim_exceptions) + SIZEOF(.spm_shim_exceptions);
#endif /* SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP) */
__RW_START__ = .;
#if SEPARATE_RWDATA_REGION
. = BL31_RWDATA_BASE;
ASSERT(BL31_RWDATA_BASE == ALIGN(PAGE_SIZE),
"BL31_RWDATA_BASE address is not aligned on a page boundary.")
/*
* Define a linker symbol to mark the start of the RW memory area for this
* image.
*/
__RW_START__ = . ;
DATA_SECTION >RAM_RW AT>RAM
__DATA_RAM_START__ = __DATA_START__;
__DATA_RAM_END__ = __DATA_END__;
__DATA_ROM_START__ = LOADADDR(.data);
. = ALIGN(PAGE_SIZE);
__RW_END__ = .;
RELA_SECTION >RAM
#else /* SEPARATE_RWDATA_REGION */
/*
* Define a linker symbol to mark the start of the RW memory area for this
* image.
*/
__RW_START__ = . ;
DATA_SECTION >RAM
RELA_SECTION >RAM
#endif /* SEPARATE_RWDATA_REGION */
#ifdef BL31_PROGBITS_LIMIT
ASSERT(
@ -151,7 +183,9 @@ SECTIONS {
#if SEPARATE_NOBITS_REGION
. = ALIGN(PAGE_SIZE);
#if !SEPARATE_RWDATA_REGION
__RW_END__ = .;
#endif /* SEPARATE_RWDATA_REGION */
__BL31_END__ = .;
ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
@ -203,7 +237,13 @@ SECTIONS {
ASSERT(. <= BL31_NOBITS_LIMIT, "BL31 NOBITS region has exceeded its limit.")
#else /* SEPARATE_NOBITS_REGION */
/*
* Define a linker symbol to mark the end of the RW memory area for this
* image.
*/
#if !SEPARATE_RWDATA_REGION
__RW_END__ = .;
#endif /* SEPARATE_RWDATA_REGION */
__BL31_END__ = .;
ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")

View file

@ -340,7 +340,9 @@
#endif
#if defined(IMAGE_BL1) || \
(defined(IMAGE_BL2) && RESET_TO_BL2 && BL2_IN_XIP_MEM)
(defined(IMAGE_BL2) && RESET_TO_BL2 && BL2_IN_XIP_MEM) || \
(defined(IMAGE_BL31) && SEPARATE_RWDATA_REGION)
adrp x0, __DATA_RAM_START__
add x0, x0, :lo12:__DATA_RAM_START__
adrp x1, __DATA_ROM_START__

View file

@ -240,6 +240,10 @@ SEPARATE_NOBITS_REGION := 0
# region, platform Makefile is free to override this value.
SEPARATE_BL2_NOLOAD_REGION := 0
# Put RW DATA sections (.rwdata) in a separate memory region, which may be
# discontiguous from the rest of BL31.
SEPARATE_RWDATA_REGION := 0
# Put SIMD context data structures in a separate memory region. Platforms
# have the choice to put it outside of default BSS region of EL3 firmware.
SEPARATE_SIMD_SECTION := 0