From c02fcc4a3849af4e534c8cf726562694f69b9a04 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 15 Jun 2016 13:53:50 +0100 Subject: BL1: Add linker symbol identifying end of ROM content This patch adds a new linker symbol in BL1's linker script named '__BL1_ROM_END__', which marks the end of BL1's ROM content. This covers BL1's code, read-only data and read-write data to relocate in Trusted SRAM. The address of this new linker symbol is exported to C code through the 'BL1_ROM_END' macro. The section related to linker symbols in the Firmware Design guide has been updated and improved. Change-Id: I5c442ff497c78d865ffba1d7d044511c134e11c7 --- docs/firmware-design.md | 67 +++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 36 deletions(-) (limited to 'docs/firmware-design.md') diff --git a/docs/firmware-design.md b/docs/firmware-design.md index 294349d9..575a822a 100644 --- a/docs/firmware-design.md +++ b/docs/firmware-design.md @@ -1052,10 +1052,10 @@ Each bootloader image can be divided in 2 parts: All PROGBITS sections are grouped together at the beginning of the image, followed by all NOBITS sections. This is true for all Trusted Firmware images and it is governed by the linker scripts. This ensures that the raw binary -images are as small as possible. If a NOBITS section would sneak in between -PROGBITS sections then the resulting binary file would contain a bunch of zero -bytes at the location of this NOBITS section, making the image unnecessarily -bigger. Smaller images allow faster loading from the FIP to the main memory. +images are as small as possible. If a NOBITS section was inserted in between +PROGBITS sections then the resulting binary file would contain zero bytes in +place of this NOBITS section, making the image unnecessarily bigger. Smaller +images allow faster loading from the FIP to the main memory. ### Linker scripts and symbols @@ -1110,47 +1110,42 @@ layout as they are easy to spot in the link map files. #### Common linker symbols -Early setup code needs to know the extents of the BSS section to zero-initialise -it before executing any C code. The following linker symbols are defined for -this purpose: +All BL images share the following requirements: -* `__BSS_START__` This address must be aligned on a 16-byte boundary. -* `__BSS_SIZE__` +* The BSS section must be zero-initialised before executing any C code. +* The coherent memory section (if enabled) must be zero-initialised as well. +* The MMU setup code needs to know the extents of the coherent and read-only + memory regions to set the right memory attributes. -Similarly, the coherent memory section (if enabled) must be zero-initialised. -Also, the MMU setup code needs to know the extents of this section to set the -right memory attributes for it. The following linker symbols are defined for -this purpose: +The following linker symbols are defined for this purpose: -* `__COHERENT_RAM_START__` This address must be aligned on a page-size boundary. -* `__COHERENT_RAM_END__` This address must be aligned on a page-size boundary. -* `__COHERENT_RAM_UNALIGNED_SIZE__` +* `__BSS_START__` Must be aligned on a 16-byte boundary. +* `__BSS_SIZE__` +* `__COHERENT_RAM_START__` Must be aligned on a page-size boundary. +* `__COHERENT_RAM_END__` Must be aligned on a page-size boundary. +* `__COHERENT_RAM_UNALIGNED_SIZE__` +* `__RO_START__` +* `__RO_END__` #### BL1's linker symbols -BL1's early setup code needs to know the extents of the .data section to -relocate it from ROM to RAM before executing any C code. The following linker -symbols are defined for this purpose: +BL1 being the ROM image, it has additional requirements. BL1 resides in ROM and +it is entirely executed in place but it needs some read-write memory for its +mutable data. Its `.data` section (i.e. its allocated read-write data) must be +relocated from ROM to RAM before executing any C code. -* `__DATA_ROM_START__` This address must be aligned on a 16-byte boundary. -* `__DATA_RAM_START__` This address must be aligned on a 16-byte boundary. -* `__DATA_SIZE__` +The following additional linker symbols are defined for BL1: -BL1's platform setup code needs to know the extents of its read-write data -region to figure out its memory layout. The following linker symbols are defined -for this purpose: +* `__BL1_ROM_END__` End address of BL1's ROM contents, covering its code + and `.data` section in ROM. +* `__DATA_ROM_START__` Start address of the `.data` section in ROM. Must be + aligned on a 16-byte boundary. +* `__DATA_RAM_START__` Address in RAM where the `.data` section should be + copied over. Must be aligned on a 16-byte boundary. +* `__DATA_SIZE__` Size of the `.data` section (in ROM or RAM). +* `__BL1_RAM_START__` Start address of BL1 read-write data. +* `__BL1_RAM_END__` End address of BL1 read-write data. -* `__BL1_RAM_START__` This is the start address of BL1 RW data. -* `__BL1_RAM_END__` This is the end address of BL1 RW data. - -#### BL2's, BL31's and TSP's linker symbols - -BL2, BL31 and TSP need to know the extents of their read-only section to set -the right memory attributes for this memory region in their MMU setup code. The -following linker symbols are defined for this purpose: - -* `__RO_START__` -* `__RO_END__` ### How to choose the right base addresses for each bootloader stage image -- cgit From 5d1c104f9aa7e1f52607679db96e5695cac266e7 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Fri, 8 Jul 2016 14:37:40 +0100 Subject: Introduce SEPARATE_CODE_AND_RODATA build flag At the moment, all BL images share a similar memory layout: they start with their code section, followed by their read-only data section. The two sections are contiguous in memory. Therefore, the end of the code section and the beginning of the read-only data one might share a memory page. This forces both to be mapped with the same memory attributes. As the code needs to be executable, this means that the read-only data stored on the same memory page as the code are executable as well. This could potentially be exploited as part of a security attack. This patch introduces a new build flag called SEPARATE_CODE_AND_RODATA, which isolates the code and read-only data on separate memory pages. This in turn allows independent control of the access permissions for the code and read-only data. This has an impact on memory footprint, as padding bytes need to be introduced between the code and read-only data to ensure the segragation of the two. To limit the memory cost, the memory layout of the read-only section has been changed in this case. - When SEPARATE_CODE_AND_RODATA=0, the layout is unchanged, i.e. the read-only section still looks like this (padding omitted): | ... | +-------------------+ | Exception vectors | +-------------------+ | Read-only data | +-------------------+ | Code | +-------------------+ BLx_BASE In this case, the linker script provides the limits of the whole read-only section. - When SEPARATE_CODE_AND_RODATA=1, the exception vectors and read-only data are swapped, such that the code and exception vectors are contiguous, followed by the read-only data. This gives the following new layout (padding omitted): | ... | +-------------------+ | Read-only data | +-------------------+ | Exception vectors | +-------------------+ | Code | +-------------------+ BLx_BASE In this case, the linker script now exports 2 sets of addresses instead: the limits of the code and the limits of the read-only data. Refer to the Firmware Design guide for more details. This provides platform code with a finer-grained view of the image layout and allows it to map these 2 regions with the appropriate access permissions. Note that SEPARATE_CODE_AND_RODATA applies to all BL images. Change-Id: I936cf80164f6b66b6ad52b8edacadc532c935a49 --- docs/firmware-design.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'docs/firmware-design.md') diff --git a/docs/firmware-design.md b/docs/firmware-design.md index 575a822a..b99a2838 100644 --- a/docs/firmware-design.md +++ b/docs/firmware-design.md @@ -1115,7 +1115,9 @@ All BL images share the following requirements: * The BSS section must be zero-initialised before executing any C code. * The coherent memory section (if enabled) must be zero-initialised as well. * The MMU setup code needs to know the extents of the coherent and read-only - memory regions to set the right memory attributes. + memory regions to set the right memory attributes. When + `SEPARATE_CODE_AND_RODATA=1`, it needs to know more specifically how the + read-only memory region is divided between code and data. The following linker symbols are defined for this purpose: @@ -1126,6 +1128,10 @@ The following linker symbols are defined for this purpose: * `__COHERENT_RAM_UNALIGNED_SIZE__` * `__RO_START__` * `__RO_END__` +* `__TEXT_START__` +* `__TEXT_END__` +* `__RODATA_START__` +* `__RODATA_END__` #### BL1's linker symbols -- cgit